lucene-java-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mikemcc...@apache.org
Subject svn commit: r782410 [1/2] - in /lucene/java/trunk: ./ contrib/miscellaneous/src/test/org/apache/lucene/misc/ src/java/org/apache/lucene/index/ src/java/org/apache/lucene/search/ src/java/org/apache/lucene/search/function/ src/java/org/apache/lucene/sea...
Date Sun, 07 Jun 2009 16:58:43 GMT
Author: mikemccand
Date: Sun Jun  7 16:58:41 2009
New Revision: 782410

URL: http://svn.apache.org/viewvc?rev=782410&view=rev
Log:
LUCENE-1614: switch next -> nextDoc, skipTo -> advance, doc -> docID in DISI

Modified:
    lucene/java/trunk/CHANGES.txt
    lucene/java/trunk/common-build.xml
    lucene/java/trunk/contrib/miscellaneous/src/test/org/apache/lucene/misc/ChainedFilterTest.java
    lucene/java/trunk/src/java/org/apache/lucene/index/DocumentsWriter.java
    lucene/java/trunk/src/java/org/apache/lucene/search/BooleanQuery.java
    lucene/java/trunk/src/java/org/apache/lucene/search/BooleanScorer.java
    lucene/java/trunk/src/java/org/apache/lucene/search/BooleanScorer2.java
    lucene/java/trunk/src/java/org/apache/lucene/search/ConjunctionScorer.java
    lucene/java/trunk/src/java/org/apache/lucene/search/ConstantScoreQuery.java
    lucene/java/trunk/src/java/org/apache/lucene/search/DisjunctionMaxQuery.java
    lucene/java/trunk/src/java/org/apache/lucene/search/DisjunctionMaxScorer.java
    lucene/java/trunk/src/java/org/apache/lucene/search/DisjunctionSumScorer.java
    lucene/java/trunk/src/java/org/apache/lucene/search/DocIdSetIterator.java
    lucene/java/trunk/src/java/org/apache/lucene/search/FieldCacheRangeFilter.java
    lucene/java/trunk/src/java/org/apache/lucene/search/FieldCacheTermsFilter.java
    lucene/java/trunk/src/java/org/apache/lucene/search/FilteredDocIdSetIterator.java
    lucene/java/trunk/src/java/org/apache/lucene/search/FilteredQuery.java
    lucene/java/trunk/src/java/org/apache/lucene/search/IndexSearcher.java
    lucene/java/trunk/src/java/org/apache/lucene/search/MatchAllDocsQuery.java
    lucene/java/trunk/src/java/org/apache/lucene/search/NonMatchingScorer.java
    lucene/java/trunk/src/java/org/apache/lucene/search/PhraseScorer.java
    lucene/java/trunk/src/java/org/apache/lucene/search/ReqExclScorer.java
    lucene/java/trunk/src/java/org/apache/lucene/search/ReqOptSumScorer.java
    lucene/java/trunk/src/java/org/apache/lucene/search/ScoreCachingWrappingScorer.java
    lucene/java/trunk/src/java/org/apache/lucene/search/Scorer.java
    lucene/java/trunk/src/java/org/apache/lucene/search/TermScorer.java
    lucene/java/trunk/src/java/org/apache/lucene/search/function/CustomScoreQuery.java
    lucene/java/trunk/src/java/org/apache/lucene/search/function/ValueSourceQuery.java
    lucene/java/trunk/src/java/org/apache/lucene/search/spans/SpanScorer.java
    lucene/java/trunk/src/java/org/apache/lucene/util/DocIdBitSet.java
    lucene/java/trunk/src/java/org/apache/lucene/util/OpenBitSetDISI.java
    lucene/java/trunk/src/java/org/apache/lucene/util/OpenBitSetIterator.java
    lucene/java/trunk/src/java/org/apache/lucene/util/ScorerDocQueue.java
    lucene/java/trunk/src/java/org/apache/lucene/util/SortedVIntList.java
    lucene/java/trunk/src/test/org/apache/lucene/search/JustCompileSearch.java
    lucene/java/trunk/src/test/org/apache/lucene/search/QueryUtils.java
    lucene/java/trunk/src/test/org/apache/lucene/search/TestBoolean2.java
    lucene/java/trunk/src/test/org/apache/lucene/search/TestBooleanScorer.java
    lucene/java/trunk/src/test/org/apache/lucene/search/TestDisjunctionMaxQuery.java
    lucene/java/trunk/src/test/org/apache/lucene/search/TestDocIdSet.java
    lucene/java/trunk/src/test/org/apache/lucene/search/TestPositiveScoresOnlyCollector.java
    lucene/java/trunk/src/test/org/apache/lucene/search/TestScoreCachingWrappingScorer.java
    lucene/java/trunk/src/test/org/apache/lucene/search/TestSpanQueryFilter.java
    lucene/java/trunk/src/test/org/apache/lucene/search/TestTermScorer.java
    lucene/java/trunk/src/test/org/apache/lucene/search/spans/JustCompileSearchSpans.java
    lucene/java/trunk/src/test/org/apache/lucene/search/spans/TestNearSpansOrdered.java
    lucene/java/trunk/src/test/org/apache/lucene/search/spans/TestSpans.java
    lucene/java/trunk/src/test/org/apache/lucene/util/TestOpenBitSet.java
    lucene/java/trunk/src/test/org/apache/lucene/util/TestSortedVIntList.java

Modified: lucene/java/trunk/CHANGES.txt
URL: http://svn.apache.org/viewvc/lucene/java/trunk/CHANGES.txt?rev=782410&r1=782409&r2=782410&view=diff
==============================================================================
--- lucene/java/trunk/CHANGES.txt (original)
+++ lucene/java/trunk/CHANGES.txt Sun Jun  7 16:58:41 2009
@@ -35,7 +35,7 @@
     code to implement this method.  If you already extend
     IndexSearcher, no further changes are needed to use Collector.
     
-    Finally, the values Float.Nan, Float.NEGATIVE_INFINITY and
+    Finally, the values Float.NaN, Float.NEGATIVE_INFINITY and
     Float.POSITIVE_INFINITY are not valid scores.  Lucene uses these
     values internally in certain places, so if you have hits with such
     scores it will cause problems. (Shai Erera via Mike McCandless)
@@ -173,6 +173,17 @@
     require up front specification of enablePositionIncrement (Mike
     McCandless)
 
+18. 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, saving an extra call to doc() in most cases.
+    For easy migration of the code, you can change the calls to next() to 
+    nextDoc() != DocIdSetIterator.NO_MORE_DOCS and similarly for skipTo(). 
+    However it is advised that you take advantage of the returned doc ID and not 
+    call doc() following those two.
+    Also, doc() was deprecated in favor of docID(). docID() should return -1 or 
+    NO_MORE_DOCS if nextDoc/advance were not called yet, or NO_MORE_DOCS if the 
+    iterator has exhausted. Otherwise it should return the current doc ID.
+    (Shai Erera via Mike McCandless)
 
 Bug fixes
 

Modified: lucene/java/trunk/common-build.xml
URL: http://svn.apache.org/viewvc/lucene/java/trunk/common-build.xml?rev=782410&r1=782409&r2=782410&view=diff
==============================================================================
--- lucene/java/trunk/common-build.xml (original)
+++ lucene/java/trunk/common-build.xml Sun Jun  7 16:58:41 2009
@@ -42,7 +42,7 @@
   <property name="Name" value="Lucene"/>
   <property name="dev.version" value="2.9-dev"/>
   <property name="version" value="${dev.version}"/>
-  <property name="compatibility.tag" value="lucene_2_4_back_compat_tests_20090607a"/>
+  <property name="compatibility.tag" value="lucene_2_4_back_compat_tests_20090607b"/>
   <property name="spec.version" value="${version}"/>	
   <property name="year" value="2000-${current.year}"/>
   <property name="final.name" value="lucene-${name}-${version}"/>

Modified: lucene/java/trunk/contrib/miscellaneous/src/test/org/apache/lucene/misc/ChainedFilterTest.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/contrib/miscellaneous/src/test/org/apache/lucene/misc/ChainedFilterTest.java?rev=782410&r1=782409&r2=782410&view=diff
==============================================================================
--- lucene/java/trunk/contrib/miscellaneous/src/test/org/apache/lucene/misc/ChainedFilterTest.java (original)
+++ lucene/java/trunk/contrib/miscellaneous/src/test/org/apache/lucene/misc/ChainedFilterTest.java Sun Jun  7 16:58:41 2009
@@ -20,16 +20,12 @@
 import junit.framework.TestCase;
 import java.util.*;
 import java.io.IOException;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
 
 import org.apache.lucene.index.IndexReader;
 import org.apache.lucene.index.IndexWriter;
 import org.apache.lucene.index.Term;
 import org.apache.lucene.index.IndexWriter.MaxFieldLength;
 import org.apache.lucene.store.Directory;
-import org.apache.lucene.store.FSDirectory;
-import org.apache.lucene.store.NoLockFactory;
 import org.apache.lucene.store.RAMDirectory;
 import org.apache.lucene.analysis.Analyzer;
 import org.apache.lucene.analysis.WhitespaceAnalyzer;
@@ -77,7 +73,7 @@
     query = bq;
 
     // date filter matches everything too
-    Date pastTheEnd = parseDate("2099 Jan 1");
+    //Date pastTheEnd = parseDate("2099 Jan 1");
     // dateFilter = DateFilter.Before("date", pastTheEnd);
     // just treat dates as strings and select the whole range for now...
     dateFilter = new RangeFilter("date","","ZZZZ",true,true);
@@ -94,15 +90,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()) != DocIdSetIterator.NO_MORE_DOCS) {
+            bits.set(doc);
           }
           return bits;
         }
-    };
+      };
     }
     return oldFilters;
   }
@@ -211,37 +209,36 @@
     }
   }
 
