SOLR-1284: use/implement DISI.advance and friends

git-svn-id: https://svn.apache.org/repos/asf/lucene/solr/trunk@794470 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Yonik Seeley 2009-07-16 00:12:17 +00:00
parent 03cf5cdad6
commit f7953e95b6
5 changed files with 86 additions and 64 deletions

View File

@ -267,18 +267,24 @@ abstract class DocSetBase implements DocSet {
public DocIdSetIterator iterator() throws IOException {
return new DocIdSetIterator() {
int pos=base-1;
public int doc() {
return pos-base;
int adjustedDoc=-1;
@Override
public int docID() {
return adjustedDoc;
}
public boolean next() throws IOException {
@Override
public int nextDoc() throws IOException {
pos = bs.nextSetBit(pos+1);
return pos>=0 && pos<max;
return adjustedDoc = (pos>=0 && pos<max) ? pos-base : NO_MORE_DOCS;
}
public boolean skipTo(int target) throws IOException {
@Override
public int advance(int target) throws IOException {
if (target==NO_MORE_DOCS) return adjustedDoc=NO_MORE_DOCS;
pos = bs.nextSetBit(target+base);
return pos>=0 && pos<max;
return adjustedDoc = (pos>=0 && pos<max) ? pos-base : NO_MORE_DOCS;
}
};
}

View File

@ -36,6 +36,7 @@ public class SortedIntDocSet extends DocSetBase {
*/
public SortedIntDocSet(int[] docs) {
this.docs = docs;
// if (firstNonSorted(docs,0,docs.length)>=0) throw new RuntimeException("NON SORTED DOCS!!!");
}
/**
@ -64,6 +65,24 @@ public class SortedIntDocSet extends DocSetBase {
return newArr;
}
/** Returns the index of the first non-sorted element or -1 if they are all sorted */
public static int firstNonSorted(int[] arr, int offset, int len) {
if (len <= 1) return -1;
int lower = arr[offset];
int end = offset + len;
for(int i=offset+1; i<end; i++) {
int next = arr[i];
if (next <= lower) {
for (int j=i-1; j>offset; j--) {
if (arr[j]<next) return j+1;
}
return offset;
}
lower = next;
}
return -1;
}
public static int intersectionSize(int[] smallerSortedList, int[] biggerSortedList) {
final int a[] = smallerSortedList;
final int b[] = biggerSortedList;
@ -573,24 +592,30 @@ public class SortedIntDocSet extends DocSetBase {
public DocIdSetIterator iterator() throws IOException {
return new DocIdSetIterator() {
int idx = startIdx;
int doc;
int adjustedDoc;
public int doc() {
return doc - base;
return adjustedDoc;
}
public boolean next() throws IOException {
if (idx > endIdx) return false;
doc = docs[idx++];
return true;
@Override
public int docID() {
return adjustedDoc;
}
public boolean skipTo(int target) throws IOException {
if (idx > endIdx) return false;
@Override
public int nextDoc() throws IOException {
return adjustedDoc = (idx > endIdx) ? NO_MORE_DOCS : (docs[idx++] - base);
}
@Override
public int advance(int target) throws IOException {
if (idx > endIdx || target==NO_MORE_DOCS) return adjustedDoc=NO_MORE_DOCS;
target += base;
// probe next
doc = docs[idx++];
if (doc >= target) return true;
int rawDoc = docs[idx++];
if (rawDoc >= target) return adjustedDoc=rawDoc-base;
int high = endIdx;
@ -599,28 +624,28 @@ public class SortedIntDocSet extends DocSetBase {
// binary search
while (idx <= high) {
int mid = (idx+high) >>> 1;
doc = docs[mid];
rawDoc = docs[mid];
if (doc < target) {
if (rawDoc < target) {
idx = mid+1;
}
else if (doc > target) {
else if (rawDoc > target) {
high = mid-1;
}
else {
idx=mid+1;
return true;
return adjustedDoc=rawDoc - base;
}
}
// low is on the insertion point...
if (idx <= endIdx) {
doc = docs[idx++];
return true;
return adjustedDoc = docs[idx++] - base;
} else {
return false;
return adjustedDoc=NO_MORE_DOCS;
}
}
};
}
};

View File

@ -111,16 +111,24 @@ public class BoostedQuery extends Query {
this.vals = vs.getValues(reader);
}
public boolean next() throws IOException {
return scorer.next();
@Override
public int docID() {
return scorer.docID();
}
public int doc() {
return scorer.doc();
@Override
public int advance(int target) throws IOException {
return scorer.advance(target);
}
@Override
public int nextDoc() throws IOException {
return scorer.nextDoc();
}
@Override
public float score() throws IOException {
float score = qWeight * scorer.score() * vals.floatVal(scorer.doc());
float score = qWeight * scorer.score() * vals.floatVal(scorer.docID());
// Current Lucene priority queues can't handle NaN and -Infinity, so
// map to -Float.MAX_VALUE. This conditional handles both -infinity
@ -128,10 +136,6 @@ public class BoostedQuery extends Query {
return score>Float.NEGATIVE_INFINITY ? score : -Float.MAX_VALUE;
}
public boolean skipTo(int target) throws IOException {
return scorer.skipTo(target);
}
public Explanation explain(int doc) throws IOException {
Explanation subQueryExpl = weight.qWeight.explain(reader,doc);
if (!subQueryExpl.isMatch()) {

View File

@ -88,29 +88,17 @@ class QueryDocValues extends DocValues {
if (doc < lastDocRequested) {
// out-of-order access.... reset scorer.
scorer = weight.scorer(reader);
boolean more = scorer.next();
if (more) {
scorerDoc = scorer.doc();
} else {
// pretend we skipped to the end
scorerDoc = Integer.MAX_VALUE;
}
scorerDoc = scorer.nextDoc();
}
lastDocRequested = doc;
if (scorerDoc < doc) {
boolean more = scorer.skipTo(doc);
if (more) {
scorerDoc = scorer.doc();
} else {
// pretend we skipped to the end
scorerDoc = Integer.MAX_VALUE;
}
scorerDoc = scorer.nextDoc();
}
if (scorerDoc > doc) {
// query doesn't match this document... either because we hit the
// end (Integer.MAX_VALUE), or because the next doc is after this doc.
// end, or because the next doc is after this doc.
return defVal;
}

View File

@ -373,12 +373,11 @@ public class TestDocSet extends TestCase {
// test for next() equivalence
for(;;) {
boolean nexta = ia.next();
boolean nextb = ib.next();
assertEquals(nexta, nextb);
if (!nexta) break;
assertEquals(ia.doc(), ib.doc());
int da = ia.nextDoc();
int db = ib.nextDoc();
assertEquals(da, db);
assertEquals(ia.docID(), ib.docID());
if (da==DocIdSetIterator.NO_MORE_DOCS) break;
}
for (int i=0; i<10; i++) {
@ -387,20 +386,20 @@ public class TestDocSet extends TestCase {
ib = b.iterator();
int doc = -1;
for (;;) {
boolean nexta,nextb;
int da,db;
if (rand.nextBoolean()) {
nexta = ia.next();
nextb = ib.next();
da = ia.nextDoc();
db = ib.nextDoc();
} else {
int target = doc + rand.nextInt(10) + 1; // keep in mind future edge cases like probing (increase if necessary)
nexta = ia.skipTo(target);
nextb = ib.skipTo(target);
da = ia.advance(target);
db = ib.advance(target);
}
assertEquals(nexta, nextb);
if (!nexta) break;
doc = ia.doc();
assertEquals(doc, ib.doc());
assertEquals(da, db);
assertEquals(ia.docID(), ib.docID());
if (da==DocIdSetIterator.NO_MORE_DOCS) break;
doc = da;
}
}
}