From c9bbcaba989e71998aa2d321f53a7a905af281fd Mon Sep 17 00:00:00 2001 From: Eugene Ware Date: Thu, 13 Jun 2013 14:53:38 +1000 Subject: [PATCH] added support for estimating the number of items in the filter --- bloomfilter.js | 19 +++++++++++++++++++ test/bloomfilter-test.js | 11 +++++++++++ 2 files changed, 30 insertions(+) diff --git a/bloomfilter.js b/bloomfilter.js index e48ae5b..0984863 100644 --- a/bloomfilter.js +++ b/bloomfilter.js @@ -72,6 +72,25 @@ return true; }; + // Provides an estimate of the number of items in the filter + // See: http://en.wikipedia.org/wiki/Bloom_filter#Approximating_the_number_of_items_in_a_Bloom_filter + BloomFilter.prototype.items = function() { + var bits = 0; + for (var i = 0; i < this.buckets.length; i++) { + bits += countBits(this.buckets[i]); + } + return -this.m*Math.log(1 - bits/this.m)/this.k; + }; + + function countBits(x) { + // See: http://bits.stephan-brumme.com/countBits.html for an explanation + x = x - ((x >> 1) & 0x55555555); + x = (x & 0x33333333) + ((x >> 2) & 0x33333333); + x = x + (x >> 4); + x &= 0xF0F0F0F; + return (x * 0x01010101) >> 24; + } + // Fowler/Noll/Vo hashing. function fnv_1a(v) { var n = v.length, diff --git a/test/bloomfilter-test.js b/test/bloomfilter-test.js index 3b0675e..3eba06f 100644 --- a/test/bloomfilter-test.js +++ b/test/bloomfilter-test.js @@ -48,6 +48,17 @@ suite.addBatch({ f.add(1); assert.equal(f.test(1), true); assert.equal(f.test(2), false); + }, + "item estimate": function() { + var i, f = new BloomFilter(1000, 4); + for (i = 0; i < 100; i++) { + f.add(i); + } + assert.equal(f.items().toString(), '101.24130826662832'); + for (i = 100; i < 1000; i++) { + f.add(i); + } + assert.equal(f.items().toString(), '1067.1744873417194'); } } });