+  /*
   private Date parseDate(String s) throws ParseException {
     return new SimpleDateFormat("yyyy MMM dd", Locale.US).parse(s);
   }
+  */
   
   public void testWithCachingFilter() throws Exception {
-    for (int mode = 0; mode < 2; mode++) {
-      boolean old = (mode==0);
-      Directory dir = new RAMDirectory();
-      Analyzer analyzer = new WhitespaceAnalyzer();
+    Directory dir = new RAMDirectory();
+    Analyzer analyzer = new WhitespaceAnalyzer();
   
-      IndexWriter writer = new IndexWriter(dir, analyzer, true, MaxFieldLength.LIMITED);
-      writer.close();
+    IndexWriter writer = new IndexWriter(dir, analyzer, true, MaxFieldLength.LIMITED);
+    writer.close();
   
-      Searcher searcher = new IndexSearcher(dir);
+    Searcher searcher = new IndexSearcher(dir);
   
-      Query query = new TermQuery(new Term("none", "none"));
+    Query query = new TermQuery(new Term("none", "none"));
   
-      QueryWrapperFilter queryFilter = new QueryWrapperFilter(query);
-      CachingWrapperFilter cachingFilter = new CachingWrapperFilter(queryFilter);
+    QueryWrapperFilter queryFilter = new QueryWrapperFilter(query);
+    CachingWrapperFilter cachingFilter = new CachingWrapperFilter(queryFilter);
   
-      searcher.search(query, cachingFilter, 1);
+    searcher.search(query, cachingFilter, 1);
   
-      CachingWrapperFilter cachingFilter2 = new CachingWrapperFilter(queryFilter);
-      Filter[] chain = new Filter[2];
-      chain[0] = cachingFilter;
-      chain[1] = cachingFilter2;
-      ChainedFilter cf = new ChainedFilter(chain);
+    CachingWrapperFilter cachingFilter2 = new CachingWrapperFilter(queryFilter);
+    Filter[] chain = new Filter[2];
+    chain[0] = cachingFilter;
+    chain[1] = cachingFilter2;
+    ChainedFilter cf = new ChainedFilter(chain);
   
-      // throws java.lang.ClassCastException: org.apache.lucene.util.OpenBitSet cannot be cast to java.util.BitSet
-      searcher.search(new MatchAllDocsQuery(), cf, 1);
-    }
+    // throws java.lang.ClassCastException: org.apache.lucene.util.OpenBitSet cannot be cast to java.util.BitSet
+    searcher.search(new MatchAllDocsQuery(), cf, 1);
   }
 
 }

Modified: lucene/java/trunk/src/java/org/apache/lucene/index/DocumentsWriter.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/src/java/org/apache/lucene/index/DocumentsWriter.java?rev=782410&r1=782409&r2=782410&view=diff
==============================================================================
--- lucene/java/trunk/src/java/org/apache/lucene/index/DocumentsWriter.java (original)
+++ lucene/java/trunk/src/java/org/apache/lucene/index/DocumentsWriter.java Sun Jun  7 16:58:41 2009
@@ -991,11 +991,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)
+      while(true)  {
+        int doc = scorer.nextDoc();
+        if (((long) docIDStart) + doc >= limit)
           break;
-        reader.deleteDocument(docID);
+        reader.deleteDocument(doc);
         any = true;
       }
     }

Modified: lucene/java/trunk/src/java/org/apache/lucene/search/BooleanQuery.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/src/java/org/apache/lucene/search/BooleanQuery.java?rev=782410&r1=782409&r2=782410&view=diff
==============================================================================
--- lucene/java/trunk/src/java/org/apache/lucene/search/BooleanQuery.java (original)
+++ lucene/java/trunk/src/java/org/apache/lucene/search/BooleanQuery.java Sun Jun  7 16:58:41 2009
@@ -217,13 +217,15 @@
       }
     }
 
