File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change 1+ package bloom
2+
3+ import (
4+ "bytes"
5+ "encoding/gob"
6+ )
7+
8+ const binVer0 = 0
9+
10+ // Data to be included in binary representation of Filter.
11+ type marshalFilter struct {
12+ Version int
13+ Data []uint64
14+ Lookups int
15+ Count int64
16+ }
17+
18+ // MarshalBinary returns a binary representation of the filter.
19+ //
20+ // This method implements the encoding.BinaryMarshaler interface.
21+ // The packages encoding/gob, encoding/json, and encoding/xml
22+ // all check for this interface.
23+ func (f * Filter ) MarshalBinary () ([]byte , error ) {
24+ mf := marshalFilter {
25+ Version : binVer0 ,
26+ Data : f .data ,
27+ Lookups : f .lookups ,
28+ Count : f .count ,
29+ }
30+ var b bytes.Buffer
31+ err := gob .NewEncoder (& b ).Encode (mf )
32+ return b .Bytes (), err
33+ }
34+
35+ // UnmarshalBinary imports binary data created by MarshalBinary
36+ // into an empty filter. If the filter is not empty, all previous
37+ // entries are overwritten.
38+ func (f * Filter ) UnmarshalBinary (data []byte ) error {
39+ var mf marshalFilter
40+ err := gob .NewDecoder (bytes .NewBuffer (data )).Decode (& mf )
41+ if err != nil {
42+ return err
43+ }
44+ f .data = mf .Data
45+ f .lookups = mf .Lookups
46+ f .count = mf .Count
47+ return nil
48+ }
Original file line number Diff line number Diff line change 11package bloom_test
22
33import (
4+ "bytes"
5+ "encoding/gob"
46 "fmt"
57 "github.com/yourbasic/bloom"
8+ "log"
69 "math/rand"
710 "strconv"
811)
@@ -72,3 +75,30 @@ func ExampleFilter_Union() {
7275 fmt .Println ("f1 ∪ f2:" , f1 .Union (f2 ).Count ())
7376 // Output: f1 ∪ f2: 505
7477}
78+
79+ // Send a filter over a network using the encoding/gob package.
80+ func ExampleFilter_MarshalBinary_network () {
81+ // Create a mock network and a new Filter.
82+ var network bytes.Buffer
83+ f1 := bloom .New (1000 , 100 )
84+ f1 .Add ("Hello, filter!" )
85+
86+ // Create an encoder and send the filter to the network.
87+ enc := gob .NewEncoder (& network )
88+ if err := enc .Encode (f1 ); err != nil {
89+ log .Fatal ("encode error:" , err )
90+ }
91+
92+ // Create a decoder and receive the filter from the network.
93+ dec := gob .NewDecoder (& network )
94+ var f2 bloom.Filter
95+ if err := dec .Decode (& f2 ); err != nil {
96+ log .Fatal ("decode error:" , err )
97+ }
98+
99+ // Check that we got the same filter back.
100+ if f2 .Test ("Hello, filter!" ) {
101+ fmt .Println ("Filter arrived safely." )
102+ }
103+ // Output: Filter arrived safely.
104+ }
Original file line number Diff line number Diff line change 55// A Bloom filter is a fast and space-efficient probabilistic data structure
66// used to test set membership.
77//
8- // A membership test returns either
9- // ”likely member” or ”definitely not a member”. Only false positives
10- // can occur: an element that has been added to the filter
11- // will be identified as ”likely member”.
8+ // A membership test returns either ”likely member” or ”definitely not
9+ // a member”. Only false positives can occur: an element that has been added
10+ // to the filter will always be identified as ”likely member”.
1211//
1312// Elements can be added, but not removed. With more elements in the filter,
1413// the probability of false positives increases.
@@ -97,11 +96,13 @@ func (f *Filter) add(h1, h2 uint64) bool {
9796}
9897
9998// TestByte tells if b is a likely member of the filter.
99+ // If true, b is probably a member; if false, b is definitely not a member.
100100func (f * Filter ) TestByte (b []byte ) bool {
101101 return f .test (hash (b ))
102102}
103103
104104// Test tells if s is a likely member of the filter.
105+ // If true, s is probably a member; if false, s is definitely not a member.
105106func (f * Filter ) Test (s string ) bool {
106107 return f .test (hashString (s ))
107108}
Original file line number Diff line number Diff line change 11package bloom
22
33import (
4+ "bytes"
5+ "encoding/gob"
6+ "reflect"
47 "testing"
58)
69
@@ -140,6 +143,27 @@ func TestUnion(t *testing.T) {
140143 }
141144}
142145
146+ func TestMarshal (t * testing.T ) {
147+ var network bytes.Buffer
148+ f1 := New (10000 , 100 )
149+ f1 .Add ("Hello, filter!" )
150+
151+ enc := gob .NewEncoder (& network )
152+ if err := enc .Encode (f1 ); err != nil {
153+ t .Errorf ("Encode->err = %v; want nil\n " , err )
154+ }
155+
156+ dec := gob .NewDecoder (& network )
157+ var f2 * Filter
158+ if err := dec .Decode (& f2 ); err != nil {
159+ t .Errorf ("Decode->err = %v; want nil\n " , err )
160+ }
161+
162+ if ! reflect .DeepEqual (f1 , f2 ) {
163+ t .Errorf ("Encode(Code(f)) = %v; want %v\n " , f1 , f2 )
164+ }
165+ }
166+
143167var fox string = "The quick brown fox jumps over the lazy dog."
144168
145169func BenchmarkAdd (b * testing.B ) {
You can’t perform that action at this time.
0 commit comments