LUCENE-1605: add BitVector.subset

git-svn-id: https://svn.apache.org/repos/asf/lucene/java/trunk@765649 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Michael McCandless 2009-04-16 14:29:26 +00:00
parent 4560d9da77
commit f5831d86ae
3 changed files with 95 additions and 1 deletions

View File

@ -285,6 +285,9 @@ New features
during rewrite (getTotalNumberOfTerms). FilteredTermEnum is also
more friendly to subclassing. (Uwe Schindler via Mike McCandless)
22. LUCENE-1605: Added BitVector.subset(). (Jeremy Volkman via Mike
McCandless)
Optimizations
1. LUCENE-1427: Fixed QueryWrapperFilter to not waste time computing

View File

@ -238,5 +238,30 @@ public final class BitVector implements Cloneable {
n -= BYTE_COUNTS[bits[last] & 0xFF];
}
}
/**
* Retrieve a subset of this BitVector.
*
* @param start
* starting index, inclusive
* @param end
* ending index, exclusive
* @return subset
*/
public BitVector subset(int start, int end) {
if (start < 0 || end > size() || end < start)
throw new IndexOutOfBoundsException();
// Special case -- return empty vector is start == end
if (end == start) return new BitVector(0);
byte[] bits = new byte[((end - start - 1) >>> 3) + 1];
int s = start >>> 3;
for (int i = 0; i < bits.length; i++) {
int cur = 0xFF & this.bits[i + s];
int next = i + s + 1 >= this.bits.length ? 0 : 0xFF & this.bits[i + s + 1];
bits[i] = (byte) ((cur >>> (start & 7)) | ((next << (8 - (start & 7)))));
}
int bitsToClear = (bits.length * 8 - (end - start)) % 8;
bits[bits.length - 1] &= ~(0xFF << (8 - bitsToClear));
return new BitVector(bits, end - start);
}
}

View File

@ -218,4 +218,70 @@ public class TestBitVector extends LuceneTestCase
}
return equal;
}
private static int[] subsetPattern = new int[] { 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1 };
/**
* Tests BitVector.subset() against the above pattern
*/
public void testSubset() {
doTestSubset(0, 0);
doTestSubset(0, 20);
doTestSubset(0, 7);
doTestSubset(0, 8);
doTestSubset(0, 9);
doTestSubset(0, 15);
doTestSubset(0, 16);
doTestSubset(0, 17);
doTestSubset(1, 7);
doTestSubset(1, 8);
doTestSubset(1, 9);
doTestSubset(1, 15);
doTestSubset(1, 16);
doTestSubset(1, 17);
doTestSubset(2, 20);
doTestSubset(3, 20);
doTestSubset(4, 20);
doTestSubset(5, 20);
doTestSubset(6, 20);
doTestSubset(7, 14);
doTestSubset(7, 15);
doTestSubset(7, 16);
doTestSubset(8, 15);
doTestSubset(9, 20);
doTestSubset(10, 20);
doTestSubset(11, 20);
doTestSubset(12, 20);
doTestSubset(13, 20);
}
/**
* Compare a subset against the corresponding portion of the test pattern
*/
private void doTestSubset(int start, int end) {
BitVector full = createSubsetTestVector();
BitVector subset = full.subset(start, end);
assertEquals(end - start, subset.size());
int count = 0;
for (int i = start, j = 0; i < end; i++, j++) {
if (subsetPattern[i] == 1) {
count++;
assertTrue(subset.get(j));
} else {
assertFalse(subset.get(j));
}
}
assertEquals(count, subset.count());
}
private BitVector createSubsetTestVector() {
BitVector bv = new BitVector(subsetPattern.length);
for (int i = 0; i < subsetPattern.length; i++) {
if (subsetPattern[i] == 1) {
bv.set(i);
}
}
return bv;
}
}