Index: CHANGES.txt =================================================================== --- CHANGES.txt (revision 775940) +++ CHANGES.txt (working copy) @@ -135,6 +135,14 @@ not make sense for all subclasses of MultiTermQuery. Check individual subclasses to see if they support #getTerm(). (Mark Miller) +14. LUCENE-1614: DocIdSetIterator's next() and skipTo() were deprecated in favor + of the new nextDoc() and advance(). The new methods return the doc Id they + landed on, which should save the extra call to doc(). + For easy migration of the code, you can change the calls to next() to + nextDoc() >= 0 and similarly for skipTo(). However it is advised that you + take advantage of the returned doc Id and not call doc() following those + two. (Shai Erera vs. Mike McCandless) + Bug fixes 1. LUCENE-1415: MultiPhraseQuery has incorrect hashCode() and equals() Index: contrib/miscellaneous/src/test/org/apache/lucene/misc/ChainedFilterTest.java =================================================================== --- contrib/miscellaneous/src/test/org/apache/lucene/misc/ChainedFilterTest.java (revision 775940) +++ contrib/miscellaneous/src/test/org/apache/lucene/misc/ChainedFilterTest.java (working copy) @@ -94,15 +94,17 @@ final Filter f = chain[i]; // create old BitSet-based Filter as wrapper oldFilters[i] = new Filter() { + /** @deprecated */ public BitSet bits(IndexReader reader) throws IOException { BitSet bits = new BitSet(reader.maxDoc()); - DocIdSetIterator it = f.getDocIdSet(reader).iterator(); - while(it.next()) { - bits.set(it.doc()); + DocIdSetIterator it = f.getDocIdSet(reader).iterator(); + int doc; + while((doc = it.nextDoc()) >= 0) { + bits.set(doc); } return bits; } - }; + }; } return oldFilters; } Index: src/java/org/apache/lucene/index/DocumentsWriter.java =================================================================== --- src/java/org/apache/lucene/index/DocumentsWriter.java (revision 775940) +++ src/java/org/apache/lucene/index/DocumentsWriter.java (working copy) @@ -983,11 +983,11 @@ int limit = ((Integer) entry.getValue()).intValue(); Weight weight = query.weight(searcher); Scorer scorer = weight.scorer(reader); - while(scorer.next()) { - final int docID = scorer.doc(); - if (docIDStart + docID >= limit) + int doc; + while((doc = scorer.nextDoc()) >= 0) { + if (docIDStart + doc >= limit) break; - reader.deleteDocument(docID); + reader.deleteDocument(doc); any = true; } } Index: src/java/org/apache/lucene/search/BooleanScorer.java =================================================================== --- src/java/org/apache/lucene/search/BooleanScorer.java (revision 775940) +++ src/java/org/apache/lucene/search/BooleanScorer.java (working copy) @@ -87,7 +87,7 @@ Collector collector, SubScorer next) throws IOException { this.scorer = scorer; - this.done = !scorer.next(); + this.done = scorer.nextDoc() < 0; this.required = required; this.prohibited = prohibited; this.collector = collector; @@ -138,7 +138,7 @@ } public void score(Collector collector) throws IOException { - next(); + nextDoc(); score(collector, Integer.MAX_VALUE); } @@ -209,7 +209,12 @@ public int doc() { return current.doc; } + /** @deprecated use {@link #nextDoc()} instead. */ public boolean next() throws IOException { + return nextDoc() >= 0; + } + + public int nextDoc() throws IOException { boolean more; do { while (bucketTable.first != null) { // more queued @@ -220,7 +225,7 @@ if ((current.bits & prohibitedMask) == 0 && (current.bits & requiredMask) == requiredMask && current.coord >= minNrShouldMatch) { - return true; + return current.doc; } } @@ -230,9 +235,12 @@ for (SubScorer sub = scorers; sub != null; sub = sub.next) { Scorer scorer = sub.scorer; sub.collector.setScorer(scorer); - while (!sub.done && scorer.doc() < end) { - sub.collector.collect(scorer.doc()); - sub.done = !scorer.next(); + // Check sub.done since if it's true we will hit NPE in doc(). + int doc = sub.done ? -1 : scorer.doc(); + while (!sub.done && doc < end) { + sub.collector.collect(doc); + doc = scorer.nextDoc(); + sub.done = doc < 0; } if (!sub.done) { more = true; @@ -240,9 +248,9 @@ } } while (bucketTable.first != null || more); - return false; + return -1; } - + public float score() { if (coordFactors == null) { computeCoordFactors(); @@ -284,14 +292,24 @@ return doc; } + /** @deprecated use {@link #nextDoc()} instead. */ public boolean next() throws IOException { return false; } + public int nextDoc() throws IOException { + return -1; + } + + /** @deprecated use {@link #advance(int)} instead. */ public boolean skipTo(int target) throws IOException { return false; } + public int advance(int target) throws IOException { + return -1; + } + } /** A simple hash table of document scores within a range. */ @@ -350,10 +368,15 @@ } } + /** @deprecated use {@link #advance(int)} instead. */ public boolean skipTo(int target) { throw new UnsupportedOperationException(); } + public int advance(int target) throws IOException { + throw new UnsupportedOperationException(); + } + public Explanation explain(int doc) { throw new UnsupportedOperationException(); } Index: src/java/org/apache/lucene/search/BooleanScorer2.java =================================================================== --- src/java/org/apache/lucene/search/BooleanScorer2.java (revision 775940) +++ src/java/org/apache/lucene/search/BooleanScorer2.java (working copy) @@ -164,12 +164,20 @@ public int doc() { return scorer.doc(); } + /** @deprecated use {@link #nextDoc()} instead. */ public boolean next() throws IOException { - return scorer.next(); + return scorer.nextDoc() >= 0; } + public int nextDoc() throws IOException { + return scorer.nextDoc(); + } + /** @deprecated use {@link #advance(int)} instead. */ public boolean skipTo(int docNr) throws IOException { - return scorer.skipTo(docNr); + return scorer.advance(docNr) >= 0; } + public int advance(int target) throws IOException { + return scorer.advance(target); + } public Explanation explain(int docNr) throws IOException { return scorer.explain(docNr); } @@ -339,8 +347,9 @@ initCountingSumScorer(); } collector.setScorer(this); - while (countingSumScorer.next()) { - collector.collect(countingSumScorer.doc()); + int doc; + while ((doc = countingSumScorer.nextDoc()) >= 0) { + collector.collect(doc); } } } @@ -371,44 +380,45 @@ collector.setScorer(this); while (docNr < max) { collector.collect(docNr); - if (!countingSumScorer.next()) { + if ((docNr = countingSumScorer.nextDoc()) < 0) { return false; } - docNr = countingSumScorer.doc(); } return true; } public int doc() { return countingSumScorer.doc(); } + /** @deprecated use {@link #nextDoc()} instead. */ public boolean next() throws IOException { + return nextDoc() >= 0; + } + + public int nextDoc() throws IOException { if (countingSumScorer == null) { initCountingSumScorer(); } - return countingSumScorer.next(); + return countingSumScorer.nextDoc(); } - + public float score() throws IOException { coordinator.nrMatchers = 0; float sum = countingSumScorer.score(); return sum * coordinator.coordFactors[coordinator.nrMatchers]; } - /** Skips to the first match beyond the current whose document number is - * greater than or equal to a given target. - * - *

