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 { public DocIdSetIterator iterator() throws IOException {
return new DocIdSetIterator() { return new DocIdSetIterator() {
int pos=base-1; int pos=base-1;
public int doc() { int adjustedDoc=-1;
return pos-base;
@Override
public int docID() {
return adjustedDoc;
} }
public boolean next() throws IOException { @Override
public int nextDoc() throws IOException {
pos = bs.nextSetBit(pos+1); 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); 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) { public SortedIntDocSet(int[] docs) {
this.docs = 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; 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) { public static int intersectionSize(int[] smallerSortedList, int[] biggerSortedList) {
final int a[] = smallerSortedList; final int a[] = smallerSortedList;
final int b[] = biggerSortedList; final int b[] = biggerSortedList;
@ -573,24 +592,30 @@ public class SortedIntDocSet extends DocSetBase {
public DocIdSetIterator iterator() throws IOException { public DocIdSetIterator iterator() throws IOException {
return new DocIdSetIterator() { return new DocIdSetIterator() {
int idx = startIdx; int idx = startIdx;
int doc; int adjustedDoc;
public int doc() { public int doc() {
return doc - base; return adjustedDoc;
} }
public boolean next() throws IOException { @Override
if (idx > endIdx) return false; public int docID() {
doc = docs[idx++]; return adjustedDoc;
return true;
} }
public boolean skipTo(int target) throws IOException { @Override
if (idx > endIdx) return false; 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; target += base;
// probe next // probe next
doc = docs[idx++]; int rawDoc = docs[idx++];
if (doc >= target) return true; if (rawDoc >= target) return adjustedDoc=rawDoc-base;
int high = endIdx; int high = endIdx;
@ -599,28 +624,28 @@ public class SortedIntDocSet extends DocSetBase {
// binary search // binary search
while (idx <= high) { while (idx <= high) {
int mid = (idx+high) >>> 1; int mid = (idx+high) >>> 1;
doc = docs[mid]; rawDoc = docs[mid];
if (doc < target) { if (rawDoc < target) {
idx = mid+1; idx = mid+1;
} }
else if (doc > target) { else if (rawDoc > target) {
high = mid-1; high = mid-1;
} }
else { else {
idx=mid+1; idx=mid+1;
return true; return adjustedDoc=rawDoc - base;
} }
} }
// low is on the insertion point... // low is on the insertion point...
if (idx <= endIdx) { if (idx <= endIdx) {
doc = docs[idx++]; return adjustedDoc = docs[idx++] - base;
return true;
} else { } else {
return false; return adjustedDoc=NO_MORE_DOCS;
} }
} }
}; };
} }
}; };

View File

@ -111,16 +111,24 @@ public class BoostedQuery extends Query {
this.vals = vs.getValues(reader); this.vals = vs.getValues(reader);
} }
public boolean next() throws IOException { @Override
return scorer.next(); public int docID() {
return scorer.docID();
} }
public int doc() { @Override
return scorer.doc(); 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 { 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 // Current Lucene priority queues can't handle NaN and -Infinity, so
// map to -Float.MAX_VALUE. This conditional handles both -infinity // 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; 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 { public Explanation explain(int doc) throws IOException {
Explanation subQueryExpl = weight.qWeight.explain(reader,doc); Explanation subQueryExpl = weight.qWeight.explain(reader,doc);
if (!subQueryExpl.isMatch()) { if (!subQueryExpl.isMatch()) {

View File

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

View File

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