-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathutils.go
75 lines (61 loc) · 1.63 KB
/
utils.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
package chord
import (
"bytes"
"math/big"
)
// Checks if a key is STRICTLY between two IDs exclusively
func between(id1, id2, key []byte) bool {
// Check for ring wrap around
if bytes.Compare(id1, id2) == 1 {
return bytes.Compare(id1, key) == -1 ||
bytes.Compare(id2, key) == 1
}
// Handle the normal case
return bytes.Compare(id1, key) == -1 &&
bytes.Compare(id2, key) == 1
}
// Checks if a key is between two IDs, left inclusive
func betweenLeftIncl(id1, id2, key []byte) bool {
// Check for ring wrap around
if bytes.Compare(id1, id2) == 1 {
return bytes.Compare(id1, key) <= 0 ||
bytes.Compare(id2, key) == 1
}
// Handle the normal case
return bytes.Compare(id1, key) <= 0 &&
bytes.Compare(id2, key) == 1
}
// Checks if a key is between two IDs, right inclusive
func betweenRightIncl(id1, id2, key []byte) bool {
// Check for ring wrap around
if bytes.Compare(id1, id2) == 1 {
return bytes.Compare(id1, key) == -1 ||
bytes.Compare(id2, key) >= 0
}
// Handle the normal case
return bytes.Compare(id1, key) == -1 &&
bytes.Compare(id2, key) >= 0
}
// Computes the offset by (n + 2^exp) % (2^mod)
func powerOffset(id []byte, exp int, mod int) []byte {
// Copy the existing slice
off := make([]byte, len(id))
copy(off, id)
// Convert the ID to a bigint
idInt := big.Int{}
idInt.SetBytes(id)
// Get the offset
two := big.NewInt(2)
offset := big.Int{}
offset.Exp(two, big.NewInt(int64(exp)), nil)
// Sum
sum := big.Int{}
sum.Add(&idInt, &offset)
// Get the ceiling
ceil := big.Int{}
ceil.Exp(two, big.NewInt(int64(mod)), nil)
// Apply the mod
idInt.Mod(&sum, &ceil)
// Add together
return idInt.Bytes()
}