When this method is used the {@link #explain(int)} method should not be used. - * - * @param target The target document number. - * @return true iff there is such a match. - */ + /** @deprecated use {@link #advance(int)} instead. */ public boolean skipTo(int target) throws IOException { + return advance(target) >= 0; + } + + public int advance(int target) throws IOException { if (countingSumScorer == null) { initCountingSumScorer(); } - return countingSumScorer.skipTo(target); + return countingSumScorer.advance(target); } - + /** Throws an UnsupportedOperationException. * TODO: Implement an explanation of the coordination factor. * @param doc The document number for the explanation. Index: src/java/org/apache/lucene/search/ConjunctionScorer.java =================================================================== --- src/java/org/apache/lucene/search/ConjunctionScorer.java (revision 775940) +++ src/java/org/apache/lucene/search/ConjunctionScorer.java (working copy) @@ -43,41 +43,51 @@ public int doc() { return lastDoc; } + /** @deprecated use {@link #nextDoc()} instead. */ public boolean next() throws IOException { + return nextDoc() >= 0; + } + + public int nextDoc() throws IOException { if (firstTime) - return init(0); + return init(0) ? lastDoc : -1; else if (more) - more = scorers[(scorers.length-1)].next(); - return doNext(); + more = scorers[(scorers.length - 1)].nextDoc() >= 0; + return doNext() ? lastDoc : -1; } - + private boolean doNext() throws IOException { int first=0; Scorer lastScorer = scorers[scorers.length-1]; Scorer firstScorer; while (more && (firstScorer=scorers[first]).doc() < (lastDoc=lastScorer.doc())) { - more = firstScorer.skipTo(lastDoc); + more = firstScorer.advance(lastDoc) >= 0; lastScorer = firstScorer; first = (first == (scorers.length-1)) ? 0 : first+1; } return more; } + /** @deprecated use {@link #advance(int)} instead. */ public boolean skipTo(int target) throws IOException { + return advance(target) >= 0; + } + + public int advance(int target) throws IOException { if (firstTime) - return init(target); + return init(target) ? lastDoc : -1; else if (more) - more = scorers[(scorers.length-1)].skipTo(target); - return doNext(); + more = scorers[(scorers.length-1)].advance(target) >= 0; + return doNext() ? lastDoc : -1; } - + // Note... most of this could be done in the constructor // thus skipping a check for firstTime per call to next() and skipTo() private boolean init(int target) throws IOException { - firstTime=false; - more = scorers.length>1; - for (int i=0; i 1; + for (int i = 0; i < scorers.length; i++) { + more = (target == 0 ? scorers[i].nextDoc() : scorers[i].advance(target)) >= 0; if (!more) return false; } Index: src/java/org/apache/lucene/search/ConstantScoreQuery.java =================================================================== --- src/java/org/apache/lucene/search/ConstantScoreQuery.java (revision 775940) +++ src/java/org/apache/lucene/search/ConstantScoreQuery.java (working copy) @@ -84,7 +84,7 @@ public Explanation explain(IndexReader reader, int doc) throws IOException { ConstantScorer cs = (ConstantScorer)scorer(reader); - boolean exists = cs.docIdSetIterator.skipTo(doc) && (cs.docIdSetIterator.doc() == doc); + boolean exists = cs.docIdSetIterator.advance(doc) == doc; ComplexExplanation result = new ComplexExplanation(); @@ -116,10 +116,15 @@ docIdSetIterator = filter.getDocIdSet(reader).iterator(); } + /** @deprecated use {@link #nextDoc()} instead. */ public boolean next() throws IOException { - return docIdSetIterator.next(); + return docIdSetIterator.nextDoc() >= 0; } + public int nextDoc() throws IOException { + return docIdSetIterator.nextDoc(); + } + public int doc() { return docIdSetIterator.doc(); } @@ -128,10 +133,15 @@ return theScore; } + /** @deprecated use {@link #advance(int)} instead. */ public boolean skipTo(int target) throws IOException { - return docIdSetIterator.skipTo(target); + return docIdSetIterator.advance(target) >= 0; } + public int advance(int target) throws IOException { + return docIdSetIterator.advance(target); + } + public Explanation explain(int doc) throws IOException { throw new UnsupportedOperationException(); } Index: src/java/org/apache/lucene/search/DisjunctionMaxScorer.java =================================================================== --- src/java/org/apache/lucene/search/DisjunctionMaxScorer.java (revision 775940) +++ src/java/org/apache/lucene/search/DisjunctionMaxScorer.java (working copy) @@ -48,35 +48,51 @@ * @param scorer the scorer of a subquery of our associated DisjunctionMaxQuery */ public void add(Scorer scorer) throws IOException { - if (scorer.next()) { // Initialize and retain only if it produces docs - subScorers.add(scorer); - more = true; - } + if (scorer.nextDoc() >= 0) { // Initialize and retain only if it produces docs + subScorers.add(scorer); + more = true; + } } - /** Generate the next document matching our associated DisjunctionMaxQuery. + /** + * Generate the next document matching our associated DisjunctionMaxQuery. + * * @return true iff there is a next document + * @deprecated use {@link #nextDoc()} instead. */ public boolean next() throws IOException { - if (!more) return false; - if (firstTime) { - heapify(); - firstTime = false; - return true; // more would have been false if no subScorers had any docs - } - // Increment all generators that generated the last doc and adjust the heap. - int lastdoc = ((Scorer) subScorers.get(0)).doc(); - do { - if (((Scorer) subScorers.get(0)).next()) - heapAdjust(0); - else { - heapRemoveRoot(); - if (subScorers.isEmpty()) return (more = false); - } - } while ( ((Scorer) subScorers.get(0)).doc()==lastdoc ); - return true; + return nextDoc() >= 0; } + /** + * Generate the next document matching our associated DisjunctionMaxQuery. + * + * @return the next document if exists or -1 otherwise. + */ + public int nextDoc() throws IOException { + if (!more) return -1; + if (firstTime) { + heapify(); + firstTime = false; + // more would have been false if no subScorers had any docs + return ((Scorer) subScorers.get(0)).doc(); + } + // Increment all generators that generated the last doc and adjust the heap. + int lastdoc = ((Scorer) subScorers.get(0)).doc(); + do { + if (((Scorer) subScorers.get(0)).nextDoc() >= 0) + heapAdjust(0); + else { + heapRemoveRoot(); + if (subScorers.isEmpty()) { + more = false; + return -1; + } + } + } while (((Scorer) subScorers.get(0)).doc() == lastdoc); + return ((Scorer) subScorers.get(0)).doc(); + } + /** Determine the current document number. Initially invalid, until {@link #next()} is called the first time. * @return the document number of the currently generated document */ @@ -107,28 +123,48 @@ } } - /** Advance to the first document beyond the current whose number is greater than or equal to target. - * @param target the minimum number of the next desired document - * @return true iff there is a document to be generated whose number is at least target + /** + * Advance to the first document beyond the current whose number is greater + * than or equal to target. + * + * @param target + * the minimum number of the next desired document + * @return true iff there is a document to be generated whose number is at + * least target + * @deprecated use {@link #advance(int)} instead. */ public boolean skipTo(int target) throws IOException { - if (firstTime) { - if (!more) return false; - heapify(); - firstTime = false; - } + return advance(target) >= 0; + } - while (subScorers.size()>0 && ((Scorer)subScorers.get(0)).doc() 0 && ((Scorer) subScorers.get(0)).doc() < target) { + if (((Scorer)subScorers.get(0)).advance(target) >= 0) + heapAdjust(0); + else + heapRemoveRoot(); + } + if (subScorers.size() == 0) { + more = false; + return -1; + } + return ((Scorer)subScorers.get(0)).doc(); } - + /** Explain a score that we computed. UNSUPPORTED -- see explanation capability in DisjunctionMaxQuery. * @param doc the number of a document we scored * @return the Explanation for our score Index: src/java/org/apache/lucene/search/DisjunctionSumScorer.java =================================================================== --- src/java/org/apache/lucene/search/DisjunctionSumScorer.java (revision 775940) +++ src/java/org/apache/lucene/search/DisjunctionSumScorer.java (working copy) @@ -102,7 +102,7 @@ scorerDocQueue = new ScorerDocQueue(nrScorers); while (si.hasNext()) { Scorer se = (Scorer) si.next(); - if (se.next()) { // doc() method will be used in scorerDocQueue. + if (se.nextDoc() >= 0) { // doc() method will be used in scorerDocQueue. scorerDocQueue.insert(se); } } @@ -124,7 +124,7 @@ */ public void score(Collector collector) throws IOException { collector.setScorer(this); - while (next()) { + while (nextDoc() >= 0) { collector.collect(currentDoc); } } @@ -153,18 +153,21 @@ collector.setScorer(this); while (currentDoc < max) { collector.collect(currentDoc); - if (!next()) { + if (nextDoc() < 0) { return false; } } return true; } + /** @deprecated use {@link #nextDoc()} instead. */ public boolean next() throws IOException { - return (scorerDocQueue.size() >= minimumNrMatchers) - && advanceAfterCurrent(); + return nextDoc() >= 0; } + public int nextDoc() throws IOException { + return scorerDocQueue.size() >= minimumNrMatchers && advanceAfterCurrent() ? currentDoc : -1; + } /** Advance all subscorers after the current document determined by the * top of the scorerDocQueue. @@ -224,31 +227,52 @@ return nrMatchers; } - /** Skips to the first match beyond the current whose document number is - * greater than or equal to a given target. - *
When this method is used the {@link #explain(int)} method should not be used. - *
The implementation uses the skipTo() method on the subscorers. - * @param target The target document number. + /** + * Skips to the first match beyond the current whose document number is + * greater than or equal to a given target.
+ * When this method is used the {@link #explain(int)} method should not be + * used.
+ * The implementation uses the skipTo() method on the subscorers. + * + * @param target + * The target document number. * @return true iff there is such a match. + * @deprecated use {@link #advance(int)} instead. */ public boolean skipTo(int target) throws IOException { + return advance(target) >= 0; + } + + /** + * Advances to the first match beyond the current whose document number is + * greater than or equal to a given target.
+ * When this method is used the {@link #explain(int)} method should not be + * used.
+ * The implementation uses the skipTo() method on the subscorers. + * + * @param target + * The target document number. + * @return the document whose number is greater than or equal to the given + * target, or -1 if none exist. + */ + public int advance(int target) throws IOException { if (scorerDocQueue.size() < minimumNrMatchers) { - return false; + return -1; } if (target <= currentDoc) { - return true; + return currentDoc; } do { if (scorerDocQueue.topDoc() >= target) { - return advanceAfterCurrent(); - } else if (! scorerDocQueue.topSkipToAndAdjustElsePop(target)) { + return advanceAfterCurrent() ? currentDoc : -1; + } else if (!scorerDocQueue.topSkipToAndAdjustElsePop(target)) { if (scorerDocQueue.size() < minimumNrMatchers) { - return false; + return -1; } } } while (true); } - + /** @return An explanation for the score of a given document. */ public Explanation explain(int doc) throws IOException { Explanation res = new Explanation(); Index: src/java/org/apache/lucene/search/DocIdSetIterator.java =================================================================== --- src/java/org/apache/lucene/search/DocIdSetIterator.java (revision 775940) +++ src/java/org/apache/lucene/search/DocIdSetIterator.java (working copy) @@ -24,26 +24,93 @@ * non-decreasing doc ids. */ public abstract class DocIdSetIterator { - /** Returns the current document number.

This is invalid until {@link + + /** Returns the current document number.

This is invalid until {@link #next()} is called for the first time.*/ - public abstract int doc(); - - /** Moves to the next docId in the set. Returns true, iff - * there is such a docId. */ - public abstract boolean next() throws IOException; - - /** Skips entries to the first beyond the current whose document number is - * greater than or equal to target.

Returns true iff there is such - * an entry.

Behaves as if written:

-     *   boolean skipTo(int target) {
-     *     do {
-     *       if (!next())
-     *         return false;
-     *     } while (target > doc());
-     *     return true;
-     *   }
-     * 
- * Some implementations are considerably more efficient than that. - */ - public abstract boolean skipTo(int target) throws IOException; + public abstract int doc(); + + /** + * Moves to the next docId in the set. Returns true, iff there is such a + * docId. + * + * @deprecated use {@link #nextDoc()} instead. This will be removed in 3.0 + */ + public abstract boolean next() throws IOException; + + /** Skips entries to the first beyond the current whose document number is + * greater than or equal to target.

Returns true iff there is such + * an entry.

Behaves as if written:

+   *   boolean skipTo(int target) {
+   *     do {
+   *       if (!next())
+   *         return false;
+   *     } while (target > doc());
+   *     return true;
+   *   }
+   * 
+ * Some implementations are considerably more efficient than that. + * + * @deprecated use {@link #advance(int)} instead. This will be removed in 3.0 + */ + public abstract boolean skipTo(int target) throws IOException; + + /** + * Advances to the next document in the set and returns the doc it is + * currently on, or -1 if there are no more docs in the set. NOTE: if + * this method returns a negative number, the result of {@link #doc()} is + * unspecified.
+ * + * NOTE: in 3.0 this method will become abstract, following the removal + * of {@link #next()}. For backward compatibility it is implemented as: + * + *
+   * public int nextDoc() throws IOException {
+   *   return next() ? doc() : -1;
+   * }
+   * 
+ */ + public int nextDoc() throws IOException { + return next() ? doc() : -1; + } + + /** + * Advances to the first beyond the current whose document number is greater + * than or equal to target. Returns the current document number or -1 + * if there are no more docs in the set. + *

+ * Behaves as if written: + * + *

+   * int advance(int target) {
+   *   int doc = doc();
+   *   while (doc < target) {
+   *     if ((doc = next()) < 0) {
+   *       return -1;
+   *     }
+   *   }
+   *   return doc;
+   * }
+   * 
+ * + * Some implementations are considerably more efficient than that. + * + * NOTE: if called multiple times with the same target it will return + * the same result. + * + * NOTE: if this method returns a negative number, the result of + * {@link #doc()} is unspecified. + * + * NOTE: in 3.0 this method will become abstract, following the removal + * of {@link #skipTo(int)}. + */ + public int advance(int target) throws IOException { + int doc = doc(); + while (doc < target) { + if ((doc = nextDoc()) < 0) { + return -1; + } + } + return doc; + } + } Index: src/java/org/apache/lucene/search/FieldCacheRangeFilter.java =================================================================== --- src/java/org/apache/lucene/search/FieldCacheRangeFilter.java (revision 775940) +++ src/java/org/apache/lucene/search/FieldCacheRangeFilter.java (working copy) @@ -163,32 +163,43 @@ return doc; } + /** @deprecated use {@link #nextDoc()} instead. */ public boolean next() { + return nextDoc() >= 0; + } + + public int nextDoc() { try { do { doc++; } while (fcsi.order[doc] > inclusiveUpperPoint || fcsi.order[doc] < inclusiveLowerPoint); - return true; + return doc; } catch (ArrayIndexOutOfBoundsException e) { doc = Integer.MAX_VALUE; - return false; + return -1; } } - + + /** @deprecated use {@link #advance(int)} instead. */ public boolean skipTo(int target) { + return advance(target) >= 0; + } + + public int advance(int target) { try { doc = target; while (fcsi.order[doc] > inclusiveUpperPoint || fcsi.order[doc] < inclusiveLowerPoint) { doc++; } - return true; + return doc; } catch (ArrayIndexOutOfBoundsException e) { doc = Integer.MAX_VALUE; - return false; + return -1; } } + } } } Index: src/java/org/apache/lucene/search/FieldCacheTermsFilter.java =================================================================== --- src/java/org/apache/lucene/search/FieldCacheTermsFilter.java (revision 775940) +++ src/java/org/apache/lucene/search/FieldCacheTermsFilter.java (working copy) @@ -17,12 +17,11 @@ * limitations under the License. */ +import java.io.IOException; + import org.apache.lucene.index.IndexReader; -import org.apache.lucene.index.TermDocs; // for javadoc import org.apache.lucene.util.OpenBitSet; -import java.io.IOException; - /** * A {@link Filter} that only accepts documents whose single * term value in the specified field is contained in the @@ -137,28 +136,36 @@ return doc; } + /** @deprecated use {@link #nextDoc()} instead. */ public boolean next() { + return nextDoc() >= 0; + } + + public int nextDoc() { try { - do { - doc++; - } while (!openBitSet.fastGet(fcsi.order[doc])); - return true; + while (!openBitSet.fastGet(fcsi.order[++doc])) {} + return doc; } catch (ArrayIndexOutOfBoundsException e) { doc = Integer.MAX_VALUE; - return false; + return -1; } } + /** @deprecated use {@link #advance(int)} instead. */ public boolean skipTo(int target) { + return advance(target) >= 0; + } + + public int advance(int target) { try { doc = target; while (!openBitSet.fastGet(fcsi.order[doc])) { doc++; } - return true; + return doc; } catch (ArrayIndexOutOfBoundsException e) { doc = Integer.MAX_VALUE; - return false; + return -1; } } } Index: src/java/org/apache/lucene/search/FilteredDocIdSetIterator.java =================================================================== --- src/java/org/apache/lucene/search/FilteredDocIdSetIterator.java (revision 775940) +++ src/java/org/apache/lucene/search/FilteredDocIdSetIterator.java (working copy) @@ -55,37 +55,46 @@ return _currentDoc; } + /** @deprecated use {@link #nextDoc()} instead. */ + public final boolean next() throws IOException{ + return nextDoc() >= 0; + } + // @Override - public final boolean next() throws IOException{ - while (_innerIter.next()) { - int doc = _innerIter.doc(); + public int nextDoc() throws IOException { + int doc; + while ((doc = _innerIter.nextDoc()) >= 0) { if (match(doc)) { _currentDoc = doc; - return true; + return _currentDoc; } } - return false; + return -1; } - + + /** @deprecated use {@link #advance(int)} instead. */ + public final boolean skipTo(int n) throws IOException{ + return advance(n) >= 0; + } + // @Override - public final boolean skipTo(int n) throws IOException{ - boolean flag = _innerIter.skipTo(n); - if (flag) { - int doc = _innerIter.doc(); + public int advance(int target) throws IOException { + int doc = _innerIter.advance(target); + if (doc >= 0) { if (match(doc)) { _currentDoc = doc; - return true; + return _currentDoc; } else { - while (_innerIter.next()) { - int docid = _innerIter.doc(); - if (match(docid)) { - _currentDoc = docid; - return true; + while ((doc = _innerIter.nextDoc()) >= 0) { + if (match(doc)) { + _currentDoc = doc; + return _currentDoc; } } - return false; + return -1; } } - return flag; + return -1; } + } Index: src/java/org/apache/lucene/search/FilteredQuery.java =================================================================== --- src/java/org/apache/lucene/search/FilteredQuery.java (revision 775940) +++ src/java/org/apache/lucene/search/FilteredQuery.java (working copy) @@ -85,7 +85,7 @@ } Filter f = FilteredQuery.this.filter; DocIdSetIterator docIdSetIterator = f.getDocIdSet(ir).iterator(); - if (docIdSetIterator.skipTo(i) && (docIdSetIterator.doc() == i)) { + if (docIdSetIterator.advance(i) == i) { return inner; } else { Explanation result = new Explanation @@ -99,36 +99,50 @@ public Query getQuery() { return FilteredQuery.this; } // return a filtering scorer - public Scorer scorer (IndexReader indexReader) throws IOException { + public Scorer scorer (IndexReader indexReader) throws IOException { final Scorer scorer = weight.scorer(indexReader); final DocIdSetIterator docIdSetIterator = filter.getDocIdSet(indexReader).iterator(); return new Scorer(similarity) { - private boolean advanceToCommon() throws IOException { - while (scorer.doc() != docIdSetIterator.doc()) { - if (scorer.doc() < docIdSetIterator.doc()) { - if (!scorer.skipTo(docIdSetIterator.doc())) { - return false; + private int advanceToCommon(int scorerDoc, int disiDoc) throws IOException { + while (scorerDoc != disiDoc) { + if (scorerDoc < disiDoc) { + if ((scorerDoc = scorer.advance(disiDoc)) < 0) { + return -1; } - } else if (!docIdSetIterator.skipTo(scorer.doc())) { - return false; + } else if ((disiDoc = docIdSetIterator.advance(scorerDoc)) < 0) { + return -1; } } - return true; + return scorerDoc; } + /** @deprecated use {@link #nextDoc()} instead. */ public boolean next() throws IOException { - return docIdSetIterator.next() && scorer.next() && advanceToCommon(); + return nextDoc() >= 0; } + public int nextDoc() throws IOException { + int scorerDoc, disiDoc; + return (disiDoc = docIdSetIterator.nextDoc()) >= 0 + && (scorerDoc = scorer.nextDoc()) >= 0 + && advanceToCommon(scorerDoc, disiDoc) >= 0 ? scorer.doc() : -1; + } + public int doc() { return scorer.doc(); } + /** @deprecated use {@link #advance(int)} instead. */ public boolean skipTo(int i) throws IOException { - return docIdSetIterator.skipTo(i) - && scorer.skipTo(docIdSetIterator.doc()) - && advanceToCommon(); + return advance(i) >= 0; } + + public int advance(int target) throws IOException { + int disiDoc, scorerDoc; + return (disiDoc = docIdSetIterator.advance(target)) >= 0 + && (scorerDoc = scorer.advance(disiDoc)) >= 0 + && advanceToCommon(scorerDoc, disiDoc) >= 0 ? scorer.doc() : -1; + } public float score() throws IOException { return getBoost() * scorer.score(); } @@ -136,7 +150,7 @@ public Explanation explain (int i) throws IOException { Explanation exp = scorer.explain(i); - if (docIdSetIterator.skipTo(i) && (docIdSetIterator.doc() == i)) { + if (docIdSetIterator.advance(i) == i) { exp.setDescription ("allowed by filter: "+exp.getDescription()); exp.setValue(getBoost() * exp.getValue()); } else { Index: src/java/org/apache/lucene/search/IndexSearcher.java =================================================================== --- src/java/org/apache/lucene/search/IndexSearcher.java (revision 775940) +++ src/java/org/apache/lucene/search/IndexSearcher.java (working copy) @@ -236,21 +236,20 @@ DocIdSetIterator filterDocIdIterator = filter.getDocIdSet(reader).iterator(); // CHECKME: use ConjunctionScorer here? - boolean more = filterDocIdIterator.next() && scorer.skipTo(filterDocIdIterator.doc()); + int filterDoc = filterDocIdIterator.nextDoc(); + int scorerDoc = scorer.advance(filterDoc); + if (filterDoc < 0 || scorerDoc < 0) return; collector.setScorer(scorer); - while (more) { - int filterDocId = filterDocIdIterator.doc(); - if (filterDocId > scorer.doc() && !scorer.skipTo(filterDocId)) { - more = false; + while (true) { + if (filterDoc > scorerDoc && (scorerDoc = scorer.advance(filterDoc)) < 0) { + break; + } + if (scorerDoc == filterDoc) { // permitted by filter + collector.collect(scorerDoc); + if ((filterDoc = filterDocIdIterator.nextDoc()) < 0) break; } else { - int scorerDocId = scorer.doc(); - if (scorerDocId == filterDocId) { // permitted by filter - collector.collect(scorerDocId); - more = filterDocIdIterator.next(); - } else { - more = filterDocIdIterator.skipTo(scorerDocId); - } + if ((filterDoc = filterDocIdIterator.advance(scorerDoc)) < 0) break; } } } Index: src/java/org/apache/lucene/search/MatchAllDocsQuery.java =================================================================== --- src/java/org/apache/lucene/search/MatchAllDocsQuery.java (revision 775940) +++ src/java/org/apache/lucene/search/MatchAllDocsQuery.java (working copy) @@ -64,10 +64,15 @@ return termDocs.doc(); } + /** @deprecated use {@link #nextDoc()} instead. */ public boolean next() throws IOException { - return termDocs.next(); + return nextDoc() >= 0; } + public int nextDoc() throws IOException { + return termDocs.next() ? termDocs.doc() : -1; + } + public float score() { if (norms == null) { return score; @@ -76,10 +81,14 @@ } } + /** @deprecated use {@link #advance(int)} instead. */ public boolean skipTo(int target) throws IOException { - return termDocs.skipTo(target); + return advance(target) >= 0; } + public int advance(int target) throws IOException { + return termDocs.skipTo(target) ? termDocs.doc() : -1; + } } private class MatchAllDocsWeight implements Weight { Index: src/java/org/apache/lucene/search/NonMatchingScorer.java =================================================================== --- src/java/org/apache/lucene/search/NonMatchingScorer.java (revision 775940) +++ src/java/org/apache/lucene/search/NonMatchingScorer.java (working copy) @@ -25,11 +25,17 @@ public int doc() { throw new UnsupportedOperationException(); } + /** @deprecated use {@link #nextDoc()} instead. */ public boolean next() throws IOException { return false; } + + public int nextDoc() throws IOException { return -1; } public float score() { throw new UnsupportedOperationException(); } + /** @deprecated use {@link #advance(int)} instead. */ public boolean skipTo(int target) { return false; } + + public int advance(int target) { return -1; } public Explanation explain(int doc) { Explanation e = new Explanation(); Index: src/java/org/apache/lucene/search/PhraseScorer.java =================================================================== --- src/java/org/apache/lucene/search/PhraseScorer.java (revision 775940) +++ src/java/org/apache/lucene/search/PhraseScorer.java (working copy) @@ -71,14 +71,19 @@ public int doc() { return first.doc; } + /** @deprecated use {@link #nextDoc()} instead. */ public boolean next() throws IOException { + return nextDoc() >= 0; + } + + public int nextDoc() throws IOException { if (firstTime) { init(); firstTime = false; } else if (more) { more = last.next(); // trigger further scanning } - return doNext(); + return doNext() ? first.doc : -1; } // next without initial increment @@ -107,16 +112,21 @@ return norms == null ? raw : raw * Similarity.decodeNorm(norms[first.doc]); // normalize } + /** @deprecated use {@link #advance(int)} instead. */ public boolean skipTo(int target) throws IOException { + return advance(target) >= 0; + } + + public int advance(int target) throws IOException { firstTime = false; for (PhrasePositions pp = first; more && pp != null; pp = pp.next) { more = pp.skipTo(target); } if (more) sort(); // re-sort - return doNext(); + return doNext() ? first.doc : -1; } - + /** * For a document containing all the phrase query terms, compute the * frequency of the phrase in that document. @@ -163,7 +173,8 @@ public Explanation explain(final int doc) throws IOException { Explanation tfExplanation = new Explanation(); - while (next() && doc() < doc) {} + int d; + while ((d = nextDoc()) >= 0 && d < doc) {} float phraseFreq = (doc() == doc) ? freq : 0.0f; tfExplanation.setValue(getSimilarity().tf(phraseFreq)); Index: src/java/org/apache/lucene/search/ReqExclScorer.java =================================================================== --- src/java/org/apache/lucene/search/ReqExclScorer.java (revision 775940) +++ src/java/org/apache/lucene/search/ReqExclScorer.java (working copy) @@ -42,22 +42,28 @@ private boolean firstTime = true; + /** @deprecated use {@link #nextDoc()} instead. */ public boolean next() throws IOException { + return nextDoc() >= 0; + } + + public int nextDoc() throws IOException { if (firstTime) { - if (! exclScorer.next()) { + if (exclScorer.nextDoc() < 0) { exclScorer = null; // exhausted at start } firstTime = false; } if (reqScorer == null) { - return false; + return -1; } - if (! reqScorer.next()) { + int reqDoc = reqScorer.nextDoc(); + if (reqDoc < 0) { reqScorer = null; // exhausted, nothing left - return false; + return -1; } if (exclScorer == null) { - return true; // reqScorer.next() already returned true + return reqDoc; } return toNonExcluded(); } @@ -73,25 +79,25 @@ * Advances reqScorer a non excluded required doc, if any. * @return true iff there is a non excluded required doc. */ - private boolean toNonExcluded() throws IOException { + private int toNonExcluded() throws IOException { int exclDoc = exclScorer.doc(); + int reqDoc = reqScorer.doc(); // may be excluded do { - int reqDoc = reqScorer.doc(); // may be excluded if (reqDoc < exclDoc) { - return true; // reqScorer advanced to before exclScorer, ie. not excluded + return reqDoc; // reqScorer advanced to before exclScorer, ie. not excluded } else if (reqDoc > exclDoc) { - if (! exclScorer.skipTo(reqDoc)) { + exclDoc = exclScorer.advance(reqDoc); + if (exclDoc < 0) { exclScorer = null; // exhausted, no more exclusions - return true; + return reqDoc; } - exclDoc = exclScorer.doc(); if (exclDoc > reqDoc) { - return true; // not excluded + return reqDoc; // not excluded } } - } while (reqScorer.next()); + } while ((reqDoc = reqScorer.nextDoc()) >= 0); reqScorer = null; // exhausted, nothing left - return false; + return -1; } public int doc() { @@ -106,35 +112,34 @@ return reqScorer.score(); // reqScorer may be null when next() or skipTo() already return false } - /** Skips to the first match beyond the current whose document number is - * greater than or equal to a given target. - *
When this method is used the {@link #explain(int)} method should not be used. - * @param target The target document number. - * @return true iff there is such a match. - */ + /** @deprecated use {@link #advance(int)} instead. */ public boolean skipTo(int target) throws IOException { + return advance(target) >= 0; + } + + public int advance(int target) throws IOException { if (firstTime) { firstTime = false; - if (! exclScorer.skipTo(target)) { + if (exclScorer.advance(target) < 0) { exclScorer = null; // exhausted } } if (reqScorer == null) { - return false; + return -1; } if (exclScorer == null) { - return reqScorer.skipTo(target); + return reqScorer.advance(target); } - if (! reqScorer.skipTo(target)) { + if (reqScorer.advance(target) < 0) { reqScorer = null; - return false; + return -1; } return toNonExcluded(); } - + public Explanation explain(int doc) throws IOException { Explanation res = new Explanation(); - if (exclScorer.skipTo(doc) && (exclScorer.doc() == doc)) { + if (exclScorer.advance(doc) == doc) { res.setDescription("excluded"); } else { res.setDescription("not excluded"); Index: src/java/org/apache/lucene/search/ReqOptSumScorer.java =================================================================== --- src/java/org/apache/lucene/search/ReqOptSumScorer.java (revision 775940) +++ src/java/org/apache/lucene/search/ReqOptSumScorer.java (working copy) @@ -45,14 +45,24 @@ private boolean firstTimeOptScorer = true; + /** @deprecated use {@link #nextDoc()} instead. */ public boolean next() throws IOException { return reqScorer.next(); } + public int nextDoc() throws IOException { + return reqScorer.nextDoc(); + } + + /** @deprecated use {@link #advance(int)} instead. */ public boolean skipTo(int target) throws IOException { return reqScorer.skipTo(target); } + public int advance(int target) throws IOException { + return reqScorer.advance(target); + } + public int doc() { return reqScorer.doc(); } @@ -67,20 +77,18 @@ float reqScore = reqScorer.score(); if (firstTimeOptScorer) { firstTimeOptScorer = false; - if (! optScorer.skipTo(curDoc)) { + if (optScorer.advance(curDoc) < 0) { optScorer = null; return reqScore; } } else if (optScorer == null) { return reqScore; - } else if ((optScorer.doc() < curDoc) && (! optScorer.skipTo(curDoc))) { + } else if (optScorer.doc() < curDoc && optScorer.advance(curDoc) < 0) { optScorer = null; return reqScore; } // assert (optScorer != null) && (optScorer.doc() >= curDoc); - return (optScorer.doc() == curDoc) - ? reqScore + optScorer.score() - : reqScore; + return optScorer.doc() == curDoc ? reqScore + optScorer.score() : reqScore; } /** Explain the score of a document. Index: src/java/org/apache/lucene/search/ScoreCachingWrappingScorer.java =================================================================== --- src/java/org/apache/lucene/search/ScoreCachingWrappingScorer.java (revision 775940) +++ src/java/org/apache/lucene/search/ScoreCachingWrappingScorer.java (working copy) @@ -68,16 +68,26 @@ return scorer.doc(); } + /** @deprecated use {@link #nextDoc()} instead. */ public boolean next() throws IOException { return scorer.next(); } + public int nextDoc() throws IOException { + return scorer.nextDoc(); + } + public void score(Collector collector) throws IOException { scorer.score(collector); } + /** @deprecated use {@link #advance(int)} instead. */ public boolean skipTo(int target) throws IOException { return scorer.skipTo(target); } + public int advance(int target) throws IOException { + return scorer.advance(target); + } + } Index: src/java/org/apache/lucene/search/Scorer.java =================================================================== --- src/java/org/apache/lucene/search/Scorer.java (revision 775940) +++ src/java/org/apache/lucene/search/Scorer.java (working copy) @@ -64,8 +64,9 @@ */ public void score(Collector collector) throws IOException { collector.setScorer(this); - while (next()) { - collector.collect(doc()); + int doc; + while ((doc = nextDoc()) >= 0) { + collector.collect(doc); } } @@ -91,9 +92,10 @@ */ protected boolean score(Collector collector, int max) throws IOException { collector.setScorer(this); - while (doc() < max) { - collector.collect(doc()); - if (!next()) + int doc = doc(); + while (doc < max) { + collector.collect(doc); + if ((doc = nextDoc()) < 0) return false; } return true; Index: src/java/org/apache/lucene/search/TermScorer.java =================================================================== --- src/java/org/apache/lucene/search/TermScorer.java (revision 775940) +++ src/java/org/apache/lucene/search/TermScorer.java (working copy) @@ -65,7 +65,7 @@ } public void score(Collector c) throws IOException { - next(); + nextDoc(); score(c, Integer.MAX_VALUE); } @@ -99,12 +99,26 @@ */ public int doc() { return doc; } - /** Advances to the next document matching the query. - *
The iterator over the matching documents is buffered using + /** + * Advances to the next document matching the query.
+ * The iterator over the matching documents is buffered using * {@link TermDocs#read(int[],int[])}. + * * @return true iff there is another document matching the query. + * @deprecated use {@link #nextDoc()} instead. */ public boolean next() throws IOException { + return nextDoc() >= 0; + } + + /** + * Advances to the next document matching the query.
+ * The iterator over the matching documents is buffered using + * {@link TermDocs#read(int[],int[])}. + * + * @return the document matching the query or -1 if there are no more documents. + */ + public int nextDoc() throws IOException { pointer++; if (pointer >= pointerMax) { pointerMax = termDocs.read(docs, freqs); // refill buffer @@ -113,13 +127,13 @@ } else { termDocs.close(); // close stream doc = Integer.MAX_VALUE; // set to sentinel value - return false; + return -1; } } doc = docs[pointer]; - return true; + return doc; } - + public float score() { int f = freqs[pointer]; float raw = // compute tf(f)*weight @@ -130,18 +144,35 @@ return norms == null ? raw : raw * SIM_NORM_DECODER[norms[doc] & 0xFF]; // normalize for field } - /** Skips to the first match beyond the current whose document number is - * greater than or equal to a given target. - *
The implementation uses {@link TermDocs#skipTo(int)}. - * @param target The target document number. + /** + * Skips to the first match beyond the current whose document number is + * greater than or equal to a given target.
+ * The implementation uses {@link TermDocs#skipTo(int)}. + * + * @param target + * The target document number. * @return true iff there is such a match. + * @deprecated use {@link #advance(int)} instead. */ public boolean skipTo(int target) throws IOException { + return advance(target) >= 0; + } + + /** + * Advances to the first match beyond the current whose document number is + * greater than or equal to a given target.
+ * The implementation uses {@link TermDocs#skipTo(int)}. + * + * @param target + * The target document number. + * @return the matching document or -1 if none exist. + */ + public int advance(int target) throws IOException { // first scan in cache - for (pointer++; pointer < pointerMax; pointer++) { + for (; pointer < pointerMax; pointer++) { if (docs[pointer] >= target) { doc = docs[pointer]; - return true; + return doc; } } @@ -152,12 +183,13 @@ pointer = 0; docs[pointer] = doc = termDocs.doc(); freqs[pointer] = termDocs.freq(); + return doc; } else { doc = Integer.MAX_VALUE; + return -1; } - return result; } - + /** Returns an explanation of the score for a document. *
When this method is used, the {@link #next()} method * and the {@link #score(HitCollector)} method should not be used. Index: src/java/org/apache/lucene/search/function/CustomScoreQuery.java =================================================================== --- src/java/org/apache/lucene/search/function/CustomScoreQuery.java (revision 775940) +++ src/java/org/apache/lucene/search/function/CustomScoreQuery.java (working copy) @@ -367,17 +367,21 @@ this.vScores = new float[valSrcScorers.length]; } - /*(non-Javadoc) @see org.apache.lucene.search.Scorer#next() */ + /** @deprecated use {@link #nextDoc()} instead. */ public boolean next() throws IOException { - boolean hasNext = subQueryScorer.next(); - if (hasNext) { - for(int i = 0; i < valSrcScorers.length; i++) { - valSrcScorers[i].skipTo(subQueryScorer.doc()); + return nextDoc() >= 0; + } + + public int nextDoc() throws IOException { + int doc = subQueryScorer.nextDoc(); + if (doc >= 0) { + for (int i = 0; i < valSrcScorers.length; i++) { + valSrcScorers[i].advance(doc); } } - return hasNext; + return doc; } - + /*(non-Javadoc) @see org.apache.lucene.search.Scorer#doc() */ public int doc() { return subQueryScorer.doc(); @@ -391,17 +395,21 @@ return qWeight * customScore(subQueryScorer.doc(), subQueryScorer.score(), vScores); } - /*(non-Javadoc) @see org.apache.lucene.search.Scorer#skipTo(int) */ + /** @deprecated use {@link #advance(int)} instead. */ public boolean skipTo(int target) throws IOException { - boolean hasNext = subQueryScorer.skipTo(target); - if (hasNext) { - for (int i = 0; i < valSrcScorers.length; i++) { - valSrcScorers[i].skipTo(subQueryScorer.doc()); + return advance(target) >= 0; + } + + public int advance(int target) throws IOException { + int doc = subQueryScorer.advance(target); + if (doc >= 0) { + for (int i = 0; i < valSrcScorers.length; i++) { + valSrcScorers[i].advance(doc); } } - return hasNext; + return doc; } - + /*(non-Javadoc) @see org.apache.lucene.search.Scorer#explain(int) */ public Explanation explain(int doc) throws IOException { Explanation subQueryExpl = weight.subQueryWeight.explain(reader,doc); Index: src/java/org/apache/lucene/search/function/ValueSourceQuery.java =================================================================== --- src/java/org/apache/lucene/search/function/ValueSourceQuery.java (revision 775940) +++ src/java/org/apache/lucene/search/function/ValueSourceQuery.java (working copy) @@ -126,13 +126,15 @@ termDocs = reader.termDocs(null); } - /*(non-Javadoc) @see org.apache.lucene.search.Scorer#next() */ + /** @deprecated use {@link #nextDoc()} instead. */ public boolean next() throws IOException { return termDocs.next(); } - /*(non-Javadoc) @see org.apache.lucene.search.Scorer#doc() - */ + public int nextDoc() throws IOException { + return termDocs.next() ? termDocs.doc() : -1; + } + public int doc() { return termDocs.doc(); } @@ -142,10 +144,14 @@ return qWeight * vals.floatVal(termDocs.doc()); } - /*(non-Javadoc) @see org.apache.lucene.search.Scorer#skipTo(int) */ + /** @deprecated use {@link #advance(int)} instead. */ public boolean skipTo(int target) throws IOException { return termDocs.skipTo(target); } + + public int advance(int target) throws IOException { + return termDocs.skipTo(target) ? termDocs.doc() : -1; + } /*(non-Javadoc) @see org.apache.lucene.search.Scorer#explain(int) */ public Explanation explain(int doc) throws IOException { Index: src/java/org/apache/lucene/search/payloads/BoostingTermQuery.java =================================================================== --- src/java/org/apache/lucene/search/payloads/BoostingTermQuery.java (revision 775940) +++ src/java/org/apache/lucene/search/payloads/BoostingTermQuery.java (working copy) @@ -81,9 +81,9 @@ } - protected boolean setFreqCurrentDoc() throws IOException { + protected int setFreqCurrentDoc() throws IOException { if (!more) { - return false; + return -1; } doc = spans.doc(); freq = 0.0f; @@ -98,7 +98,7 @@ more = spans.next();//this moves positions to the next match in this document } - return more || (freq != 0); + return more || freq != 0 ? doc : -1; } Index: src/java/org/apache/lucene/search/spans/SpanScorer.java =================================================================== --- src/java/org/apache/lucene/search/spans/SpanScorer.java (revision 775940) +++ src/java/org/apache/lucene/search/spans/SpanScorer.java (working copy) @@ -49,7 +49,12 @@ doc = -1; } + /** @deprecated use {@link #nextDoc()} instead. */ public boolean next() throws IOException { + return nextDoc() >= 0; + } + + public int nextDoc() throws IOException { if (firstTime) { more = spans.next(); firstTime = false; @@ -57,23 +62,28 @@ return setFreqCurrentDoc(); } + /** @deprecated use {@link #advance(int)} instead. */ public boolean skipTo(int target) throws IOException { + return advance(target) >= 0; + } + + public int advance(int target) throws IOException { if (firstTime) { more = spans.skipTo(target); firstTime = false; } - if (! more) { - return false; + if (!more) { + return -1; } if (spans.doc() < target) { // setFreqCurrentDoc() leaves spans.doc() ahead more = spans.skipTo(target); } return setFreqCurrentDoc(); } - - protected boolean setFreqCurrentDoc() throws IOException { - if (! more) { - return false; + + protected int setFreqCurrentDoc() throws IOException { + if (!more) { + return -1; } doc = spans.doc(); freq = 0.0f; @@ -82,7 +92,7 @@ freq += getSimilarity().sloppyFreq(matchLength); more = spans.next(); } while (more && (doc == spans.doc())); - return true; + return doc; } public int doc() { return doc; } @@ -95,9 +105,9 @@ public Explanation explain(final int doc) throws IOException { Explanation tfExplanation = new Explanation(); - skipTo(doc); + int expDoc = advance(doc); - float phraseFreq = (doc() == doc) ? freq : 0.0f; + float phraseFreq = (expDoc == doc) ? freq : 0.0f; tfExplanation.setValue(getSimilarity().tf(phraseFreq)); tfExplanation.setDescription("tf(phraseFreq=" + phraseFreq + ")"); Index: src/java/org/apache/lucene/util/DocIdBitSet.java =================================================================== --- src/java/org/apache/lucene/util/DocIdBitSet.java (revision 775940) +++ src/java/org/apache/lucene/util/DocIdBitSet.java (working copy) @@ -18,6 +18,7 @@ */ import java.util.BitSet; + import org.apache.lucene.search.DocIdSet; import org.apache.lucene.search.DocIdSetIterator; @@ -55,15 +56,26 @@ return docId; } + /** @deprecated use {@link #nextDoc()} instead. */ public boolean next() { // (docId + 1) on next line requires -1 initial value for docNr: - return checkNextDocId(bitSet.nextSetBit(docId + 1)); + return nextDoc() >= 0; } + + public int nextDoc() { + // (docId + 1) on next line requires -1 initial value for docNr: + return checkNextDocId(bitSet.nextSetBit(docId + 1)) ? docId : -1; + } + /** @deprecated use {@link #advance(int)} instead. */ public boolean skipTo(int skipDocNr) { - return checkNextDocId( bitSet.nextSetBit(skipDocNr)); + return advance(skipDocNr) >= 0; } + public int advance(int target) { + return checkNextDocId(bitSet.nextSetBit(target)) ? docId : -1; + } + private boolean checkNextDocId(int d) { if (d == -1) { // -1 returned by BitSet.nextSetBit() when exhausted docId = Integer.MAX_VALUE; Index: src/java/org/apache/lucene/util/OpenBitSetDISI.java =================================================================== --- src/java/org/apache/lucene/util/OpenBitSetDISI.java (revision 775940) +++ src/java/org/apache/lucene/util/OpenBitSetDISI.java (working copy) @@ -47,8 +47,10 @@ * constructor. */ public void inPlaceOr(DocIdSetIterator disi) throws IOException { - while (disi.next() && (disi.doc() < size())) { - fastSet(disi.doc()); + int doc; + long size = size(); + while ((doc = disi.nextDoc()) >= 0 && doc < size) { + fastSet(doc); } } @@ -60,8 +62,8 @@ */ public void inPlaceAnd(DocIdSetIterator disi) throws IOException { int bitSetDoc = nextSetBit(0); - while ((bitSetDoc != -1) && disi.skipTo(bitSetDoc)) { - int disiDoc = disi.doc(); + int disiDoc; + while (bitSetDoc != -1 && (disiDoc = disi.advance(bitSetDoc)) >= 0) { clear(bitSetDoc, disiDoc); bitSetDoc = nextSetBit(disiDoc + 1); } @@ -77,8 +79,10 @@ * constructor. */ public void inPlaceNot(DocIdSetIterator disi) throws IOException { - while (disi.next() && (disi.doc() < size())) { - fastClear(disi.doc()); + int doc; + long size = size(); + while ((doc = disi.nextDoc()) >= 0 && doc < size) { + fastClear(doc); } } @@ -89,8 +93,10 @@ * constructor. */ public void inPlaceXor(DocIdSetIterator disi) throws IOException { - while (disi.next() && (disi.doc() < size())) { - fastFlip(disi.doc()); + int doc; + long size = size(); + while ((doc = disi.nextDoc()) >= 0 && doc < size) { + fastFlip(doc); } } } Index: src/java/org/apache/lucene/util/OpenBitSetIterator.java =================================================================== --- src/java/org/apache/lucene/util/OpenBitSetIterator.java (revision 775940) +++ src/java/org/apache/lucene/util/OpenBitSetIterator.java (working copy) @@ -17,8 +17,6 @@ package org.apache.lucene.util; -import java.io.IOException; - import org.apache.lucene.search.DocIdSetIterator; /** An iterator to iterate over set bits in an OpenBitSet. @@ -104,33 +102,9 @@ } ******/ + /** @deprecated use {@link #nextDoc()} instead. */ public boolean next() { - if (indexArray==0) { - if (word!=0) { - word >>>= 8; - wordShift += 8; - } - - while (word==0) { - if (++i >= words) { - curDocId = -1; - return false; - } - word = arr[i]; - wordShift =-1; // loop invariant code motion should move this - } - - // 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. - curDocId = (i<<6) + bitIndex; - return true; + return nextDoc() >= 0; } /** Moves iterator to the next doc and returns its id; @@ -162,13 +136,18 @@ return curDocId = (i<<6) + bitIndex; } + /** @deprecated use {@link #advance(int)} instead. */ public boolean skipTo(int target) { + return advance(target) >= 0; + } + + public int advance(int target) { indexArray=0; i = target >> 6; if (i>=words) { word =0; // setup so next() will also return -1 curDocId = -1; - return false; + return -1; } wordShift = target & 0x3f; word = arr[i] >>> wordShift; @@ -178,7 +157,7 @@ while (word ==0) { if (++i >= words) { curDocId = -1; - return false; + return -1; } word = arr[i]; } @@ -192,7 +171,7 @@ // should i<<6 be cached as a separate variable? // it would only save one cycle in the best circumstances. curDocId = (i<<6) + bitIndex; - return true; + return curDocId; } /** Behaves like {@link #skipTo(int)} and returns the docId the iterator Index: src/java/org/apache/lucene/util/ScorerDocQueue.java =================================================================== --- src/java/org/apache/lucene/util/ScorerDocQueue.java (revision 775940) +++ src/java/org/apache/lucene/util/ScorerDocQueue.java (working copy) @@ -113,11 +113,11 @@ } public final boolean topNextAndAdjustElsePop() throws IOException { - return checkAdjustElsePop( topHSD.scorer.next()); + return checkAdjustElsePop(topHSD.scorer.nextDoc() >= 0); } public final boolean topSkipToAndAdjustElsePop(int target) throws IOException { - return checkAdjustElsePop( topHSD.scorer.skipTo(target)); + return checkAdjustElsePop(topHSD.scorer.advance(target) >= 0); } private boolean checkAdjustElsePop(boolean cond) { Index: src/java/org/apache/lucene/util/SortedVIntList.java =================================================================== --- src/java/org/apache/lucene/util/SortedVIntList.java (revision 775940) +++ src/java/org/apache/lucene/util/SortedVIntList.java (working copy) @@ -99,8 +99,9 @@ */ public SortedVIntList(DocIdSetIterator docIdSetIterator) throws IOException { SortedVIntListBuilder builder = new SortedVIntListBuilder(); - while (docIdSetIterator.next()) { - builder.addInt(docIdSetIterator.doc()); + int doc; + while ((doc = docIdSetIterator.nextDoc()) >= 0) { + builder.addInt(doc); } builder.done(); } @@ -194,24 +195,35 @@ public int doc() {return lastInt;} + /** @deprecated use {@link #nextDoc()} instead. */ public boolean next() { + return nextDoc() >= 0; + } + + public int nextDoc() { if (bytePos >= lastBytePos) { - return false; + return -1; } else { advance(); - return true; + return lastInt; } } - + + /** @deprecated use {@link #advance(int)} instead. */ public boolean skipTo(int docNr) { + return advance(docNr) >= 0; + } + + public int advance(int target) { while (bytePos < lastBytePos) { advance(); - if (lastInt >= docNr) { // No skipping to docNr available. - return true; + if (lastInt >= target) { + return lastInt; } } - return false; + return -1; } + }; } } Index: src/test/org/apache/lucene/search/JustCompileSearch.java =================================================================== --- src/test/org/apache/lucene/search/JustCompileSearch.java (revision 775940) +++ src/test/org/apache/lucene/search/JustCompileSearch.java (working copy) @@ -179,14 +179,23 @@ throw new UnsupportedOperationException(UNSUPPORTED_MSG); } + /** @deprecated delete in 3.0 */ public boolean next() throws IOException { throw new UnsupportedOperationException(UNSUPPORTED_MSG); } + /** @deprecated delete in 3.0 */ public boolean skipTo(int target) throws IOException { throw new UnsupportedOperationException(UNSUPPORTED_MSG); } + public int nextDoc() throws IOException { + throw new UnsupportedOperationException(UNSUPPORTED_MSG); + } + + public int advance(int target) throws IOException { + throw new UnsupportedOperationException(UNSUPPORTED_MSG); + } } static final class JustCompileFieldCache implements FieldCache { @@ -482,14 +491,23 @@ throw new UnsupportedOperationException(UNSUPPORTED_MSG); } + /** @deprecated delete in 3.0. */ public boolean next() throws IOException { throw new UnsupportedOperationException(UNSUPPORTED_MSG); } + /** @deprecated delete in 3.0. */ public boolean skipTo(int target) throws IOException { throw new UnsupportedOperationException(UNSUPPORTED_MSG); } + + public int nextDoc() throws IOException { + throw new UnsupportedOperationException(UNSUPPORTED_MSG); + } + public int advance(int target) throws IOException { + throw new UnsupportedOperationException(UNSUPPORTED_MSG); + } } static final class JustCompileSimilarity extends Similarity { Index: src/test/org/apache/lucene/search/QueryUtils.java =================================================================== --- src/test/org/apache/lucene/search/QueryUtils.java (revision 775940) +++ src/test/org/apache/lucene/search/QueryUtils.java (working copy) @@ -1,13 +1,13 @@ package org.apache.lucene.search; -import junit.framework.TestCase; - import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; +import junit.framework.Assert; + import org.apache.lucene.index.IndexReader; /** @@ -56,17 +56,17 @@ } public static void checkEqual(Query q1, Query q2) { - TestCase.assertEquals(q1, q2); - TestCase.assertEquals(q1.hashCode(), q2.hashCode()); + Assert.assertEquals(q1, q2); + Assert.assertEquals(q1.hashCode(), q2.hashCode()); } public static void checkUnequal(Query q1, Query q2) { - TestCase.assertTrue(!q1.equals(q2)); - TestCase.assertTrue(!q2.equals(q1)); + Assert.assertTrue(!q1.equals(q2)); + Assert.assertTrue(!q2.equals(q1)); // possible this test can fail on a hash collision... if that // happens, please change test to use a different example. - TestCase.assertTrue(q1.hashCode() != q2.hashCode()); + Assert.assertTrue(q1.hashCode() != q2.hashCode()); } /** deep check that explanations of a query 'score' correctly */ @@ -169,7 +169,7 @@ try { int op = order[(opidx[0]++)%order.length]; //System.out.println(op==skip_op ? "skip("+(sdoc[0]+1)+")":"next()"); - boolean more = op==skip_op ? scorer.skipTo(sdoc[0]+1) : scorer.next(); + boolean more = op==skip_op ? scorer.advance(sdoc[0]+1) >= 0 : scorer.nextDoc() >= 0; sdoc[0] = scorer.doc(); float scorerScore = scorer.score(); float scorerScore2 = scorer.score(); @@ -204,8 +204,8 @@ // make sure next call to scorer is false. int op = order[(opidx[0]++)%order.length]; //System.out.println(op==skip_op ? "last: skip()":"last: next()"); - boolean more = op==skip_op ? scorer.skipTo(sdoc[0]+1) : scorer.next(); - TestCase.assertFalse(more); + boolean more = op==skip_op ? scorer.advance(sdoc[0]+1) >= 0 : scorer.nextDoc() >= 0; + Assert.assertFalse(more); } } @@ -228,11 +228,11 @@ for (int i=lastDoc[0]+1; i<=doc; i++) { Weight w = q.weight(s); Scorer scorer = w.scorer(s.getIndexReader()); - TestCase.assertTrue("query collected "+doc+" but skipTo("+i+") says no more docs!",scorer.skipTo(i)); - TestCase.assertEquals("query collected "+doc+" but skipTo("+i+") got to "+scorer.doc(),doc,scorer.doc()); + Assert.assertTrue("query collected "+doc+" but skipTo("+i+") says no more docs!",scorer.advance(i) >= 0); + Assert.assertEquals("query collected "+doc+" but skipTo("+i+") got to "+scorer.doc(),doc,scorer.doc()); float skipToScore = scorer.score(); - TestCase.assertEquals("unstable skipTo("+i+") score!",skipToScore,scorer.score(),maxDiff); - TestCase.assertEquals("query assigned doc "+doc+" a score of <"+score+"> but skipTo("+i+") has <"+skipToScore+">!",score,skipToScore,maxDiff); + Assert.assertEquals("unstable skipTo("+i+") score!",skipToScore,scorer.score(),maxDiff); + Assert.assertEquals("query assigned doc "+doc+" a score of <"+score+"> but skipTo("+i+") has <"+skipToScore+">!",score,skipToScore,maxDiff); } lastDoc[0] = doc; } catch (IOException e) { @@ -245,8 +245,8 @@ }); Weight w = q.weight(s); Scorer scorer = w.scorer(s.getIndexReader()); - boolean more = scorer.skipTo(lastDoc[0]+1); + boolean more = scorer.advance(lastDoc[0] + 1) >= 0; if (more) - TestCase.assertFalse("query's last doc was "+lastDoc[0]+" but skipTo("+(lastDoc[0]+1)+") got to "+scorer.doc(),more); + Assert.assertFalse("query's last doc was "+lastDoc[0]+" but skipTo("+(lastDoc[0]+1)+") got to "+scorer.doc(),more); } } Index: src/test/org/apache/lucene/search/TestDisjunctionMaxQuery.java =================================================================== --- src/test/org/apache/lucene/search/TestDisjunctionMaxQuery.java (revision 775940) +++ src/test/org/apache/lucene/search/TestDisjunctionMaxQuery.java (working copy) @@ -136,7 +136,7 @@ final Weight dw = dq.weight(s); final Scorer ds = dw.scorer(r); - final boolean skipOk = ds.skipTo(3); + final boolean skipOk = ds.advance(3) >= 0; if (skipOk) { fail("firsttime skipTo found a match? ... " + r.document(ds.doc()).get("id")); @@ -152,7 +152,7 @@ final Weight dw = dq.weight(s); final Scorer ds = dw.scorer(r); - assertTrue("firsttime skipTo found no match", ds.skipTo(3)); + assertTrue("firsttime skipTo found no match", ds.advance(3) >= 0); assertEquals("found wrong docid", "d4", r.document(ds.doc()).get("id")); } Index: src/test/org/apache/lucene/search/TestDocIdSet.java =================================================================== --- src/test/org/apache/lucene/search/TestDocIdSet.java (revision 775940) +++ src/test/org/apache/lucene/search/TestDocIdSet.java (working copy) @@ -35,26 +35,36 @@ return new DocIdSetIterator() { int docid=-1; + //@Override public int doc() { return docid; } + /** @deprecated use {@link #nextDoc()} instead. */ + public boolean next() throws IOException { + return nextDoc() >= 0; + } + //@Override - public boolean next() throws IOException { + public int nextDoc() throws IOException { docid++; - return (docid= 0; + } + //@Override - public boolean skipTo(int target) throws IOException { - do { - if (!next()) { - return false; + public int advance(int target) throws IOException { + while (docid < target) { + if (nextDoc() < 0) { + return -1; } - } while (target > doc()); - - return true; + } + return docid; } }; } @@ -70,10 +80,11 @@ DocIdSetIterator iter = filteredSet.iterator(); ArrayList/**/ list = new ArrayList/**/(); - if (iter.skipTo(3)) { - list.add(new Integer(iter.doc())); - while(iter.next()) { - list.add(new Integer(iter.doc())); + int doc = iter.advance(3); + if (doc >= 0) { + list.add(Integer.valueOf(doc)); + while((doc = iter.nextDoc()) >= 0) { + list.add(Integer.valueOf(doc)); } } Index: src/test/org/apache/lucene/search/TestPositiveScoresOnlyCollector.java =================================================================== --- src/test/org/apache/lucene/search/TestPositiveScoresOnlyCollector.java (revision 775940) +++ src/test/org/apache/lucene/search/TestPositiveScoresOnlyCollector.java (working copy) @@ -38,13 +38,23 @@ public int doc() { return idx; } - public boolean next() throws IOException { - return ++idx == scores.length; + /** @deprecated use {@link #nextDoc()} instead. */ + public boolean next() throws IOException { + return nextDoc() >= 0; } + public int nextDoc() throws IOException { + return ++idx != scores.length ? idx : -1; + } + + /** @deprecated use {@link #advance(int)} instead. */ public boolean skipTo(int target) throws IOException { + return advance(target) >= 0; + } + + public int advance(int target) throws IOException { idx = target; - return idx >= scores.length; + return idx < scores.length ? idx : -1; } } @@ -71,7 +81,7 @@ TopDocsCollector tdc = TopScoreDocCollector.create(scores.length, true); Collector c = new PositiveScoresOnlyCollector(tdc); c.setScorer(s); - while (!s.next()) { + while (s.nextDoc() >= 0) { c.collect(0); } TopDocs td = tdc.topDocs(); Index: src/test/org/apache/lucene/search/TestScoreCachingWrappingScorer.java =================================================================== --- src/test/org/apache/lucene/search/TestScoreCachingWrappingScorer.java (revision 775940) +++ src/test/org/apache/lucene/search/TestScoreCachingWrappingScorer.java (working copy) @@ -44,14 +44,25 @@ public int doc() { return doc; } + /** @deprecated use {@link #nextDoc()} instead. */ public boolean next() throws IOException { - return ++doc == scores.length; + return nextDoc() >= 0; } + public int nextDoc() throws IOException { + return ++doc < scores.length ? doc : -1; + } + + /** @deprecated use {@link #advance(int)} instead. */ public boolean skipTo(int target) throws IOException { + return advance(target) >= 0; + } + + public int advance(int target) throws IOException { doc = target; - return doc >= scores.length; + return doc < scores.length ? doc : -1; } + } private static final class ScoreCachingCollector extends Collector { @@ -98,8 +109,9 @@ scc.setScorer(s); // We need to iterate on the scorer so that its doc() advances. - while (!s.next()) { - scc.collect(s.doc()); + int doc; + while ((doc = s.nextDoc()) >= 0) { + scc.collect(doc); } for (int i = 0; i < scores.length; i++) { Index: src/test/org/apache/lucene/search/TestSpanQueryFilter.java =================================================================== --- src/test/org/apache/lucene/search/TestSpanQueryFilter.java (revision 775940) +++ src/test/org/apache/lucene/search/TestSpanQueryFilter.java (working copy) @@ -77,7 +77,7 @@ int getDocIdSetSize(DocIdSet docIdSet) throws Exception { int size = 0; DocIdSetIterator it = docIdSet.iterator(); - while (it.next()) { + while (it.nextDoc() >= 0) { size++; } return size; @@ -85,7 +85,7 @@ public void assertContainsDocId(String msg, DocIdSet docIdSet, int docId) throws Exception { DocIdSetIterator it = docIdSet.iterator(); - assertTrue(msg, it.skipTo(docId)); + assertTrue(msg, it.advance(docId) >= 0); assertTrue(msg, it.doc() == docId); } } Index: src/test/org/apache/lucene/search/TestTermScorer.java =================================================================== --- src/test/org/apache/lucene/search/TestTermScorer.java (revision 775940) +++ src/test/org/apache/lucene/search/TestTermScorer.java (working copy) @@ -134,11 +134,11 @@ TermScorer ts = new TermScorer(weight, indexReader.termDocs(allTerm), indexSearcher.getSimilarity(), indexReader.norms(FIELD)); - assertTrue("next did not return a doc", ts.next() == true); + assertTrue("next did not return a doc", ts.nextDoc() >= 0); assertTrue("score is not correct", ts.score() == 1.6931472f); - assertTrue("next did not return a doc", ts.next() == true); + assertTrue("next did not return a doc", ts.nextDoc() >= 0); assertTrue("score is not correct", ts.score() == 1.6931472f); - assertTrue("next returned a doc and it should not have", ts.next() == false); + assertTrue("next returned a doc and it should not have", ts.nextDoc() < 0); } public void testSkipTo() throws Exception { @@ -151,7 +151,7 @@ TermScorer ts = new TermScorer(weight, indexReader.termDocs(allTerm), indexSearcher.getSimilarity(), indexReader.norms(FIELD)); - assertTrue("Didn't skip", ts.skipTo(3) == true); + assertTrue("Didn't skip", ts.advance(3) >= 0); //The next doc should be doc 5 assertTrue("doc should be number 5", ts.doc() == 5); } Index: src/test/org/apache/lucene/search/spans/TestNearSpansOrdered.java =================================================================== --- src/test/org/apache/lucene/search/spans/TestNearSpansOrdered.java (revision 775940) +++ src/test/org/apache/lucene/search/spans/TestNearSpansOrdered.java (working copy) @@ -165,8 +165,7 @@ SpanNearQuery q = makeQuery(); Weight w = q.createWeight(searcher); Scorer s = w.scorer(searcher.getIndexReader()); - assertEquals(true, s.skipTo(1)); - assertEquals(1, s.doc()); + assertEquals(1, s.advance(1)); } /** * not a direct test of NearSpans, but a demonstration of how/when Index: src/test/org/apache/lucene/search/spans/TestSpans.java =================================================================== --- src/test/org/apache/lucene/search/spans/TestSpans.java (revision 775940) +++ src/test/org/apache/lucene/search/spans/TestSpans.java (working copy) @@ -392,11 +392,11 @@ Scorer spanScorer = snq.weight(searcher).scorer(searcher.getIndexReader()); - assertTrue("first doc", spanScorer.next()); + assertTrue("first doc", spanScorer.nextDoc() >= 0); assertEquals("first doc number", spanScorer.doc(), 11); float score = spanScorer.score(); assertTrue("first doc score should be zero, " + score, score == 0.0f); - assertTrue("no second doc", ! spanScorer.next()); + assertTrue("no second doc", spanScorer.nextDoc() < 0); } // LUCENE-1404 Index: src/test/org/apache/lucene/util/TestOpenBitSet.java =================================================================== --- src/test/org/apache/lucene/util/TestOpenBitSet.java (revision 775940) +++ src/test/org/apache/lucene/util/TestOpenBitSet.java (working copy) @@ -55,12 +55,8 @@ OpenBitSetIterator iterator = new OpenBitSetIterator(b); do { aa = a.nextSetBit(aa+1); - if (rand.nextBoolean()) - iterator.next(); - else - iterator.skipTo(bb+1); - bb = iterator.doc(); - assertEquals(aa,bb); + bb = rand.nextBoolean() ? iterator.nextDoc() : iterator.advance(bb + 1); + assertEquals(aa, bb); } while (aa>=0); } Index: src/test/org/apache/lucene/util/TestSortedVIntList.java =================================================================== --- src/test/org/apache/lucene/util/TestSortedVIntList.java (revision 775940) +++ src/test/org/apache/lucene/util/TestSortedVIntList.java (working copy) @@ -42,10 +42,10 @@ } DocIdSetIterator m = vintList.iterator(); for (int i = 0; i < ints.length; i++) { - assertTrue("No end of Matcher at: " + i, m.next()); + assertTrue("No end of Matcher at: " + i, m.nextDoc() >= 0); assertEquals(ints[i], m.doc()); } - assertTrue("End of Matcher", (! m.next())); + assertTrue("End of Matcher", m.nextDoc() < 0); } void tstVIntList(