@@ -30,7 +30,7 @@ type bloom struct {
30
30
schema string
31
31
storage string
32
32
prob float64
33
- nfilter int64
33
+ bytes int64
34
34
hashes int
35
35
}
36
36
@@ -41,15 +41,17 @@ func create(db *sqlite3.Conn, _, schema, table string, arg ...string) (_ *bloom,
41
41
storage : table + "_storage" ,
42
42
}
43
43
44
- nelem := 100
44
+ var nelem int64
45
45
if len (arg ) > 0 {
46
- nelem , err = strconv .Atoi (arg [0 ])
46
+ nelem , err = strconv .ParseInt (arg [0 ], 10 , 64 )
47
47
if err != nil {
48
48
return nil , err
49
49
}
50
50
if nelem <= 0 {
51
51
return nil , errors .New ("bloom: number of elements in filter must be positive" )
52
52
}
53
+ } else {
54
+ nelem = 100
53
55
}
54
56
55
57
if len (arg ) > 1 {
@@ -73,10 +75,10 @@ func create(db *sqlite3.Conn, _, schema, table string, arg ...string) (_ *bloom,
73
75
return nil , errors .New ("bloom: number of hash functions must be positive" )
74
76
}
75
77
} else {
76
- t .hashes = int ( math . Round ( - math . Log2 ( t .prob ) ))
78
+ t .hashes = max ( 1 , numHashes ( t .prob ))
77
79
}
78
80
79
- t .nfilter = computeLength (nelem , t .prob )
81
+ t .bytes = numBytes (nelem , t .prob )
80
82
81
83
err = db .Exec (fmt .Sprintf (
82
84
`CREATE TABLE %s.%s (data BLOB, p REAL, n INTEGER, m INTEGER, k INTEGER)` ,
@@ -89,7 +91,7 @@ func create(db *sqlite3.Conn, _, schema, table string, arg ...string) (_ *bloom,
89
91
`INSERT INTO %s.%s (rowid, data, p, n, m, k)
90
92
VALUES (1, zeroblob(%d), %f, %d, %d, %d)` ,
91
93
sqlite3 .QuoteIdentifier (t .schema ), sqlite3 .QuoteIdentifier (t .storage ),
92
- t .nfilter , t .prob , nelem , t . nfilter * 8 , t .hashes ))
94
+ t .bytes , t .prob , nelem , 8 * t . bytes , t .hashes ))
93
95
if err != nil {
94
96
return nil , err
95
97
}
@@ -131,7 +133,7 @@ func connect(db *sqlite3.Conn, _, schema, table string, arg ...string) (_ *bloom
131
133
return nil , err
132
134
}
133
135
134
- t .nfilter = load .ColumnInt64 (0 )
136
+ t .bytes = load .ColumnInt64 (0 )
135
137
t .prob = load .ColumnFloat (1 )
136
138
t .hashes = load .ColumnInt (2 )
137
139
return & t , nil
@@ -188,7 +190,7 @@ func (b *bloom) Update(arg ...sqlite3.Value) (rowid int64, err error) {
188
190
189
191
for n := 0 ; n < b .hashes ; n ++ {
190
192
hash := calcHash (n , blob )
191
- hash %= uint64 (b .nfilter * 8 )
193
+ hash %= uint64 (b .bytes * 8 )
192
194
bitpos := byte (hash % 8 )
193
195
bytepos := int64 (hash / 8 )
194
196
@@ -202,7 +204,7 @@ func (b *bloom) Update(arg ...sqlite3.Value) (rowid int64, err error) {
202
204
return 0 , err
203
205
}
204
206
205
- buf [0 ] |= ( 1 << bitpos )
207
+ buf [0 ] |= 1 << bitpos
206
208
207
209
_ , err = f .Seek (bytepos , io .SeekStart )
208
210
if err != nil {
@@ -241,9 +243,9 @@ func (c *cursor) Filter(idxNum int, idxStr string, arg ...sqlite3.Value) error {
241
243
}
242
244
defer f .Close ()
243
245
244
- for n := 0 ; n < c .hashes ; n ++ {
246
+ for n := 0 ; n < c .hashes && ! c . eof ; n ++ {
245
247
hash := calcHash (n , blob )
246
- hash %= uint64 (c .nfilter * 8 )
248
+ hash %= uint64 (c .bytes * 8 )
247
249
bitpos := byte (hash % 8 )
248
250
bytepos := int64 (hash / 8 )
249
251
@@ -257,10 +259,7 @@ func (c *cursor) Filter(idxNum int, idxStr string, arg ...sqlite3.Value) error {
257
259
return err
258
260
}
259
261
260
- c .eof = (buf [0 ] & (1 << bitpos )) == 0
261
- if c .eof {
262
- break
263
- }
262
+ c .eof = buf [0 ]& (1 << bitpos ) == 0
264
263
}
265
264
return nil
266
265
}
@@ -294,7 +293,12 @@ func calcHash(k int, b []byte) uint64 {
294
293
return siphash .Hash (^ uint64 (k ), uint64 (k ), b )
295
294
}
296
295
297
- func computeLength (n int , p float64 ) int64 {
298
- bits := math .Ceil (- ((float64 (n ) * math .Log (p )) / (math .Ln2 * math .Ln2 )))
299
- return (int64 (bits ) + 7 ) / 8
296
+ func numHashes (p float64 ) int {
297
+ k := math .Round (- math .Log2 (p ))
298
+ return max (1 , int (k ))
299
+ }
300
+
301
+ func numBytes (n int64 , p float64 ) int64 {
302
+ m := math .Ceil (float64 (n ) * math .Log (p ) / - (math .Ln2 * math .Ln2 ))
303
+ return (int64 (m ) + 7 ) / 8
300
304
}
0 commit comments