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 0baa3d247..5e308404e 100644 --- a/src/main/java/org/apache/commons/collections4/bloomfilter/ArrayCountingBloomFilter.java +++ b/src/main/java/org/apache/commons/collections4/bloomfilter/ArrayCountingBloomFilter.java @@ -160,6 +160,11 @@ public final class ArrayCountingBloomFilter implements CountingBloomFilter { return indexExtractor.processIndices(idx -> cells[idx] != 0); } + /** + * Creates a new instance of this {@link ArrayCountingBloomFilter} with the same properties as the current one. + * + * @return a copy of this BloomFilter. + */ @Override public ArrayCountingBloomFilter copy() { return new ArrayCountingBloomFilter(this); 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 0a6e1b38e..6f850c025 100644 --- a/src/main/java/org/apache/commons/collections4/bloomfilter/BloomFilter.java +++ b/src/main/java/org/apache/commons/collections4/bloomfilter/BloomFilter.java @@ -23,11 +23,13 @@ import java.util.Objects; *

* See implementation notes for {@link BitMapExtractor} and {@link IndexExtractor}. *

+ * + * @param The BloomFilter type. * @see BitMapExtractor * @see IndexExtractor * @since 4.5.0 */ -public interface BloomFilter extends IndexExtractor, BitMapExtractor { +public interface BloomFilter> extends IndexExtractor, BitMapExtractor { /** * The sparse characteristic used to determine the best method for matching. @@ -84,7 +86,7 @@ public interface BloomFilter extends IndexExtractor, BitMapExtractor { * @param other the other Bloom filter * @return true if all enabled bits in the other filter are enabled in this filter. */ - default boolean contains(final BloomFilter other) { + default boolean contains(final BloomFilter other) { Objects.requireNonNull(other, "other"); return (characteristics() & SPARSE) != 0 ? contains((IndexExtractor) other) : contains((BitMapExtractor) other); } @@ -117,12 +119,11 @@ public interface BloomFilter extends IndexExtractor, BitMapExtractor { boolean contains(IndexExtractor indexExtractor); /** - * Creates a new instance of the BloomFilter with the same properties as the current one. + * Creates a new instance of this {@link BloomFilter} with the same properties as the current one. * - * @param Type of BloomFilter. - * @return a copy of this BloomFilter + * @return a copy of this {@link BloomFilter}. */ - T copy(); + T copy(); // update operations @@ -142,7 +143,7 @@ public interface BloomFilter extends IndexExtractor, BitMapExtractor { * @see #estimateN() * @see Shape */ - default int estimateIntersection(final BloomFilter other) { + default int estimateIntersection(final BloomFilter other) { Objects.requireNonNull(other, "other"); final double eThis = getShape().estimateN(cardinality()); final double eOther = getShape().estimateN(other.cardinality()); @@ -157,7 +158,7 @@ public interface BloomFilter extends IndexExtractor, BitMapExtractor { } else if (Double.isInfinite(eOther)) { estimate = Math.round(eThis); } else { - final BloomFilter union = this.copy(); + final T union = this.copy(); union.merge(other); final double eUnion = getShape().estimateN(union.cardinality()); if (Double.isInfinite(eUnion)) { @@ -220,11 +221,11 @@ public interface BloomFilter extends IndexExtractor, BitMapExtractor { * @see #estimateN() * @see Shape */ - default int estimateUnion(final BloomFilter other) { + default int estimateUnion(final BloomFilter other) { Objects.requireNonNull(other, "other"); - final BloomFilter cpy = this.copy(); - cpy.merge(other); - return cpy.estimateN(); + final T copy = this.copy(); + copy.merge(other); + return copy.estimateN(); } /** @@ -290,7 +291,7 @@ public interface BloomFilter extends IndexExtractor, BitMapExtractor { * @param other The bloom filter to merge into this one. * @return true if the merge was successful */ - default boolean merge(final BloomFilter other) { + default boolean merge(final BloomFilter other) { return (characteristics() & SPARSE) != 0 ? merge((IndexExtractor) other) : merge((BitMapExtractor) other); } diff --git a/src/main/java/org/apache/commons/collections4/bloomfilter/BloomFilterExtractor.java b/src/main/java/org/apache/commons/collections4/bloomfilter/BloomFilterExtractor.java index 004c2e38f..3fcc0026f 100644 --- a/src/main/java/org/apache/commons/collections4/bloomfilter/BloomFilterExtractor.java +++ b/src/main/java/org/apache/commons/collections4/bloomfilter/BloomFilterExtractor.java @@ -41,12 +41,14 @@ public interface BloomFilterExtractor { * *

All modifications to the Bloom filters are reflected in the original filters

* + * @param The BloomFilter type. * @param filters The filters to be returned by the extractor. * @return THe BloomFilterExtractor containing the filters. */ - static BloomFilterExtractor fromBloomFilterArray(final BloomFilter... filters) { + static > BloomFilterExtractor fromBloomFilterArray(final BloomFilter... filters) { Objects.requireNonNull(filters, "filters"); return new BloomFilterExtractor() { + /** * This implementation returns a copy the original array, the contained Bloom filters * are references to the originals, any modifications to them are reflected in the original 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 00e8a6231..60f597fbc 100644 --- a/src/main/java/org/apache/commons/collections4/bloomfilter/CountingBloomFilter.java +++ b/src/main/java/org/apache/commons/collections4/bloomfilter/CountingBloomFilter.java @@ -54,7 +54,7 @@ import java.util.Objects; * @see CellExtractor * @since 4.5.0 */ -public interface CountingBloomFilter extends BloomFilter, CellExtractor { +public interface CountingBloomFilter extends BloomFilter, CellExtractor { // Query Operations @@ -74,13 +74,6 @@ public interface CountingBloomFilter extends BloomFilter, CellExtractor { */ boolean add(CellExtractor other); - /** - * Creates a new instance of the CountingBloomFilter with the same properties as the current one. - * @return a copy of this CountingBloomFilter - */ - @Override - CountingBloomFilter copy(); - /** * Returns the maximum allowable value for a cell count in this Counting filter. * @return the maximum allowable value for a cell count in this Counting filter. @@ -114,7 +107,7 @@ public interface CountingBloomFilter extends BloomFilter, CellExtractor { * @param bloomFilter the Bloom filter the check for. * @return the maximum number of times the Bloom filter could have been inserted. */ - default int getMaxInsert(final BloomFilter bloomFilter) { + default int getMaxInsert(final BloomFilter bloomFilter) { return getMaxInsert((BitMapExtractor) bloomFilter); } @@ -204,7 +197,7 @@ public interface CountingBloomFilter extends BloomFilter, CellExtractor { * @see #add(CellExtractor) */ @Override - default boolean merge(final BloomFilter other) { + default boolean merge(final BloomFilter other) { Objects.requireNonNull(other, "other"); return merge((IndexExtractor) other); } @@ -288,7 +281,7 @@ public interface CountingBloomFilter extends BloomFilter, CellExtractor { * @see #isValid() * @see #subtract(CellExtractor) */ - default boolean remove(final BloomFilter other) { + default boolean remove(final BloomFilter other) { return remove((IndexExtractor) other); } diff --git a/src/main/java/org/apache/commons/collections4/bloomfilter/LayerManager.java b/src/main/java/org/apache/commons/collections4/bloomfilter/LayerManager.java index 110a514d1..2afb352b3 100644 --- a/src/main/java/org/apache/commons/collections4/bloomfilter/LayerManager.java +++ b/src/main/java/org/apache/commons/collections4/bloomfilter/LayerManager.java @@ -53,14 +53,14 @@ import java.util.function.Supplier; * @param the {@link BloomFilter} type. * @since 4.5.0 */ -public class LayerManager implements BloomFilterExtractor { +public class LayerManager> implements BloomFilterExtractor { /** * Builds new instances of {@link LayerManager}. * * @param the {@link BloomFilter} type. */ - public static class Builder implements Supplier> { + public static class Builder> implements Supplier> { private Predicate> extendCheck; private Supplier supplier; @@ -131,7 +131,7 @@ public class LayerManager implements BloomFilterExtractor * @param Type of BloomFilter. * @return A Consumer suitable for the LayerManager {@code cleanup} parameter. */ - public static Consumer> noCleanup() { + public static > Consumer> noCleanup() { return x -> { // empty }; @@ -147,7 +147,7 @@ public class LayerManager implements BloomFilterExtractor * @return A Consumer suitable for the LayerManager {@code cleanup} parameter. * @throws IllegalArgumentException if {@code maxSize <= 0}. */ - public static Consumer> onMaxSize(final int maxSize) { + public static > Consumer> onMaxSize(final int maxSize) { if (maxSize <= 0) { throw new IllegalArgumentException("'maxSize' must be greater than 0"); } @@ -165,7 +165,7 @@ public class LayerManager implements BloomFilterExtractor * @param Type of BloomFilter. * @return A Consumer suitable for the LayerManager {@code cleanup} parameter. */ - public static Consumer> removeEmptyTarget() { + public static > Consumer> removeEmptyTarget() { return x -> { if (!x.isEmpty() && x.getLast().isEmpty()) { x.removeLast(); @@ -180,7 +180,7 @@ public class LayerManager implements BloomFilterExtractor * @param test Predicate. * @return A Consumer suitable for the LayerManager {@code cleanup} parameter. */ - public static Consumer> removeIf(final Predicate test) { + public static > Consumer> removeIf(final Predicate test) { return x -> x.removeIf(test); } @@ -202,7 +202,7 @@ public class LayerManager implements BloomFilterExtractor * @return A Predicate suitable for the LayerManager {@code extendCheck} parameter. * @throws IllegalArgumentException if {@code breakAt <= 0} */ - public static Predicate> advanceOnCount(final int breakAt) { + public static > Predicate> advanceOnCount(final int breakAt) { if (breakAt <= 0) { throw new IllegalArgumentException("'breakAt' must be greater than 0"); } @@ -226,7 +226,7 @@ public class LayerManager implements BloomFilterExtractor * @param Type of BloomFilter. * @return A Predicate suitable for the LayerManager {@code extendCheck} parameter. */ - public static Predicate> advanceOnPopulated() { + public static > Predicate> advanceOnPopulated() { return lm -> !lm.last().isEmpty(); } @@ -242,12 +242,12 @@ public class LayerManager implements BloomFilterExtractor * @return A Predicate suitable for the LayerManager {@code extendCheck} parameter. * @throws IllegalArgumentException if {@code maxN <= 0} */ - public static Predicate> advanceOnSaturation(final double maxN) { + public static > Predicate> advanceOnSaturation(final double maxN) { if (maxN <= 0) { throw new IllegalArgumentException("'maxN' must be greater than 0"); } return manager -> { - final BloomFilter bf = manager.last(); + final T bf = manager.last(); return maxN <= bf.getShape().estimateN(bf.cardinality()); }; } @@ -259,13 +259,14 @@ public class LayerManager implements BloomFilterExtractor * @param Type of BloomFilter. * @return A Predicate suitable for the LayerManager {@code extendCheck} parameter. */ - public static Predicate> neverAdvance() { + public static > Predicate> neverAdvance() { return x -> false; } private ExtendCheck() { } } + /** * Creates a new Builder with defaults of {@code ExtendCheck.neverAdvance()} and * {@code Cleanup.noCleanup()}. @@ -275,7 +276,7 @@ public class LayerManager implements BloomFilterExtractor * @see ExtendCheck#neverAdvance() * @see Cleanup#noCleanup() */ - public static Builder builder() { + public static > Builder builder() { return new Builder<>(); } @@ -337,13 +338,15 @@ public class LayerManager implements BloomFilterExtractor } /** - * Creates a deep copy of this LayerManager. - *

Filters in the copy are deep copies, not references, so changes in the copy - * are NOT reflected in the original.

- *

The {@code filterSupplier}, {@code extendCheck}, and the {@code filterCleanup} are shared between - * the copy and this instance.

+ * Creates a deep copy of this {@link LayerManager}. + *

+ * Filters in the copy are deep copies, not references, so changes in the copy are NOT reflected in the original. + *

+ *

+ * The {@code filterSupplier}, {@code extendCheck}, and the {@code filterCleanup} are shared between the copy and this instance. + *

* - * @return a copy of this layer Manager. + * @return a copy of this {@link LayerManager}. */ public LayerManager copy() { final LayerManager newMgr = new LayerManager<>(filterSupplier, extendCheck, filterCleanup, false); @@ -438,7 +441,7 @@ public class LayerManager implements BloomFilterExtractor */ @Override public boolean processBloomFilters(final Predicate bloomFilterPredicate) { - for (final BloomFilter bf : filters) { + for (final T bf : filters) { if (!bloomFilterPredicate.test(bf)) { return false; } diff --git a/src/main/java/org/apache/commons/collections4/bloomfilter/LayeredBloomFilter.java b/src/main/java/org/apache/commons/collections4/bloomfilter/LayeredBloomFilter.java index 9f5e3e4a4..207e0fe73 100644 --- a/src/main/java/org/apache/commons/collections4/bloomfilter/LayeredBloomFilter.java +++ b/src/main/java/org/apache/commons/collections4/bloomfilter/LayeredBloomFilter.java @@ -59,10 +59,11 @@ import java.util.function.Predicate; * removes them. It also checks it a new layer should be added, and if so adds * it and sets the {@code target} before the operation. * + * * @param The type of Bloom Filter that is used for the layers. * @since 4.5.0 */ -public class LayeredBloomFilter implements BloomFilter, BloomFilterExtractor { +public class LayeredBloomFilter> implements BloomFilter>, BloomFilterExtractor { /** * A class used to locate matching filters across all the layers. */ @@ -70,9 +71,9 @@ public class LayeredBloomFilter implements BloomFilter, B int[] result = new int[layerManager.getDepth()]; int bfIdx; int resultIdx; - BloomFilter bf; + BloomFilter bf; - Finder(final BloomFilter bf) { + Finder(final BloomFilter bf) { this.bf = bf; } @@ -180,6 +181,11 @@ public class LayeredBloomFilter implements BloomFilter, B return contains(createFilter(indexExtractor)); } + /** + * Creates a new instance of this {@link LayeredBloomFilter} with the same properties as the current one. + * + * @return a copy of this {@link LayeredBloomFilter}. + */ @Override public LayeredBloomFilter copy() { return new LayeredBloomFilter<>(shape, layerManager.copy()); @@ -191,7 +197,7 @@ public class LayeredBloomFilter implements BloomFilter, B * @param bitMapExtractor the BitMapExtractor to create the filter from. * @return the BloomFilter. */ - private BloomFilter createFilter(final BitMapExtractor bitMapExtractor) { + private SimpleBloomFilter createFilter(final BitMapExtractor bitMapExtractor) { final SimpleBloomFilter bf = new SimpleBloomFilter(shape); bf.merge(bitMapExtractor); return bf; @@ -203,7 +209,7 @@ public class LayeredBloomFilter implements BloomFilter, B * @param hasher the hasher to create the filter from. * @return the BloomFilter. */ - private BloomFilter createFilter(final Hasher hasher) { + private SimpleBloomFilter createFilter(final Hasher hasher) { final SimpleBloomFilter bf = new SimpleBloomFilter(shape); bf.merge(hasher); return bf; @@ -215,7 +221,7 @@ public class LayeredBloomFilter implements BloomFilter, B * @param indexExtractor the IndexExtractor to create the filter from. * @return the BloomFilter. */ - private BloomFilter createFilter(final IndexExtractor indexExtractor) { + private SimpleBloomFilter createFilter(final IndexExtractor indexExtractor) { final SimpleBloomFilter bf = new SimpleBloomFilter(shape); bf.merge(indexExtractor); return bf; @@ -289,8 +295,8 @@ public class LayeredBloomFilter implements BloomFilter, B * @return the merged bloom filter. */ @Override - public BloomFilter flatten() { - final BloomFilter bf = new SimpleBloomFilter(shape); + public SimpleBloomFilter flatten() { + final SimpleBloomFilter bf = new SimpleBloomFilter(shape); processBloomFilters(bf::merge); return bf; } diff --git a/src/main/java/org/apache/commons/collections4/bloomfilter/SetOperations.java b/src/main/java/org/apache/commons/collections4/bloomfilter/SetOperations.java index 85040ff45..5226b35b1 100644 --- a/src/main/java/org/apache/commons/collections4/bloomfilter/SetOperations.java +++ b/src/main/java/org/apache/commons/collections4/bloomfilter/SetOperations.java @@ -112,7 +112,7 @@ public final class SetOperations { * @param second the second Bloom filter. * @return the Cosine similarity. */ - public static double cosineSimilarity(final BloomFilter first, final BloomFilter second) { + public static double cosineSimilarity(final BloomFilter first, final BloomFilter second) { final int numerator = andCardinality(first, second); // Given that the cardinality is an int then the product as a double will not // overflow, we can use one sqrt: diff --git a/src/main/java/org/apache/commons/collections4/bloomfilter/SimpleBloomFilter.java b/src/main/java/org/apache/commons/collections4/bloomfilter/SimpleBloomFilter.java index 1b646d4a5..f98fceeb8 100644 --- a/src/main/java/org/apache/commons/collections4/bloomfilter/SimpleBloomFilter.java +++ b/src/main/java/org/apache/commons/collections4/bloomfilter/SimpleBloomFilter.java @@ -24,9 +24,10 @@ import java.util.function.LongPredicate; /** * A bloom filter using an array of bit maps to track enabled bits. This is a standard * implementation and should work well for most Bloom filters. + * * @since 4.5.0 */ -public final class SimpleBloomFilter implements BloomFilter { +public final class SimpleBloomFilter implements BloomFilter { /** * The array of bit map longs that defines this Bloom filter. Will be null if the filter is empty. @@ -96,6 +97,11 @@ public final class SimpleBloomFilter implements BloomFilter { return indexExtractor.processIndices(idx -> BitMaps.contains(bitMap, idx)); } + /** + * Creates a new instance of this {@link SimpleBloomFilter} with the same properties as the current one. + * + * @return a copy of this {@link SimpleBloomFilter}. + */ @Override public SimpleBloomFilter copy() { return new SimpleBloomFilter(this); @@ -140,7 +146,7 @@ public final class SimpleBloomFilter implements BloomFilter { } @Override - public boolean merge(final BloomFilter other) { + public boolean merge(final BloomFilter other) { Objects.requireNonNull(other, "other"); if ((other.characteristics() & SPARSE) != 0) { merge((IndexExtractor) other); diff --git a/src/main/java/org/apache/commons/collections4/bloomfilter/SparseBloomFilter.java b/src/main/java/org/apache/commons/collections4/bloomfilter/SparseBloomFilter.java index e53a5a2ff..b7f15ddfa 100644 --- a/src/main/java/org/apache/commons/collections4/bloomfilter/SparseBloomFilter.java +++ b/src/main/java/org/apache/commons/collections4/bloomfilter/SparseBloomFilter.java @@ -26,7 +26,7 @@ import java.util.function.LongPredicate; * implementation and should work well for most low cardinality Bloom filters. * @since 4.5.0 */ -public final class SparseBloomFilter implements BloomFilter { +public final class SparseBloomFilter implements BloomFilter { /** * The bitSet that defines this BloomFilter. @@ -98,6 +98,11 @@ public final class SparseBloomFilter implements BloomFilter { return indexExtractor.processIndices(indices::contains); } + /** + * Creates a new instance of this {@link SparseBloomFilter} with the same properties as the current one. + * + * @return a copy of this {@link SparseBloomFilter}. + */ @Override public SparseBloomFilter copy() { return new SparseBloomFilter(this); @@ -120,7 +125,7 @@ public final class SparseBloomFilter implements BloomFilter { } @Override - public boolean merge(final BloomFilter other) { + public boolean merge(final BloomFilter other) { Objects.requireNonNull(other, "other"); final IndexExtractor indexExtractor = (other.characteristics() & SPARSE) != 0 ? (IndexExtractor) other : IndexExtractor.fromBitMapExtractor(other); merge(indexExtractor); diff --git a/src/main/java/org/apache/commons/collections4/bloomfilter/WrappedBloomFilter.java b/src/main/java/org/apache/commons/collections4/bloomfilter/WrappedBloomFilter.java index a03ab0e85..9b3d9b629 100644 --- a/src/main/java/org/apache/commons/collections4/bloomfilter/WrappedBloomFilter.java +++ b/src/main/java/org/apache/commons/collections4/bloomfilter/WrappedBloomFilter.java @@ -22,17 +22,20 @@ import java.util.function.LongPredicate; /** * An abstract class to assist in implementing Bloom filter decorators. * + * @param The WrappedBloomFilter type. + * @param The wrapped BloomFilter type. * @since 4.5.0 */ -public abstract class WrappedBloomFilter implements BloomFilter { - private final BloomFilter wrapped; +public abstract class WrappedBloomFilter, W extends BloomFilter> implements BloomFilter { + + private final W wrapped; /** * Wraps a Bloom filter. The wrapped filter is maintained as a reference * not a copy. Changes in one will be reflected in the other. * @param wrapped The Bloom filter. */ - public WrappedBloomFilter(final BloomFilter wrapped) { + public WrappedBloomFilter(final W wrapped) { this.wrapped = wrapped; } @@ -67,7 +70,7 @@ public abstract class WrappedBloomFilter implements BloomFilter { } @Override - public boolean contains(final BloomFilter other) { + public boolean contains(final BloomFilter other) { return wrapped.contains(other); } @@ -82,7 +85,7 @@ public abstract class WrappedBloomFilter implements BloomFilter { } @Override - public int estimateIntersection(final BloomFilter other) { + public int estimateIntersection(final BloomFilter other) { return wrapped.estimateIntersection(other); } @@ -92,7 +95,7 @@ public abstract class WrappedBloomFilter implements BloomFilter { } @Override - public int estimateUnion(final BloomFilter other) { + public int estimateUnion(final BloomFilter other) { return wrapped.estimateUnion(other); } @@ -106,7 +109,7 @@ public abstract class WrappedBloomFilter implements BloomFilter { * * @return the wrapped BloomFilter. */ - protected BloomFilter getWrapped() { + protected W getWrapped() { return wrapped; } @@ -121,7 +124,7 @@ public abstract class WrappedBloomFilter implements BloomFilter { } @Override - public boolean merge(final BloomFilter other) { + public boolean merge(final BloomFilter other) { return wrapped.merge(other); } diff --git a/src/test/java/org/apache/commons/collections4/bloomfilter/AbstractBloomFilterExtractorTest.java b/src/test/java/org/apache/commons/collections4/bloomfilter/AbstractBloomFilterExtractorTest.java index 32c7097c2..4f9112e73 100644 --- a/src/test/java/org/apache/commons/collections4/bloomfilter/AbstractBloomFilterExtractorTest.java +++ b/src/test/java/org/apache/commons/collections4/bloomfilter/AbstractBloomFilterExtractorTest.java @@ -29,8 +29,8 @@ import org.junit.jupiter.api.Test; public abstract class AbstractBloomFilterExtractorTest { private final Shape shape = Shape.fromKM(17, 72); - BloomFilter one = new SimpleBloomFilter(shape); - BloomFilter two = new SimpleBloomFilter(shape); + SimpleBloomFilter one = new SimpleBloomFilter(shape); + SimpleBloomFilter two = new SimpleBloomFilter(shape); int[] nullCount = { 0, 0 }; int[] equalityCount = { 0 }; BiPredicate counter = (x, y) -> { diff --git a/src/test/java/org/apache/commons/collections4/bloomfilter/BitMapExtractorFromWrappedBloomFilterTest.java b/src/test/java/org/apache/commons/collections4/bloomfilter/BitMapExtractorFromWrappedBloomFilterTest.java index 4040efb95..0c04e784b 100644 --- a/src/test/java/org/apache/commons/collections4/bloomfilter/BitMapExtractorFromWrappedBloomFilterTest.java +++ b/src/test/java/org/apache/commons/collections4/bloomfilter/BitMapExtractorFromWrappedBloomFilterTest.java @@ -24,8 +24,8 @@ public class BitMapExtractorFromWrappedBloomFilterTest extends AbstractBitMapExt protected BitMapExtractor createEmptyExtractor() { return new WrappedBloomFilter(new DefaultBloomFilterTest.SparseDefaultBloomFilter(shape)) { @Override - public BloomFilter copy() { - final BloomFilter result = new DefaultBloomFilterTest.SparseDefaultBloomFilter(shape); + public DefaultBloomFilterTest.SparseDefaultBloomFilter copy() { + final DefaultBloomFilterTest.SparseDefaultBloomFilter result = new DefaultBloomFilterTest.SparseDefaultBloomFilter(shape); result.merge(getWrapped()); return result; } @@ -35,10 +35,10 @@ public class BitMapExtractorFromWrappedBloomFilterTest extends AbstractBitMapExt @Override protected BitMapExtractor createExtractor() { final Hasher hasher = new IncrementingHasher(0, 1); - final BloomFilter bf = new WrappedBloomFilter(new DefaultBloomFilterTest.SparseDefaultBloomFilter(shape)) { + final WrappedBloomFilter bf = new WrappedBloomFilter(new DefaultBloomFilterTest.SparseDefaultBloomFilter(shape)) { @Override - public BloomFilter copy() { - final BloomFilter result = new DefaultBloomFilterTest.SparseDefaultBloomFilter(shape); + public DefaultBloomFilterTest.SparseDefaultBloomFilter copy() { + final DefaultBloomFilterTest.SparseDefaultBloomFilter result = new DefaultBloomFilterTest.SparseDefaultBloomFilter(shape); result.merge(getWrapped()); return result; } diff --git a/src/test/java/org/apache/commons/collections4/bloomfilter/BloomFilterExtractorFromLayeredBloomFilterTest.java b/src/test/java/org/apache/commons/collections4/bloomfilter/BloomFilterExtractorFromLayeredBloomFilterTest.java index 644dc253a..4d81a49c1 100644 --- a/src/test/java/org/apache/commons/collections4/bloomfilter/BloomFilterExtractorFromLayeredBloomFilterTest.java +++ b/src/test/java/org/apache/commons/collections4/bloomfilter/BloomFilterExtractorFromLayeredBloomFilterTest.java @@ -24,13 +24,15 @@ public class BloomFilterExtractorFromLayeredBloomFilterTest extends AbstractBloo @Override protected BloomFilterExtractor createUnderTest(final BloomFilter... filters) { final Builder builder = LayerManager.builder(); - if (!ArrayUtils.isEmpty(filters)) { + final BloomFilter bloomFilter0 = ArrayUtils.get(filters, 0); + final Shape shape0 = bloomFilter0 != null ? bloomFilter0.getShape() : null; + if (shape0 != null) { // Avoid an NPE in test code and let the domain classes decide what to do when there is no supplier set. - builder.setSupplier(() -> new SimpleBloomFilter(filters[0].getShape())); + builder.setSupplier(() -> new SimpleBloomFilter(shape0)); } final LayerManager layerManager = builder.setExtendCheck(LayerManager.ExtendCheck.advanceOnPopulated()) .setCleanup(LayerManager.Cleanup.noCleanup()).get(); - final LayeredBloomFilter underTest = new LayeredBloomFilter(filters[0].getShape(), layerManager); + final LayeredBloomFilter underTest = new LayeredBloomFilter(shape0, layerManager); for (final BloomFilter bf : filters) { underTest.merge(bf); } diff --git a/src/test/java/org/apache/commons/collections4/bloomfilter/DefaultBloomFilterTest.java b/src/test/java/org/apache/commons/collections4/bloomfilter/DefaultBloomFilterTest.java index 081bc0fbc..0ce88a0ea 100644 --- a/src/test/java/org/apache/commons/collections4/bloomfilter/DefaultBloomFilterTest.java +++ b/src/test/java/org/apache/commons/collections4/bloomfilter/DefaultBloomFilterTest.java @@ -30,7 +30,9 @@ import org.junit.jupiter.api.Test; * Tests for the {@link BloomFilter}. */ public class DefaultBloomFilterTest extends AbstractBloomFilterTest { - abstract static class AbstractDefaultBloomFilter implements BloomFilter { + + abstract static class AbstractDefaultBloomFilter> implements BloomFilter { + private final Shape shape; protected TreeSet indices; @@ -146,7 +148,7 @@ public class DefaultBloomFilterTest extends AbstractBloomFilterTest { public SparseDefaultBloomFilter(final Shape shape) { super(shape); @@ -158,8 +160,8 @@ public class DefaultBloomFilterTest extends AbstractBloomFilterTest> underTest = LayerManager.ExtendCheck.advanceOnCount(breakAt); - final LayerManager layerManager = testingBuilder().get(); + final Predicate> underTest = LayerManager.ExtendCheck.advanceOnCount(breakAt); + final LayerManager layerManager = testingBuilder().get(); for (int i = 0; i < breakAt - 1; i++) { assertFalse(underTest.test(layerManager), "at " + i); layerManager.getTarget().merge(TestingHashers.FROM1); @@ -62,8 +62,8 @@ public class LayerManagerTest { @Test public void testAdvanceOnPopulated() { - final Predicate> underTest = LayerManager.ExtendCheck.advanceOnPopulated(); - final LayerManager layerManager = testingBuilder().get(); + final Predicate> underTest = LayerManager.ExtendCheck.advanceOnPopulated(); + final LayerManager layerManager = testingBuilder().get(); assertFalse(underTest.test(layerManager)); layerManager.getTarget().merge(TestingHashers.FROM1); assertTrue(underTest.test(layerManager)); @@ -73,8 +73,8 @@ public class LayerManagerTest { public void testAdvanceOnSaturation() { final double maxN = shape.estimateMaxN(); int hashStart = 0; - final Predicate> underTest = LayerManager.ExtendCheck.advanceOnSaturation(maxN); - final LayerManager layerManager = testingBuilder().get(); + final Predicate> underTest = LayerManager.ExtendCheck.advanceOnSaturation(maxN); + final LayerManager layerManager = testingBuilder().get(); while (layerManager.getTarget().getShape().estimateN(layerManager.getTarget().cardinality()) < maxN) { assertFalse(underTest.test(layerManager)); layerManager.getTarget().merge(new IncrementingHasher(hashStart, shape.getNumberOfHashFunctions())); @@ -87,7 +87,7 @@ public class LayerManagerTest { @Test public void testBuilder() { - final LayerManager.Builder underTest = LayerManager.builder(); + final LayerManager.Builder underTest = LayerManager.builder(); NullPointerException npe = assertThrows(NullPointerException.class, underTest::get); assertTrue(npe.getMessage().contains("filterSupplier")); underTest.setSupplier(() -> null).setCleanup(null); @@ -105,7 +105,7 @@ public class LayerManagerTest { @Test public void testClear() { - final LayerManager underTest = LayerManager.builder().setSupplier(() -> new SimpleBloomFilter(shape)).get(); + final LayerManager underTest = LayerManager.builder().setSupplier(() -> new SimpleBloomFilter(shape)).get(); underTest.getTarget().merge(TestingHashers.randomHasher()); underTest.next(); underTest.getTarget().merge(TestingHashers.randomHasher()); @@ -119,7 +119,7 @@ public class LayerManagerTest { @Test public void testCopy() { - final LayerManager underTest = LayerManager.builder().setSupplier(() -> new SimpleBloomFilter(shape)).get(); + final LayerManager underTest = LayerManager.builder().setSupplier(() -> new SimpleBloomFilter(shape)).get(); underTest.getTarget().merge(TestingHashers.randomHasher()); underTest.next(); underTest.getTarget().merge(TestingHashers.randomHasher()); @@ -127,7 +127,7 @@ public class LayerManagerTest { underTest.getTarget().merge(TestingHashers.randomHasher()); assertEquals(3, underTest.getDepth()); - final LayerManager copy = underTest.copy(); + final LayerManager copy = underTest.copy(); assertNotSame(underTest, copy); // object equals not implemented assertNotEquals(underTest, copy); @@ -139,12 +139,12 @@ public class LayerManagerTest { @Test public void testForEachBloomFilter() { - final LayerManager underTest = LayerManager.builder().setSupplier(() -> new SimpleBloomFilter(shape)) + final LayerManager underTest = LayerManager.builder().setSupplier(() -> new SimpleBloomFilter(shape)) .setExtendCheck(LayerManager.ExtendCheck.advanceOnPopulated()).get(); - final List lst = new ArrayList<>(); + final List lst = new ArrayList<>(); for (int i = 0; i < 10; i++) { - final BloomFilter bf = new SimpleBloomFilter(shape); + final SimpleBloomFilter bf = new SimpleBloomFilter(shape); bf.merge(TestingHashers.randomHasher()); lst.add(bf); underTest.getTarget().merge(bf); @@ -161,21 +161,21 @@ public class LayerManagerTest { @Test public void testGet() { final SimpleBloomFilter f = new SimpleBloomFilter(shape); - final LayerManager underTest = LayerManager.builder().setSupplier(() -> f).get(); + final LayerManager underTest = LayerManager.builder().setSupplier(() -> f).get(); assertEquals(1, underTest.getDepth()); assertSame(f, underTest.get(0)); assertThrows(NoSuchElementException.class, () -> underTest.get(-1)); assertThrows(NoSuchElementException.class, () -> underTest.get(1)); } - private LayerManager.Builder testingBuilder() { - return LayerManager.builder().setSupplier(() -> new SimpleBloomFilter(shape)); + private LayerManager.Builder testingBuilder() { + return LayerManager.builder().setSupplier(() -> new SimpleBloomFilter(shape)); } @Test public void testNeverAdvance() { - final Predicate> underTest = LayerManager.ExtendCheck.neverAdvance(); - final LayerManager layerManager = testingBuilder().get(); + final Predicate> underTest = LayerManager.ExtendCheck.neverAdvance(); + final LayerManager layerManager = testingBuilder().get(); assertFalse(underTest.test(layerManager)); for (int i = 0; i < 10; i++) { layerManager.getTarget().merge(TestingHashers.randomHasher()); @@ -185,7 +185,7 @@ public class LayerManagerTest { @Test public void testNextAndGetDepth() { - final LayerManager underTest = LayerManager.builder().setSupplier(() -> new SimpleBloomFilter(shape)).get(); + final LayerManager underTest = LayerManager.builder().setSupplier(() -> new SimpleBloomFilter(shape)).get(); assertEquals(1, underTest.getDepth()); underTest.getTarget().merge(TestingHashers.randomHasher()); assertEquals(1, underTest.getDepth()); @@ -195,8 +195,8 @@ public class LayerManagerTest { @Test public void testNoCleanup() { - final Consumer> underTest = LayerManager.Cleanup.noCleanup(); - final Deque list = new LinkedList<>(); + final Consumer> underTest = LayerManager.Cleanup.noCleanup(); + final Deque list = new LinkedList<>(); for (int i = 0; i < 20; i++) { assertEquals(i, list.size()); list.add(new SimpleBloomFilter(shape)); @@ -207,8 +207,8 @@ public class LayerManagerTest { @ParameterizedTest @ValueSource(ints = {5, 100, 2, 1}) public void testOnMaxSize(final int maxSize) { - final Consumer> underTest = LayerManager.Cleanup.onMaxSize(maxSize); - final LinkedList list = new LinkedList<>(); + final Consumer> underTest = LayerManager.Cleanup.onMaxSize(maxSize); + final LinkedList list = new LinkedList<>(); for (int i = 0; i < maxSize; i++) { assertEquals(i, list.size()); list.add(new SimpleBloomFilter(shape)); @@ -231,11 +231,11 @@ public class LayerManagerTest { @Test public void testRemoveEmptyTarget() { - final Consumer> underTest = LayerManager.Cleanup.removeEmptyTarget(); - final LinkedList list = new LinkedList<>(); + final Consumer> underTest = LayerManager.Cleanup.removeEmptyTarget(); + final LinkedList list = new LinkedList<>(); // removes an empty filter - final BloomFilter bf = new SimpleBloomFilter(shape); + final SimpleBloomFilter bf = new SimpleBloomFilter(shape); list.add(bf); assertEquals(bf, list.get(0)); underTest.accept(list); @@ -273,7 +273,7 @@ public class LayerManagerTest { final boolean[] extendCheckCalled = { false }; final boolean[] cleanupCalled = { false }; final int[] supplierCount = { 0 }; - final LayerManager underTest = LayerManager.builder().setSupplier(() -> { + final LayerManager underTest = LayerManager.builder().setSupplier(() -> { supplierCount[0]++; return new SimpleBloomFilter(shape); }).setExtendCheck(lm -> { diff --git a/src/test/java/org/apache/commons/collections4/bloomfilter/LayeredBloomFilterTest.java b/src/test/java/org/apache/commons/collections4/bloomfilter/LayeredBloomFilterTest.java index 270e139d5..c84bf88a0 100644 --- a/src/test/java/org/apache/commons/collections4/bloomfilter/LayeredBloomFilterTest.java +++ b/src/test/java/org/apache/commons/collections4/bloomfilter/LayeredBloomFilterTest.java @@ -40,7 +40,7 @@ public class LayeredBloomFilterTest extends AbstractBloomFilterTest> { + static class AdvanceOnTimeQuanta> implements Predicate>> { Duration quanta; AdvanceOnTimeQuanta(final Duration quanta) { @@ -48,7 +48,7 @@ public class LayeredBloomFilterTest extends AbstractBloomFilterTest layerManager) { + public boolean test(final LayerManager> layerManager) { // can not use getTarget() as it causes recursion. return layerManager.last().getTimestamp().plus(quanta).isBefore(Instant.now()); } @@ -80,9 +80,11 @@ public class LayeredBloomFilterTest extends AbstractBloomFilterTest { + int value; int sequence; + NumberedBloomFilter(final Shape shape, final int value, final int sequence) { super(new SimpleBloomFilter(shape)); this.value = value; @@ -90,7 +92,7 @@ public class LayeredBloomFilterTest extends AbstractBloomFilterTest> extends WrappedBloomFilter, T> { private final Instant timestamp; - TimestampedBloomFilter(final BloomFilter bf) { + TimestampedBloomFilter(final T bf) { this(bf, Instant.now()); } - TimestampedBloomFilter(final BloomFilter bf, final Instant timestamp) { + TimestampedBloomFilter(final T bf, final Instant timestamp) { super(bf); this.timestamp = timestamp; } @Override - public TimestampedBloomFilter copy() { - return new TimestampedBloomFilter(getWrapped().copy(), timestamp); + public TimestampedBloomFilter copy() { + return new TimestampedBloomFilter<>(getWrapped().copy(), timestamp); } public Instant getTimestamp() { @@ -135,11 +137,11 @@ public class LayeredBloomFilterTest extends AbstractBloomFilterTest createTimedLayeredFilter(final Shape shape, final Duration duration, final Duration quanta) { - final LayerManager.Builder builder = LayerManager.builder(); - final Consumer> cleanup = Cleanup.removeEmptyTarget().andThen(new CleanByTime(duration)); - final LayerManager layerManager = builder - .setSupplier(() -> new TimestampedBloomFilter(new SimpleBloomFilter(shape))) + static LayeredBloomFilter> createTimedLayeredFilter(final Shape shape, final Duration duration, final Duration quanta) { + final LayerManager.Builder> builder = LayerManager.builder(); + final Consumer>> cleanup = Cleanup.removeEmptyTarget().andThen(new CleanByTime(duration)); + final LayerManager> layerManager = builder + .setSupplier(() -> new TimestampedBloomFilter<>(new SimpleBloomFilter(shape))) .setCleanup(cleanup) .setExtendCheck(new AdvanceOnTimeQuanta(quanta) .or(LayerManager.ExtendCheck.advanceOnSaturation(shape.estimateMaxN()))) @@ -156,7 +158,7 @@ public class LayeredBloomFilterTest extends AbstractBloomFilterTest fixed(final Shape shape, final int maxDepth) { + public static LayeredBloomFilter fixed(final Shape shape, final int maxDepth) { return fixed(shape, maxDepth, () -> new SimpleBloomFilter(shape)); } @@ -170,7 +172,7 @@ public class LayeredBloomFilterTest extends AbstractBloomFilterTest LayeredBloomFilter fixed(final Shape shape, final int maxDepth, final Supplier supplier) { + public static > LayeredBloomFilter fixed(final Shape shape, final int maxDepth, final Supplier supplier) { final LayerManager.Builder builder = LayerManager.builder(); builder.setExtendCheck(LayerManager.ExtendCheck.advanceOnPopulated()) .setCleanup(LayerManager.Cleanup.onMaxSize(maxDepth)).setSupplier(supplier); @@ -188,7 +190,7 @@ public class LayeredBloomFilterTest extends AbstractBloomFilterTest createEmptyFilter(final Shape shape) { + protected LayeredBloomFilter createEmptyFilter(final Shape shape) { return LayeredBloomFilterTest.fixed(shape, 10); } @@ -208,8 +210,8 @@ public class LayeredBloomFilterTest extends AbstractBloomFilterTest setupFindTest() { - final LayeredBloomFilter filter = LayeredBloomFilterTest.fixed(getTestShape(), 10); + private LayeredBloomFilter setupFindTest() { + final LayeredBloomFilter filter = LayeredBloomFilterTest.fixed(getTestShape(), 10); filter.merge(TestingHashers.FROM1); filter.merge(TestingHashers.FROM11); filter.merge(new IncrementingHasher(11, 2)); @@ -220,7 +222,7 @@ public class LayeredBloomFilterTest extends AbstractBloomFilterTest layerManager = LayerManager.builder().setExtendCheck(ExtendCheck.neverAdvance()) + final LayerManager layerManager = LayerManager.builder().setExtendCheck(ExtendCheck.neverAdvance()) .setSupplier(() -> new SimpleBloomFilter(getTestShape())).get(); testCardinalityAndIsEmpty(new LayeredBloomFilter<>(getTestShape(), layerManager)); } @@ -230,11 +232,11 @@ public class LayeredBloomFilterTest extends AbstractBloomFilterTest layerManager = LayerManager.builder() .setSupplier(() -> new NumberedBloomFilter(getTestShape(), 3, sequence[0]++)) .setExtendCheck(ExtendCheck.neverAdvance()) - .setCleanup(ll -> ll.removeIf(f -> (((NumberedBloomFilter) f).value-- == 0))).get(); - final LayeredBloomFilter underTest = new LayeredBloomFilter(getTestShape(), layerManager); + .setCleanup(ll -> ll.removeIf(f -> (f.value-- == 0))).get(); + final LayeredBloomFilter underTest = new LayeredBloomFilter<>(getTestShape(), layerManager); assertEquals(1, underTest.getDepth()); underTest.merge(TestingHashers.randomHasher()); underTest.cleanup(); // first count == 2 @@ -243,19 +245,19 @@ public class LayeredBloomFilterTest extends AbstractBloomFilterTest underTest = createTimedLayeredFilter(shape, Duration.ofMillis(600), Duration.ofMillis(150)); + final LayeredBloomFilter> underTest = createTimedLayeredFilter(shape, Duration.ofMillis(600), + Duration.ofMillis(150)); for (int i = 0; i < 10; i++) { underTest.merge(TestingHashers.randomHasher()); @@ -314,7 +317,7 @@ public class LayeredBloomFilterTest extends AbstractBloomFilterTest filter = setupFindTest(); + final LayeredBloomFilter filter = setupFindTest(); IndexExtractor indexExtractor = TestingHashers.FROM1.indices(getTestShape()); BitMapExtractor bitMapExtractor = BitMapExtractor.fromIndexExtractor(indexExtractor, getTestShape().getNumberOfBits()); @@ -332,7 +335,7 @@ public class LayeredBloomFilterTest extends AbstractBloomFilterTest filter = setupFindTest(); + final LayeredBloomFilter filter = setupFindTest(); int[] expected = {0, 3}; int[] result = filter.find(TestingHashers.FROM1); assertArrayEquals(expected, result); @@ -344,7 +347,7 @@ public class LayeredBloomFilterTest extends AbstractBloomFilterTest filter = setupFindTest(); + final LayeredBloomFilter filter = setupFindTest(); int[] expected = {0, 3}; int[] result = filter.find(indexExtractor); @@ -360,7 +363,7 @@ public class LayeredBloomFilterTest extends AbstractBloomFilterTest filter = LayeredBloomFilterTest.fixed(getTestShape(), 10); + final LayeredBloomFilter filter = LayeredBloomFilterTest.fixed(getTestShape(), 10); filter.merge(TestingHashers.FROM1); filter.merge(TestingHashers.FROM11); filter.merge(new IncrementingHasher(11, 2)); @@ -370,7 +373,7 @@ public class LayeredBloomFilterTest extends AbstractBloomFilterTest filter = LayeredBloomFilterTest.fixed(getTestShape(), 10); + final LayeredBloomFilter filter = LayeredBloomFilterTest.fixed(getTestShape(), 10); filter.merge(TestingHashers.FROM1); filter.merge(TestingHashers.FROM11); assertEquals(2, filter.getDepth()); @@ -384,10 +387,8 @@ public class LayeredBloomFilterTest extends AbstractBloomFilterTest layerManager = LayerManager.builder().setSupplier(() -> new SimpleBloomFilter(getTestShape())) - .get(); - - final LayeredBloomFilter filter = new LayeredBloomFilter<>(getTestShape(), layerManager); + final LayerManager layerManager = LayerManager.builder().setSupplier(() -> new SimpleBloomFilter(getTestShape())).get(); + final LayeredBloomFilter filter = new LayeredBloomFilter<>(getTestShape(), layerManager); filter.merge(TestingHashers.FROM1); filter.merge(TestingHashers.FROM11); assertEquals(1, filter.getDepth());