Skip to content

Commit

Permalink
Cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
korthaj committed May 8, 2017
1 parent bc34adf commit 281c5d8
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 28 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Golang Bloom filter implementation

![Neutral density filter](ND-filter.jpg)

*Neutral density filter, image by [Robert Emperley][re], [CC BY-SA 2.0][ccbysa].*
*Image by [Robert Emperley][re], [CC BY-SA 2.0][ccbysa].*

### Installation

Expand Down
6 changes: 3 additions & 3 deletions example_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ func Example_basics() {
// Output: https://rascal.com seems to be shady.
}

// Count the number of false positives.
// Estimate the number of false positives.
func Example_falsePositives() {
// Create a Bloom filter with room for n elements
// at a false-positives rate less than 1/p.
Expand All @@ -51,8 +51,8 @@ func Example_falsePositives() {
}

// Compute the union of two filters.
func ExampleFilter_Or() {
// Create two Bloom filter with room for 1000 elements
func ExampleFilter_Union() {
// Create two Bloom filters, each with room for 1000 elements
// at a false-positives rate less than 1/100.
n, p := 1000, 100
f1 := bloom.New(n, p)
Expand Down
27 changes: 15 additions & 12 deletions filter.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@
//
// Bloom filters
//
// A Bloom filter is a space-efficient probabilistic data structure
// used to test set membership. A member test returns either
// A Bloom filter is a fast and space-efficient probabilistic data structure
// used to test set membership.
//
// A membership test returns either
// ”likely member” or ”definitely not a member”. Only false positives
// can occur: an element that has been added to the filter
// will be identified as ”likely member”.
Expand Down Expand Up @@ -31,8 +33,8 @@
//
// This implementation is not intended for cryptographic use.
// Each membership test makes a single call to a 128-bit MurmurHash3 function.
// This saves on hashing without increasing the false-positives
// probability as shown by Kirsch and Mitzenmacher.
// This improves speed without increasing the false-positives rate
// as shown by Kirsch and Mitzenmacher.
//
package bloom

Expand All @@ -49,23 +51,24 @@ const (
type Filter struct {
data []uint64 // Bit array, the length is a power of 2.
lookups int // Lookups per query
count int64 // Estimated number of unique elements
count int64 // Estimate number of elements
}

// MurmurHash3 function.
var murmur = new(digest)

// New creates an empty Bloom filter with room for n elements
// at a false-positives rate less than 1/p.
func New(n int, p int) *Filter {
f := &Filter{}
minWords := int(0.0325 * math.Log(float64(p)) * float64(n))
words := 1
for words < minWords {
words *= 2
}
f.data = make([]uint64, words)
f.lookups = int(1.4*math.Log(float64(p)) + 1)
return f
return &Filter{
data: make([]uint64, words),
lookups: int(1.4*math.Log(float64(p)) + 1),
}
}

// AddByte adds b to the filter and tells if b was already a likely member.
Expand Down Expand Up @@ -95,7 +98,7 @@ func (f *Filter) Add(s string) bool {
return f.AddByte(b)
}

// TestByte tells if b is a likely member of this filter.
// TestByte tells if b is a likely member of the filter.
func (f *Filter) TestByte(b []byte) bool {
h1, h2 := murmur.hash(b)
trunc := uint64(len(f.data))<<shift - 1
Expand All @@ -110,14 +113,14 @@ func (f *Filter) TestByte(b []byte) bool {
return true
}

// Test tells if s is a likely member of this filter.
// Test tells if s is a likely member of the filter.
func (f *Filter) Test(s string) bool {
b := make([]byte, len(s))
copy(b, s)
return f.TestByte(b)
}

// Count returns an estimate of the number of elements in this filter.
// Count returns an estimate of the number of elements in the filter.
func (f *Filter) Count() int64 {
return f.count
}
Expand Down
16 changes: 8 additions & 8 deletions filter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ func TestFilter(t *testing.T) {

member = filter.Add(s3)
if member {
t.Errorf("Add(s1) = %v; want false\n", member)
t.Errorf("Add(s3) = %v; want false\n", member)
}
count = filter.Count()
if count != 2 {
Expand All @@ -72,15 +72,15 @@ func TestUnion(t *testing.T) {
or := f1.Union(f2)
member := or.Test(s1)
if !member {
t.Errorf("or.Test(s1) = %v; want true\n", member)
t.Errorf("f1.Union(f2).Test(s1) = %v; want true\n", member)
}
member = or.Test(s2)
if !member {
t.Errorf("or.Test(s2) = %v; want true\n", member)
t.Errorf("f1.Union(f2).Test(s2) = %v; want true\n", member)
}
member = or.Test(s3)
if !member {
t.Errorf("or.Test(s3) = %v; want true\n", member)
t.Errorf("f1.Union(f2).Test(s3) = %v; want true\n", member)
}
}
}
Expand All @@ -93,7 +93,7 @@ func BenchmarkAdd(b *testing.B) {
filter := New(1<<30, 200)
b.StartTimer()
for i := 0; i < b.N; i++ {
filter.Add(fox)
_ = filter.Add(fox)
}
}

Expand All @@ -103,7 +103,7 @@ func BenchmarkAddByte(b *testing.B) {
b.StartTimer()
bytes := []byte(fox)
for i := 0; i < b.N; i++ {
filter.AddByte(bytes)
_ = filter.AddByte(bytes)
}
}

Expand All @@ -112,7 +112,7 @@ func BenchmarkTest(b *testing.B) {
filter := New(1<<30, 200)
b.StartTimer()
for i := 0; i < b.N; i++ {
filter.Test(fox)
_ = filter.Test(fox)
}
}

Expand All @@ -122,7 +122,7 @@ func BenchmarkTestByte(b *testing.B) {
b.StartTimer()
bytes := []byte(fox)
for i := 0; i < b.N; i++ {
filter.TestByte(bytes)
_ = filter.TestByte(bytes)
}
}

Expand Down
7 changes: 3 additions & 4 deletions hash_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,8 @@ import (
func TestHash(t *testing.T) {
d := new(digest)
var data = []struct {
h1 uint64
h2 uint64
s string
h1, h2 uint64
s string
}{
{0x0000000000000000, 0x0000000000000000, ""},
{0xcbd8a7b341bd9b02, 0x5b1e906a48ae1d19, "hello"},
Expand All @@ -23,7 +22,7 @@ func TestHash(t *testing.T) {
t.Errorf("hash(%q).h1 = %d; want %d\n", x.s, h1, x.h1)
}
if h2 != x.h2 {
t.Errorf("hash(%q).h1 = %d; want %d\n", x.s, h2, x.h2)
t.Errorf("hash(%q).h2 = %d; want %d\n", x.s, h2, x.h2)
}
}
}

0 comments on commit 281c5d8

Please sign in to comment.