diff --git a/lucene/core/src/java/org/apache/lucene/util/FixedBitSet.java b/lucene/core/src/java/org/apache/lucene/util/FixedBitSet.java index e763410..555771a 100644 --- a/lucene/core/src/java/org/apache/lucene/util/FixedBitSet.java +++ b/lucene/core/src/java/org/apache/lucene/util/FixedBitSet.java @@ -78,68 +78,7 @@ public final class FixedBitSet extends DocIdSet implements Bits { @Override public DocIdSetIterator iterator() { - // define locally so we don't have "enclosing acces" issue - final long[] bits = this.bits; - final int wordLength = this.wordLength; - final int numBits = this.numBits; - return new DocIdSetIterator() { - int doc = -1; - @Override - public int nextDoc() throws IOException { - if (doc == NO_MORE_DOCS || ++doc >= numBits) { - return doc = NO_MORE_DOCS; - } - int i = doc >> 6; - final int subIndex = doc & 0x3f; // index within the word - long word = bits[i] >> subIndex; // skip all the bits to the right of index - - if (word != 0) { - return doc = doc + Long.numberOfTrailingZeros(word); - } - - while (++i < wordLength) { - word = bits[i]; - if (word != 0) { - return doc = (i << 6) + Long.numberOfTrailingZeros(word); - } - } - - return doc = NO_MORE_DOCS; - } - - @Override - public int docID() { - return doc; - } - - @Override - public long cost() { - return bits.length; - } - - @Override - public int advance(int target) throws IOException { - if (doc == NO_MORE_DOCS || target >= numBits) { - return doc = NO_MORE_DOCS; - } - int i = target >> 6; - final int subIndex = target & 0x3f; // index within the word - long word = bits[i] >> subIndex; // skip all the bits to the right of index - - if (word != 0) { - return doc = target + Long.numberOfTrailingZeros(word); - } - - while (++i < wordLength) { - word = bits[i]; - if (word != 0) { - return doc = (i << 6) + Long.numberOfTrailingZeros(word); - } - } - - return doc = NO_MORE_DOCS; - } - }; + return new OpenBitSetIterator(bits, wordLength); } @Override diff --git a/lucene/core/src/java/org/apache/lucene/util/OpenBitSetIterator.java b/lucene/core/src/java/org/apache/lucene/util/OpenBitSetIterator.java index 699e731..06107e2 100644 --- a/lucene/core/src/java/org/apache/lucene/util/OpenBitSetIterator.java +++ b/lucene/core/src/java/org/apache/lucene/util/OpenBitSetIterator.java @@ -30,12 +30,11 @@ public class OpenBitSetIterator extends DocIdSetIterator { // for efficiency, or have a common root interface? (or // maybe both? could ask for a SetBitsIterator, etc... - final long[] arr; - final int words; + final long[] bits; + final int numWords; + final int numBits; private int i=-1; private long word; - private int wordShift; - private int indexArray; private int curDocId = -1; public OpenBitSetIterator(OpenBitSet obs) { @@ -43,97 +42,55 @@ public class OpenBitSetIterator extends DocIdSetIterator { } public OpenBitSetIterator(long[] bits, int numWords) { - arr = bits; - words = numWords; + this.bits = bits; + this.numWords = numWords; + this.numBits = numWords * 64; } - // 64 bit shifts - private void shift() { - if ((int)word ==0) {wordShift +=32; word = word >>>32; } - if ((word & 0x0000FFFF) == 0) { wordShift +=16; word >>>=16; } - if ((word & 0x000000FF) == 0) { wordShift +=8; word >>>=8; } - indexArray = BitUtil.bitList((byte) word); - } - - /***** alternate shift implementations - // 32 bit shifts, but a long shift needed at the end - private void shift2() { - int y = (int)word; - if (y==0) {wordShift +=32; y = (int)(word >>>32); } - if ((y & 0x0000FFFF) == 0) { wordShift +=16; y>>>=16; } - if ((y & 0x000000FF) == 0) { wordShift +=8; y>>>=8; } - indexArray = bitlist[y & 0xff]; - word >>>= (wordShift +1); - } + @Override + public int nextDoc() { + if (curDocId == NO_MORE_DOCS || ++curDocId >= numBits) { + return curDocId = NO_MORE_DOCS; + } + int i = curDocId >> 6; + final int subIndex = curDocId & 0x3f; // index within the word + word = bits[i] >> subIndex; // skip all the bits to the right of index - private void shift3() { - int lower = (int)word; - int lowByte = lower & 0xff; - if (lowByte != 0) { - indexArray=bitlist[lowByte]; - return; + if (word != 0) { + return curDocId = curDocId + Long.numberOfTrailingZeros(word); } - shift(); - } - ******/ - @Override - public int nextDoc() { - if (indexArray == 0) { + while (++i < numWords) { + word = bits[i]; if (word != 0) { - word >>>= 8; - wordShift += 8; - } - - while (word == 0) { - if (++i >= words) { - return curDocId = NO_MORE_DOCS; - } - word = arr[i]; - wordShift = -1; // loop invariant code motion should move this + return curDocId = (i << 6) + Long.numberOfTrailingZeros(word); } - - // after the first time, should I go with a linear search, or - // stick with the binary search in shift? - shift(); } - int bitIndex = (indexArray & 0x0f) + wordShift; - indexArray >>>= 4; - // should i<<6 be cached as a separate variable? - // it would only save one cycle in the best circumstances. - return curDocId = (i<<6) + bitIndex; + return curDocId = NO_MORE_DOCS; } @Override public int advance(int target) { - indexArray = 0; - i = target >> 6; - if (i >= words) { - word = 0; // setup so next() will also return -1 + if (curDocId == NO_MORE_DOCS || target >= numBits) { return curDocId = NO_MORE_DOCS; } - wordShift = target & 0x3f; - word = arr[i] >>> wordShift; + int i = target >> 6; + final int subIndex = target & 0x3f; // index within the word + word = bits[i] >> subIndex; // skip all the bits to the right of index + if (word != 0) { - wordShift--; // compensate for 1 based arrIndex - } else { - while (word == 0) { - if (++i >= words) { - return curDocId = NO_MORE_DOCS; - } - word = arr[i]; - } - wordShift = -1; + return curDocId = target + Long.numberOfTrailingZeros(word); } - shift(); + while (++i < numWords) { + word = bits[i]; + if (word != 0) { + return curDocId = (i << 6) + Long.numberOfTrailingZeros(word); + } + } - int bitIndex = (indexArray & 0x0f) + wordShift; - indexArray >>>= 4; - // should i<<6 be cached as a separate variable? - // it would only save one cycle in the best circumstances. - return curDocId = (i<<6) + bitIndex; + return curDocId = NO_MORE_DOCS; } @Override @@ -143,6 +100,6 @@ public class OpenBitSetIterator extends DocIdSetIterator { @Override public long cost() { - return words / 64; + return numWords / 64; } }