mirror of
https://github.com/ipfs/kubo.git
synced 2025-09-09 23:42:20 +08:00
Add hamming distance calculation to bloom filters
This commit is contained in:
@ -6,6 +6,7 @@ import (
|
||||
"errors"
|
||||
// Non crypto hash, because speed
|
||||
"github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/mtchavez/jenkins"
|
||||
"github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/steakknife/hamming"
|
||||
"hash"
|
||||
)
|
||||
|
||||
@ -13,6 +14,7 @@ type Filter interface {
|
||||
Add([]byte)
|
||||
Find([]byte) bool
|
||||
Merge(Filter) (Filter, error)
|
||||
HammingDistance(Filter) (int, error)
|
||||
}
|
||||
|
||||
func NewFilter(size int) Filter {
|
||||
@ -100,3 +102,23 @@ func (f *filter) Merge(o Filter) (Filter, error) {
|
||||
|
||||
return nfilt, nil
|
||||
}
|
||||
|
||||
func (f *filter) HammingDistance(o Filter) (int, error) {
|
||||
casfil, ok := o.(*filter)
|
||||
if !ok {
|
||||
return 0, errors.New("Unsupported filter type")
|
||||
}
|
||||
|
||||
if len(f.filter) != len(casfil.filter) {
|
||||
return 0, errors.New("filter lengths must match!")
|
||||
}
|
||||
|
||||
acc := 0
|
||||
|
||||
// xor together
|
||||
for i := 0; i < len(f.filter); i++ {
|
||||
acc += hamming.Byte(f.filter[i], casfil.filter[i])
|
||||
}
|
||||
|
||||
return acc, nil
|
||||
}
|
||||
|
@ -78,3 +78,17 @@ func TestMerge(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestHamming(t *testing.T) {
|
||||
f1 := NewFilter(128)
|
||||
f2 := NewFilter(128)
|
||||
|
||||
f1.Add([]byte("no collision"))
|
||||
f1.Add([]byte("collision? no!"))
|
||||
|
||||
dist, _ := f1.HammingDistance(f2)
|
||||
|
||||
if dist != 6 {
|
||||
t.Fatal("Should have 6 bit difference")
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user