pcm-coordinator/api/internal/scheduler/algorithm/weightDistributing/weightDistributing.go

79 lines
1.2 KiB
Go

package weightDistributing
import (
"errors"
"math"
)
type Weight struct {
Id string
Weight int32
Replica int32
}
func DistributeReplicas(weights []*Weight, replicas int32) error {
var weightSum int32
weightSum = 0
for _, w := range weights {
weightSum += w.Weight
}
if weightSum == 0 {
return errors.New("static weights are empty")
}
weightRatio := make([]float64, len(weights))
for i, w := range weights {
weightRatio[i] = float64(w.Weight) / float64(weightSum)
}
var rest = replicas
for i := 0; i < len(weights); i++ {
var n = math.Round(float64(replicas) * weightRatio[i])
rest -= int32(n)
weights[i].Replica = int32(n)
}
for {
if rest == 0 {
break
}
maxIdx := 0
minIdx := 0
if rest > 0 {
for i, ratio := range weightRatio {
if ratio > weightRatio[maxIdx] {
maxIdx = i
}
}
} else {
for i, ratio := range weightRatio {
if ratio < weightRatio[minIdx] {
minIdx = i
}
}
}
if rest > 0 {
weights[maxIdx].Replica++
weightRatio[maxIdx]--
rest--
} else {
if weights[minIdx].Replica == 0 {
weightRatio[minIdx]++
continue
}
weights[minIdx].Replica--
weightRatio[minIdx]++
rest++
}
}
return nil
}