1
1
package bitFilter
2
2
3
3
import (
4
+ "fmt"
5
+ //"hash"
6
+ "encoding/binary"
7
+ "hash/fnv"
4
8
"testing"
5
9
)
6
10
7
11
var bits * TBits
8
12
var maxMask uint32
9
13
10
- func init () {
11
- bits = New (1024 )
12
- maxMask = 1024 << 3 - 1
13
- }
14
-
15
14
func TestFilter (t * testing.T ) {
16
- if len (bits .bytes ) != 1024 {
17
- t .Fatalf ("len bytes: %d != 2014" , len (bits .bytes ))
15
+ bits = New (128 )
16
+ maxMask = 128 << 6 - 1
17
+
18
+ if len (bits .buckets ) != 128 {
19
+ t .Fatalf ("len buckets: %d != 128" , len (bits .buckets ))
18
20
}
19
21
20
- bits .AddCollisionKeys ([]uint32 {0 , 1 , 2 , 3 , 4 , 8192 , 8193 , 8194 , 8195 , 8196 })
21
- bits .AddAllHashKeys ([]uint32 {0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 })
22
+ keys := []uint64 {0 , 1 , 2 , 3 , 4 , 8192 , 8193 , 8194 , 8195 , 8196 , 16385 }
23
+ collHashKeys := []uint32 {0 , 1 , 2 , 3 , 4 , 0 , 1 , 2 , 3 , 4 , 1 }
24
+ hashKeys := []uint32 {0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 }
25
+ bits .InitCollisionKeys (keys , collHashKeys )
26
+ bits .InitAllHashKeys (hashKeys )
22
27
23
- if len (bits .collision ) != 10 {
24
- t .Fatalf ("collision len != 10" )
28
+ if len (bits .collision ) != len ( collHashKeys ) {
29
+ t .Fatalf ("collision len != %d" , len ( collHashKeys ) )
25
30
}
26
31
27
- if bits .bytes [0 ] != 255 {
28
- t .Fatalf ("bytes [0]:%d != 255 " , bits .bytes [0 ])
32
+ if bits .buckets [0 ] != 1023 {
33
+ t .Fatalf ("buckets [0]:%d != 1023 " , bits .buckets [0 ])
29
34
}
30
35
31
- if bits .bytes [1 ] != 3 {
32
- t .Fatalf ("bytes [1]:%d != 3 " , bits .bytes [1 ])
36
+ if bits .buckets [1 ] != 0 {
37
+ t .Fatalf ("buckets [1]:%d != 0 " , bits .buckets [1 ])
33
38
}
34
39
35
- var i , hashKey uint32
36
- var exist bool
40
+ var (
41
+ i uint64
42
+ hashKey uint32
43
+ exist bool
44
+ )
37
45
for i = 0 ; i < 10000 ; i ++ {
38
- hashKey = i & maxMask
46
+ hashKey = uint32 ( i ) & maxMask
39
47
//println(i, hashKey)
40
48
exist = bits .Filter (i , hashKey )
41
49
if hashKey < 10 {
@@ -49,3 +57,103 @@ func TestFilter(t *testing.T) {
49
57
}
50
58
}
51
59
}
60
+
61
+ func TestNew (t * testing.T ) {
62
+ newBits := bits .Copy ()
63
+
64
+ if len (newBits .collision ) != 11 {
65
+ t .Fatalf ("collision len != 11" )
66
+ }
67
+
68
+ if newBits .buckets [0 ] != 1023 {
69
+ t .Fatalf ("buckets[0]:%d != 1023" , newBits .buckets [0 ])
70
+ }
71
+
72
+ if newBits .buckets [1 ] != 0 {
73
+ t .Fatalf ("buckets[1]:%d != 0" , newBits .buckets [1 ])
74
+ }
75
+
76
+ newBits .Remove (8192 , 0 )
77
+
78
+ if len (newBits .collision ) != 9 {
79
+ t .Fatalf ("collision len:9 != %d" , len (newBits .collision ))
80
+ }
81
+
82
+ if newBits .buckets [0 ] != 1023 {
83
+ t .Fatalf ("buckets[0]:%d != 1023" , newBits .buckets [0 ])
84
+ }
85
+
86
+ if isExist := newBits .Filter (8192 , 0 ); ! isExist {
87
+ // 8192这个值虽然remove了,但是0这个值还没remove
88
+ // 所以这里还是存在的,这是误判
89
+ t .Fatalf ("error" )
90
+ }
91
+
92
+ newBits .Remove (0 , 0 )
93
+ if isExist := newBits .Filter (0 , 0 ); isExist {
94
+ t .Fatalf ("error" )
95
+ }
96
+
97
+ if newBits .buckets [0 ] != 1022 {
98
+ t .Fatalf ("buckets[0]:%d != 1022" , newBits .buckets [0 ])
99
+ }
100
+
101
+ newBits .Remove (16385 , 1 )
102
+ if len (newBits .collision ) != 8 {
103
+ t .Fatalf ("collision len:8 != %d" , len (newBits .collision ))
104
+ }
105
+
106
+ if isExist := newBits .Filter (1 , 1 ); ! isExist {
107
+ t .Fatalf ("error" )
108
+ }
109
+
110
+ if newBits .buckets [0 ] != 1022 {
111
+ t .Fatalf ("buckets[0]:%d != 1022" , newBits .buckets [0 ])
112
+ }
113
+
114
+ }
115
+
116
+ func TestRand (t * testing.T ) {
117
+ bits = New (Size2MB )
118
+ maxMask = uint32 (Size2MB << 6 - 1 )
119
+
120
+ var exist = make (map [uint32 ]bool )
121
+ var errorCount int
122
+ var projectId , posId , n1 , n2 uint32
123
+ var b1 = make ([]byte , 4 )
124
+ var b2 = make ([]byte , 4 )
125
+ alg := fnv .New32a ()
126
+ n1 , n2 = 68000 , 100
127
+ for projectId = 1 ; projectId < n1 ; projectId ++ {
128
+ binary .BigEndian .PutUint32 (b1 , projectId )
129
+ for posId = 1 ; posId < n2 ; posId ++ {
130
+ binary .BigEndian .PutUint32 (b2 , posId )
131
+ alg .Reset ()
132
+ alg .Write (append (b1 , b2 ... ))
133
+ hashKey := alg .Sum32 ()
134
+ hashKey = hashKey << 6 - 1
135
+ if _ , ok := exist [hashKey ]; ok {
136
+ errorCount ++
137
+ } else {
138
+ exist [hashKey ] = true
139
+ }
140
+ }
141
+ }
142
+
143
+ fmt .Printf ("Error Count: %d in %d*%d\n Error Rate: %f\n " , errorCount , n1 , n2 , float32 (errorCount )/ (float32 (n1 )* float32 (n2 )))
144
+
145
+ projectId , posId = 32314 , 23413
146
+ binary .BigEndian .PutUint32 (b1 , projectId )
147
+ binary .BigEndian .PutUint32 (b2 , posId )
148
+ alg .Reset ()
149
+ alg .Write (append (b1 , b2 ... ))
150
+ fmt .Printf ("fnv.New32a: %d, %d: %d\n " , projectId , posId , alg .Sum32 ()& maxMask )
151
+ }
152
+
153
+ func BenchmarkFilter (b * testing.B ) {
154
+ b .RunParallel (func (pb * testing.PB ) {
155
+ for pb .Next () {
156
+ _ = bits .Filter (1234 , 43 )
157
+ }
158
+ })
159
+ }
0 commit comments