-
Notifications
You must be signed in to change notification settings - Fork 25
/
uhamt_test.go
57 lines (50 loc) · 1.19 KB
/
uhamt_test.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
package hamt
import (
"math/big"
"math/bits"
"math/rand"
"testing"
)
func TestIndexForBitRandom(t *testing.T) {
t.Parallel()
r := rand.New(rand.NewSource(int64(42)))
count := 100000
slot := make([]byte, 32)
for i := 0; i < count; i++ {
_, err := r.Read(slot)
if err != nil {
t.Fatal("couldn't create random bitfield")
}
bi := big.NewInt(0).SetBytes(slot)
for k := 0; k < 256; k++ {
if indexForBitPos(k, bi) != indexForBitPosOriginal(k, bi) {
t.Fatalf("indexForBit doesn't match with original")
}
}
}
}
func TestIndexForBitLinear(t *testing.T) {
t.Parallel()
var i int64
for i = 0; i < 1<<16-1; i++ {
bi := big.NewInt(i)
for k := 0; k < 16; k++ {
if indexForBitPos(k, bi) != indexForBitPosOriginal(k, bi) {
t.Fatalf("indexForBit doesn't match with original")
}
}
}
}
// Original implementation of indexForBit, before #39.
func indexForBitPosOriginal(bp int, bitfield *big.Int) int {
mask := new(big.Int).Sub(new(big.Int).Exp(big.NewInt(2), big.NewInt(int64(bp)), nil), big.NewInt(1))
mask.And(mask, bitfield)
return popCount(mask)
}
func popCount(i *big.Int) int {
var n int
for _, v := range i.Bits() {
n += bits.OnesCount64(uint64(v))
}
return n
}