@@ -20,6 +20,8 @@ import (
2020 "context"
2121 "time"
2222
23+ "github.com/emirpasic/gods/maps/treemap"
24+
2325 clusterv1alpha1 "github.com/karmada-io/karmada/pkg/apis/cluster/v1alpha1"
2426 workv1alpha2 "github.com/karmada-io/karmada/pkg/apis/work/v1alpha2"
2527)
@@ -30,26 +32,83 @@ import (
3032const UnauthenticReplica = - 1
3133
3234var (
33- replicaEstimators = map [string ]ReplicaEstimator {}
34- unschedulableReplicaEstimators = map [string ]UnschedulableReplicaEstimator {}
35+ // replicaEstimators are organized in a TreeMap, sorted by descending priority.
36+ // The key is of type EstimatorPriority, indicating the estimator's priority level.
37+ // The value is a map with string keys and ReplicaEstimator values, grouping estimators by their respective priorities.
38+ replicaEstimators = treemap .NewWith (estimatorPriorityComparator )
39+
40+ // unschedulableReplicaEstimators are organized in a TreeMap, sorted by descending priority.
41+ // The key is of type EstimatorPriority, indicating the estimator's priority level.
42+ // The value is a map with string keys and UnschedulableReplicaEstimator values, grouping estimators by their respective priorities.
43+ unschedulableReplicaEstimators = treemap .NewWith (estimatorPriorityComparator )
3544)
3645
46+ // registerReplicaEstimator add a estimator to replicaEstimators
47+ func registerReplicaEstimator (estimatorName string , estimator ReplicaEstimator ) {
48+ if val , ok := replicaEstimators .Get (estimator .Priority ()); ! ok {
49+ replicaEstimators .Put (estimator .Priority (), map [string ]ReplicaEstimator {estimatorName : estimator })
50+ } else {
51+ estimatorsWithSamePriority := val .(map [string ]ReplicaEstimator )
52+ estimatorsWithSamePriority [estimatorName ] = estimator
53+ }
54+ }
55+
56+ // registerUnschedulableReplicaEstimator add a estimator to unschedulableReplicaEstimators
57+ func registerUnschedulableReplicaEstimator (estimatorName string , estimator UnschedulableReplicaEstimator ) {
58+ if val , ok := unschedulableReplicaEstimators .Get (estimator .Priority ()); ! ok {
59+ unschedulableReplicaEstimators .Put (estimator .Priority (), map [string ]UnschedulableReplicaEstimator {estimatorName : estimator })
60+ } else {
61+ estimatorsWithSamePriority := val .(map [string ]UnschedulableReplicaEstimator )
62+ estimatorsWithSamePriority [estimatorName ] = estimator
63+ }
64+ }
65+
3766// ReplicaEstimator is an estimator which estimates the maximum replicas that can be applied to the target cluster.
3867type ReplicaEstimator interface {
3968 MaxAvailableReplicas (ctx context.Context , clusters []* clusterv1alpha1.Cluster , replicaRequirements * workv1alpha2.ReplicaRequirements ) ([]workv1alpha2.TargetCluster , error )
69+ Priority () EstimatorPriority
4070}
4171
4272// UnschedulableReplicaEstimator is an estimator which estimates the unschedulable replicas which belong to a specified workload.
4373type UnschedulableReplicaEstimator interface {
4474 GetUnschedulableReplicas (ctx context.Context , clusters []string , reference * workv1alpha2.ObjectReference , unschedulableThreshold time.Duration ) ([]workv1alpha2.TargetCluster , error )
75+ Priority () EstimatorPriority
4576}
4677
4778// GetReplicaEstimators returns all replica estimators.
48- func GetReplicaEstimators () map [ string ] ReplicaEstimator {
79+ func GetReplicaEstimators () * treemap. Map {
4980 return replicaEstimators
5081}
5182
5283// GetUnschedulableReplicaEstimators returns all unschedulable replica estimators.
53- func GetUnschedulableReplicaEstimators () map [ string ] UnschedulableReplicaEstimator {
84+ func GetUnschedulableReplicaEstimators () * treemap. Map {
5485 return unschedulableReplicaEstimators
5586}
87+
88+ // EstimatorPriority the priority of estimator
89+ // 1. If two estimators are of the same priority, call both and choose the minimum value of each estimated result.
90+ // 2. If higher-priority estimators have formed a full result of member clusters, no longer to call lower-priority estimator.
91+ // 3. If higher-priority estimators haven't given the result for certain member clusters, lower-priority estimator will
92+ // continue to estimate for such clusters haven't got a result.
93+ type EstimatorPriority int32
94+
95+ const (
96+ // General general priority, e.g: ResourceModel
97+ General EstimatorPriority = 10
98+ // Accurate accurate priority, e.g: SchedulerEstimator
99+ Accurate EstimatorPriority = 20
100+ )
101+
102+ // estimatorPriorityComparator provides a basic comparison on EstimatorPriority.
103+ func estimatorPriorityComparator (a , b interface {}) int {
104+ aAsserted := a .(EstimatorPriority )
105+ bAsserted := b .(EstimatorPriority )
106+ switch {
107+ case aAsserted > bAsserted :
108+ return - 1
109+ case aAsserted < bAsserted :
110+ return 1
111+ default :
112+ return 0
113+ }
114+ }
0 commit comments