Inbloom 跨语言 Bloom filter 实现 Inbloom

polaris • 1516 次点击    
这是一个分享于 的项目,其中的信息可能已经有所发展或是发生改变。
Inbloom 是跨语言的 Bloom filter 实现。Bloom filter 是由 Howard Bloom 在 1970 年提出的二进制向量数据结构,它具有很好的空间和时间效率,被用来检测一个元素是不是集合中的一个成员。如果检测结果为是,该元素不一定在集合中;但如果 检测结果为否,该元素一定不在集合中。因此Bloom filter具有100%的召回率。这样每个检测请求返回有“在集合内(可能错误)”和“不在集合内(绝对不在集合内)”两种情况,可见 Bloom filter 是牺牲了正确率和时间以节省空间。 ![image](http://static.oschina.net/uploads/space/2015/0731/112657_Miz7_2306979.png) 示例代码: Python: <pre class="brush:python;toolbar: true; auto-links: false;">import inbloom import base64 import requests # Basic usage bf = inbloom.Filter(entries=100, error=0.01) bf.add(&#34;abc&#34;) bf.add(&#34;def&#34;) assert bf.contains(&#34;abc&#34;) assert bf.contains(&#34;def&#34;) assert not bf.contains(&#34;ghi&#34;) bf2 = inbloom.Filter(entries=100, error=0.01, data=bf.buffer()) assert bf2.contains(&#34;abc&#34;) assert bf2.contains(&#34;def&#34;) assert not bf2.contains(&#34;ghi&#34;) # Serialization payload = &#39;Yg0AZAAAABQAAAAAACAAEAAIAAAAAAAAIAAQAAgABAA=&#39; assert base64.b64encode(inbloom.dump(inbloom.load(base64.b64decode(payload)))) == payload # Sending it over HTTP serialized = base64.b64encode(inbloom.dump(bf)) requests.get(&#39;http://api.endpoint.me&#39;, params={&#39;filter&#39;: serialized})</pre> Go: <pre class="brush:cpp ;toolbar: true; auto-links: false;">// create a blank filter - expecting 20 members and an error rate of 1/100 f, err := NewFilter(20, 0.01) if err != nil {     panic(err) } // the size of the filter fmt.Println(f.Len()) // insert some values f.Add(&#34;foo&#34;) f.Add(&#34;bar&#34;) // test for existence of keys fmt.Println(f.Contains(&#34;foo&#34;)) fmt.Println(f.Contains(&#34;wat&#34;)) fmt.Println(&#34;marshaled data:&#34;, f.MarshalBase64()) // Output: // 24 // true // false // marshaled data: oU4AZAAAABQAAAAAAEIAABEAGAQAAgAgAAAwEAAJAAA=</pre> <pre class="brush:cpp ;toolbar: true; auto-links: false;">// a 20 cardinality 0.01 precision filter with &#34;foo&#34; and &#34;bar&#34; in it data := &#34;oU4AZAAAABQAAAAAAEIAABEAGAQAAgAgAAAwEAAJAAA=&#34; // load it from base64 f, err := UnmarshalBase64(data) if err != nil {     panic(err) } // test it... fmt.Println(f.Contains(&#34;foo&#34;)) fmt.Println(f.Contains(&#34;wat&#34;)) fmt.Println(f.Len()) // dump to pure binary fmt.Printf(&#34;%x\n&#34;, f.Marshal()) // Output: // true // false // 24 // a14e006400000014000000000042000011001804000200200000301000090000</pre> Java: <pre class="brush:java;toolbar: true; auto-links: false;">// The basics BloomFilter bf = new BloomFilter(20, 0.01); bf.add(&#34;foo&#34;); bf.add(&#34;bar&#34;); assertTrue(bf.contains(&#34;foo&#34;)); assertTrue(bf.contains(&#34;bar&#34;)); assertFalse(bf.contains(&#34;baz&#34;)); BloomFilter bf2 = new BloomFilter(bf.bf, bf.entries, bf.error); assertTrue(bf2.contains(&#34;foo&#34;)); assertTrue(bf2.contains(&#34;bar&#34;)); assertFalse(bf2.contains(&#34;baz&#34;)); // Serialization String serialized = BinAscii.hexlify(BloomFilter.dump(bf)); System.out.printf(&#34;Serialized: %s\n&#34;, serialized); String hexPayload = &#34;620d006400000014000000000020001000080000000000002000100008000400&#34;; BloomFilter deserialized = BloomFilter.load(BinAscii.unhexlify(hexPayload)); String dump = BinAscii.hexlify(BloomFilter.dump(deserialized)); System.out.printf(&#34;Re-Serialized: %s\n&#34;, dump); assertEquals(dump.toLowerCase(), hexPayload); assertEquals(deserialized.entries, 20); assertEquals(deserialized.error, 0.01); assertTrue(deserialized.contains(&#34;abc&#34;));</pre>
授权协议:
BSD
开发语言:
JavaGoogle Go 查看源码»
操作系统:
跨平台
1516 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传