-
Notifications
You must be signed in to change notification settings - Fork 0
/
weight_table.go
55 lines (43 loc) · 1.19 KB
/
weight_table.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
package balancer
type weightTable[T any] struct {
storedValues []T
weights []weightTableEntry
totalWeight uint64
}
type weightTableEntry struct {
start uint64
end uint64
storedValuesIdx int
}
func newWeightTable[T any](weightedValues []WeightedValue[T]) *weightTable[T] {
if len(weightedValues) < 1 {
return &weightTable[T]{totalWeight: 1}
}
storedValues := make([]T, len(weightedValues))
weights := make([]weightTableEntry, len(weightedValues))
currentWeight := uint64(0)
for idx, weightedValue := range weightedValues {
weights[idx] = weightTableEntry{
start: currentWeight,
end: currentWeight + uint64(weightedValue.Weight),
storedValuesIdx: idx,
}
storedValues[idx] = weightedValue.Value
currentWeight += uint64(weightedValue.Weight)
}
return &weightTable[T]{
storedValues: storedValues,
weights: weights,
totalWeight: currentWeight,
}
}
func (w *weightTable[T]) get(i uint64) T {
weightIndex := i % w.totalWeight
for _, entry := range w.weights {
if entry.start <= weightIndex && weightIndex < entry.end {
return w.storedValues[entry.storedValuesIdx]
}
}
var zeroValue T
return zeroValue
}