Author: schor
Date: Fri Oct 24 21:23:32 2014
New Revision: 1634141
URL: http://svn.apache.org/r1634141
Log:
[UIMA-4061] improve Positive Int Set switching logic and measurements, update
tests
Modified:
uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/internal/util/IntBitSet.java
uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/internal/util/IntHashSet.java
uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/internal/util/PositiveIntSet.java
uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/internal/util/IntBitSetTest.java
uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/internal/util/IntHashSetTest.java
uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/internal/util/PositiveIntSetTest.java
Modified:
uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/internal/util/IntBitSet.java
URL:
http://svn.apache.org/viewvc/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/internal/util/IntBitSet.java?rev=1634141&r1=1634140&r2=1634141&view=diff
==============================================================================
---
uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/internal/util/IntBitSet.java
(original)
+++
uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/internal/util/IntBitSet.java
Fri Oct 24 21:23:32 2014
@@ -42,25 +42,25 @@ public class IntBitSet {
private int size = 0; // tracked here to avoid slow counting of cardinality
- private int offset = 0;
+ private final int offset;
- /**
- * Sets the lowest int value that can be kept; trying to add a lower one
throws an error
- * <ul>
- * <li>Allows for a more compact representation, potentially</li>
- * <li>only can be set if the size is 0</li>
- * </ul>
- * @param offset - the lowest value that can be kept in the set. 0 is
allowed.
- */
- public void setOffset(int offset) {
- if (size != 0) {
- throw new IllegalStateException("Cannot set offset unless set is empty");
- }
- if (offset < 0) {
- throw new IllegalArgumentException("Offset must be 0 or a positive int,
was " + offset);
- }
- this.offset = offset;
- }
+// /**
+// * Sets the lowest int value that can be kept; trying to add a lower one
throws an error
+// * <ul>
+// * <li>Allows for a more compact representation, potentially</li>
+// * <li>only can be set if the size is 0</li>
+// * </ul>
+// * @param offset - the lowest value that can be kept in the set. 0 is
allowed.
+// */
+// public void setOffset(int offset) {
+// if (size != 0) {
+// throw new IllegalStateException("Cannot set offset unless set is
empty");
+// }
+// if (offset < 0) {
+// throw new IllegalArgumentException("Offset must be 0 or a positive
int, was " + offset);
+// }
+// this.offset = offset;
+// }
/**
* @return the current offset
*/
@@ -80,7 +80,12 @@ public class IntBitSet {
* @param maxInt the biggest int (perhaps plus an offset) that can be held
without growing the space
*/
public IntBitSet(int maxInt) {
+ this(maxInt, 0);
+ }
+
+ public IntBitSet(int maxInt, int offset) {
set = new BitSet(Math.max(1, maxInt));
+ this.offset = offset;
}
/**
Modified:
uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/internal/util/IntHashSet.java
URL:
http://svn.apache.org/viewvc/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/internal/util/IntHashSet.java?rev=1634141&r1=1634140&r2=1634141&view=diff
==============================================================================
---
uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/internal/util/IntHashSet.java
(original)
+++
uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/internal/util/IntHashSet.java
Fri Oct 24 21:23:32 2014
@@ -36,6 +36,7 @@ import org.apache.uima.jcas.impl.JCasHas
*/
public class IntHashSet {
+ public static final float DEFAULT_LOAD_FACTOR = 0.66F;
// set to true to collect statistics for tuning
// you have to also put a call to showHistogram() at the end of the run
private static final boolean TUNE = false;
@@ -49,7 +50,7 @@ public class IntHashSet {
// 3 * 4 12 bytes per entry
// This compares with 160 bytes/entry for the IntArrayRBT impl
- private final float loadFactor = 0.66F;
+ private final float loadFactor = DEFAULT_LOAD_FACTOR;
private final int initialCapacity;
@@ -81,6 +82,32 @@ public class IntHashSet {
}
}
+ /**
+ * The number of 32 bit words that are reserved when
+ * creating a table to hold the specified number of elements
+ *
+ * The number is a power of 2.
+ *
+ * The number is at least 16.
+ *
+ * The number is such that you could add this many elements without
+ * triggering the capacity expansion.
+ *
+ * @param numberOfElements
+ * @return
+ */
+ public int tableSpace(int numberOfElements) {
+ return tableSpace(numberOfElements, loadFactor);
+ }
+
+ public static int tableSpace(int numberOfElements, Float factor) {
+ if (numberOfElements < 0) {
+ throw new IllegalArgumentException("must be > 0");
+ }
+ final int capacity = Math.round(numberOfElements / factor);
+ return Math.max(16, nextHigherPowerOf2(capacity));
+ }
+
private void newTableKeepSize(int capacity) {
capacity = Math.max(16, nextHigherPowerOf2(capacity));
keys = new int[capacity];
@@ -94,8 +121,20 @@ public class IntHashSet {
size++;
}
+ public boolean wontExpand() {
+ return wontExpand(1);
+ }
+
+ public boolean wontExpand(int n) {
+ return (size + n) < sizeWhichTriggersExpansion;
+ }
+
public int getSpaceUsedInWords() {
- return keys.length + 8; // 8 is overhead for this class excluding any
Java object overhead
+ return keys.length; // 8 is overhead for this class excluding any Java
object overhead
+ }
+
+ public static int getSpaceOverheadInWords() {
+ return 8;
}
private void increaseTableCapacity() {
@@ -256,6 +295,12 @@ public class IntHashSet {
if (keys[i] != 0) {
keys[i] = 0;
size--;
+ if (key == mostPositive) {
+ mostPositive --; // a weak adjustment
+ }
+ if (key == mostNegative) {
+ mostNegative ++; // a weak adjustment
+ }
return true;
}
return false;
Modified:
uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/internal/util/PositiveIntSet.java
URL:
http://svn.apache.org/viewvc/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/internal/util/PositiveIntSet.java?rev=1634141&r1=1634140&r2=1634141&view=diff
==============================================================================
---
uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/internal/util/PositiveIntSet.java
(original)
+++
uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/internal/util/PositiveIntSet.java
Fri Oct 24 21:23:32 2014
@@ -32,19 +32,29 @@ import java.util.NoSuchElementException;
*
* For more dense ints, it uses bitSets or bitSets with an offset
*
- * It switches when adding new members if the other representation is
sufficiently smaller (using a Hysteresis of 16 words)
+ * It switches when adding new members if the other representation is
sufficiently smaller
*/
public class PositiveIntSet {
// number of words a inthashset has to be better than intbitset to cause
switch
private static final int HYSTERESIS = 16;
-
- private IntBitSet intBitSet;
- private IntHashSet intHashSet;
+ // Extra space in bitset for initial capacity - can add an int up to that
size
+ // 64 *4 is 8 words, = 256.
+ private static final int BIT_SET_OVERALLOCATE = 64 * 4;
+
+ // Extra space in hashset for initial capacity - can add a minimum of that
many more members
+ // without hitting the hash-set doubling.
+ private static final int HASH_SET_OVERALLOCATE = 8;
+ // Extra space in hashset for initial capacity - when creating from bitmap
set - multiplier of existing size
+ private static final int HASH_SET_OVERALLOCATE_MULTIPLIER = 1; // bit shift
right = divide by 2 = 50% of existing capacity
+
+ private IntBitSet intBitSet = null;
+
+ private IntHashSet intHashSet = null;
//package private for test case
- boolean isBitSet;
+ boolean isBitSet = true;
/**
* Set false once we find we have to reduce the bit offset
@@ -52,11 +62,6 @@ public class PositiveIntSet {
//package private for test case
boolean useOffset = true;
- public PositiveIntSet() {
- intBitSet = new IntBitSet();
- isBitSet = true;
- }
-
public IntListIterator getUnorderedIterator() {
if (isBitSet) {
return intBitSet.getIterator();
@@ -166,13 +171,13 @@ public class PositiveIntSet {
*/
private void adjustBitSetForLowerOffset(int key) {
final int largestInt = intBitSet.getLargestMenber();
- final int bitSetSpaceNeeded = getBitSetSpaceFromMaxInt(largestInt); //
doesn't use offset
+ final int bitSetSpaceNeeded = getBitSetSpaceFromMaxInt(largestInt, 0); //
doesn't use offset
final int hashSetSpaceNeeded = getHashSetSpace(intBitSet.size());
if (hashSetSpaceNeeded < (bitSetSpaceNeeded - HYSTERESIS)) {
switchToHashSet(size());
} else {
- IntBitSet bs = new IntBitSet(largestInt);
+ IntBitSet bs = new IntBitSet(largestInt + BIT_SET_OVERALLOCATE);
IntListIterator it = intBitSet.getIterator();
while (it.hasNext()) {
bs.add(it.next());
@@ -224,40 +229,75 @@ public class PositiveIntSet {
}
/**
- * number of 32 bit words in use by bit set, given the max key (less offset)
+ * Only called if key won't fit in existing hashset allocation
+ *
+ * Using existing bitset, compute what its size() (capacity) would be if the
+ * key were added; include the overhead of the intbitset class.
+ *
+ * long words required = larger of double the current size, or the number of
words required
+
* @param maxKeyLessOffset
* @return number of words needed to store the highest value
*/
- private int getBitSetSpaceFromMaxInt(int maxKeyLessOffset) {
+ private int getBitSetSpaceFromMaxInt(int maxKeyLessOffset, int spaceUsed) {
+ int w64 = 1 + (maxKeyLessOffset >> 6); // 64 bits per long, add one
because 0 to 63 takes one word)
+ spaceUsed = spaceUsed >> 5; // in # of long words, * 2 because the alloc
doubles the space
+
+ int newSpace = Math.max(spaceUsed, w64) << 1; // size is in 32 bit words
at the end
// e.g., 31 key => 1 word, 32 key => 2 words
- return 2 + (maxKeyLessOffset >> 5) + 2; // add 2 because the bits are
stored in 2 words (1 long), and 2 more for IntBitSet object overhead
+ return newSpace + 2; // 2 more for IntBitSet object overhead
}
- private int getHashSetSpace(int numberOfEntries) {
- long v = numberOfEntries * 3 + 8; // plus 8 is for the overhead of the
intHashSet object.
- if (v > Integer.MAX_VALUE) {
- throw new RuntimeException("value overflowed int, orig was " +
numberOfEntries);
- }
- return (int) v; // the number of 32 bit words needed is 1.5 to 3; 3 is
worst case
+ /**
+ * Only called if key won't fit in existing allocation
+ *
+ * returns new hash table size ( usually double) + overhead
+ *
+ * @param numberOfEntries
+ * @return
+ */
+ private int getHashSetSpace() {
+ return intHashSet.getSpaceUsedInWords() * 2 +
IntHashSet.getSpaceOverheadInWords();
+ }
+
+ /**
+ * When converting from bitset to hash set, the initial hash set should be
+ * big enough so that it takes a while before it is doubled-expanded.
+ *
+ * @param existingSize
+ * @return
+ */
+ private int getHashSetOverAllocateSize(int existingSize) {
+ return existingSize + (existingSize >> HASH_SET_OVERALLOCATE_MULTIPLIER) +
HASH_SET_OVERALLOCATE;
+ }
+
+ /**
+ * For the case where the intHashSet doesn't yet exist
+ * @param numberOfElements -
+ * @return the size in words
+ */
+ private int getHashSetSpace(int numberOfElements) {
+ return IntHashSet.tableSpace(numberOfElements,
IntHashSet.DEFAULT_LOAD_FACTOR) +
+ IntHashSet.getSpaceOverheadInWords();
}
/**
* logic for switching representation
*
* BitSet preferred - is faster, can be more compact, and permits ordered
iteration
- *
* HashSet used when BitSet is too space inefficient.
- * MaxInt stored determines size: = MaxInt / 8 bytes.
- * HashSet takes 12 bytes / entry.
- *
- * switch to HashSet from BitSet if:
- * HashSet space < BitSet space
- * size * 12 MaxInt / 8
- * with hysteresis
+ *
+ * Avoid switching if the new key being added won't increase the
representation size
+ * - for hash: if number of elements +1 won't cause doubling of the hash
table
+ * - for bitset: if key will fit in existing "capacity"
+ *
+ * Compute space needed after adding
+ * - bitset: array doubles
+ * - hashset: array doubles
*
- * switch to BitSet from HashSet if:
- * BitSet used when its space requirement is less than hashset, with
hysteresis:
- *
+ * Preventing jitters back and forth:
+ * - removes don't cause switching
+ * - compare against other size including its non-linear space jumps.
*/
private void maybeSwitchRepresentation(int key) {
@@ -272,11 +312,24 @@ public class PositiveIntSet {
* unless that has been a bad strategy for this
* instance already
********/
- if (intBitSet.size() == 0 && useOffset) {
- // initialize bitSetOffset to the key, minus some amount to allow a
bit of previous values
- intBitSet.setOffset(Math.max(0, key - 63));
- // because of offset, won't have to switch to hash for this key
- return;
+ if (intBitSet == null) {
+ if (useOffset) {
+
+ // initialize bitSetOffset to the key, minus some amount to allow
some storage of previous values
+ // a minimum of 63, a maximum of 512 == 16 words, when key is > 4K
(128 words)
+ final int spaceForLesserKeys = Math.min(1023, Math.max(63, key >>
3));
+ final int offset = Math.max(0, key - spaceForLesserKeys);
+ intBitSet = new IntBitSet(BIT_SET_OVERALLOCATE + key - offset,
offset);
+ // because of offset, won't have to switch to hash for this key
+ //
+ // force an initial allocation of this sufficient to keep
+ // a) the space below, plus
+ // b)
+ return;
+ } else {
+ intBitSet = new IntBitSet(BIT_SET_OVERALLOCATE + key);
+ // don't return, see if we should immediately switch to hash
representation
+ }
}
final int offset = intBitSet.getOffset();
@@ -287,16 +340,18 @@ public class PositiveIntSet {
}
// return if key fits in existing allocation
- if ((key - offset) < intBitSet.getSpaceUsed_in_bits()) {
+ final int spaceUsed = intBitSet.getSpaceUsed_in_bits();
+ if ((key - offset) < spaceUsed) {
return;
}
// space used in words (32 bit words)
- final int bitSetSpaceNeeded = getBitSetSpaceFromMaxInt(key - offset);
- final int hashSetSpaceNeeded = getHashSetSpace(intBitSet.size());
+ final int bitSetSpaceNeeded = getBitSetSpaceFromMaxInt(key - offset,
spaceUsed);
+ final int hashSetOverAllocateSize =
getHashSetOverAllocateSize(intBitSet.size() + 1);
+ final int hashSetOverAllocateSpace =
getHashSetSpace(hashSetOverAllocateSize);
// switch if hashmap space plus hysteresis would be < bitmap space
- if (hashSetSpaceNeeded < (bitSetSpaceNeeded - HYSTERESIS)) {
- switchToHashSet(intBitSet.size());
+ if (hashSetOverAllocateSpace < (bitSetSpaceNeeded - HYSTERESIS)) {
+ switchToHashSet(hashSetOverAllocateSize);
}
return;
}
@@ -308,12 +363,16 @@ public class PositiveIntSet {
// space used in words (32 bit words)
// don't bother to include the new element - it might not be "added"
// if it was already there, and only serves to decrease hysteresis a bit
+
+ if (intHashSet.wontExpand()) {
+ return;
+ }
- final int hashSetSpaceNeeded = getHashSetSpace(size());
+ final int hashSetSpaceNeeded = getHashSetSpace();
final int maxInt = intHashSet.getMostPositive();
final int offset = useOffset ? intHashSet.getMostNegative() : 0;
- final int bitSetSpaceNeeded = getBitSetSpaceFromMaxInt(maxInt - offset);
+ final int bitSetSpaceNeeded =
getBitSetSpaceFromMaxInt(BIT_SET_OVERALLOCATE + maxInt - offset, 0);
if (bitSetSpaceNeeded < (hashSetSpaceNeeded - HYSTERESIS)) {
switchToBitSet(maxInt, offset);
@@ -332,8 +391,7 @@ public class PositiveIntSet {
private void switchToBitSet(int maxInt, int offset) {
isBitSet = true;
- intBitSet = new IntBitSet(maxInt - offset);
- intBitSet.setOffset(offset);
+ intBitSet = new IntBitSet(BIT_SET_OVERALLOCATE + maxInt - offset, offset);
IntListIterator it = intHashSet.getIterator();
while (it.hasNext()) {
intBitSet.add(it.next());
Modified:
uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/internal/util/IntBitSetTest.java
URL:
http://svn.apache.org/viewvc/uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/internal/util/IntBitSetTest.java?rev=1634141&r1=1634140&r2=1634141&view=diff
==============================================================================
---
uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/internal/util/IntBitSetTest.java
(original)
+++
uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/internal/util/IntBitSetTest.java
Fri Oct 24 21:23:32 2014
@@ -29,8 +29,7 @@ public class IntBitSetTest extends TestC
public void setUp() {
ibs = new IntBitSet();
- ibs1k = new IntBitSet();
- ibs1k.setOffset(1000);
+ ibs1k = new IntBitSet(63, 1000);
}
public void testBasic() {
@@ -62,20 +61,18 @@ public class IntBitSetTest extends TestC
assertEquals(3*64, ibs.getSpaceUsed_in_bits());
assertEquals(6, ibs.getSpaceUsed_in_words());
- ibs = new IntBitSet(64);
- ibs.setOffset(1000);
+ ibs = new IntBitSet(64, 1000);
ibs.add(1064);
assertEquals(1,ibs.size());
assertEquals(2*64, ibs.getSpaceUsed_in_bits());
- ibs = new IntBitSet(64);
- ibs.setOffset(1000);
+ ibs = new IntBitSet(64, 1000);
+
ibs.add(1063);
assertEquals(1*64, ibs.getSpaceUsed_in_bits());
assertEquals(1,ibs.size());
- ibs = new IntBitSet(6 * 64);
- ibs.setOffset(1000);
+ ibs = new IntBitSet(6 * 64, 1000);
ibs.add(1000 + 6 * 64 - 1);
assertEquals(6*64, ibs.getSpaceUsed_in_bits());
@@ -103,8 +100,7 @@ public class IntBitSetTest extends TestC
}
public void testContains() {
- ibs = new IntBitSet();
- ibs.setOffset(1000);
+ ibs = new IntBitSet(63, 1000);
ibs.add(1015);
ibs.add(1188);
Modified:
uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/internal/util/IntHashSetTest.java
URL:
http://svn.apache.org/viewvc/uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/internal/util/IntHashSetTest.java?rev=1634141&r1=1634140&r2=1634141&view=diff
==============================================================================
---
uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/internal/util/IntHashSetTest.java
(original)
+++
uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/internal/util/IntHashSetTest.java
Fri Oct 24 21:23:32 2014
@@ -57,7 +57,7 @@ public class IntHashSetTest extends Test
assertEquals(1000, ihs.getMostPositive());
assertEquals(-1000, ihs.getMostNegative());
ihs.remove(1000);
- assertEquals(1000, ihs.getMostPositive());
+ assertEquals(999, ihs.getMostPositive());
assertEquals(-1000, ihs.getMostNegative());
ihs.add(1001);
assertEquals(1001, ihs.getMostPositive());
@@ -80,7 +80,24 @@ public class IntHashSetTest extends Test
assertTrue(ihs.contains(1188));
assertTrue(ihs.contains(1040));
assertFalse(ihs.contains(0));
- assertFalse(ihs.contains(99));
-
+ assertFalse(ihs.contains(99));
+ }
+
+ public void testTableSpace() {
+ assertEquals(32, IntHashSet.tableSpace(19, 0.6f)); // 19 / .6 = 31.xxx,
round to 32
+ assertEquals(64, IntHashSet.tableSpace(21, 0.6f));
+ assertEquals(32, ihs.tableSpace(21));
+ }
+
+ public void testWontExpand() {
+ ihs = new IntHashSet(21);
+ assertEquals(32, ihs.getSpaceUsedInWords());
+ assertTrue(ihs.wontExpand(20));
+ assertFalse(ihs.wontExpand(21));
}
+
+
+
+
+
}
Modified:
uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/internal/util/PositiveIntSetTest.java
URL:
http://svn.apache.org/viewvc/uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/internal/util/PositiveIntSetTest.java?rev=1634141&r1=1634140&r2=1634141&view=diff
==============================================================================
---
uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/internal/util/PositiveIntSetTest.java
(original)
+++
uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/internal/util/PositiveIntSetTest.java
Fri Oct 24 21:23:32 2014
@@ -53,20 +53,22 @@ public class PositiveIntSetTest extends
s = new PositiveIntSet();
assertTrue(s.useOffset);
s.add(bb);
+
s.add(bb);
s.add(bb+1);
+ assertTrue(s.isBitSet);
s.add(bb+2);
- assertEquals(3, s.size());
assertTrue(s.isBitSet);
+ assertEquals(3, s.size());
assertTrue(s.useOffset);
// test offset converting to hashset
- s.add(bb - 66);
+ s.add(bb - 6000);
assertEquals(4, s.size());
assertFalse(s.isBitSet);
it = s.getOrderedIterator();
- assertEquals(bb-66, it.next());
+ assertEquals(bb-6000, it.next());
assertEquals(bb, it.next());
assertEquals(bb+1, it.next());
assertEquals(bb+2, it.next());
@@ -96,37 +98,28 @@ public class PositiveIntSetTest extends
// test switch from hash set to bit set
s.clear(); // keeps useOffset false
- s.add(767 - 64); // makes the space used by bit set = 25 words
+ s.add(1216); // makes the space used by bit set = 41 words
- for (int i = 1; i < 13; i++) {
+ for (int i = 1; i < 23; i++) {
s.add(i);
// System.out.println("i is " + i + ", isBitSet = " + s.isBitSet);
- assertTrue("i is " + i, (i < 12) ? (!s.isBitSet) : s.isBitSet);
+ assertTrue("i is " + i, (i < 20) ? (!s.isBitSet) : s.isBitSet);
}
it = s.getOrderedIterator();
- assertEquals(1,it.next());
- assertEquals(2,it.next());
- assertEquals(3,it.next());
- assertEquals(4,it.next());
- assertEquals(5,it.next());
- assertEquals(6,it.next());
- assertEquals(7,it.next());
- assertEquals(8,it.next());
- assertEquals(9,it.next());
- assertEquals(10,it.next());
- assertEquals(11,it.next());
- assertEquals(12,it.next());
- assertEquals(767-64,it.next());
+ for (int i = 1; i < 23; i++) {
+ assertEquals(i, it.next());
+ }
+ assertEquals(1216,it.next());
boolean reached = false;
- for (int i = 10; i < 5122; i = i <<1) {
+ for (int i = 10; i < 20000/*5122*/; i = i <<1) {
s.add(i); // switches to hash set when i = 2560. == 1010 0000 0000
(>>5 = 101 0000 = 80 (decimal)
// hash set size for 19 entries = 19 * 3 = 57
// bit set size for 2560 = 80 words
// bit set size for prev i (1280 dec) = 101 0000 0000 (>>5 =
10 1000) = 40 words
// if (!s.isBitSet) {
-// System.out.println("is Bit set? " + s.isBitSet + ", # of entries is
" + s.size());
+// System.out.println("is Bit set? " + s.isBitSet + ", i = " + i + ", #
of entries is " + s.size());
// }
reached = i >= 5120;
assertTrue((!reached) ? s.isBitSet : !s.isBitSet);