Update DynamicHasher to have a specialised iterator when empty.

Add tests to exercise the empty and non-empty iterators and their
expected exceptions when no more elements.
This commit is contained in:
aherbert 2020-02-18 12:39:11 +00:00
parent 39f0955920
commit 66b418f3e9
2 changed files with 45 additions and 6 deletions

View File

@ -102,9 +102,7 @@ public class DynamicHasher implements Hasher {
@Override
public boolean hasNext() {
if (buffers.isEmpty()) {
return false;
}
// Note: This iterator is only used when buffers.size() is not zero
return buffer < buffers.size() - 1 || funcCount < shape.getNumberOfHashFunctions();
}
@ -123,6 +121,29 @@ public class DynamicHasher implements Hasher {
}
}
/**
* An iterator of integers to use then there are no values.
*/
private static class NoValuesIterator implements PrimitiveIterator.OfInt {
/** The singleton instance. */
private static final NoValuesIterator INSTANCE = new NoValuesIterator();
/**
* Empty constructor.
*/
private NoValuesIterator() {}
@Override
public boolean hasNext() {
return false;
}
@Override
public int nextInt() {
throw new NoSuchElementException();
}
}
/**
* The list of byte arrays that are to be hashed.
*/
@ -163,7 +184,8 @@ public class DynamicHasher implements Hasher {
HashFunctionIdentity.asCommonString(shape.getHashFunctionIdentity()),
HashFunctionIdentity.asCommonString(getHashFunctionIdentity())));
}
return new Iterator(shape);
// Use optimised iterator for no values
return buffers.isEmpty() ? NoValuesIterator.INSTANCE : new Iterator(shape);
}
@Override

View File

@ -22,6 +22,7 @@ import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.util.NoSuchElementException;
import java.util.PrimitiveIterator.OfInt;
import org.apache.commons.collections4.bloomfilter.hasher.function.MD5Cyclic;
@ -108,6 +109,12 @@ public class DynamicHasherTest {
assertEquals(element, iter.nextInt());
}
assertFalse(iter.hasNext());
try {
iter.next();
fail("Should have thown NoSuchElementException");
} catch (final NoSuchElementException ignore) {
// do nothing
}
}
/**
@ -127,11 +134,21 @@ public class DynamicHasherTest {
}
/**
* Tests if isEmpty() reports correctly.
* Tests if isEmpty() reports correctly and the iterator returns no values.
*/
@Test
public void testIsEmpty() {
assertTrue(builder.build().isEmpty());
DynamicHasher hasher = builder.build();
assertTrue(hasher.isEmpty());
final OfInt iter = hasher.getBits(shape);
assertFalse(iter.hasNext());
try {
iter.next();
fail("Should have thown NoSuchElementException");
} catch (final NoSuchElementException expected) {
// do nothing
}
assertFalse(builder.with("Hello").build().isEmpty());
}
}