-    /** @return Returns BooleanScorer2 that uses and provides skipTo(),
-     *          and scores documents in document number order.
+    /**
+     * @return Returns BooleanScorer2 that uses and provides advance(), and
+     *         scores documents in document number order.
      */
     public Scorer scorer(IndexReader reader) throws IOException {
       // TODO (3.0): instantiate either BS or BS2, according to
       // allowDocsOutOfOrder (basically, try to inline BS2.score(Collector)'s
       // logic.
+      
       BooleanScorer2 result = new BooleanScorer2(similarity,
                                                  minNrShouldMatch,
                                                  allowDocsOutOfOrder);

Modified: lucene/java/trunk/src/java/org/apache/lucene/search/BooleanScorer.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/src/java/org/apache/lucene/search/BooleanScorer.java?rev=782410&r1=782409&r2=782410&view=diff
==============================================================================
--- lucene/java/trunk/src/java/org/apache/lucene/search/BooleanScorer.java (original)
+++ lucene/java/trunk/src/java/org/apache/lucene/search/BooleanScorer.java Sun Jun  7 16:58:41 2009
@@ -18,8 +18,11 @@
  */
 
 import java.io.IOException;
+import java.util.Iterator;
+import java.util.List;
 
 import org.apache.lucene.index.IndexReader;
+
 /* Description from Doug Cutting (excerpted from
  * LUCENE-1483):
  *
@@ -54,30 +57,105 @@
  * updates for the optional terms. */
 
 final class BooleanScorer extends Scorer {
-  private SubScorer scorers = null;
-  private BucketTable bucketTable = new BucketTable();
+  
+  private static final class BooleanScorerCollector extends Collector {
+    private BucketTable bucketTable;
+    private int mask;
+    private Scorer scorer;
+    
+    public BooleanScorerCollector(int mask, BucketTable bucketTable) {
+      this.mask = mask;
+      this.bucketTable = bucketTable;
+    }
+    public final void collect(final int doc) throws IOException {
+      final BucketTable table = bucketTable;
+      final int i = doc & BucketTable.MASK;
+      Bucket bucket = table.buckets[i];
+      if (bucket == null)
+        table.buckets[i] = bucket = new Bucket();
+      
+      if (bucket.doc != doc) {                    // invalid bucket
+        bucket.doc = doc;                         // set doc
+        bucket.score = scorer.score();            // initialize score
+        bucket.bits = mask;                       // initialize mask
+        bucket.coord = 1;                         // initialize coord
 
-  private int maxCoord = 1;
-  private float[] coordFactors = null;
+        bucket.next = table.first;                // push onto valid list
+        table.first = bucket;
+      } else {                                    // valid bucket
+        bucket.score += scorer.score();           // increment score
+        bucket.bits |= mask;                      // add bits in mask
+        bucket.coord++;                           // increment coord
+      }
+    }
+    
+    public void setNextReader(IndexReader reader, int docBase) {
+      // not needed by this implementation
+    }
+    public void setScorer(Scorer scorer) throws IOException {
+      this.scorer = scorer;
+    }
+  }
+  
+  // An internal class which is used in score(Collector, int) for setting the
+  // current score. This is required since Collector exposes a setScorer method
+  // and implementations that need the score will call scorer.score().
+  // Therefore the only methods that are implemented are score() and doc().
+  private static final class BucketScorer extends Scorer {
 
-  private int requiredMask = 0;
-  private int prohibitedMask = 0;
-  private int nextMask = 1;
+    float score;
+    int doc = NO_MORE_DOCS;
+    
+    public BucketScorer() { super(null); }
+    
+    public int advance(int target) throws IOException { return NO_MORE_DOCS; }
 
-  private final int minNrShouldMatch;
+    /** @deprecated use {@link #docID()} instead. */
+    public int doc() { return doc; }
+
+    public int docID() { return doc; }
 
-  BooleanScorer(Similarity similarity) {
-    this(similarity, 1);
+    public Explanation explain(int doc) throws IOException { return null; }
+    
+    /** @deprecated use {@link #nextDoc()} instead. */
+    public boolean next() throws IOException { return false; }
+
+    public int nextDoc() throws IOException { return NO_MORE_DOCS; }
+    
+    public float score() throws IOException { return score; }
+    
+    /** @deprecated use {@link #advance(int)} instead. */
+    public boolean skipTo(int target) throws IOException { return false; }
+    
   }
-  
-  BooleanScorer(Similarity similarity, int minNrShouldMatch) {
-    super(similarity);
-    this.minNrShouldMatch = minNrShouldMatch;
+
+  static final class Bucket {
+    int doc = -1;            // tells if bucket is valid
+    float score;             // incremental score
+    int bits;                // used for bool constraints
+    int coord;               // count of terms in score
+    Bucket next;             // next valid bucket
   }
   
+  /** A simple hash table of document scores within a range. */
+  static final class BucketTable {
+    public static final int SIZE = 1 << 11;
+    public static final int MASK = SIZE - 1;
+
+    final Bucket[] buckets = new Bucket[SIZE];
+    Bucket first = null;                          // head of valid list
+  
+    public BucketTable() {}
+
+    public Collector newCollector(int mask) {
+      return new BooleanScorerCollector(mask, this);
+    }
+
+    public final int size() { return SIZE; }
+  }
+
   static final class SubScorer {
     public Scorer scorer;
-    public boolean done;
     public boolean required = false;
     public boolean prohibited = false;
     public Collector collector;
@@ -87,41 +165,52 @@
         Collector collector, SubScorer next)
       throws IOException {
       this.scorer = scorer;
-      this.done = !scorer.next();
       this.required = required;
       this.prohibited = prohibited;
       this.collector = collector;
       this.next = next;
     }
   }
+  
+  private SubScorer scorers = null;
+  private BucketTable bucketTable = new BucketTable();
+  private int maxCoord = 1;
+  private final float[] coordFactors;
+  private int requiredMask = 0;
+  private int prohibitedMask = 0;
+  private int nextMask = 1;
+  private final int minNrShouldMatch;
+  private int end;
+  private Bucket current;
+  private int doc = -1;
 
-  final void add(Scorer scorer, boolean required, boolean prohibited)
-    throws IOException {
-    int mask = 0;
-    if (required || prohibited) {
-      if (nextMask == 0) {
-        throw new IndexOutOfBoundsException(
-            "More than 32 required/prohibited clauses in query.");
+  BooleanScorer(Similarity similarity, int minNrShouldMatch,
+      List optionalScorers, List prohibitedScorers) throws IOException {
+    super(similarity);
+    this.minNrShouldMatch = minNrShouldMatch;
+
+    if (optionalScorers != null && optionalScorers.size() > 0) {
+      for (Iterator si = optionalScorers.iterator(); si.hasNext();) {
+        Scorer scorer = (Scorer) si.next();
+        maxCoord++;
+        if (scorer.nextDoc() != NO_MORE_DOCS) {
+          scorers = new SubScorer(scorer, false, false, bucketTable.newCollector(0), scorers);
+        }
       }
-      mask = nextMask;
-      nextMask = nextMask << 1;
     }
-
-    if (!prohibited) {
-      maxCoord++;
-      if (required) {
-        requiredMask |= mask;                       // update required mask
+    
+    if (prohibitedScorers != null && prohibitedScorers.size() > 0) {
+      for (Iterator si = prohibitedScorers.iterator(); si.hasNext();) {
+        Scorer scorer = (Scorer) si.next();
+        int mask = nextMask;
+        nextMask = nextMask << 1;
+        prohibitedMask |= mask;                     // update prohibited mask
+        if (scorer.nextDoc() != NO_MORE_DOCS) {
+          scorers = new SubScorer(scorer, false, true, bucketTable.newCollector(mask), scorers);
+        }
       }
-    } else {
-      // prohibited
-      prohibitedMask |= mask;                     // update prohibited mask
     }
 
-    scorers = new SubScorer(scorer, required, prohibited,
-                            bucketTable.newCollector(mask), scorers);
-  }
-
-  private final void computeCoordFactors() {
     coordFactors = new float[maxCoord];
     Similarity sim = getSimilarity();
     for (int i = 0; i < maxCoord; i++) {
@@ -129,31 +218,10 @@
     }
   }
 
-  private int end;
-  private Bucket current;
-
-  /** @deprecated use {@link #score(Collector)} instead. */
-  public void score(HitCollector hc) throws IOException {
-    score(new HitCollectorWrapper(hc));
-  }
-  
-  public void score(Collector collector) throws IOException {
-    next();
-    score(collector, Integer.MAX_VALUE);
-  }
-
-  /** @deprecated use {@link #score(Collector, int)} instead. */
-  protected boolean score(HitCollector hc, int max) throws IOException {
-    return score(new HitCollectorWrapper(hc), max);
-  }
-
-  protected boolean score(Collector collector, int max) throws IOException {
-    if (coordFactors == null) {
-      computeCoordFactors();
-    }
+  // firstDocID is ignored since nextDoc() initializes 'current'
+  protected boolean score(Collector collector, int max, int firstDocID) throws IOException {
     boolean more;
     Bucket tmp;
-    
     BucketScorer bs = new BucketScorer();
     // The internal loop will set the score and doc before calling collect.
     collector.setScorer(bs);
@@ -194,10 +262,9 @@
       more = false;
       end += BucketTable.SIZE;
       for (SubScorer sub = scorers; sub != null; sub = sub.next) {
-        if (!sub.done) {
-          sub.done = !sub.scorer.score(sub.collector, end);
-          if (!sub.done)
-            more = true;
+        int subScorerDocID = sub.scorer.docID();
+        if (subScorerDocID != NO_MORE_DOCS) {
+          more |= sub.scorer.score(sub.collector, end, subScorerDocID);
         }
       }
       current = bucketTable.first;
@@ -207,9 +274,32 @@
     return false;
   }
 
+  /** @deprecated use {@link #score(Collector, int)} instead. */
+  protected boolean score(HitCollector hc, int max) throws IOException {
+    return score(new HitCollectorWrapper(hc), max, docID());
+  }
+  
+  public int advance(int target) throws IOException {
+    throw new UnsupportedOperationException();
+  }
+
+  /** @deprecated use {@link #docID()} instead. */
   public int doc() { return current.doc; }
+  
+  public int docID() {
+    return doc;
+  }
 
+  public Explanation explain(int doc) {
+    throw new UnsupportedOperationException();
+  }
+
+  /** @deprecated use {@link #nextDoc()} instead. */
   public boolean next() throws IOException {
+    return nextDoc() != NO_MORE_DOCS;
+  }
+  
+  public int nextDoc() throws IOException {
     boolean more;
     do {
       while (bucketTable.first != null) {         // more queued
@@ -220,7 +310,7 @@
         if ((current.bits & prohibitedMask) == 0 &&
             (current.bits & requiredMask) == requiredMask &&
             current.coord >= minNrShouldMatch) {
-          return true;
+          return doc = current.doc;
         }
       }
 
@@ -230,134 +320,36 @@
       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();
-        }
-        if (!sub.done) {
-          more = true;
+        int doc = scorer.docID();
+        while (doc < end) {
+          sub.collector.collect(doc);
+          doc = scorer.nextDoc();
         }
+        more |= (doc != NO_MORE_DOCS);
       }
     } while (bucketTable.first != null || more);
 
-    return false;
+    return doc = NO_MORE_DOCS;
   }
 
   public float score() {
-    if (coordFactors == null) {
-      computeCoordFactors();
-    }
     return current.score * coordFactors[current.coord];
   }
 
-  static final class Bucket {
-    int doc = -1;                                 // tells if bucket is valid
-    float       score;                            // incremental score
-    int bits;                                     // used for bool constraints
-    int coord;                                    // count of terms in score
-    Bucket      next;                             // next valid bucket
+  public void score(Collector collector) throws IOException {
+    score(collector, Integer.MAX_VALUE, nextDoc());
   }
 
-  // An internal class which is used in score(Collector, int) for setting the
-  // current score. This is required since Collector exposes a setScorer method
-  // and implementations that need the score will call scorer.score().
-  // Therefore the only methods that are implemented are score() and doc().
-  private static final class BucketScorer extends Scorer {
-
-    float score;
-    int doc;
-    
-    public BucketScorer() {
-      super(null);
-    }
-    
-    
-    public Explanation explain(int doc) throws IOException {
-      return null;
-    }
-
-    public float score() throws IOException {
-      return score;
-    }
-
-    public int doc() {
-      return doc;
-    }
-
-    public boolean next() throws IOException {
-      return false;
-    }
-
-    public boolean skipTo(int target) throws IOException {
-      return false;
-    }
-    
+  /** @deprecated use {@link #score(Collector)} instead. */
+  public void score(HitCollector hc) throws IOException {
+    score(new HitCollectorWrapper(hc));
   }
   
-  /** A simple hash table of document scores within a range. */
-  static final class BucketTable {
-    public static final int SIZE = 1 << 11;
-    public static final int MASK = SIZE - 1;
-
-    final Bucket[] buckets = new Bucket[SIZE];
-    Bucket first = null;                          // head of valid list
-  
-    public BucketTable() {}
-
-    public final int size() { return SIZE; }
-
-    public Collector newCollector(int mask) {
-      return new BooleanScorerCollector(mask, this);
-    }
-  }
-
-  private static final class BooleanScorerCollector extends Collector {
-    private BucketTable bucketTable;
-    private int mask;
-    private Scorer scorer;
-    
-    public BooleanScorerCollector(int mask, BucketTable bucketTable) {
-      this.mask = mask;
-      this.bucketTable = bucketTable;
-    }
-    public void setScorer(Scorer scorer) throws IOException {
-      this.scorer = scorer;
-    }
-    
-    public final void collect(final int doc) throws IOException {
-      final BucketTable table = bucketTable;
-      final int i = doc & BucketTable.MASK;
-      Bucket bucket = table.buckets[i];
-      if (bucket == null)
-        table.buckets[i] = bucket = new Bucket();
-      
-      if (bucket.doc != doc) {                    // invalid bucket
-        bucket.doc = doc;                         // set doc
-        bucket.score = scorer.score();            // initialize score
-        bucket.bits = mask;                       // initialize mask
-        bucket.coord = 1;                         // initialize coord
-
-        bucket.next = table.first;                // push onto valid list
-        table.first = bucket;
-      } else {                                    // valid bucket
-        bucket.score += scorer.score();           // increment score
-        bucket.bits |= mask;                      // add bits in mask
-        bucket.coord++;                           // increment coord
-      }
-    }
-    public void setNextReader(IndexReader reader, int docBase) {
-      // not needed by this implementation
-    }
-  }
-
+  /** @deprecated use {@link #advance(int)} instead. */
   public boolean skipTo(int target) {
     throw new UnsupportedOperationException();
   }
 
-  public Explanation explain(int doc) {
-    throw new UnsupportedOperationException();
-  }
-
   public String toString() {
     StringBuffer buffer = new StringBuffer();
     buffer.append("boolean(");

Modified: lucene/java/trunk/src/java/org/apache/lucene/search/BooleanScorer2.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/src/java/org/apache/lucene/search/BooleanScorer2.java?rev=782410&r1=782409&r2=782410&view=diff
==============================================================================
--- lucene/java/trunk/src/java/org/apache/lucene/search/BooleanScorer2.java (original)
+++ lucene/java/trunk/src/java/org/apache/lucene/search/BooleanScorer2.java Sun Jun  7 16:58:41 2009
@@ -20,7 +20,6 @@
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
-import java.util.Iterator;
 
 /* See the description in BooleanScorer.java, comparing
  * BooleanScorer & BooleanScorer2 */
@@ -65,6 +64,7 @@
    */  
   private boolean allowDocsOutOfOrder;
 
+  private int doc = -1;
 
   /** Create a BooleanScorer2.
    * @param similarity The similarity to be used.
@@ -151,7 +151,7 @@
       this.scorer = scorer;
     }
     public float score() throws IOException {
-      int doc = doc();
+      int doc = docID();
       if (doc >= lastScoredDoc) {
         if (doc > lastScoredDoc) {
           lastDocScore = scorer.score();
@@ -161,14 +161,26 @@
       }
       return lastDocScore;
     }
+    /** @deprecated use {@link #docID()} instead. */
     public int doc() {
       return scorer.doc();
     }
+    public int docID() {
+      return scorer.docID();
+    }
+    /** @deprecated use {@link #nextDoc()} instead. */
     public boolean next() throws IOException {
-      return scorer.next();
+      return scorer.nextDoc() != NO_MORE_DOCS;
+    }
+    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) != NO_MORE_DOCS;
+    }
+    public int advance(int target) throws IOException {
+      return scorer.advance(target);
     }
     public Explanation explain(int docNr) throws IOException {
       return scorer.explain(docNr);
@@ -184,7 +196,7 @@
       // once in score().
       private float lastDocScore = Float.NaN;
       public float score() throws IOException {
-        int doc = doc();
+        int doc = docID();
         if (doc >= lastScoredDoc) {
           if (doc > lastScoredDoc) {
             lastDocScore = super.score();
@@ -208,7 +220,7 @@
       // once in score().
       private float lastDocScore = Float.NaN;
       public float score() throws IOException {
-        int doc = doc();
+        int doc = docID();
         if (doc >= lastScoredDoc) {
           if (doc > lastScoredDoc) {
             lastDocScore = super.score();
@@ -323,24 +335,16 @@
   public void score(Collector collector) throws IOException {
     if (allowDocsOutOfOrder && requiredScorers.size() == 0
             && prohibitedScorers.size() < 32) {
-      // fall back to BooleanScorer, scores documents somewhat out of order
-      BooleanScorer bs = new BooleanScorer(getSimilarity(), minNrShouldMatch);
-      Iterator si = optionalScorers.iterator();
-      while (si.hasNext()) {
-        bs.add((Scorer) si.next(), false /* required */, false /* prohibited */);
-      }
-      si = prohibitedScorers.iterator();
-      while (si.hasNext()) {
-        bs.add((Scorer) si.next(), false /* required */, true /* prohibited */);
-      }
-      bs.score(collector);
+      new BooleanScorer(getSimilarity(), minNrShouldMatch, optionalScorers,
+          prohibitedScorers).score(collector);
     } else {
       if (countingSumScorer == null) {
         initCountingSumScorer();
       }
       collector.setScorer(this);
-      while (countingSumScorer.next()) {
-        collector.collect(countingSumScorer.doc());
+      int doc;
+      while ((doc = countingSumScorer.nextDoc()) != NO_MORE_DOCS) {
+        collector.collect(doc);
       }
     }
   }
@@ -355,60 +359,57 @@
    * @deprecated use {@link #score(Collector, int)} instead.
    */
   protected boolean score(HitCollector hc, int max) throws IOException {
-    return score(new HitCollectorWrapper(hc), max);
+    return score(new HitCollectorWrapper(hc), max, docID());
   }
   
-  /** Expert: Collects matching documents in a range.
-   * <br>Note that {@link #next()} must be called once before this method is
-   * called for the first time.
-   * @param collector The collector to which all matching documents are passed through.
-   * @param max Do not score documents past this.
-   * @return true if more matching documents may remain.
-   */
-  protected boolean score(Collector collector, int max) throws IOException {
+  protected boolean score(Collector collector, int max, int firstDocID) throws IOException {
     // null pointer exception when next() was not called before:
-    int docNr = countingSumScorer.doc();
+    int docNr = firstDocID;
     collector.setScorer(this);
     while (docNr < max) {
       collector.collect(docNr);
-      if (!countingSumScorer.next()) {
-        return false;
-      }
-      docNr = countingSumScorer.doc();
+      docNr = countingSumScorer.nextDoc();
     }
-    return true;
+    return docNr != NO_MORE_DOCS;
   }
 
+  /** @deprecated use {@link #docID()} instead. */
   public int doc() { return countingSumScorer.doc(); }
 
+  public int docID() {
+    return doc;
+  }
+  
+  /** @deprecated use {@link #nextDoc()} instead. */
   public boolean next() throws IOException {
+    return nextDoc() != NO_MORE_DOCS;
+  }
+
+  public int nextDoc() throws IOException {
     if (countingSumScorer == null) {
       initCountingSumScorer();
     }
-    return countingSumScorer.next();
+    return doc = 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.
-   * 
-   * <p>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) != NO_MORE_DOCS;
+  }
+
+  public int advance(int target) throws IOException {
     if (countingSumScorer == null) {
       initCountingSumScorer();
     }
-    return countingSumScorer.skipTo(target);
+    return doc = countingSumScorer.advance(target);
   }
-
+  
   /** Throws an UnsupportedOperationException.
    * TODO: Implement an explanation of the coordination factor.
    * @param doc The document number for the explanation.

Modified: lucene/java/trunk/src/java/org/apache/lucene/search/ConjunctionScorer.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/src/java/org/apache/lucene/search/ConjunctionScorer.java?rev=782410&r1=782409&r2=782410&view=diff
==============================================================================
--- lucene/java/trunk/src/java/org/apache/lucene/search/ConjunctionScorer.java (original)
+++ lucene/java/trunk/src/java/org/apache/lucene/search/ConjunctionScorer.java Sun Jun  7 16:58:41 2009
@@ -24,76 +24,54 @@
 
 /** Scorer for conjunctions, sets of queries, all of which are required. */
 class ConjunctionScorer extends Scorer {
+  
   private final Scorer[] scorers;
-
-  private boolean firstTime=true;
-  private boolean more;
   private final float coord;
-  private int lastDoc=-1;
+  private int lastDoc = -1;
 
   public ConjunctionScorer(Similarity similarity, Collection scorers) throws IOException {
-    this(similarity, (Scorer[])scorers.toArray(new Scorer[scorers.size()]));
+    this(similarity, (Scorer[]) scorers.toArray(new Scorer[scorers.size()]));
   }
 
   public ConjunctionScorer(Similarity similarity, Scorer[] scorers) throws IOException {
     super(similarity);
     this.scorers = scorers;
-    coord = getSimilarity().coord(this.scorers.length, this.scorers.length);
-  }
-
-  public int doc() { return lastDoc; }
-
-  public boolean next() throws IOException {
-    if (firstTime)
-      return init(0);
-    else if (more)
-      more = scorers[(scorers.length-1)].next();
-    return doNext();
-  }
-
-  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);
-      lastScorer = firstScorer;
-      first = (first == (scorers.length-1)) ? 0 : first+1;
-    }
-    return more;
-  }
-
-  public boolean skipTo(int target) throws IOException {
-    if (firstTime)
-      return init(target);
-    else if (more)
-      more = scorers[(scorers.length-1)].skipTo(target);
-    return doNext();
-  }
-
-  // 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<scorers.length; i++) {
-      more = target==0 ? scorers[i].next() : scorers[i].skipTo(target);
-      if (!more)
-        return false;
+    coord = similarity.coord(scorers.length, scorers.length);
+    
+    for (int i = 0; i < scorers.length; i++) {
+      if (scorers[i].nextDoc() == NO_MORE_DOCS) {
+        // If even one of the sub-scorers does not have any documents, this
+        // scorer should not attempt to do any more work.
+        lastDoc = NO_MORE_DOCS;
+        return;
+      }
     }
 
     // Sort the array the first time...
     // We don't need to sort the array in any future calls because we know
     // it will already start off sorted (all scorers on same doc).
-
+    
     // note that this comparator is not consistent with equals!
     Arrays.sort(scorers, new Comparator() {         // sort the array
-        public int compare(Object o1, Object o2) {
-          return ((Scorer)o1).doc() - ((Scorer)o2).doc();
-        }
-      });
-
-    doNext();
+      public int compare(Object o1, Object o2) {
+        return ((Scorer) o1).docID() - ((Scorer) o2).docID();
+      }
+    });
+
+    // NOTE: doNext() must be called before the re-sorting of the array later on.
+    // The reason is this: assume there are 5 scorers, whose first docs are 1,
+    // 2, 3, 5, 5 respectively. Sorting (above) leaves the array as is. Calling
+    // doNext() here advances all the first scorers to 5 (or a larger doc ID
+    // they all agree on). 
+    // However, if we re-sort before doNext() is called, the order will be 5, 3,
+    // 2, 1, 5 and then doNext() will stop immediately, since the first scorer's
+    // docs equals the last one. So the invariant that after calling doNext() 
+    // all scorers are on the same doc ID is broken.
+    if (doNext() == NO_MORE_DOCS) {
+      // The scorers did not agree on any document.
+      lastDoc = NO_MORE_DOCS;
+      return;
+    }
 
     // If first-time skip distance is any predictor of
     // scorer sparseness, then we should always try to skip first on
@@ -101,16 +79,62 @@
     // Keep last scorer in it's last place (it will be the first
     // to be skipped on), but reverse all of the others so that
     // they will be skipped on in order of original high skip.
-    int end=(scorers.length-1);
-    for (int i=0; i<(end>>1); i++) {
+    int end = scorers.length - 1;
+    int max = end >> 1;
+    for (int i = 0; i < max; i++) {
       Scorer tmp = scorers[i];
-      scorers[i] = scorers[end-i-1];
-      scorers[end-i-1] = tmp;
+      int idx = end - i - 1;
+      scorers[i] = scorers[idx];
+      scorers[idx] = tmp;
     }
+  }
 
-    return more;
+  private int doNext() throws IOException {
+    int first = 0;
+    int doc = scorers[scorers.length - 1].docID();
+    Scorer firstScorer;
+    while ((firstScorer = scorers[first]).docID() < doc) {
+      doc = firstScorer.advance(doc);
+      first = first == scorers.length - 1 ? 0 : first + 1;
+    }
+    return doc;
+  }
+  
+  public int advance(int target) throws IOException {
+    if (lastDoc == NO_MORE_DOCS) {
+      return lastDoc;
+    } else if (scorers[(scorers.length - 1)].docID() < target) {
+      scorers[(scorers.length - 1)].advance(target);
+    }
+    return lastDoc = doNext();
+  }
+
+  /** @deprecated use {@link #docID()} instead. */
+  public int doc() { return lastDoc; }
+
+  public int docID() {
+    return lastDoc;
+  }
+  
+  public Explanation explain(int doc) {
+    throw new UnsupportedOperationException();
   }
 
+  /** @deprecated use {@link #nextDoc()} instead. */
+  public boolean next() throws IOException {
+    return nextDoc() != NO_MORE_DOCS;
+  }
+
+  public int nextDoc() throws IOException {
+    if (lastDoc == NO_MORE_DOCS) {
+      return lastDoc;
+    } else if (lastDoc == -1) {
+      return lastDoc = scorers[scorers.length - 1].docID();
+    }
+    scorers[(scorers.length - 1)].nextDoc();
+    return lastDoc = doNext();
+  }
+  
   public float score() throws IOException {
     float sum = 0.0f;
     for (int i = 0; i < scorers.length; i++) {
@@ -119,8 +143,9 @@
     return sum * coord;
   }
 
-  public Explanation explain(int doc) {
-    throw new UnsupportedOperationException();
+  /** @deprecated use {@link #advance(int)} instead. */
+  public boolean skipTo(int target) throws IOException {
+    return advance(target) != NO_MORE_DOCS;
   }
 
 }

Modified: lucene/java/trunk/src/java/org/apache/lucene/search/ConstantScoreQuery.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/src/java/org/apache/lucene/search/ConstantScoreQuery.java?rev=782410&r1=782409&r2=782410&view=diff
==============================================================================
--- lucene/java/trunk/src/java/org/apache/lucene/search/ConstantScoreQuery.java (original)
+++ lucene/java/trunk/src/java/org/apache/lucene/search/ConstantScoreQuery.java Sun Jun  7 16:58:41 2009
@@ -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();
 
@@ -108,7 +108,7 @@
   protected class ConstantScorer extends Scorer {
     final DocIdSetIterator docIdSetIterator;
     final float theScore;
-    int doc=-1;
+    int doc = -1;
 
     public ConstantScorer(Similarity similarity, IndexReader reader, Weight w) throws IOException {
       super(similarity);
@@ -116,36 +116,48 @@
       docIdSetIterator = filter.getDocIdSet(reader).iterator();
     }
 
+    /** @deprecated use {@link #nextDoc()} instead. */
     public boolean next() throws IOException {
-      return docIdSetIterator.next();
+      return docIdSetIterator.nextDoc() != NO_MORE_DOCS;
     }
 
+    public int nextDoc() throws IOException {
+      return docIdSetIterator.nextDoc();
+    }
+    
+    /** @deprecated use {@link #docID()} instead. */
     public int doc() {
       return docIdSetIterator.doc();
     }
+    
+    public int docID() {
+      return docIdSetIterator.docID();
+    }
 
     public float score() throws IOException {
       return theScore;
     }
 
+    /** @deprecated use {@link #advance(int)} instead. */
     public boolean skipTo(int target) throws IOException {
-      return docIdSetIterator.skipTo(target);
+      return docIdSetIterator.advance(target) != NO_MORE_DOCS;
     }
 
+    public int advance(int target) throws IOException {
+      return docIdSetIterator.advance(target);
+    }
+    
     public Explanation explain(int doc) throws IOException {
       throw new UnsupportedOperationException();
     }
   }
 
-
   protected Weight createWeight(Searcher searcher) {
     return new ConstantScoreQuery.ConstantWeight(searcher);
   }
 
-
   /** Prints a user-readable version of this query. */
-  public String toString(String field)
-  {
+  public String toString(String field) {
     return "ConstantScore(" + filter.toString()
       + (getBoost()==1.0 ? ")" : "^" + getBoost());
   }
@@ -165,6 +177,3 @@
   }
 
 }
-
-
-

Modified: lucene/java/trunk/src/java/org/apache/lucene/search/DisjunctionMaxQuery.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/src/java/org/apache/lucene/search/DisjunctionMaxQuery.java?rev=782410&r1=782409&r2=782410&view=diff
==============================================================================
--- lucene/java/trunk/src/java/org/apache/lucene/search/DisjunctionMaxQuery.java (original)
+++ lucene/java/trunk/src/java/org/apache/lucene/search/DisjunctionMaxQuery.java Sun Jun  7 16:58:41 2009
@@ -16,14 +16,14 @@
  * limitations under the License.
  */
 
-import org.apache.lucene.index.IndexReader;
-
 import java.io.IOException;
 import java.util.ArrayList;
-import java.util.Iterator;
 import java.util.Collection;
+import java.util.Iterator;
 import java.util.Set;
 
+import org.apache.lucene.index.IndexReader;
+
 /**
  * A query that generates the union of documents produced by its subqueries, and that scores each document with the maximum
  * score for that document as produced by any subquery, plus a tie breaking increment for any additional matching subqueries.
@@ -124,13 +124,19 @@
 
     /* Create the scorer used to score our associated DisjunctionMaxQuery */
     public Scorer scorer(IndexReader reader) throws IOException {
-      DisjunctionMaxScorer result = new DisjunctionMaxScorer(tieBreakerMultiplier, similarity);
-      for (int i = 0 ; i < weights.size(); i++) {
-        Weight w = (Weight) weights.get(i);
+      Scorer[] scorers = new Scorer[weights.size()];
+      int idx = 0;
+      for (Iterator iter = weights.iterator(); iter.hasNext();) {
+        Weight w = (Weight) iter.next();
         Scorer subScorer = w.scorer(reader);
-        if (subScorer == null) return null;
-        result.add(subScorer);
+        if (subScorer == null) {
+          return null;
+        } else if (subScorer.nextDoc() != DocIdSetIterator.NO_MORE_DOCS) {
+          scorers[idx++] = subScorer;
+        }
       }
+      if (idx == 0) return null; // all scorers did not have documents
+      DisjunctionMaxScorer result = new DisjunctionMaxScorer(tieBreakerMultiplier, similarity, scorers, idx);
       return result;
     }
 

Modified: lucene/java/trunk/src/java/org/apache/lucene/search/DisjunctionMaxScorer.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/src/java/org/apache/lucene/search/DisjunctionMaxScorer.java?rev=782410&r1=782409&r2=782410&view=diff
==============================================================================
--- lucene/java/trunk/src/java/org/apache/lucene/search/DisjunctionMaxScorer.java (original)
+++ lucene/java/trunk/src/java/org/apache/lucene/search/DisjunctionMaxScorer.java Sun Jun  7 16:58:41 2009
@@ -17,7 +17,6 @@
  */
 
 import java.io.IOException;
-import java.util.ArrayList;
 
 /**
  * The Scorer for DisjunctionMaxQuery's.  The union of all documents generated by the the subquery scorers
@@ -27,168 +26,192 @@
  */
 class DisjunctionMaxScorer extends Scorer {
 
-    /* The scorers for subqueries that have remaining docs, kept as a min heap by number of next doc. */
-    private ArrayList subScorers = new ArrayList();
-
-    /* Multiplier applied to non-maximum-scoring subqueries for a document as they are summed into the result. */
-    private float tieBreakerMultiplier;
-
-    private boolean more = false;          // True iff there is a next document
-    private boolean firstTime = true;      // True iff next() has not yet been called
-
-    /** Creates a new instance of DisjunctionMaxScorer
-     * @param tieBreakerMultiplier Multiplier applied to non-maximum-scoring subqueries for a document as they are summed into the result.
-     * @param similarity -- not used since our definition involves neither coord nor terms directly */
-    public DisjunctionMaxScorer(float tieBreakerMultiplier, Similarity similarity) {
-        super(similarity);
-        this.tieBreakerMultiplier = tieBreakerMultiplier;
-    }
-
-    /** Add the scorer for a subquery
-     * @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;
-        }
-    }
-
-    /** Generate the next document matching our associated DisjunctionMaxQuery.
-     * @return true iff there is a next document
-     */
-    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;
-    }
-
-    /** Determine the current document number.  Initially invalid, until {@link #next()} is called the first time.
-     * @return the document number of the currently generated document
-     */
-    public int doc() {
-        return ((Scorer) subScorers.get(0)).doc();
-    }
-
-    /** Determine the current document score.  Initially invalid, until {@link #next()} is called the first time.
-     * @return the score of the current generated document
-     */
-    public float score() throws IOException {
-        int doc = ((Scorer) subScorers.get(0)).doc();
-        float[] sum = {((Scorer) subScorers.get(0)).score()}, max = {sum[0]};
-        int size = subScorers.size();
-        scoreAll(1, size, doc, sum, max);
-        scoreAll(2, size, doc, sum, max);
-        return max[0] + (sum[0] - max[0])*tieBreakerMultiplier;
-    }
-
-    // Recursively iterate all subScorers that generated last doc computing sum and max
-    private void scoreAll(int root, int size, int doc, float[] sum, float[] max) throws IOException {
-        if (root<size && ((Scorer) subScorers.get(root)).doc() == doc) {
-            float sub = ((Scorer) subScorers.get(root)).score();
-            sum[0] += sub;
-            max[0] = Math.max(max[0], sub);
-            scoreAll((root<<1)+1, size, doc, sum, max);
-            scoreAll((root<<1)+2, size, doc, sum, max);
-        }
-    }
-
-    /** 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
-     */
-    public boolean skipTo(int target) throws IOException {
-        if (firstTime) {
-          if (!more) return false;
-          heapify();
-          firstTime = false;
-        }
-
-        while (subScorers.size()>0 && ((Scorer)subScorers.get(0)).doc()<target) {
-            if (((Scorer)subScorers.get(0)).skipTo(target))
-                heapAdjust(0);
-            else
-                heapRemoveRoot();
-        }
-        if ((subScorers.size()==0))
-            return (more = false);
-        return true;
-    }
-
-    /** 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
-     */
-    public Explanation explain(int doc) throws IOException {
-        throw new UnsupportedOperationException();
-    }
-
-    // Organize subScorers into a min heap with scorers generating the earlest document on top.
-    private void heapify() {
-        int size = subScorers.size();
-        for (int i=(size>>1)-1; i>=0; i--)
-            heapAdjust(i);
-    }
-
-    /* The subtree of subScorers at root is a min heap except possibly for its root element.
-     * Bubble the root down as required to make the subtree a heap.
-     */
-    private void heapAdjust(int root) {
-        Scorer scorer=(Scorer)subScorers.get(root);
-        int doc=scorer.doc();
-        int i=root, size=subScorers.size();
-        while (i<=(size>>1)-1) {
-            int lchild=(i<<1)+1;
-            Scorer lscorer=(Scorer)subScorers.get(lchild);
-            int ldoc=lscorer.doc();
-            int rdoc=Integer.MAX_VALUE, rchild=(i<<1)+2;
-            Scorer rscorer=null;
-            if (rchild<size) {
-                rscorer=(Scorer)subScorers.get(rchild);
-                rdoc=rscorer.doc();
-            }
-            if (ldoc<doc) {
-                if (rdoc<ldoc) {
-                    subScorers.set(i, rscorer);
-                    subScorers.set(rchild, scorer);
-                    i=rchild;
-                } else {
-                    subScorers.set(i, lscorer);
-                    subScorers.set(lchild, scorer);
-                    i=lchild;
-                }
-            } else if (rdoc<doc) {
-                subScorers.set(i, rscorer);
-                subScorers.set(rchild, scorer);
-                i=rchild;
-            } else return;
-        }
-    }
-
-    // Remove the root Scorer from subScorers and re-establish it as a heap
-    private void heapRemoveRoot() {
-        int size=subScorers.size();
-        if (size==1)
-            subScorers.remove(0);
-        else {
-            subScorers.set(0, subScorers.get(size-1));
-            subScorers.remove(size-1);
-            heapAdjust(0);
-        }
+  /* The scorers for subqueries that have remaining docs, kept as a min heap by number of next doc. */
+  private final Scorer[] subScorers;
+  private int numScorers;
+  /* Multiplier applied to non-maximum-scoring subqueries for a document as they are summed into the result. */
+  private final float tieBreakerMultiplier;
+  private int doc = -1;
+
+  /**
+   * Creates a new instance of DisjunctionMaxScorer
+   * 
+   * @param tieBreakerMultiplier
+   *          Multiplier applied to non-maximum-scoring subqueries for a
+   *          document as they are summed into the result.
+   * @param similarity
+   *          -- not used since our definition involves neither coord nor terms
+   *          directly
+   * @param subScorers
+   *          The sub scorers this Scorer should iterate on
+   * @param numScorers
+   *          The actual number of scorers to iterate on. Note that the array's
+   *          length may be larger than the actual number of scorers.
+   */
+  public DisjunctionMaxScorer(float tieBreakerMultiplier,
+      Similarity similarity, Scorer[] subScorers, int numScorers) throws IOException {
+    super(similarity);
+
+    this.tieBreakerMultiplier = tieBreakerMultiplier;
+    // The passed subScorers array includes only scorers which have documents
+    // (DisjunctionMaxQuery takes care of that), and their nextDoc() was already
+    // called.
+    this.subScorers = subScorers;
+    this.numScorers = numScorers;
+    
+    heapify();
+  }
+
+  /**
+   * 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 {
+    return nextDoc() != NO_MORE_DOCS;
+  }
+
+  public int nextDoc() throws IOException {
+    if (numScorers == 0) return doc = NO_MORE_DOCS;
+    while (subScorers[0].docID() == doc) {
+      if (subScorers[0].nextDoc() != NO_MORE_DOCS) {
+        heapAdjust(0);
+      } else {
+        heapRemoveRoot();
+        if (numScorers == 0) {
+          return doc = NO_MORE_DOCS;
+        }
+      }
+    }
+    
+    return doc = subScorers[0].docID();
+  }
+
+  /** @deprecated use {@link #docID()} instead. */
+  public int doc() {
+    return subScorers[0].doc();
+  }
+
+  public int docID() {
+    return doc;
+  }
+
+  /** Determine the current document score.  Initially invalid, until {@link #next()} is called the first time.
+   * @return the score of the current generated document
+   */
+  public float score() throws IOException {
+    int doc = subScorers[0].docID();
+    float[] sum = { subScorers[0].score() }, max = { sum[0] };
+    int size = numScorers;
+    scoreAll(1, size, doc, sum, max);
+    scoreAll(2, size, doc, sum, max);
+    return max[0] + (sum[0] - max[0]) * tieBreakerMultiplier;
+  }
+
+  // Recursively iterate all subScorers that generated last doc computing sum and max
+  private void scoreAll(int root, int size, int doc, float[] sum, float[] max) throws IOException {
+    if (root < size && subScorers[root].docID() == doc) {
+      float sub = subScorers[root].score();
+      sum[0] += sub;
+      max[0] = Math.max(max[0], sub);
+      scoreAll((root<<1)+1, size, doc, sum, max);
+      scoreAll((root<<1)+2, size, doc, sum, max);
+    }
+  }
+
+  /**
+   * 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 {
+    return advance(target) != NO_MORE_DOCS;
+  }
+
+  public int advance(int target) throws IOException {
+    if (numScorers == 0) return doc = NO_MORE_DOCS;
+    while (subScorers[0].docID() < target) {
+      if (subScorers[0].advance(target) != NO_MORE_DOCS) {
+        heapAdjust(0);
+      } else {
+        heapRemoveRoot();
+        if (numScorers == 0) {
+          return doc = NO_MORE_DOCS;
+        }
+      }
+    }
+    return doc = subScorers[0].docID();
+  }
+
+  /** 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
+   */
+  public Explanation explain(int doc) throws IOException {
+    throw new UnsupportedOperationException();
+  }
+
+  // Organize subScorers into a min heap with scorers generating the earliest document on top.
+  private void heapify() {
+    for (int i = (numScorers >> 1) - 1; i >= 0; i--) {
+      heapAdjust(i);
+    }
+  }
+
+  /* The subtree of subScorers at root is a min heap except possibly for its root element.
+   * Bubble the root down as required to make the subtree a heap.
+   */
+  private void heapAdjust(int root) {
+    Scorer scorer = subScorers[root];
+    int doc = scorer.docID();
+    int i = root;
+    while (i <= (numScorers >> 1) - 1) {
+      int lchild = (i << 1) + 1;
+      Scorer lscorer = subScorers[lchild];
+      int ldoc = lscorer.docID();
+      int rdoc = Integer.MAX_VALUE, rchild = (i << 1) + 2;
+      Scorer rscorer = null;
+      if (rchild < numScorers) {
+        rscorer = subScorers[rchild];
+        rdoc = rscorer.docID();
+      }
+      if (ldoc < doc) {
+        if (rdoc < ldoc) {
+          subScorers[i] = rscorer;
+          subScorers[rchild] = scorer;
+          i = rchild;
+        } else {
+          subScorers[i] = lscorer;
+          subScorers[lchild] = scorer;
+          i = lchild;
+        }
+      } else if (rdoc < doc) {
+        subScorers[i] = rscorer;
+        subScorers[rchild] = scorer;
+        i = rchild;
+      } else {
+        return;
+      }
+    }
+  }
+
+  // Remove the root Scorer from subScorers and re-establish it as a heap
+  private void heapRemoveRoot() {
+    if (numScorers == 1) {
+      subScorers[0] = null;
+      numScorers = 0;
+    } else {
+      subScorers[0] = subScorers[numScorers - 1];
+      subScorers[numScorers - 1] = null;
+      --numScorers;
+      heapAdjust(0);
     }
+  }
 
 }

Modified: lucene/java/trunk/src/java/org/apache/lucene/search/DisjunctionSumScorer.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/src/java/org/apache/lucene/search/DisjunctionSumScorer.java?rev=782410&r1=782409&r2=782410&view=diff
==============================================================================
--- lucene/java/trunk/src/java/org/apache/lucene/search/DisjunctionSumScorer.java (original)
+++ lucene/java/trunk/src/java/org/apache/lucene/search/DisjunctionSumScorer.java Sun Jun  7 16:58:41 2009
@@ -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() != NO_MORE_DOCS) { // 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() != NO_MORE_DOCS) {
       collector.collect(currentDoc);
     }
   }
@@ -139,7 +139,7 @@
    * @deprecated use {@link #score(Collector, int)} instead.
    */
   protected boolean score(HitCollector hc, int max) throws IOException {
-    return score(new HitCollectorWrapper(hc), max);
+    return score(new HitCollectorWrapper(hc), max, docID());
   }
   
   /** Expert: Collects matching documents in a range.  Hook for optimization.
@@ -149,22 +149,29 @@
    * @param max Do not score documents past this.
    * @return true if more matching documents may remain.
    */
-  protected boolean score(Collector collector, int max) throws IOException {
+  protected boolean score(Collector collector, int max, int firstDocID) throws IOException {
+    // firstDocID is ignored since nextDoc() sets 'currentDoc'
     collector.setScorer(this);
     while (currentDoc < max) {
       collector.collect(currentDoc);
-      if (!next()) {
+      if (nextDoc() == NO_MORE_DOCS) {
         return false;
       }
     }
     return true;
   }
 
+  /** @deprecated use {@link #nextDoc()} instead. */
   public boolean next() throws IOException {
-    return (scorerDocQueue.size() >= minimumNrMatchers)
-          && advanceAfterCurrent();
+    return nextDoc() != NO_MORE_DOCS;
   }
 
+  public int nextDoc() throws IOException {
+    if (scorerDocQueue.size() < minimumNrMatchers || !advanceAfterCurrent()) {
+      currentDoc = NO_MORE_DOCS;
+    }
+    return currentDoc;
+  }
 
   /** Advance all subscorers after the current document determined by the
    * top of the <code>scorerDocQueue</code>.
@@ -176,7 +183,7 @@
    * <br>In case there is a match, </code>currentDoc</code>, </code>currentSumScore</code>,
    * and </code>nrMatchers</code> describe the match.
    *
-   * @todo Investigate whether it is possible to use skipTo() when
+   * TODO: Investigate whether it is possible to use skipTo() when
    * the minimum number of matchers is bigger than one, ie. try and use the
    * character of ConjunctionScorer for the minimum number of matchers.
    * Also delay calling score() on the sub scorers until the minimum number of
@@ -190,7 +197,7 @@
       currentScore = scorerDocQueue.topScore();
       nrMatchers = 1;
       do { // Until all subscorers are after currentDoc
-        if (! scorerDocQueue.topNextAndAdjustElsePop()) {
+        if (!scorerDocQueue.topNextAndAdjustElsePop()) {
           if (scorerDocQueue.size() == 0) {
             break; // nothing more to advance, check for last match.
           }
@@ -215,8 +222,13 @@
    */
   public float score() throws IOException { return currentScore; }
    
+  /** @deprecated use {@link #docID()} instead. */
   public int doc() { return currentDoc; }
 
+  public int docID() {
+    return currentDoc;
+  }
+  
   /** Returns the number of subscorers matching the current document.
    * Initially invalid, until {@link #next()} is called the first time.
    */
@@ -224,31 +236,52 @@
     return nrMatchers;
   }
 
-  /** Skips to the first match beyond the current whose document number is
-   * greater than or equal to a given target.
-   * <br>When this method is used the {@link #explain(int)} method should not be used.
-   * <br>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. <br>
+   * When this method is used the {@link #explain(int)} method should not be
+   * used. <br>
+   * 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) != NO_MORE_DOCS;
+  }
+
+  /**
+   * Advances to the first match beyond the current whose document number is
+   * greater than or equal to a given target. <br>
+   * When this method is used the {@link #explain(int)} method should not be
+   * used. <br>
+   * 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 currentDoc = NO_MORE_DOCS;
     }
     if (target <= currentDoc) {
-      return true;
+      return currentDoc;
     }
     do {
       if (scorerDocQueue.topDoc() >= target) {
-        return advanceAfterCurrent();
-      } else if (! scorerDocQueue.topSkipToAndAdjustElsePop(target)) {
+        return advanceAfterCurrent() ? currentDoc : (currentDoc = NO_MORE_DOCS);
+      } else if (!scorerDocQueue.topSkipToAndAdjustElsePop(target)) {
         if (scorerDocQueue.size() < minimumNrMatchers) {
-          return false;
+          return currentDoc = NO_MORE_DOCS;
         }
       }
     } while (true);
   }
-
+  
   /** @return An explanation for the score of a given document. */
   public Explanation explain(int doc) throws IOException {
     Explanation res = new Explanation();

Modified: lucene/java/trunk/src/java/org/apache/lucene/search/DocIdSetIterator.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/src/java/org/apache/lucene/search/DocIdSetIterator.java?rev=782410&r1=782409&r2=782410&view=diff
==============================================================================
--- lucene/java/trunk/src/java/org/apache/lucene/search/DocIdSetIterator.java (original)
+++ lucene/java/trunk/src/java/org/apache/lucene/search/DocIdSetIterator.java Sun Jun  7 16:58:41 2009
@@ -20,30 +20,130 @@
 import java.io.IOException;
 
 /**
- * This abstract class defines methods to iterate over a set of
- * non-decreasing doc ids.
+ * This abstract class defines methods to iterate over a set of non-decreasing
+ * doc ids. Note that this class assumes it iterates on doc Ids, and therefore
+ * {@link #NO_MORE_DOCS} is set to {@value #NO_MORE_DOCS} in order to be used as
+ * a sentinel object. Implementations of this class are expected to consider
+ * {@link Integer#MAX_VALUE} as an invalid value.
  */
 public abstract class DocIdSetIterator {
-    /** Returns the current document number.  <p> 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 <i>target</i>. <p>Returns true iff there is such
-     * an entry.  <p>Behaves as if written: <pre>
-     *   boolean skipTo(int target) {
-     *     do {
-     *       if (!next())
-     *         return false;
-     *     } while (target > doc());
-     *     return true;
-     *   }
-     * </pre>
-     * Some implementations are considerably more efficient than that.
-     */
-    public abstract boolean skipTo(int target) throws IOException;
+  
+  // TODO (3.0): review the javadocs and remove any references to '3.0'.
+  private int doc = -1;
+  
+  /**
+   * When returned by {@link #nextDoc()}, {@link #advance(int)} and
+   * {@link #doc()} it means there are no more docs in the iterator.
+   */
+  public static final int NO_MORE_DOCS = Integer.MAX_VALUE;
+
+  /**
+   * Unsupported anymore. Call {@link #docID()} instead. This method throws
+   * {@link UnsupportedOperationException} if called.
+   * 
+   * @deprecated use {@link #docID()} instead.
+   */
+  public int doc() {
+    throw new UnsupportedOperationException("Call docID() instead.");
+  }
+
+  /**
+   * Returns the following:
+   * <ul>
+   * <li>-1 or {@link #NO_MORE_DOCS} if {@link #nextDoc()} or
+   * {@link #advance(int)} were not called yet.
+   * <li>{@link #NO_MORE_DOCS} if the iterator has exhausted.
+   * <li>Otherwise it should return the doc ID it is currently on.
+   * </ul>
+   * <p>
+   * <b>NOTE:</b> in 3.0, this method will become abstract.
+   * 
+   * @since 2.9
+   */
+  public int docID() {
+    return doc;
+  }
+
+  /**
+   * Unsupported anymore. Call {@link #nextDoc()} instead. This method throws
+   * {@link UnsupportedOperationException} if called.
+   * 
+   * @deprecated use {@link #nextDoc()} instead. This will be removed in 3.0
+   */
+  public boolean next() throws IOException {
+    throw new UnsupportedOperationException("Call nextDoc() instead.");
+  }
+
+  /**
+   * Unsupported anymore. Call {@link #advance(int)} instead. This method throws
+   * {@link UnsupportedOperationException} if called.
+   * 
+   * @deprecated use {@link #advance(int)} instead. This will be removed in 3.0
+   */
+  public boolean skipTo(int target) throws IOException {
+    throw new UnsupportedOperationException("Call advance() instead.");
+  }
+
+  /**
+   * Advances to the next document in the set and returns the doc it is
+   * currently on, or {@link #NO_MORE_DOCS} if there are no more docs in the
+   * set.<br>
+   * 
+   * <b>NOTE:</b> in 3.0 this method will become abstract, following the removal
+   * of {@link #next()}. For backward compatibility it is implemented as:
+   * 
+   * <pre>
+   * public int nextDoc() throws IOException {
+   *   return next() ? doc() : NO_MORE_DOCS;
+   * }
+   * </pre>
+   * 
+   * <b>NOTE:</b> after the iterator has exhausted you should not call this
+   * method, as it may result in unpredicted behavior.
+   * 
+   * @since 2.9
+   */
+  public int nextDoc() throws IOException {
+    return doc = next() ? doc() : NO_MORE_DOCS;
+  }
+
+  /**
+   * Advances to the first beyond the current whose document number is greater
+   * than or equal to <i>target</i>. Returns the current document number or
+   * {@link #NO_MORE_DOCS} if there are no more docs in the set.
+   * <p>
+   * Behaves as if written:
+   * 
+   * <pre>
+   * int advance(int target) {
+   *   int doc;
+   *   while ((doc = nextDoc()) &lt; target) {
+   *   }
+   *   return doc;
+   * }
+   * </pre>
+   * 
+   * Some implementations are considerably more efficient than that.
+   * <p>
+   * <b>NOTE:</b> certain implemenations may return a different value (each
+   * time) if called several times in a row with the same target.
+   * <p>
+   * <b>NOTE:</b> this method may be called with {@value #NO_MORE_DOCS} for
+   * efficiency by some Scorers. If your implementation cannot efficiently
+   * determine that it should exhaust, it is recommended that you check for that
+   * value in each call to this method.
+   * <p>
+   * <b>NOTE:</b> after the iterator has exhausted you should not call this
+   * method, as it may result in unpredicted behavior.
+   * <p>
+   * <b>NOTE:</b> in 3.0 this method will become abstract, following the removal
+   * of {@link #skipTo(int)}.
+   * 
+   * @since 2.9
+   */
+  public int advance(int target) throws IOException {
+    while (nextDoc() < target) {}
+    return doc;
+  }
+
 }

Modified: lucene/java/trunk/src/java/org/apache/lucene/search/FieldCacheRangeFilter.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/src/java/org/apache/lucene/search/FieldCacheRangeFilter.java?rev=782410&r1=782409&r2=782410&view=diff
==============================================================================
--- lucene/java/trunk/src/java/org/apache/lucene/search/FieldCacheRangeFilter.java (original)
+++ lucene/java/trunk/src/java/org/apache/lucene/search/FieldCacheRangeFilter.java Sun Jun  7 16:58:41 2009
@@ -158,37 +158,51 @@
     
     protected class RangeMultiFilterIterator extends DocIdSetIterator {
       private int doc = -1;
-      
+
+      /** @deprecated use {@link #docID()} instead. */
       public int doc() {
         return doc;
       }
 
+      public int docID() {
+        return doc;
+      }
+      
+      /** @deprecated use {@link #nextDoc()} instead. */
       public boolean next() {
+        return nextDoc() != NO_MORE_DOCS;
+      }
+
+      public int nextDoc() {
         try {
           do {
             doc++;
           } while (fcsi.order[doc] > inclusiveUpperPoint 
                    || fcsi.order[doc] < inclusiveLowerPoint);
-          return true;
         } catch (ArrayIndexOutOfBoundsException e) {
-          doc = Integer.MAX_VALUE;
-          return false;
+          doc = NO_MORE_DOCS;
         }
+        return doc;
       }
-
+      
+      /** @deprecated use {@link #advance(int)} instead. */
       public boolean skipTo(int target) {
+        return advance(target) != NO_MORE_DOCS;
+      }
+      
+      public int advance(int target) {
         try {
           doc = target;
           while (fcsi.order[doc] > inclusiveUpperPoint 
                 || fcsi.order[doc] < inclusiveLowerPoint) { 
             doc++;
           }
-          return true;
         } catch (ArrayIndexOutOfBoundsException e) {
-          doc = Integer.MAX_VALUE;
-          return false;
+          doc = NO_MORE_DOCS;
         }
+        return doc;
       }
+      
     }
   }
 }

Modified: lucene/java/trunk/src/java/org/apache/lucene/search/FieldCacheTermsFilter.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/src/java/org/apache/lucene/search/FieldCacheTermsFilter.java?rev=782410&r1=782409&r2=782410&view=diff
==============================================================================
--- lucene/java/trunk/src/java/org/apache/lucene/search/FieldCacheTermsFilter.java (original)
+++ lucene/java/trunk/src/java/org/apache/lucene/search/FieldCacheTermsFilter.java Sun Jun  7 16:58:41 2009
@@ -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
@@ -133,33 +132,44 @@
     protected class FieldCacheTermsFilterDocIdSetIterator extends DocIdSetIterator {
       private int doc = -1;
 
+      /** @deprecated use {@link #docID()} instead. */
       public int doc() {
         return doc;
       }
+      
+      public int docID() {
+        return doc;
+      }
 
+      /** @deprecated use {@link #nextDoc()} instead. */
       public boolean next() {
+        return nextDoc() != NO_MORE_DOCS;
+      }
+      
+      public int nextDoc() {
         try {
-          do {
-            doc++;
-          } while (!openBitSet.fastGet(fcsi.order[doc]));
-          return true;
+          while (!openBitSet.fastGet(fcsi.order[++doc])) {}
         } catch (ArrayIndexOutOfBoundsException e) {
-          doc = Integer.MAX_VALUE;
-          return false;
+          doc = NO_MORE_DOCS;
         }
+        return doc;
       }
 
+      /** @deprecated use {@link #advance(int)} instead. */
       public boolean skipTo(int target) {
+        return advance(target) != NO_MORE_DOCS;
+      }
+      
+      public int advance(int target) {
         try {
           doc = target;
           while (!openBitSet.fastGet(fcsi.order[doc])) {
             doc++;
           }
-          return true;
         } catch (ArrayIndexOutOfBoundsException e) {
-          doc = Integer.MAX_VALUE;
-          return false;
+          doc = NO_MORE_DOCS;
         }
+        return doc;
       }
     }
   }

Modified: lucene/java/trunk/src/java/org/apache/lucene/search/FilteredDocIdSetIterator.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/src/java/org/apache/lucene/search/FilteredDocIdSetIterator.java?rev=782410&r1=782409&r2=782410&view=diff
==============================================================================
--- lucene/java/trunk/src/java/org/apache/lucene/search/FilteredDocIdSetIterator.java (original)
+++ lucene/java/trunk/src/java/org/apache/lucene/search/FilteredDocIdSetIterator.java Sun Jun  7 16:58:41 2009
@@ -25,10 +25,9 @@
  * mechanism on an underlying DocIdSetIterator.  See {@link
  * FilteredDocIdSet}.
  */
-
 public abstract class FilteredDocIdSetIterator extends DocIdSetIterator {
   protected DocIdSetIterator _innerIter;
-  private int _currentDoc;
+  private int doc;
 	
   /**
    * Constructor.
@@ -39,7 +38,7 @@
       throw new IllegalArgumentException("null iterator");
     }
     _innerIter = innerIter;
-    _currentDoc = -1;
+    doc = -1;
   }
 	
   /**
@@ -50,42 +49,49 @@
    */
   abstract protected boolean match(int doc);
 	
-  // @Override
+  /** @deprecated use {@link #docID()} instead. */
   public final int doc() {
-    return _currentDoc;
+    return doc;
   }
 
-  // @Override
+  public int docID() {
+    return doc;
+  }
+  
+  /** @deprecated use {@link #nextDoc()} instead. */
   public final boolean next() throws IOException{
-    while (_innerIter.next()) {
-      int doc = _innerIter.doc();
+    return nextDoc() != NO_MORE_DOCS;
+  }
+
+  public int nextDoc() throws IOException {
+    while ((doc = _innerIter.nextDoc()) != NO_MORE_DOCS) {
       if (match(doc)) {
-        _currentDoc = doc;
-        return true;
+        return doc;
       }
     }
-    return false;
+    return doc;
   }
-
-  // @Override
+  
+  /** @deprecated use {@link #advance(int)} instead. */
   public final boolean skipTo(int n) throws IOException{
-    boolean flag = _innerIter.skipTo(n);
-    if (flag) {
-      int doc = _innerIter.doc();
+    return advance(n) != NO_MORE_DOCS;
+  }
+  
+  public int advance(int target) throws IOException {
+    doc = _innerIter.advance(target);
+    if (doc != NO_MORE_DOCS) {
       if (match(doc)) {
-        _currentDoc = doc;
-        return true;
+        return doc;
       } else {
-        while (_innerIter.next()) {
-          int docid = _innerIter.doc();
-          if (match(docid)) {
-            _currentDoc = docid;
-            return true;
+        while ((doc = _innerIter.nextDoc()) != NO_MORE_DOCS) {
+          if (match(doc)) {
+            return doc;
           }
         }
-        return false;
+        return doc;
       }
     }
-    return flag;
+    return doc;
   }
+  
 }

Modified: lucene/java/trunk/src/java/org/apache/lucene/search/FilteredQuery.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/src/java/org/apache/lucene/search/FilteredQuery.java?rev=782410&r1=782409&r2=782410&view=diff
==============================================================================
--- lucene/java/trunk/src/java/org/apache/lucene/search/FilteredQuery.java (original)
+++ lucene/java/trunk/src/java/org/apache/lucene/search/FilteredQuery.java Sun Jun  7 16:58:41 2009
@@ -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,35 +99,51 @@
       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;
-                }
-              } else if (!docIdSetIterator.skipTo(scorer.doc())) {
-                return false;
+          private int doc = -1;
+          
+          private int advanceToCommon(int scorerDoc, int disiDoc) throws IOException {
+            while (scorerDoc != disiDoc) {
+              if (scorerDoc < disiDoc) {
+                scorerDoc = scorer.advance(disiDoc);
+              } else {
+                disiDoc = docIdSetIterator.advance(scorerDoc);
               }
             }
-            return true;
+            return scorerDoc;
           }
 
+          /** @deprecated use {@link #nextDoc()} instead. */
           public boolean next() throws IOException {
-            return docIdSetIterator.next() && scorer.next() && advanceToCommon();
+            return nextDoc() != NO_MORE_DOCS;
           }
 
+          public int nextDoc() throws IOException {
+            int scorerDoc, disiDoc;
+            return doc = (disiDoc = docIdSetIterator.nextDoc()) != NO_MORE_DOCS
+                && (scorerDoc = scorer.nextDoc()) != NO_MORE_DOCS
+                && advanceToCommon(scorerDoc, disiDoc) != NO_MORE_DOCS ? scorer.docID() : NO_MORE_DOCS;
+          }
+          
+          /** @deprecated use {@link #docID()} instead. */
           public int doc() { return scorer.doc(); }
-
+          public int docID() { return 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) != NO_MORE_DOCS;
+          }
+          
+          public int advance(int target) throws IOException {
+            int disiDoc, scorerDoc;
+            return doc = (disiDoc = docIdSetIterator.advance(target)) != NO_MORE_DOCS
+                && (scorerDoc = scorer.advance(disiDoc)) != NO_MORE_DOCS 
+                && advanceToCommon(scorerDoc, disiDoc) != NO_MORE_DOCS ? scorer.docID() : NO_MORE_DOCS;
           }
 
           public float score() throws IOException { return getBoost() * scorer.score(); }
@@ -136,7 +152,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 {

Modified: lucene/java/trunk/src/java/org/apache/lucene/search/IndexSearcher.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/src/java/org/apache/lucene/search/IndexSearcher.java?rev=782410&r1=782409&r2=782410&view=diff
==============================================================================
--- lucene/java/trunk/src/java/org/apache/lucene/search/IndexSearcher.java (original)
+++ lucene/java/trunk/src/java/org/apache/lucene/search/IndexSearcher.java Sun Jun  7 16:58:41 2009
@@ -258,28 +258,34 @@
     if (scorer == null)
       return;
 
+    int docID = scorer.docID();
+    assert docID == -1 || docID == DocIdSetIterator.NO_MORE_DOCS;
+    
     if (filter == null) {
       scorer.score(collector);
       return;
     }
 
-    DocIdSetIterator filterDocIdIterator = filter.getDocIdSet(reader).iterator(); // CHECKME: use ConjunctionScorer here?
+    // CHECKME: use ConjunctionScorer here?
+    DocIdSetIterator filterIter = filter.getDocIdSet(reader).iterator();
+    
+    int filterDoc = filterIter.nextDoc();
+    int scorerDoc = scorer.advance(filterDoc);
     
-    boolean more = filterDocIdIterator.next() && scorer.skipTo(filterDocIdIterator.doc());
-
     collector.setScorer(scorer);
-    while (more) {
-      int filterDocId = filterDocIdIterator.doc();
-      if (filterDocId > scorer.doc() && !scorer.skipTo(filterDocId)) {
-        more = false;
-      } else {
-        int scorerDocId = scorer.doc();
-        if (scorerDocId == filterDocId) { // permitted by filter
-          collector.collect(scorerDocId);
-          more = filterDocIdIterator.next();
-        } else {
-          more = filterDocIdIterator.skipTo(scorerDocId);
+    while (true) {
+      if (scorerDoc == filterDoc) {
+        // Check if scorer has exhausted, only before collecting.
+        if (scorerDoc == DocIdSetIterator.NO_MORE_DOCS) {
+          break;
         }
+        collector.collect(scorerDoc);
+        filterDoc = filterIter.nextDoc();
+        scorerDoc = scorer.advance(filterDoc);
+      } else if (scorerDoc > filterDoc) {
+        filterDoc = filterIter.advance(scorerDoc);
+      } else {
+        scorerDoc = scorer.advance(filterDoc);
       }
     }
   }

Modified: lucene/java/trunk/src/java/org/apache/lucene/search/MatchAllDocsQuery.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/src/java/org/apache/lucene/search/MatchAllDocsQuery.java?rev=782410&r1=782409&r2=782410&view=diff
==============================================================================
--- lucene/java/trunk/src/java/org/apache/lucene/search/MatchAllDocsQuery.java (original)
+++ lucene/java/trunk/src/java/org/apache/lucene/search/MatchAllDocsQuery.java Sun Jun  7 16:58:41 2009
@@ -47,9 +47,10 @@
     final TermDocs termDocs;
     final float score;
     final byte[] norms;
-
-    MatchAllScorer(IndexReader reader, Similarity similarity, Weight w, byte[] norms) throws IOException
-    {
+    private int doc = -1;
+    
+    MatchAllScorer(IndexReader reader, Similarity similarity, Weight w,
+        byte[] norms) throws IOException {
       super(similarity);
       this.termDocs = reader.termDocs(null);
       score = w.getValue();
@@ -60,26 +61,36 @@
       return null; // not called... see MatchAllDocsWeight.explain()
     }
 
+    /** @deprecated use {@link #docID()} instead. */
     public int doc() {
       return termDocs.doc();
     }
+    
+    public int docID() {
+      return doc;
+    }
 
+    /** @deprecated use {@link #nextDoc()} instead. */
     public boolean next() throws IOException {
-      return termDocs.next();
+      return nextDoc() != NO_MORE_DOCS;
     }
 
+    public int nextDoc() throws IOException {
+      return doc = termDocs.next() ? termDocs.doc() : NO_MORE_DOCS;
+    }
+    
     public float score() {
-      if (norms == null) {
-        return score;
-      } else {
-        return score * Similarity.decodeNorm(norms[doc()]); // normalize for field
-      }
+      return norms == null ? score : score * Similarity.decodeNorm(norms[docID()]);
     }
 
+    /** @deprecated use {@link #advance(int)} instead. */
     public boolean skipTo(int target) throws IOException {
-      return termDocs.skipTo(target);
+      return advance(target) != NO_MORE_DOCS;
     }
 
+    public int advance(int target) throws IOException {
+      return doc = termDocs.skipTo(target) ? termDocs.doc() : NO_MORE_DOCS;
+    }
   }
 
   private class MatchAllDocsWeight implements Weight {



Mime
View raw message