LUCENE-3179: Add missing long methods and add good tests for uncovered code. The cutover to Long.numberOfLeadingZeroes was not done, see issue comment.

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1143558 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Uwe Schindler 2011-07-06 20:43:55 +00:00
parent 18cbe7ce70
commit bec184fa39
2 changed files with 97 additions and 3 deletions

View File

@ -692,6 +692,39 @@ public class OpenBitSet extends DocIdSet implements Bits, Cloneable {
return -1;
}
/** Returns the index of the first set bit starting downwards at
* the index specified.
* -1 is returned if there are no more set bits.
*/
public long prevSetBit(long index) {
int i = (int) (index >> 6);
final int subIndex;
long word;
if (i >= wlen) {
i = wlen - 1;
if (i < 0) return -1;
subIndex = 63; // last possible bit
word = bits[i];
} else {
if (i < 0) return -1;
subIndex = (int)index & 0x3f; // index within the word
word = (bits[i] << (63-subIndex)); // skip all the bits to the left of index
}
if (word != 0) {
return (((long)i)<<6) + subIndex - Long.numberOfLeadingZeros(word); // See LUCENE-3197
}
while (--i >= 0) {
word = bits[i];
if (word !=0 ) {
return (((long)i)<<6) + 63 - Long.numberOfLeadingZeros(word);
}
}
return -1;
}
@Override
public Object clone() {
try {

View File

@ -29,6 +29,20 @@ public class TestOpenBitSet extends LuceneTestCase {
if (a.get(i) != b.get(i)) {
fail("mismatch: BitSet=["+i+"]="+a.get(i));
}
if (a.get(i) != b.get((long) i)) {
fail("mismatch: BitSet=["+i+"]="+a.get(i));
}
}
}
void doGetFast(BitSet a, OpenBitSet b, int max) {
for (int i=0; i<max; i++) {
if (a.get(i) != b.fastGet(i)) {
fail("mismatch: BitSet=["+i+"]="+a.get(i));
}
if (a.get(i) != b.fastGet((long) i)) {
fail("mismatch: BitSet=["+i+"]="+a.get(i));
}
}
}
@ -41,6 +55,15 @@ public class TestOpenBitSet extends LuceneTestCase {
} while (aa>=0);
}
void doNextSetBitLong(BitSet a, OpenBitSet b) {
int aa=-1,bb=-1;
do {
aa = a.nextSetBit(aa+1);
bb = (int) b.nextSetBit((long) (bb+1));
assertEquals(aa,bb);
} while (aa>=0);
}
void doPrevSetBit(BitSet a, OpenBitSet b) {
int aa = a.size() + random.nextInt(100);
int bb = aa;
@ -55,6 +78,20 @@ public class TestOpenBitSet extends LuceneTestCase {
} while (aa>=0);
}
void doPrevSetBitLong(BitSet a, OpenBitSet b) {
int aa = a.size() + random.nextInt(100);
int bb = aa;
do {
// aa = a.prevSetBit(aa-1);
aa--;
while ((aa >= 0) && (! a.get(aa))) {
aa--;
}
bb = (int) b.prevSetBit((long) (bb-1));
assertEquals(aa,bb);
} while (aa>=0);
}
// test interleaving different OpenBitSetIterator.next()/skipTo()
void doIterate(BitSet a, OpenBitSet b, int mode) {
if (mode==1) doIterate1(a, b);
@ -99,9 +136,19 @@ public class TestOpenBitSet extends LuceneTestCase {
idx = random.nextInt(sz);
a.set(idx);
b.fastSet(idx);
idx = random.nextInt(sz);
a.set(idx);
b.fastSet((long) idx);
idx = random.nextInt(sz);
a.clear(idx);
b.fastClear(idx);
idx = random.nextInt(sz);
a.clear(idx);
b.fastClear((long) idx);
idx = random.nextInt(sz);
a.flip(idx);
b.fastFlip(idx);
@ -110,6 +157,14 @@ public class TestOpenBitSet extends LuceneTestCase {
boolean val2 = b.flipAndGet(idx);
assertTrue(val != val2);
idx = random.nextInt(sz);
a.flip(idx);
b.fastFlip((long) idx);
val = b.flipAndGet((long) idx);
val2 = b.flipAndGet((long) idx);
assertTrue(val != val2);
val = b.getAndSet(idx);
assertTrue(val2 == val);
assertTrue(b.get(idx));
@ -121,6 +176,7 @@ public class TestOpenBitSet extends LuceneTestCase {
// test that the various ways of accessing the bits are equivalent
doGet(a,b);
doGetFast(a, b, sz);
// test ranges, including possible extension
int fromIndex, toIndex;
@ -136,17 +192,22 @@ public class TestOpenBitSet extends LuceneTestCase {
aa = (BitSet)a.clone(); aa.clear(fromIndex,toIndex);
bb = (OpenBitSet)b.clone(); bb.clear(fromIndex,toIndex);
doNextSetBit(aa,bb); // a problem here is from clear() or nextSetBit
doNextSetBit(aa,bb); // a problem here is from clear() or nextSetBit
doNextSetBitLong(aa,bb);
doPrevSetBit(aa,bb);
doPrevSetBitLong(aa,bb);
fromIndex = random.nextInt(sz+80);
toIndex = fromIndex + random.nextInt((sz>>1)+1);
aa = (BitSet)a.clone(); aa.set(fromIndex,toIndex);
bb = (OpenBitSet)b.clone(); bb.set(fromIndex,toIndex);
doNextSetBit(aa,bb); // a problem here is from set() or nextSetBit
doNextSetBit(aa,bb); // a problem here is from set() or nextSetBit
doNextSetBitLong(aa,bb);
doPrevSetBit(aa,bb);
doPrevSetBitLong(aa,bb);
if (a0 != null) {
assertEquals( a.equals(a0), b.equals(b0));