-
Notifications
You must be signed in to change notification settings - Fork 1
/
wr.go
58 lines (48 loc) · 942 Bytes
/
wr.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
package balancer
import (
"sort"
"github.com/fufuok/load-balancer/utils"
)
// WeightedRand
type wr struct {
items []*Choice
weights []int
count int
max uint32
}
func NewWeightedRand(choices ...*Choice) (lb *wr) {
lb = &wr{}
lb.Update(choices)
return
}
func (b *wr) Select(_ ...string) (item interface{}) {
switch b.count {
case 0:
item = nil
case 1:
item = b.items[0].Item
default:
r := utils.FastRandn(b.max) + 1
i := utils.SearchInts(b.weights, int(r))
item = b.items[i].Item
}
return
}
func (b *wr) Name() string {
return "WeightedRand"
}
func (b *wr) Update(choices []*Choice) bool {
b.items, b.count = cleanWeight(choices)
sort.Slice(b.items, func(i, j int) bool {
return b.items[i].Weight < b.items[j].Weight
})
max := 0
weights := make([]int, b.count)
for i := range b.items {
max += b.items[i].Weight
weights[i] = max
}
b.weights = weights
b.max = uint32(max)
return true
}