From 2c35b9c1c9bdad91c4ebba47eb506692faab3400 Mon Sep 17 00:00:00 2001
From: Gary Gregory
Date: Sat, 13 Apr 2024 16:13:01 -0400
Subject: [PATCH 1/4] Remove useless call to String.format()
---
.../org/apache/commons/collections4/bloomfilter/Shape.java | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/src/main/java/org/apache/commons/collections4/bloomfilter/Shape.java b/src/main/java/org/apache/commons/collections4/bloomfilter/Shape.java
index 28667c309..86cd9cd07 100644
--- a/src/main/java/org/apache/commons/collections4/bloomfilter/Shape.java
+++ b/src/main/java/org/apache/commons/collections4/bloomfilter/Shape.java
@@ -137,8 +137,7 @@ public final class Shape {
// exp(-1/Integer.MAX_INT) approx 0.9999999995343387 so Math.pow( x, y ) will
// always be 00
if (probability >= 1.0) {
- throw new IllegalArgumentException(
- String.format("Calculated probability is greater than or equal to 1: " + probability));
+ throw new IllegalArgumentException("Calculated probability is greater than or equal to 1: " + probability);
}
}
From de05f5f126e39a0e907abbcec68ee2554eece779 Mon Sep 17 00:00:00 2001
From: Gary Gregory
Date: Sat, 13 Apr 2024 16:14:55 -0400
Subject: [PATCH 2/4] Use long lines
---
.../commons/collections4/bloomfilter/Shape.java | 15 +++++----------
1 file changed, 5 insertions(+), 10 deletions(-)
diff --git a/src/main/java/org/apache/commons/collections4/bloomfilter/Shape.java b/src/main/java/org/apache/commons/collections4/bloomfilter/Shape.java
index 86cd9cd07..8a184e7da 100644
--- a/src/main/java/org/apache/commons/collections4/bloomfilter/Shape.java
+++ b/src/main/java/org/apache/commons/collections4/bloomfilter/Shape.java
@@ -111,8 +111,7 @@ public final class Shape {
// than integer math.
final long k = Math.round(LN_2 * numberOfBits / numberOfItems);
if (k < 1) {
- throw new IllegalArgumentException(
- String.format("Filter too small: Calculated number of hash functions (%s) was less than 1", k));
+ throw new IllegalArgumentException(String.format("Filter too small: Calculated number of hash functions (%s) was less than 1", k));
}
// Normally we would check that numberOfHashFunctions <= Integer.MAX_VALUE but
// since numberOfBits is at most Integer.MAX_VALUE the numerator of
@@ -164,8 +163,7 @@ public final class Shape {
*/
private static int checkNumberOfHashFunctions(final int numberOfHashFunctions) {
if (numberOfHashFunctions < 1) {
- throw new IllegalArgumentException(
- "Number of hash functions must be greater than 0: " + numberOfHashFunctions);
+ throw new IllegalArgumentException("Number of hash functions must be greater than 0: " + numberOfHashFunctions);
}
return numberOfHashFunctions;
}
@@ -329,8 +327,7 @@ public final class Shape {
// Number of items (n):
// n = ceil(m / (-k / ln(1 - exp(ln(p) / k))))
- final double n = Math.ceil(numberOfBits
- / (-numberOfHashFunctions / Math.log(-Math.expm1(Math.log(probability) / numberOfHashFunctions))));
+ final double n = Math.ceil(numberOfBits / (-numberOfHashFunctions / Math.log(-Math.expm1(Math.log(probability) / numberOfHashFunctions))));
// log of probability is always < 0
// number of hash functions is >= 1
@@ -377,8 +374,7 @@ public final class Shape {
// Shape is final so no check for the same class as inheritance is not possible
if (obj instanceof Shape) {
final Shape other = (Shape) obj;
- return numberOfBits == other.numberOfBits &&
- numberOfHashFunctions == other.numberOfHashFunctions;
+ return numberOfBits == other.numberOfBits && numberOfHashFunctions == other.numberOfHashFunctions;
}
return false;
}
@@ -462,8 +458,7 @@ public final class Shape {
if (numberOfItems == 0) {
return 0;
}
- return Math.pow(-Math.expm1(-1.0 * numberOfHashFunctions * numberOfItems / numberOfBits),
- numberOfHashFunctions);
+ return Math.pow(-Math.expm1(-1.0 * numberOfHashFunctions * numberOfItems / numberOfBits), numberOfHashFunctions);
}
@Override
From cc651b2db9eed97e9e02ee2bb521c3c47807f4a9 Mon Sep 17 00:00:00 2001
From: Claude Warren
Date: Wed, 17 Apr 2024 13:48:39 +0100
Subject: [PATCH 3/4] Collections-852: add layerd bloom filter clean method
(#476)
* Initial implementation and LayerManager test
* updated LayeredBloomFilterTest - fixed checkstyle issues
* changes as requested in review
---
.../bloomfilter/LayerManager.java | 16 ++++++++-
.../bloomfilter/LayeredBloomFilter.java | 18 ++++++++--
.../bloomfilter/LayerManagerTest.java | 9 +++++
.../bloomfilter/LayeredBloomFilterTest.java | 34 +++++++++++++++++++
4 files changed, 73 insertions(+), 4 deletions(-)
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 a80d3c4cc..b139d16ce 100644
--- a/src/main/java/org/apache/commons/collections4/bloomfilter/LayerManager.java
+++ b/src/main/java/org/apache/commons/collections4/bloomfilter/LayerManager.java
@@ -82,7 +82,7 @@ public class LayerManager implements BloomFilterProducer {
*
* @param cleanup the Consumer that will modify the list of filters removing out
* dated or stale filters.
- * @return this for chaining.
+ * @return this
*/
public Builder setCleanup(Consumer> cleanup) {
this.cleanup = cleanup;
@@ -375,9 +375,23 @@ public class LayerManager implements BloomFilterProducer {
* Ths method is used within {@link #getTarget()} when the configured
* {@code ExtendCheck} returns {@code true}.
*
+ * @see LayerManager.Builder#setExtendCheck(Predicate)
+ * @see LayerManager.Builder#setCleanup(Consumer)
*/
void next() {
this.filterCleanup.accept(filters);
addFilter();
}
+
+ /**
+ * Forces execution the configured cleanup without creating a new filter except in cases
+ * where the cleanup removes all the layers.
+ * @see LayerManager.Builder#setCleanup(Consumer)
+ */
+ void cleanup() {
+ this.filterCleanup.accept(filters);
+ if (filters.isEmpty()) {
+ addFilter();
+ }
+ }
}
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 01e32d8b6..9ed2688bb 100644
--- a/src/main/java/org/apache/commons/collections4/bloomfilter/LayeredBloomFilter.java
+++ b/src/main/java/org/apache/commons/collections4/bloomfilter/LayeredBloomFilter.java
@@ -369,12 +369,24 @@ public class LayeredBloomFilter implements BloomFilter, BloomFilterProducer {
}
/**
- * Forces and advance to the next layer. Executes the same logic as when
- * LayerManager.extendCheck returns {@code true}
+ * Forces and advance to the next layer. This method will clean-up the current
+ * layers and generate a new filter layer. In most cases is it unnecessary to
+ * call this method directly.
*
- * @see LayerManager
+ * @see LayerManager.Builder#setCleanup(java.util.function.Consumer)
+ * @see LayerManager.Builder#setExtendCheck(Predicate)
*/
public void next() {
layerManager.next();
}
+
+ /**
+ * Forces the execution of the cleanup Consumer that was provided when the associated LayerManager
+ * was built.
+ *
+ * @see LayerManager.Builder#setCleanup(java.util.function.Consumer)
+ */
+ public void cleanup() {
+ layerManager.cleanup();
+ }
}
diff --git a/src/test/java/org/apache/commons/collections4/bloomfilter/LayerManagerTest.java b/src/test/java/org/apache/commons/collections4/bloomfilter/LayerManagerTest.java
index 679f263e3..4ee438b89 100644
--- a/src/test/java/org/apache/commons/collections4/bloomfilter/LayerManagerTest.java
+++ b/src/test/java/org/apache/commons/collections4/bloomfilter/LayerManagerTest.java
@@ -291,4 +291,13 @@ public class LayerManagerTest {
assertEquals(2, supplierCount[0]);
}
+ static class NumberedBloomFilter extends WrappedBloomFilter {
+ int value;
+ int sequence;
+ NumberedBloomFilter(Shape shape, int value, int sequence) {
+ super(new SimpleBloomFilter(shape));
+ this.value = value;
+ this.sequence = sequence;
+ }
+ }
}
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 bd4e59ca9..0859e58c6 100644
--- a/src/test/java/org/apache/commons/collections4/bloomfilter/LayeredBloomFilterTest.java
+++ b/src/test/java/org/apache/commons/collections4/bloomfilter/LayeredBloomFilterTest.java
@@ -16,6 +16,7 @@
*/
package org.apache.commons.collections4.bloomfilter;
+import static org.junit.Assert.assertEquals;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
@@ -30,6 +31,7 @@ import java.util.function.Predicate;
import org.apache.commons.collections4.bloomfilter.LayerManager.Cleanup;
import org.apache.commons.collections4.bloomfilter.LayerManager.ExtendCheck;
+import org.apache.commons.collections4.bloomfilter.LayerManagerTest.NumberedBloomFilter;
import org.junit.jupiter.api.Test;
public class LayeredBloomFilterTest extends AbstractBloomFilterTest {
@@ -311,4 +313,36 @@ public class LayeredBloomFilterTest extends AbstractBloomFilterTest new NumberedBloomFilter(getTestShape(), 3, sequence[0]++))
+ .setExtendCheck(ExtendCheck.neverAdvance())
+ .setCleanup(ll -> ll.removeIf( f -> (((NumberedBloomFilter) f).value-- == 0))).build();
+ LayeredBloomFilter underTest = new LayeredBloomFilter(getTestShape(), layerManager );
+ assertEquals(1, underTest.getDepth());
+ underTest.merge(TestingHashers.randomHasher());
+ underTest.cleanup(); // first count == 2
+ assertEquals(1, underTest.getDepth());
+ underTest.next(); // first count == 1
+ assertEquals(2, underTest.getDepth());
+ underTest.merge(TestingHashers.randomHasher());
+ underTest.cleanup(); // first count == 0
+ NumberedBloomFilter f = (NumberedBloomFilter) underTest.get(0);
+ assertEquals(1, f.sequence);
+
+ assertEquals(2, underTest.getDepth());
+ underTest.cleanup(); // should be removed ; second is now 1st with value 1
+ assertEquals(1, underTest.getDepth());
+ f = (NumberedBloomFilter) underTest.get(0);
+ assertEquals(2, f.sequence);
+
+ underTest.cleanup(); // first count == 0
+ underTest.cleanup(); // should be removed. But there is always at least one
+ assertEquals(1, underTest.getDepth());
+ f = (NumberedBloomFilter) underTest.get(0);
+ assertEquals(3, f.sequence); // it is a new one.
+ }
}
From cb47bc8c5a00c887b168befa3f499410deba5289 Mon Sep 17 00:00:00 2001
From: Gary Gregory
Date: Wed, 17 Apr 2024 08:50:51 -0400
Subject: [PATCH 4/4] [COLLECTIONS-852] Add layerd bloom filter clean method
#476
---
src/changes/changes.xml | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index bfd18c3aa..b49aeba4d 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -23,6 +23,8 @@
+
+ Add layerd bloom filter clean method #476 .
Bump org.apache.commons:commons-parent from 67 to 69 #473.