From f7953e95b6f9ff5ac0bf148bb4e9617c9f45e1c4 Mon Sep 17 00:00:00 2001 From: Yonik Seeley Date: Thu, 16 Jul 2009 00:12:17 +0000 Subject: [PATCH] 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 --- src/java/org/apache/solr/search/DocSet.java | 18 ++++-- .../apache/solr/search/SortedIntDocSet.java | 59 +++++++++++++------ .../solr/search/function/BoostedQuery.java | 22 ++++--- .../search/function/QueryValueSource.java | 22 ++----- .../org/apache/solr/search/TestDocSet.java | 29 +++++---- 5 files changed, 86 insertions(+), 64 deletions(-) diff --git a/src/java/org/apache/solr/search/DocSet.java b/src/java/org/apache/solr/search/DocSet.java index 058faf13d45..a25095738e6 100644 --- a/src/java/org/apache/solr/search/DocSet.java +++ b/src/java/org/apache/solr/search/DocSet.java @@ -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=0 && pos=0 && pos=0 && pos=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; ioffset; j--) { + if (arr[j] 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; } } + }; } }; diff --git a/src/java/org/apache/solr/search/function/BoostedQuery.java b/src/java/org/apache/solr/search/function/BoostedQuery.java index 37f518d0348..7bbdf0c8357 100755 --- a/src/java/org/apache/solr/search/function/BoostedQuery.java +++ b/src/java/org/apache/solr/search/function/BoostedQuery.java @@ -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()) { diff --git a/src/java/org/apache/solr/search/function/QueryValueSource.java b/src/java/org/apache/solr/search/function/QueryValueSource.java index d678a2b27f8..3ad766115ae 100755 --- a/src/java/org/apache/solr/search/function/QueryValueSource.java +++ b/src/java/org/apache/solr/search/function/QueryValueSource.java @@ -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; } @@ -119,8 +107,8 @@ class QueryDocValues extends DocValues { } catch (IOException e) { throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, "caught exception in QueryDocVals("+q+") doc="+doc, e); } - } - + } + public int intVal(int doc) { return (int)floatVal(doc); } diff --git a/src/test/org/apache/solr/search/TestDocSet.java b/src/test/org/apache/solr/search/TestDocSet.java index c545080406e..920f5946fa2 100644 --- a/src/test/org/apache/solr/search/TestDocSet.java +++ b/src/test/org/apache/solr/search/TestDocSet.java @@ -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; } } }