Sort members
This commit is contained in:
parent
1a9ff2f6ba
commit
5051dbf0b5
|
@ -299,6 +299,18 @@ public class LayerManager<T extends BloomFilter> implements BloomFilterProducer
|
|||
filters.add(bf);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all the filters from the layer manager, and sets up a new one as the
|
||||
* target.
|
||||
|
@ -325,6 +337,16 @@ public class LayerManager<T extends BloomFilter> implements BloomFilterProducer
|
|||
return newMgr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Bloom filter from the first layer.
|
||||
* No extension check is performed during this call.
|
||||
* @return The Bloom filter from the first layer.
|
||||
* @see #getTarget()
|
||||
*/
|
||||
public final T first() {
|
||||
return filters.getFirst();
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes a Bloom filter Predicate on each Bloom filter in the manager in
|
||||
* depth order. Oldest filter first.
|
||||
|
@ -369,26 +391,6 @@ public class LayerManager<T extends BloomFilter> implements BloomFilterProducer
|
|||
return filters.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Bloom filter from the first layer.
|
||||
* No extension check is performed during this call.
|
||||
* @return The Bloom filter from the first layer.
|
||||
* @see #getTarget()
|
||||
*/
|
||||
public final T first() {
|
||||
return filters.getFirst();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Bloom filter from the last layer.
|
||||
* No extension check is performed during this call.
|
||||
* @return The Bloom filter from the last layer.
|
||||
* @see #getTarget()
|
||||
*/
|
||||
public final T last() {
|
||||
return filters.getLast();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current target filter. If a new filter should be created based on
|
||||
* {@code extendCheck} it will be created before this method returns.
|
||||
|
@ -402,6 +404,16 @@ public class LayerManager<T extends BloomFilter> implements BloomFilterProducer
|
|||
return last();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Bloom filter from the last layer.
|
||||
* No extension check is performed during this call.
|
||||
* @return The Bloom filter from the last layer.
|
||||
* @see #getTarget()
|
||||
*/
|
||||
public final T last() {
|
||||
return filters.getLast();
|
||||
}
|
||||
|
||||
/**
|
||||
* Forces an advance to the next depth. This method will clean-up the current
|
||||
* layers and generate a new filter layer. In most cases is it unnecessary to
|
||||
|
@ -417,16 +429,4 @@ public class LayerManager<T extends BloomFilter> implements BloomFilterProducer
|
|||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -115,6 +115,16 @@ public class LayeredBloomFilter<T extends BloomFilter> implements BloomFilter, B
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void clear() {
|
||||
layerManager.clear();
|
||||
|
@ -366,14 +376,4 @@ public class LayeredBloomFilter<T extends BloomFilter> implements BloomFilter, B
|
|||
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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,10 +36,6 @@ public abstract class WrappedBloomFilter implements BloomFilter {
|
|||
this.wrapped = bf;
|
||||
}
|
||||
|
||||
protected BloomFilter getWrapped() {
|
||||
return wrapped;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long[] asBitMapArray() {
|
||||
return wrapped.asBitMapArray();
|
||||
|
@ -120,6 +116,10 @@ public abstract class WrappedBloomFilter implements BloomFilter {
|
|||
return wrapped.getShape();
|
||||
}
|
||||
|
||||
protected BloomFilter getWrapped() {
|
||||
return wrapped;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFull() {
|
||||
return wrapped.isFull();
|
||||
|
|
|
@ -36,36 +36,6 @@ import org.junit.jupiter.api.Test;
|
|||
|
||||
public class LayeredBloomFilterTest extends AbstractBloomFilterTest<LayeredBloomFilter<?>> {
|
||||
|
||||
/**
|
||||
* Creates a fixed size layered bloom filter that adds new filters to the list,
|
||||
* but never merges them. List will never exceed maxDepth. As additional filters
|
||||
* are added earlier filters are removed. Uses SimpleBloomFilters.
|
||||
*
|
||||
* @param shape The shape for the enclosed Bloom filters.
|
||||
* @param maxDepth The maximum depth of layers.
|
||||
* @return An empty layered Bloom filter of the specified shape and depth.
|
||||
*/
|
||||
public static LayeredBloomFilter<BloomFilter> fixed(final Shape shape, int maxDepth) {
|
||||
return fixed(shape, maxDepth, () -> new SimpleBloomFilter(shape));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a fixed size layered bloom filter that adds new filters to the list,
|
||||
* but never merges them. List will never exceed maxDepth. As additional filters
|
||||
* are added earlier filters are removed.
|
||||
*
|
||||
* @param shape The shape for the enclosed Bloom filters.
|
||||
* @param maxDepth The maximum depth of layers.
|
||||
* @param supplier A supplier of the Bloom filters to create layers with.
|
||||
* @return An empty layered Bloom filter of the specified shape and depth.
|
||||
*/
|
||||
public static <T extends BloomFilter> LayeredBloomFilter<T> fixed(final Shape shape, int maxDepth, Supplier<T> supplier) {
|
||||
LayerManager.Builder<T> builder = LayerManager.builder();
|
||||
builder.setExtendCheck(LayerManager.ExtendCheck.advanceOnPopulated())
|
||||
.setCleanup(LayerManager.Cleanup.onMaxSize(maxDepth)).setSupplier(supplier);
|
||||
return new LayeredBloomFilter<>(shape, builder.build());
|
||||
}
|
||||
|
||||
/**
|
||||
* A Predicate that advances after a quantum of time.
|
||||
*/
|
||||
|
@ -111,6 +81,21 @@ public class LayeredBloomFilterTest extends AbstractBloomFilterTest<LayeredBloom
|
|||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BloomFilter copy() {
|
||||
return new NumberedBloomFilter(getShape(), value, sequence);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A Bloomfilter implementation that tracks the creation time.
|
||||
*/
|
||||
|
@ -127,14 +112,14 @@ public class LayeredBloomFilterTest extends AbstractBloomFilterTest<LayeredBloom
|
|||
this.timestamp = timestamp;
|
||||
}
|
||||
|
||||
public long getTimestamp() {
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TimestampedBloomFilter copy() {
|
||||
return new TimestampedBloomFilter(this.getWrapped().copy(), timestamp);
|
||||
}
|
||||
|
||||
public long getTimestamp() {
|
||||
return timestamp;
|
||||
}
|
||||
}
|
||||
|
||||
// ***example of instrumentation ***
|
||||
|
@ -166,6 +151,36 @@ public class LayeredBloomFilterTest extends AbstractBloomFilterTest<LayeredBloom
|
|||
return new LayeredBloomFilter<>(shape, layerManager);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a fixed size layered bloom filter that adds new filters to the list,
|
||||
* but never merges them. List will never exceed maxDepth. As additional filters
|
||||
* are added earlier filters are removed. Uses SimpleBloomFilters.
|
||||
*
|
||||
* @param shape The shape for the enclosed Bloom filters.
|
||||
* @param maxDepth The maximum depth of layers.
|
||||
* @return An empty layered Bloom filter of the specified shape and depth.
|
||||
*/
|
||||
public static LayeredBloomFilter<BloomFilter> fixed(final Shape shape, int maxDepth) {
|
||||
return fixed(shape, maxDepth, () -> new SimpleBloomFilter(shape));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a fixed size layered bloom filter that adds new filters to the list,
|
||||
* but never merges them. List will never exceed maxDepth. As additional filters
|
||||
* are added earlier filters are removed.
|
||||
*
|
||||
* @param shape The shape for the enclosed Bloom filters.
|
||||
* @param maxDepth The maximum depth of layers.
|
||||
* @param supplier A supplier of the Bloom filters to create layers with.
|
||||
* @return An empty layered Bloom filter of the specified shape and depth.
|
||||
*/
|
||||
public static <T extends BloomFilter> LayeredBloomFilter<T> fixed(final Shape shape, int maxDepth, Supplier<T> supplier) {
|
||||
LayerManager.Builder<T> builder = LayerManager.builder();
|
||||
builder.setExtendCheck(LayerManager.ExtendCheck.advanceOnPopulated())
|
||||
.setCleanup(LayerManager.Cleanup.onMaxSize(maxDepth)).setSupplier(supplier);
|
||||
return new LayeredBloomFilter<>(shape, builder.build());
|
||||
}
|
||||
|
||||
// instrumentation to record timestamps in dbgInstrument list
|
||||
private final Predicate<BloomFilter> dbg = (bf) -> {
|
||||
TimestampedBloomFilter tbf = (TimestampedBloomFilter) bf;
|
||||
|
@ -214,6 +229,39 @@ public class LayeredBloomFilterTest extends AbstractBloomFilterTest<LayeredBloom
|
|||
testCardinalityAndIsEmpty(new LayeredBloomFilter<>(getTestShape(), layerManager));
|
||||
}
|
||||
|
||||
// ***** TESTS THAT CHECK LAYERED PROCESSING ******
|
||||
|
||||
@Test
|
||||
public void testCleanup() {
|
||||
int[] sequence = {1};
|
||||
LayerManager layerManager = LayerManager.builder()
|
||||
.setSupplier(() -> 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.
|
||||
}
|
||||
/**
|
||||
* Tests that the estimated union calculations are correct.
|
||||
*/
|
||||
|
@ -227,8 +275,6 @@ public class LayeredBloomFilterTest extends AbstractBloomFilterTest<LayeredBloom
|
|||
assertEquals(2, bf2.estimateUnion(bf));
|
||||
}
|
||||
|
||||
// ***** TESTS THAT CHECK LAYERED PROCESSING ******
|
||||
|
||||
@Test
|
||||
public void testExpiration() throws InterruptedException {
|
||||
// this test uses the instrumentation noted above to track changes for debugging
|
||||
|
@ -270,6 +316,7 @@ public class LayeredBloomFilterTest extends AbstractBloomFilterTest<LayeredBloom
|
|||
assertTrue(underTest.forEachBloomFilter(dbg.and(x -> !lst.contains(((TimestampedBloomFilter) x).timestamp))),
|
||||
"Found filter that should have been deleted: " + dbgInstrument.get(dbgInstrument.size() - 1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFindBitMapProducer() {
|
||||
LayeredBloomFilter<BloomFilter> filter = setupFindTest();
|
||||
|
@ -359,51 +406,4 @@ public class LayeredBloomFilterTest extends AbstractBloomFilterTest<LayeredBloom
|
|||
assertFalse(filter.get(1).contains(TestingHashers.FROM11));
|
||||
assertTrue(filter.get(1).contains(new IncrementingHasher(11, 2)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCleanup() {
|
||||
int[] sequence = {1};
|
||||
LayerManager layerManager = LayerManager.builder()
|
||||
.setSupplier(() -> 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.
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BloomFilter copy() {
|
||||
return new NumberedBloomFilter(getShape(), value, sequence);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,6 +32,22 @@ import org.junit.jupiter.api.Test;
|
|||
*/
|
||||
public class DefaultAbstractLinkedListForJava21Test<E> extends AbstractListTest<E> {
|
||||
|
||||
private static class DefaultAbstractLinkedListForJava21<E> extends AbstractLinkedListForJava21<E> {
|
||||
DefaultAbstractLinkedListForJava21() {
|
||||
init();
|
||||
}
|
||||
|
||||
private void readObject(final ObjectInputStream in) throws IOException, ClassNotFoundException {
|
||||
in.defaultReadObject();
|
||||
doReadObject(in);
|
||||
}
|
||||
|
||||
private void writeObject(final ObjectOutputStream out) throws IOException {
|
||||
out.defaultWriteObject();
|
||||
doWriteObject(out);
|
||||
}
|
||||
}
|
||||
|
||||
public DefaultAbstractLinkedListForJava21Test() {
|
||||
super(DefaultAbstractLinkedListForJava21Test.class.getSimpleName());
|
||||
}
|
||||
|
@ -47,6 +63,26 @@ public class DefaultAbstractLinkedListForJava21Test<E> extends AbstractListTest<
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public AbstractLinkedListForJava21<E> getCollection() {
|
||||
return (AbstractLinkedListForJava21<E>) super.getCollection();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCompatibilityVersion() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<E> makeObject() {
|
||||
return new DefaultAbstractLinkedListForJava21<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean skipSerializedCanonicalTests() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testAddNodeAfter() {
|
||||
|
@ -178,26 +214,6 @@ public class DefaultAbstractLinkedListForJava21Test<E> extends AbstractListTest<
|
|||
checkNodes();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCompatibilityVersion() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean skipSerializedCanonicalTests() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AbstractLinkedListForJava21<E> getCollection() {
|
||||
return (AbstractLinkedListForJava21<E>) super.getCollection();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<E> makeObject() {
|
||||
return new DefaultAbstractLinkedListForJava21<>();
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testSubList() {
|
||||
|
@ -297,20 +313,4 @@ public class DefaultAbstractLinkedListForJava21Test<E> extends AbstractListTest<
|
|||
assertEquals("[]", sublist.toString());
|
||||
assertEquals("[A, E]", list.toString());
|
||||
}
|
||||
|
||||
private static class DefaultAbstractLinkedListForJava21<E> extends AbstractLinkedListForJava21<E> {
|
||||
DefaultAbstractLinkedListForJava21() {
|
||||
init();
|
||||
}
|
||||
|
||||
private void readObject(final ObjectInputStream in) throws IOException, ClassNotFoundException {
|
||||
in.defaultReadObject();
|
||||
doReadObject(in);
|
||||
}
|
||||
|
||||
private void writeObject(final ObjectOutputStream out) throws IOException {
|
||||
out.defaultWriteObject();
|
||||
doWriteObject(out);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue