diff --git a/src/main/java/com/clearspring/analytics/stream/membership/BloomFilter.java b/src/main/java/com/clearspring/analytics/stream/membership/BloomFilter.java index a374b088a..9fc5561ab 100644 --- a/src/main/java/com/clearspring/analytics/stream/membership/BloomFilter.java +++ b/src/main/java/com/clearspring/analytics/stream/membership/BloomFilter.java @@ -144,6 +144,23 @@ public Filter merge(Filter... filters) { return merged; } + /** + * Intersect a Bloom Filter with a number of other bloom filters. + * @param filters + * @return a new Bloom Filter that has each filter bit set if and only if all the input bloom filters had that bit set + */ + public Filter intersect(Filter... filters) { + BitSet intersection = (BitSet) this.filter().clone(); + BloomFilter intersectionBloomFilter = new BloomFilter(this.getHashCount(), intersection); + for (Filter otherFilter : filters) { + if (!(otherFilter instanceof BloomFilter) || this.hashCount != otherFilter.hashCount) { + throw new IllegalArgumentException(("Cannot merge filters of different class or size")); + } + intersection.and(((BloomFilter) otherFilter).filter()); + } + return intersectionBloomFilter; + } + /** * @return a BloomFilter that always returns a positive match, for testing */ diff --git a/src/test/java/com/clearspring/analytics/stream/membership/BloomFilterTest.java b/src/test/java/com/clearspring/analytics/stream/membership/BloomFilterTest.java index 178d53c6a..59a59a1b6 100644 --- a/src/test/java/com/clearspring/analytics/stream/membership/BloomFilterTest.java +++ b/src/test/java/com/clearspring/analytics/stream/membership/BloomFilterTest.java @@ -55,6 +55,7 @@ public BloomFilterTest() { @Before public void clear() { bf.clear(); + bf2.clear(); } @Test @@ -76,6 +77,18 @@ public void testMerge() { assertTrue(mergeBf.isPresent("c")); } + @Test + public void testIntersect() { + bf.add("a"); + bf.add("b"); + bf2.add("a"); + bf2.add("c"); + BloomFilter intersectionBf = (BloomFilter) bf.intersect(bf2); + assertTrue(intersectionBf.isPresent("a")); + assertFalse(intersectionBf.isPresent("b")); + assertFalse(intersectionBf.isPresent("c")); + } + @Test(expected=IllegalArgumentException.class) public void testMergeException() { BloomFilter bf3 = new BloomFilter(ELEMENTS*10, 1);