Index: lucene/core/src/java/org/apache/lucene/util/OpenBitSet.java =================================================================== --- lucene/core/src/java/org/apache/lucene/util/OpenBitSet.java (revision 1531190) +++ lucene/core/src/java/org/apache/lucene/util/OpenBitSet.java (working copy) @@ -150,17 +150,9 @@ /** Expert: returns the long[] storing the bits */ public long[] getBits() { return bits; } - /** Expert: sets a new long[] to use as the bit storage */ - public void setBits(long[] bits) { this.bits = bits; } - /** Expert: gets the number of longs in the array that are in use */ public int getNumWords() { return wlen; } - /** Expert: sets the number of longs in the array that are in use */ - public void setNumWords(int nWords) { this.wlen=nWords; } - - - /** Returns true or false for the specified bit index. */ @Override public boolean get(int index) { @@ -310,7 +302,6 @@ ensureCapacity(index+1); wlen = wordNum+1; } - assert (numBits = Math.max(numBits, index+1)) >= 0; return wordNum; } @@ -841,14 +832,22 @@ public void ensureCapacityWords(int numWords) { if (bits.length < numWords) { bits = ArrayUtil.grow(bits, numWords); + if (numWords >= wlen) { + wlen = numWords + 1; + } } + assert (this.numBits = Math.max(this.numBits, numWords<<6)) >= 0; } - /** Ensure that the long[] is big enough to hold numBits, expanding it if necessary. - * getNumWords() is unchanged by this call. + /** + * Ensure that the long[] is big enough to hold numBits, expanding it if + * necessary. */ public void ensureCapacity(long numBits) { ensureCapacityWords(bits2words(numBits)); + // ensureCapacityWords sets numBits to numWords << 6, but if the app asked + // for 53 bits, we want numBits to be 53, not 64. + assert (this.numBits = Math.max(this.numBits, numBits + 1)) >= 0; } /** Lowers numWords, the number of words in use, @@ -862,10 +861,9 @@ /** returns the number of 64 bit words it would take to hold numBits */ public static int bits2words(long numBits) { - return (int)(((numBits-1)>>>6)+1); + return (int)(((numBits-1)>>>6)+1); } - /** returns true if both sets have the same bits set */ @Override public boolean equals(Object o) { Index: lucene/core/src/test/org/apache/lucene/util/TestOpenBitSet.java =================================================================== --- lucene/core/src/test/org/apache/lucene/util/TestOpenBitSet.java (revision 1531190) +++ lucene/core/src/test/org/apache/lucene/util/TestOpenBitSet.java (working copy) @@ -331,6 +331,38 @@ checkPrevSetBitArray(new int[] {0,2}); } + public void testEnsureCapacity() { + OpenBitSet bits = new OpenBitSet(1); + int bit = random().nextInt(100) + 10; + bits.ensureCapacity(bit); // make room for more bits + bits.fastSet(bit); + assertTrue(bits.fastGet(bit)); + bits.ensureCapacity(bit + 1); + bits.fastSet(bit + 1); + assertTrue(bits.fastGet(bit + 1)); + bits.ensureCapacity(3); // should not change numBits nor grow the array + bits.fastSet(3); + assertTrue(bits.fastGet(3)); + bits.fastSet(bit-1); + assertTrue(bits.fastGet(bit-1)); + + // test ensureCapacityWords + int numWords = random().nextInt(10) + 2; // make sure we grow the array (at least 128 bits) + bits.ensureCapacityWords(numWords); + bit = _TestUtil.nextInt(random(), 128, numWords << 6); // pick a higher bit than 128, but still within range + bits.fastSet(bit); + assertTrue(bits.fastGet(bit)); + bits.fastClear(bit); + assertFalse(bits.fastGet(bit)); + bits.fastFlip(bit); + assertTrue(bits.fastGet(bit)); + bits.ensureCapacityWords(2); // should not change numBits nor grow the array + bits.fastSet(3); + assertTrue(bits.fastGet(3)); + bits.fastSet(bit-1); + assertTrue(bits.fastGet(bit-1)); + } + }