-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfilter.go
63 lines (50 loc) · 1.14 KB
/
filter.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
package filter
import (
"hash"
"hash/fnv"
"github.com/zentures/cityhash"
)
// Filter is a bloom filter
type Filter struct {
bits []bool //TODO: bool is 8 bits wide, need single bit implementation
n uint //Number of elements
hashFuncs []hash.Hash64 // hash functions
}
// New Filter with size s
func New(s uint) *Filter {
return &Filter{
bits: make([]bool, s),
n: uint(0),
hashFuncs: []hash.Hash64{cityhash.New64(), fnv.New64(), fnv.New64a()},
}
}
// Add an item as []byte to the filter
func (f *Filter) Add(item []byte) {
hashes := f.hashes(item)
for _, h := range hashes {
p := h % uint64(len(f.bits))
f.bits[p] = true
}
f.n++
}
// Lookup if an item as []byte matches the contents of the filter
// (can result in false positives)
func (f *Filter) Lookup(item []byte) bool {
hashes := f.hashes(item)
for _, h := range hashes {
p := h % uint64(len(f.bits))
if !f.bits[p] {
return false
}
}
return true
}
func (f *Filter) hashes(item []byte) []uint64 {
var h []uint64
for _, hf := range f.hashFuncs {
hf.Write(item)
h = append(h, hf.Sum64())
hf.Reset()
}
return h
}