-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathvshard.go
76 lines (57 loc) · 1.35 KB
/
vshard.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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
package goconsist
import "net/netip"
type section struct {
min uint32
max uint32
serverAddr netip.AddrPort
}
func (v section) more(x uint32) bool {
return x > v.max
}
func (v section) less(x uint32) bool {
return x < v.min
}
func (v section) between(x uint32) bool {
// NOTE: corner case where maxFactor is end of ring and equals to zero.
if (v.min > v.max) && x >= v.min {
return true
}
return x >= v.min && x <= v.max
}
// Search for specific section in the ring.
//
// NOTE: If target valued does not fit into any section of the ring
// the last vhsard will be returned.
func search(list []section, target uint32) (section, bool) {
l, r := 0, len(list)-1
for l <= r {
mid := l + (r-l)/2
curr := list[mid]
if curr.between(target) {
return curr, true
}
if curr.less(target) {
r = mid - 1
continue
}
if curr.more(target) {
l = mid + 1
continue
}
}
return section{}, false
}
// Distribute ranges across ring.
func distribute(sectionFactor, sectionCount uint32) []section {
ranges := make([]section, 0, sectionCount)
start := uint32(0)
for i := 0; i < int(sectionCount)-1; i++ {
next := start + sectionFactor
vshard := section{min: start, max: next}
start = next + 1
ranges = append(ranges, vshard)
}
lastShard := section{min: start, max: 0}
ranges = append(ranges, lastShard)
return ranges
}