...
1 package targets
2
3 import (
4 "fmt"
5 "strconv"
6 "strings"
7 )
8
9 const MinDelegationHashPrefixBitLen = 1
10 const MaxDelegationHashPrefixBitLen = 32
11
12
13
14 func hexEncode(x uint64, padWidth int) string {
15
16 s := strconv.FormatUint(x, 16)
17 if len(s) >= padWidth {
18 return s
19 }
20 return strings.Repeat("0", padWidth-len(s)) + s
21 }
22
23 const bitsPerHexDigit = 4
24
25
26
27 func numHexDigits(numBits int) int {
28
29 return ((numBits - 1) / bitsPerHexDigit) + 1
30 }
31
32
33
34
35 type HashBins struct {
36 rolePrefix string
37 bitLen int
38 hexDigitLen int
39
40 numBins uint64
41 numPrefixesPerBin uint64
42 }
43
44
45 func NewHashBins(rolePrefix string, bitLen int) (*HashBins, error) {
46 if bitLen < MinDelegationHashPrefixBitLen || bitLen > MaxDelegationHashPrefixBitLen {
47 return nil, fmt.Errorf("bitLen is out of bounds, should be between %v and %v inclusive", MinDelegationHashPrefixBitLen, MaxDelegationHashPrefixBitLen)
48 }
49
50 hexDigitLen := numHexDigits(bitLen)
51 numBins := uint64(1) << bitLen
52
53 numPrefixesTotal := uint64(1) << (bitsPerHexDigit * hexDigitLen)
54 numPrefixesPerBin := numPrefixesTotal / numBins
55
56 return &HashBins{
57 rolePrefix: rolePrefix,
58 bitLen: bitLen,
59 hexDigitLen: hexDigitLen,
60 numBins: numBins,
61 numPrefixesPerBin: numPrefixesPerBin,
62 }, nil
63 }
64
65
66 func (hb *HashBins) NumBins() uint64 {
67 return hb.numBins
68 }
69
70
71 func (hb *HashBins) GetBin(i uint64) *HashBin {
72 if i >= hb.numBins {
73 return nil
74 }
75
76 return &HashBin{
77 rolePrefix: hb.rolePrefix,
78 hexDigitLen: hb.hexDigitLen,
79 first: i * hb.numPrefixesPerBin,
80 last: ((i + 1) * hb.numPrefixesPerBin) - 1,
81 }
82 }
83
84
85 type HashBin struct {
86 rolePrefix string
87 hexDigitLen int
88 first uint64
89 last uint64
90 }
91
92
93 func (b *HashBin) RoleName() string {
94 if b.first == b.last {
95 return b.rolePrefix + hexEncode(b.first, b.hexDigitLen)
96 }
97
98 return b.rolePrefix + hexEncode(b.first, b.hexDigitLen) + "-" + hexEncode(b.last, b.hexDigitLen)
99 }
100
101
102 func (b *HashBin) HashPrefixes() []string {
103 n := int(b.last - b.first + 1)
104 ret := make([]string, int(n))
105
106 x := b.first
107 for i := 0; i < n; i++ {
108 ret[i] = hexEncode(x, b.hexDigitLen)
109 x++
110 }
111
112 return ret
113 }
114
View as plain text