fix(scheduler): consider perfer and avoid score when sorting HostPriorityList

This commit is contained in:
rainzm
2021-12-03 14:54:48 +08:00
parent a66adb55e7
commit 02656f6c59
4 changed files with 23 additions and 86 deletions
+10 -7
View File
@@ -26,7 +26,6 @@ import (
schedapi "yunion.io/x/onecloud/pkg/apis/scheduler"
"yunion.io/x/onecloud/pkg/compute/models"
"yunion.io/x/onecloud/pkg/scheduler/api"
"yunion.io/x/onecloud/pkg/scheduler/core/score"
)
func transToInstanceGroupSchedResult(result *SchedResultItemList, schedInfo *api.SchedInfo) *schedapi.ScheduleOutput {
@@ -123,16 +122,20 @@ func sortHosts(hosts []*sSchedResultItem, guestInfo *sGuestInfo, isBackup *bool)
// scoreNormalization compare the value of s1 and s2.
// If s1 is less than s2, return 1, 0 which means s2 is better than s1.
func scoreNormalization(s1, s2 Score) (int64, int64) {
sb1, sb2 := s1.ScoreBucket, s2.ScoreBucket
preferLess := score.PreferLess(sb1, sb2)
avoidLess := score.AvoidLess(sb1, sb2)
normalLess := score.AvoidLess(sb1, sb2)
if preferLess || normalLess {
preferScore1, preferScore2 := s1.PreferScore()-s1.AvoidScore(), s2.PreferScore()-s2.AvoidScore()
normalScore1, normalScore2 := s1.NormalScore(), s2.NormalScore()
if preferScore1 < preferScore2 {
return 0, 1
}
if preferScore1 > preferScore2 {
return 1, 0
}
if avoidLess {
if normalScore1 < normalScore2 {
return 0, 1
}
if normalScore1 > normalScore2 {
return 1, 0
}
return 0, 0
}
+6 -10
View File
@@ -104,20 +104,16 @@ func (b *ScoreBucket) SetScore(score SScore, prefer tristate.TriState) *ScoreBuc
return b
}
func PreferLess(b1, b2 *ScoreBucket) bool {
return b1.preferScore.Total() < b2.preferScore.Total()
func (b *ScoreBucket) PreferScore() int {
return b.preferScore.Total()
}
func AvoidLess(b1, b2 *ScoreBucket) bool {
return b1.avoidScore.Total() < b2.avoidScore.Total()
func (b *ScoreBucket) AvoidScore() int {
return b.avoidScore.Total()
}
func NormalLess(b1, b2 *ScoreBucket) bool {
return b1.normalScore.Total() < b2.normalScore.Total()
}
func NormalEqual(b1, b2 *ScoreBucket) bool {
return b1.normalScore.Total() == b2.normalScore.Total()
func (b *ScoreBucket) NormalScore() int {
return b.normalScore.Total()
}
func (b *ScoreBucket) debugString(kind string, vals map[string]int) string {
-60
View File
@@ -1,60 +0,0 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package score
import (
"testing"
"yunion.io/x/pkg/tristate"
)
func TestLess(t *testing.T) {
type args struct {
b1 *ScoreBucket
b2 *ScoreBucket
lessFunc func(s1, s2 *ScoreBucket) bool
}
tests := []struct {
name string
args args
want bool
}{
{
name: "equal",
args: args{
b1: NewScoreBuckets(),
b2: NewScoreBuckets(),
lessFunc: NormalLess,
},
want: false,
},
{
name: "less",
args: args{
b1: NewScoreBuckets().SetScore(SScore{1, "p1"}, tristate.True),
b2: NewScoreBuckets().SetScore(SScore{1, "p1"}, tristate.True).SetScore(SScore{2, "p2"}, tristate.True),
lessFunc: PreferLess,
},
want: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := tt.args.lessFunc(tt.args.b1, tt.args.b2); got != tt.want {
t.Errorf("Less() = %v, want %v", got, tt.want)
}
})
}
}
+7 -9
View File
@@ -157,19 +157,17 @@ func (h HostPriorityList) Len() int {
func (h HostPriorityList) Less(i, j int) bool {
s1 := h[i].Score.ScoreBucket
s2 := h[j].Score.ScoreBucket
preferLess := score.PreferLess(s1, s2)
avoidLess := score.AvoidLess(s1, s2)
preferScorei, preferScorej := s1.PreferScore()-s1.AvoidScore(), s2.PreferScore()-s1.AvoidScore()
if preferLess {
return true
if preferScorei != preferScorej {
return preferScorei < preferScorej
}
if avoidLess {
return false
}
if score.NormalEqual(s1, s2) {
normalScorei, normalScorej := s1.NormalScore(), s2.NormalScore()
if normalScorei == normalScorej {
return h[i].Host < h[j].Host
}
return score.NormalLess(s1, s2)
return normalScorei < normalScorej
}
func (h HostPriorityList) Swap(i, j int) {