Index: lucene/src/test/org/apache/lucene/util/TestBitVector.java =================================================================== --- lucene/src/test/org/apache/lucene/util/TestBitVector.java (revision 1144235) +++ lucene/src/test/org/apache/lucene/util/TestBitVector.java (working copy) @@ -19,7 +19,7 @@ import java.io.IOException; -import org.apache.lucene.store.IOContext; +import org.apache.lucene.store.Directory; import org.apache.lucene.store.MockDirectoryWrapper; import org.apache.lucene.store.RAMDirectory; @@ -153,7 +153,7 @@ assertTrue(doCompare(bv,compare)); } } - + /** * Test r/w when size/count cause switching between bit-set and d-gaps file formats. */ @@ -165,6 +165,26 @@ doTestDgaps(10000,40,43); doTestDgaps(100000,415,418); doTestDgaps(1000000,3123,3126); + // now exercise skipping of fully populated byte in the bitset (they are omitted if bitset is sparse) + MockDirectoryWrapper d = new MockDirectoryWrapper(random, new RAMDirectory()); + d.setPreventDoubleWrite(false); + BitVector bv = new BitVector(10000); + bv.set(0); + for (int i = 8; i < 16; i++) { + bv.set(i); + } // make sure we have once byte full of set bits + for (int i = 32; i < 40; i++) { + bv.set(i); + } // get a second byte full of set bits + // add some more bits here + for (int i = 40; i < 10000; i++) { + if (random.nextInt(1000) == 0) { + bv.set(i); + } + } + bv.write(d, "TESTBV", newIOContext(random)); + BitVector compare = new BitVector(d, "TESTBV", newIOContext(random)); + assertTrue(doCompare(bv,compare)); } private void doTestDgaps(int size, int count1, int count2) throws IOException { @@ -183,7 +203,7 @@ assertTrue(doCompare(bv,bv2)); bv = bv2; bv.clear(i); - assertEquals(i+1,size-bv.count()); + assertEquals(i+1, size-bv.count()); bv.write(d, "TESTBV", newIOContext(random)); } // now start decreasing number of set bits @@ -196,6 +216,54 @@ bv.write(d, "TESTBV", newIOContext(random)); } } + + public void testSparseWrite() throws IOException { + Directory d = newDirectory(); + final int numBits = 10240; + BitVector bv = new BitVector(numBits); + bv.invertAll(); + int numToClear = random.nextInt(5); + for(int i=0;i> 3) + 1]; // allocate bits + bits = new byte[getNumBytes(size)]; // allocate bits int last=0; int n = count(); while (n>0) { @@ -383,7 +394,7 @@ private void readClearedDgaps(IndexInput input) throws IOException { size = input.readInt(); // (re)read size count = input.readInt(); // read count - bits = new byte[(size >> 3) + 1]; // allocate bits + bits = new byte[getNumBytes(size)]; // allocate bits Arrays.fill(bits, (byte) 0xff); clearUnusedBits(); int last=0; @@ -392,7 +403,7 @@ last += input.readVInt(); bits[last] = input.readByte(); numCleared -= 8-BYTE_COUNTS[bits[last] & 0xFF]; - assert numCleared >= 0; + assert numCleared >= 0 || (last == (bits.length-1) && numCleared == -(8-(size&7))); } } }