diff --git a/blocks/bloom/filter.go b/blocks/bloom/filter.go new file mode 100644 index 000000000..853bad5e4 --- /dev/null +++ b/blocks/bloom/filter.go @@ -0,0 +1,70 @@ +package bloom + +import ( + "fmt" + "hash" + "hash/adler32" + "hash/crc32" + "hash/fnv" + "math/big" +) + +type Filter interface { + Add([]byte) + Find([]byte) bool +} + +func BasicFilter() Filter { + // Non crypto hashes, because speed + return NewFilter(2048, adler32.New(), fnv.New32(), crc32.NewIEEE()) +} + +func NewFilter(size int, hashes ...hash.Hash) Filter { + return &filter{ + filter: make([]byte, size), + hashes: hashes, + } +} + +type filter struct { + filter []byte + hashes []hash.Hash +} + +func (f *filter) Add(k []byte) { + for _, h := range f.hashes { + i := bytesMod(h.Sum(k), int64(len(f.filter)*8)) + f.setBit(i) + } +} + +func (f *filter) Find(k []byte) bool { + for _, h := range f.hashes { + i := bytesMod(h.Sum(k), int64(len(f.filter)*8)) + if !f.getBit(i) { + return false + } + } + return true +} + +func (f *filter) setBit(i int64) { + fmt.Printf("setting bit %d\n", i) + f.filter[i/8] |= (1 << byte(i%8)) +} + +func (f *filter) getBit(i int64) bool { + fmt.Printf("getting bit %d\n", i) + return f.filter[i/8]&(1<