This is an automated email from the ASF dual-hosted git repository. aherbert pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/commons-collections.git
commit 86bac5e60207934937537fd78b7313f634352137 Author: Alex Herbert <aherb...@apache.org> AuthorDate: Sun Mar 15 21:36:21 2020 +0000 Change BloomFilter merge return type from void to boolean. This is to support the extension to a counting Bloom filter which can return true/false if the state is valid. Drops redundant abstract methods from the AbstractBloomFilter that are overrides of the BloomFilter interface . --- .../bloomfilter/AbstractBloomFilter.java | 13 ------------- .../bloomfilter/ArrayCountingBloomFilter.java | 6 ++++-- .../bloomfilter/BitSetBloomFilter.java | 6 ++++-- .../collections4/bloomfilter/BloomFilter.java | 6 ++++-- .../bloomfilter/CountingBloomFilter.java | 10 +++++++--- .../bloomfilter/HasherBloomFilter.java | 7 ++++--- .../bloomfilter/AbstractBloomFilterTest.java | 8 ++++---- .../bloomfilter/ArrayCountingBloomFilterTest.java | 22 ++++++++++++---------- .../bloomfilter/DefaultBloomFilterMethodsTest.java | 6 ++++-- 9 files changed, 43 insertions(+), 41 deletions(-) diff --git a/src/main/java/org/apache/commons/collections4/bloomfilter/AbstractBloomFilter.java b/src/main/java/org/apache/commons/collections4/bloomfilter/AbstractBloomFilter.java index 90f274b..71a029e 100644 --- a/src/main/java/org/apache/commons/collections4/bloomfilter/AbstractBloomFilter.java +++ b/src/main/java/org/apache/commons/collections4/bloomfilter/AbstractBloomFilter.java @@ -22,7 +22,6 @@ import java.util.function.LongBinaryOperator; import org.apache.commons.collections4.bloomfilter.hasher.HashFunctionIdentity; import org.apache.commons.collections4.bloomfilter.hasher.Hasher; import org.apache.commons.collections4.bloomfilter.hasher.Shape; -import org.apache.commons.collections4.bloomfilter.hasher.StaticHasher; /** * An abstract Bloom filter providing default implementations for most Bloom filter @@ -100,12 +99,6 @@ public abstract class AbstractBloomFilter implements BloomFilter { } @Override - public abstract long[] getBits(); - - @Override - public abstract StaticHasher getHasher(); - - @Override public final Shape getShape() { return shape; } @@ -121,12 +114,6 @@ public abstract class AbstractBloomFilter implements BloomFilter { } @Override - public abstract void merge(BloomFilter other); - - @Override - public abstract void merge(Hasher hasher); - - @Override public int orCardinality(final BloomFilter other) { // Logical OR return opCardinality(other, (a, b) -> a | b); diff --git a/src/main/java/org/apache/commons/collections4/bloomfilter/ArrayCountingBloomFilter.java b/src/main/java/org/apache/commons/collections4/bloomfilter/ArrayCountingBloomFilter.java index 55e503f..5c30917 100644 --- a/src/main/java/org/apache/commons/collections4/bloomfilter/ArrayCountingBloomFilter.java +++ b/src/main/java/org/apache/commons/collections4/bloomfilter/ArrayCountingBloomFilter.java @@ -237,13 +237,15 @@ public class ArrayCountingBloomFilter extends AbstractBloomFilter implements Cou } @Override - public void merge(final BloomFilter other) { + public boolean merge(final BloomFilter other) { applyAsBloomFilter(other, this::increment); + return isValid(); } @Override - public void merge(final Hasher hasher) { + public boolean merge(final Hasher hasher) { applyAsHasher(hasher, this::increment); + return isValid(); } @Override diff --git a/src/main/java/org/apache/commons/collections4/bloomfilter/BitSetBloomFilter.java b/src/main/java/org/apache/commons/collections4/bloomfilter/BitSetBloomFilter.java index 6ce3532..936a70e 100644 --- a/src/main/java/org/apache/commons/collections4/bloomfilter/BitSetBloomFilter.java +++ b/src/main/java/org/apache/commons/collections4/bloomfilter/BitSetBloomFilter.java @@ -97,19 +97,21 @@ public class BitSetBloomFilter extends AbstractBloomFilter { } @Override - public void merge(final BloomFilter other) { + public boolean merge(final BloomFilter other) { verifyShape(other); if (other instanceof BitSetBloomFilter) { bitSet.or(((BitSetBloomFilter) other).bitSet); } else { bitSet.or(BitSet.valueOf(other.getBits())); } + return true; } @Override - public void merge(final Hasher hasher) { + public boolean merge(final Hasher hasher) { verifyHasher(hasher); hasher.getBits(getShape()).forEachRemaining((IntConsumer) bitSet::set); + return true; } @Override diff --git a/src/main/java/org/apache/commons/collections4/bloomfilter/BloomFilter.java b/src/main/java/org/apache/commons/collections4/bloomfilter/BloomFilter.java index 33c6467..63adc2b 100644 --- a/src/main/java/org/apache/commons/collections4/bloomfilter/BloomFilter.java +++ b/src/main/java/org/apache/commons/collections4/bloomfilter/BloomFilter.java @@ -90,18 +90,20 @@ public interface BloomFilter { * Merges the other Bloom filter into this one. * * @param other the other Bloom filter. + * @return true if the merge was successful */ - void merge(BloomFilter other); + boolean merge(BloomFilter other); /** * Merges the decomposed Bloom filter defined by the hasher into this Bloom * filter. The hasher provides an iterator of bit indexes to enable. * * @param hasher the hasher to provide the indexes. + * @return true if the merge was successful * @throws IllegalArgumentException if the shape argument does not match the shape of * this filter, or if the hasher is not the specified one */ - void merge(Hasher hasher); + boolean merge(Hasher hasher); /** * Performs a logical "OR" with the other Bloom filter and returns the cardinality of diff --git a/src/main/java/org/apache/commons/collections4/bloomfilter/CountingBloomFilter.java b/src/main/java/org/apache/commons/collections4/bloomfilter/CountingBloomFilter.java index 8174d1e..adce2a5 100644 --- a/src/main/java/org/apache/commons/collections4/bloomfilter/CountingBloomFilter.java +++ b/src/main/java/org/apache/commons/collections4/bloomfilter/CountingBloomFilter.java @@ -75,20 +75,24 @@ public interface CountingBloomFilter extends BloomFilter { /** * {@inheritDoc} * - * <p>Note: If the hasher contains duplicate bit indexes these are ignored. + * <p>Note: If the other filter is a counting Bloom filter the index counts are ignored. * All counts for the indexes identified by the other filter will be incremented by 1. + * + * <p>This method will return true if the filter is valid after the operation. */ @Override - void merge(BloomFilter other); + boolean merge(BloomFilter other); /** * {@inheritDoc} * * <p>Note: If the hasher contains duplicate bit indexes these are ignored. * All counts for the indexes identified by the other filter will be incremented by 1. + * + * <p>This method will return true if the filter is valid after the operation. */ @Override - void merge(Hasher other); + boolean merge(Hasher other); /** * Removes the other Bloom filter from this one. diff --git a/src/main/java/org/apache/commons/collections4/bloomfilter/HasherBloomFilter.java b/src/main/java/org/apache/commons/collections4/bloomfilter/HasherBloomFilter.java index 3a5ab71..df61426 100644 --- a/src/main/java/org/apache/commons/collections4/bloomfilter/HasherBloomFilter.java +++ b/src/main/java/org/apache/commons/collections4/bloomfilter/HasherBloomFilter.java @@ -140,15 +140,16 @@ public class HasherBloomFilter extends AbstractBloomFilter { } @Override - public void merge(final BloomFilter other) { - merge(other.getHasher()); + public boolean merge(final BloomFilter other) { + return merge(other.getHasher()); } @Override - public void merge(final Hasher hasher) { + public boolean merge(final Hasher hasher) { verifyHasher(hasher); final IteratorChain<Integer> iter = new IteratorChain<>(this.hasher.getBits(getShape()), hasher.getBits(getShape())); this.hasher = new StaticHasher(iter, getShape()); + return true; } } diff --git a/src/test/java/org/apache/commons/collections4/bloomfilter/AbstractBloomFilterTest.java b/src/test/java/org/apache/commons/collections4/bloomfilter/AbstractBloomFilterTest.java index 089051e..a47219b 100644 --- a/src/test/java/org/apache/commons/collections4/bloomfilter/AbstractBloomFilterTest.java +++ b/src/test/java/org/apache/commons/collections4/bloomfilter/AbstractBloomFilterTest.java @@ -65,12 +65,12 @@ public abstract class AbstractBloomFilterTest { } @Override - public void merge(BloomFilter other) { + public boolean merge(BloomFilter other) { throw new UnsupportedOperationException(); } @Override - public void merge(Hasher hasher) { + public boolean merge(Hasher hasher) { throw new UnsupportedOperationException(); } } @@ -466,7 +466,7 @@ public abstract class AbstractBloomFilterTest { final BloomFilter bf2 = filterFactory.apply(hasher2, shape); - bf.merge(bf2); + assertTrue("Merge should not fail", bf.merge(bf2)); assertEquals(27, bf.cardinality()); } @@ -506,7 +506,7 @@ public abstract class AbstractBloomFilterTest { final List<Integer> lst2 = Arrays.asList(11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27); final Hasher hasher2 = new StaticHasher(lst2.iterator(), shape); - bf.merge(hasher2); + assertTrue("Merge should not fail", bf.merge(hasher2)); assertEquals(27, bf.cardinality()); } diff --git a/src/test/java/org/apache/commons/collections4/bloomfilter/ArrayCountingBloomFilterTest.java b/src/test/java/org/apache/commons/collections4/bloomfilter/ArrayCountingBloomFilterTest.java index 1940287..3f26a87 100644 --- a/src/test/java/org/apache/commons/collections4/bloomfilter/ArrayCountingBloomFilterTest.java +++ b/src/test/java/org/apache/commons/collections4/bloomfilter/ArrayCountingBloomFilterTest.java @@ -24,7 +24,6 @@ import java.util.Arrays; import java.util.HashMap; import java.util.Map; import java.util.concurrent.ThreadLocalRandom; -import java.util.function.BiConsumer; import java.util.function.BiPredicate; import java.util.function.Function; import java.util.function.ToIntBiFunction; @@ -216,11 +215,11 @@ public class ArrayCountingBloomFilterTest extends AbstractBloomFilterTest { * @param merge the merge operation */ private <F> void assertMerge(Function<int[], F> converter, - BiConsumer<ArrayCountingBloomFilter, F> merge) { + BiPredicate<ArrayCountingBloomFilter, F> merge) { final int[] indexes1 = { 1, 2, 4, 5, 6}; final int[] indexes2 = { 3, 4, 6}; final int[] expected = {0, 1, 1, 1, 2, 1, 2}; - assertOperation(indexes1, indexes2, converter, merge, expected); + assertOperation(indexes1, indexes2, converter, merge, true, expected); } /** @@ -232,11 +231,11 @@ public class ArrayCountingBloomFilterTest extends AbstractBloomFilterTest { * @param remove the remove operation */ private <F> void assertRemove(Function<int[], F> converter, - BiConsumer<ArrayCountingBloomFilter, F> remove) { + BiPredicate<ArrayCountingBloomFilter, F> remove) { final int[] indexes1 = { 1, 2, 4, 5, 6}; final int[] indexes2 = { 2, 5, 6}; final int[] expected = {0, 1, 0, 0, 1, 0, 0}; - assertOperation(indexes1, indexes2, converter, remove, expected); + assertOperation(indexes1, indexes2, converter, remove, true, expected); } /** @@ -252,16 +251,19 @@ public class ArrayCountingBloomFilterTest extends AbstractBloomFilterTest { * @param indexes2 the second set of indexes * @param converter the converter * @param operation the operation + * @param isValid the expected value for the operation result * @param expected the expected counts after the operation */ private <F> void assertOperation(int[] indexes1, int[] indexes2, Function<int[], F> converter, - BiConsumer<ArrayCountingBloomFilter, F> operation, - int[] expected) { + BiPredicate<ArrayCountingBloomFilter, F> operation, + boolean isValid, int[] expected) { final Hasher hasher = new FixedIndexesTestHasher(shape, indexes1); final ArrayCountingBloomFilter bf = createFilter(hasher, shape); final F filter = converter.apply(indexes2); - operation.accept(bf, filter); + final boolean result = operation.test(bf, filter); + assertEquals(isValid, result); + assertEquals(isValid, bf.isValid()); assertCounts(bf, expected); } @@ -277,13 +279,13 @@ public class ArrayCountingBloomFilterTest extends AbstractBloomFilterTest { // Small + 1 = OK // should not fail as the counts are ignored - bf.merge(bf2); + assertTrue(bf.merge(bf2)); assertTrue(bf.isValid()); assertCounts(bf, new int[] {0, 1, 2, 1}); // Big + 1 = Overflow assertTrue(bf2.isValid()); - bf2.merge(bf); + assertFalse(bf2.merge(bf)); assertFalse("Merge should overflow and the filter is invalid", bf2.isValid()); // The counts are not clipped to max. They have simply overflowed. diff --git a/src/test/java/org/apache/commons/collections4/bloomfilter/DefaultBloomFilterMethodsTest.java b/src/test/java/org/apache/commons/collections4/bloomfilter/DefaultBloomFilterMethodsTest.java index db20990..6891a47 100644 --- a/src/test/java/org/apache/commons/collections4/bloomfilter/DefaultBloomFilterMethodsTest.java +++ b/src/test/java/org/apache/commons/collections4/bloomfilter/DefaultBloomFilterMethodsTest.java @@ -72,15 +72,17 @@ public class DefaultBloomFilterMethodsTest extends AbstractBloomFilterTest { } @Override - public void merge(final BloomFilter other) { + public boolean merge(final BloomFilter other) { verifyShape(other); bitSet.or(BitSet.valueOf(other.getBits())); + return true; } @Override - public void merge(final Hasher hasher) { + public boolean merge(final Hasher hasher) { verifyHasher(hasher); hasher.getBits(getShape()).forEachRemaining((IntConsumer) bitSet::set); + return true; } }