lucene-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From da...@apache.org
Subject [25/36] lucene-solr:jira/http2: LUCENE-8431: Top-docs collectors now collect lower bounds of the hit count.
Date Tue, 31 Jul 2018 02:32:41 GMT
LUCENE-8431: Top-docs collectors now collect lower bounds of the hit count.


Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/61e89e3c
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/61e89e3c
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/61e89e3c

Branch: refs/heads/jira/http2
Commit: 61e89e3ca05802a95bcc185092bc73f3e25e7fa3
Parents: 9ca0537
Author: Adrien Grand <jpountz@gmail.com>
Authored: Mon Jul 30 10:35:10 2018 +0200
Committer: Adrien Grand <jpountz@gmail.com>
Committed: Mon Jul 30 16:38:05 2018 +0200

----------------------------------------------------------------------
 .../lucene/benchmark/byTask/tasks/ReadTask.java |  4 +-
 .../byTask/tasks/SearchWithCollectorTask.java   |  2 +-
 .../org/apache/lucene/search/IndexSearcher.java |  4 +-
 .../org/apache/lucene/search/SortRescorer.java  |  2 +-
 .../apache/lucene/search/TopFieldCollector.java | 60 ++++++++------
 .../lucene/search/TopScoreDocCollector.java     | 69 ++++++++++------
 .../apache/lucene/index/TestIndexSorting.java   |  4 +-
 .../org/apache/lucene/search/TestBoolean2.java  | 18 ++---
 .../search/TestBooleanMinShouldMatch.java       |  2 +-
 .../apache/lucene/search/TestBooleanQuery.java  |  2 +-
 .../search/TestBooleanQueryVisitSubscorers.java |  2 +-
 .../lucene/search/TestDisjunctionMaxQuery.java  |  2 +-
 .../lucene/search/TestElevationComparator.java  |  2 +-
 .../apache/lucene/search/TestPhraseQuery.java   |  4 +-
 .../search/TestPositiveScoresOnlyCollector.java |  2 +-
 .../lucene/search/TestReqOptSumScorer.java      |  8 +-
 .../lucene/search/TestSubScorerFreqs.java       |  6 +-
 .../apache/lucene/search/TestSynonymQuery.java  | 21 ++---
 .../apache/lucene/search/TestTermScorer.java    |  8 +-
 .../lucene/search/TestTopDocsCollector.java     | 48 ++++++-----
 .../apache/lucene/search/TestTopDocsMerge.java  |  8 +-
 .../lucene/search/TestTopFieldCollector.java    | 84 ++++++++++++++++++--
 .../TestTopFieldCollectorEarlyTermination.java  |  4 +-
 .../org/apache/lucene/facet/DrillSideways.java  |  8 +-
 .../apache/lucene/facet/FacetsCollector.java    |  4 +-
 .../search/grouping/BlockGroupingCollector.java |  4 +-
 .../search/grouping/TopGroupsCollector.java     |  4 +-
 .../apache/lucene/search/join/TestJoinUtil.java |  4 +-
 .../analyzing/AnalyzingInfixSuggester.java      |  2 +-
 .../org/apache/lucene/search/CheckHits.java     |  4 +-
 .../solr/handler/component/ExpandComponent.java |  4 +-
 .../java/org/apache/solr/search/Grouping.java   |  4 +-
 .../org/apache/solr/search/ReRankCollector.java |  4 +-
 .../apache/solr/search/SolrIndexSearcher.java   |  4 +-
 .../distributed/command/QueryCommand.java       |  4 +-
 .../test/org/apache/solr/search/TestSort.java   |  2 +-
 36 files changed, 262 insertions(+), 156 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/61e89e3c/lucene/benchmark/src/java/org/apache/lucene/benchmark/byTask/tasks/ReadTask.java
----------------------------------------------------------------------
diff --git a/lucene/benchmark/src/java/org/apache/lucene/benchmark/byTask/tasks/ReadTask.java b/lucene/benchmark/src/java/org/apache/lucene/benchmark/byTask/tasks/ReadTask.java
index b05a429..908808c 100644
--- a/lucene/benchmark/src/java/org/apache/lucene/benchmark/byTask/tasks/ReadTask.java
+++ b/lucene/benchmark/src/java/org/apache/lucene/benchmark/byTask/tasks/ReadTask.java
@@ -112,7 +112,7 @@ public abstract class ReadTask extends PerfTask {
             // Weight public again, we can go back to
             // pulling the Weight ourselves:
             TopFieldCollector collector = TopFieldCollector.create(sort, numHits,
-                                                                   withTotalHits());
+                                                                   withTotalHits() ? Integer.MAX_VALUE : 1);
             searcher.search(q, collector);
             hits = collector.topDocs();
           } else {
@@ -174,7 +174,7 @@ public abstract class ReadTask extends PerfTask {
   }
 
   protected Collector createCollector() throws Exception {
-    return TopScoreDocCollector.create(numHits());
+    return TopScoreDocCollector.create(numHits(), withTotalHits() ? Integer.MAX_VALUE : 1);
   }
 
 

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/61e89e3c/lucene/benchmark/src/java/org/apache/lucene/benchmark/byTask/tasks/SearchWithCollectorTask.java
----------------------------------------------------------------------
diff --git a/lucene/benchmark/src/java/org/apache/lucene/benchmark/byTask/tasks/SearchWithCollectorTask.java b/lucene/benchmark/src/java/org/apache/lucene/benchmark/byTask/tasks/SearchWithCollectorTask.java
index 0826c86..f557f93 100644
--- a/lucene/benchmark/src/java/org/apache/lucene/benchmark/byTask/tasks/SearchWithCollectorTask.java
+++ b/lucene/benchmark/src/java/org/apache/lucene/benchmark/byTask/tasks/SearchWithCollectorTask.java
@@ -53,7 +53,7 @@ public class SearchWithCollectorTask extends SearchTask {
   protected Collector createCollector() throws Exception {
     Collector collector = null;
     if (clnName.equalsIgnoreCase("topScoreDoc") == true) {
-      collector = TopScoreDocCollector.create(numHits());
+      collector = TopScoreDocCollector.create(numHits(), Integer.MAX_VALUE);
     } else if (clnName.length() > 0){
       collector = Class.forName(clnName).asSubclass(Collector.class).newInstance();
 

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/61e89e3c/lucene/core/src/java/org/apache/lucene/search/IndexSearcher.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/search/IndexSearcher.java b/lucene/core/src/java/org/apache/lucene/search/IndexSearcher.java
index 7d18d4f..d2e5d01 100644
--- a/lucene/core/src/java/org/apache/lucene/search/IndexSearcher.java
+++ b/lucene/core/src/java/org/apache/lucene/search/IndexSearcher.java
@@ -384,7 +384,7 @@ public class IndexSearcher {
 
       @Override
       public TopScoreDocCollector newCollector() throws IOException {
-        return TopScoreDocCollector.create(cappedNumHits, after, true);
+        return TopScoreDocCollector.create(cappedNumHits, after, Integer.MAX_VALUE);
       }
 
       @Override
@@ -513,7 +513,7 @@ public class IndexSearcher {
       @Override
       public TopFieldCollector newCollector() throws IOException {
         // TODO: don't pay the price for accurate hit counts by default
-        return TopFieldCollector.create(rewrittenSort, cappedNumHits, after, true);
+        return TopFieldCollector.create(rewrittenSort, cappedNumHits, after, Integer.MAX_VALUE);
       }
 
       @Override

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/61e89e3c/lucene/core/src/java/org/apache/lucene/search/SortRescorer.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/search/SortRescorer.java b/lucene/core/src/java/org/apache/lucene/search/SortRescorer.java
index 5d35a58..ff8f46a 100644
--- a/lucene/core/src/java/org/apache/lucene/search/SortRescorer.java
+++ b/lucene/core/src/java/org/apache/lucene/search/SortRescorer.java
@@ -50,7 +50,7 @@ public class SortRescorer extends Rescorer {
 
     List<LeafReaderContext> leaves = searcher.getIndexReader().leaves();
 
-    TopFieldCollector collector = TopFieldCollector.create(sort, topN, true);
+    TopFieldCollector collector = TopFieldCollector.create(sort, topN, Integer.MAX_VALUE);
 
     // Now merge sort docIDs from hits, with reader's leaves:
     int hitUpto = 0;

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/61e89e3c/lucene/core/src/java/org/apache/lucene/search/TopFieldCollector.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/search/TopFieldCollector.java b/lucene/core/src/java/org/apache/lucene/search/TopFieldCollector.java
index af2310b..8f0e059 100644
--- a/lucene/core/src/java/org/apache/lucene/search/TopFieldCollector.java
+++ b/lucene/core/src/java/org/apache/lucene/search/TopFieldCollector.java
@@ -33,7 +33,7 @@ import org.apache.lucene.util.PriorityQueue;
  * A {@link Collector} that sorts by {@link SortField} using
  * {@link FieldComparator}s.
  * <p>
- * See the {@link #create(org.apache.lucene.search.Sort, int, boolean)} method
+ * See the {@link #create(org.apache.lucene.search.Sort, int, int)} method
  * for instantiating a TopFieldCollector.
  *
  * @lucene.experimental
@@ -86,13 +86,13 @@ public abstract class TopFieldCollector extends TopDocsCollector<Entry> {
 
     final Sort sort;
     final FieldValueHitQueue<Entry> queue;
-    final boolean trackTotalHits;
+    final int totalHitsThreshold;
 
-    public SimpleFieldCollector(Sort sort, FieldValueHitQueue<Entry> queue, int numHits, boolean trackTotalHits) {
+    public SimpleFieldCollector(Sort sort, FieldValueHitQueue<Entry> queue, int numHits, int totalHitsThreshold) {
       super(queue, numHits, sort.needsScores());
       this.sort = sort;
       this.queue = queue;
-      this.trackTotalHits = trackTotalHits;
+      this.totalHitsThreshold = totalHitsThreshold;
     }
 
     @Override
@@ -102,8 +102,7 @@ public abstract class TopFieldCollector extends TopDocsCollector<Entry> {
       final LeafFieldComparator[] comparators = queue.getComparators(context);
       final int[] reverseMul = queue.getReverseMul();
       final Sort indexSort = context.reader().getMetaData().getSort();
-      final boolean canEarlyTerminate = trackTotalHits == false &&
-          indexSort != null &&
+      final boolean canEarlyTerminate = indexSort != null &&
           canEarlyTerminate(sort, indexSort);
 
       return new MultiComparatorLeafCollector(comparators, reverseMul) {
@@ -116,7 +115,7 @@ public abstract class TopFieldCollector extends TopDocsCollector<Entry> {
               // since docs are visited in doc Id order, if compare is 0, it means
               // this document is largest than anything else in the queue, and
               // therefore not competitive.
-              if (canEarlyTerminate) {
+              if (canEarlyTerminate && totalHits >= totalHitsThreshold) {
                 totalHitsRelation = Relation.GREATER_THAN_OR_EQUAL_TO;
                 throw new CollectionTerminatedException();
               } else {
@@ -156,15 +155,15 @@ public abstract class TopFieldCollector extends TopDocsCollector<Entry> {
     int collectedHits;
     final FieldValueHitQueue<Entry> queue;
     final FieldDoc after;
-    final boolean trackTotalHits;
+    final int totalHitsThreshold;
 
     public PagingFieldCollector(Sort sort, FieldValueHitQueue<Entry> queue, FieldDoc after, int numHits,
-                                boolean trackTotalHits) {
+                                int totalHitsThreshold) {
       super(queue, numHits, sort.needsScores());
       this.sort = sort;
       this.queue = queue;
       this.after = after;
-      this.trackTotalHits = trackTotalHits;
+      this.totalHitsThreshold = totalHitsThreshold;
 
       FieldComparator<?>[] comparators = queue.comparators;
       // Tell all comparators their top value:
@@ -180,8 +179,7 @@ public abstract class TopFieldCollector extends TopDocsCollector<Entry> {
       docBase = context.docBase;
       final int afterDoc = after.doc - docBase;
       final Sort indexSort = context.reader().getMetaData().getSort();
-      final boolean canEarlyTerminate = trackTotalHits == false &&
-          indexSort != null &&
+      final boolean canEarlyTerminate = indexSort != null &&
           canEarlyTerminate(sort, indexSort);
       return new MultiComparatorLeafCollector(queue.getComparators(context), queue.getReverseMul()) {
 
@@ -197,7 +195,7 @@ public abstract class TopFieldCollector extends TopDocsCollector<Entry> {
             final int cmp = reverseMul * comparator.compareBottom(doc);
             if (cmp <= 0) {
               // not competitive since documents are visited in doc id order
-              if (canEarlyTerminate) {
+              if (canEarlyTerminate && totalHits >= totalHitsThreshold) {
                 totalHitsRelation = Relation.GREATER_THAN_OR_EQUAL_TO;
                 throw new CollectionTerminatedException();
               } else {
@@ -277,15 +275,18 @@ public abstract class TopFieldCollector extends TopDocsCollector<Entry> {
    *          the sort criteria (SortFields).
    * @param numHits
    *          the number of results to collect.
-   * @param trackTotalHits
-   *          specifies whether the total number of hits should be tracked. If
-   *          set to false, the value of {@link TopFieldDocs#totalHits} will be
-   *          approximated.
+   * @param totalHitsThreshold
+   *          the number of docs to count accurately. If the query matches
+   *          {@code totalHitsThreshold} hits or more then its hit count will be a
+   *          lower bound. On the other hand if the query matches less than
+   *          {@code totalHitsThreshold} hits then the hit count of the result will
+   *          be accurate. {@link Integer#MAX_VALUE} may be used to make the hit
+   *          count accurate, but this will also make query processing slower.
    * @return a {@link TopFieldCollector} instance which will sort the results by
    *         the sort criteria.
    */
-  public static TopFieldCollector create(Sort sort, int numHits, boolean trackTotalHits) {
-    return create(sort, numHits, null, trackTotalHits);
+  public static TopFieldCollector create(Sort sort, int numHits, int totalHitsThreshold) {
+    return create(sort, numHits, null, totalHitsThreshold);
   }
 
   /**
@@ -302,15 +303,18 @@ public abstract class TopFieldCollector extends TopDocsCollector<Entry> {
    *          the number of results to collect.
    * @param after
    *          only hits after this FieldDoc will be collected
-   * @param trackTotalHits
-   *          specifies whether the total number of hits should be tracked. If
-   *          set to false, the value of {@link TopFieldDocs#totalHits} will be
-   *          approximated.
+   * @param totalHitsThreshold
+   *          the number of docs to count accurately. If the query matches
+   *          {@code totalHitsThreshold} hits or more then its hit count will be a
+   *          lower bound. On the other hand if the query matches less than
+   *          {@code totalHitsThreshold} hits then the hit count of the result will
+   *          be accurate. {@link Integer#MAX_VALUE} may be used to make the hit
+   *          count accurate, but this will also make query processing slower.
    * @return a {@link TopFieldCollector} instance which will sort the results by
    *         the sort criteria.
    */
   public static TopFieldCollector create(Sort sort, int numHits, FieldDoc after,
-      boolean trackTotalHits) {
+      int totalHitsThreshold) {
 
     if (sort.fields.length == 0) {
       throw new IllegalArgumentException("Sort must contain at least one field");
@@ -320,10 +324,14 @@ public abstract class TopFieldCollector extends TopDocsCollector<Entry> {
       throw new IllegalArgumentException("numHits must be > 0; please use TotalHitCountCollector if you just need the total hit count");
     }
 
+    if (totalHitsThreshold <= 0) {
+      throw new IllegalArgumentException("totalHitsThreshold must be > 0, got " + totalHitsThreshold);
+    }
+
     FieldValueHitQueue<Entry> queue = FieldValueHitQueue.create(sort.fields, numHits);
 
     if (after == null) {
-      return new SimpleFieldCollector(sort, queue, numHits, trackTotalHits);
+      return new SimpleFieldCollector(sort, queue, numHits, totalHitsThreshold);
     } else {
       if (after.fields == null) {
         throw new IllegalArgumentException("after.fields wasn't set; you must pass fillFields=true for the previous search");
@@ -333,7 +341,7 @@ public abstract class TopFieldCollector extends TopDocsCollector<Entry> {
         throw new IllegalArgumentException("after.fields has " + after.fields.length + " values but sort has " + sort.getSort().length);
       }
 
-      return new PagingFieldCollector(sort, queue, after, numHits, trackTotalHits);
+      return new PagingFieldCollector(sort, queue, after, numHits, totalHitsThreshold);
     }
   }
 

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/61e89e3c/lucene/core/src/java/org/apache/lucene/search/TopScoreDocCollector.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/search/TopScoreDocCollector.java b/lucene/core/src/java/org/apache/lucene/search/TopScoreDocCollector.java
index 839a626..f769f1a 100644
--- a/lucene/core/src/java/org/apache/lucene/search/TopScoreDocCollector.java
+++ b/lucene/core/src/java/org/apache/lucene/search/TopScoreDocCollector.java
@@ -20,7 +20,6 @@ package org.apache.lucene.search;
 import java.io.IOException;
 
 import org.apache.lucene.index.LeafReaderContext;
-import org.apache.lucene.search.TotalHits.Relation;
 
 /**
  * A {@link Collector} implementation that collects the top-scoring hits,
@@ -50,14 +49,11 @@ public abstract class TopScoreDocCollector extends TopDocsCollector<ScoreDoc> {
 
   private static class SimpleTopScoreDocCollector extends TopScoreDocCollector {
 
-    private final boolean trackTotalHits;
+    private final int totalHitsThreshold;
 
-    SimpleTopScoreDocCollector(int numHits, boolean trackTotalHits) {
+    SimpleTopScoreDocCollector(int numHits, int totalHitsThreshold) {
       super(numHits);
-      this.trackTotalHits = trackTotalHits;
-      if (trackTotalHits == false) {
-        totalHitsRelation = Relation.GREATER_THAN_OR_EQUAL_TO;
-      }
+      this.totalHitsThreshold = totalHitsThreshold;
     }
 
     @Override
@@ -66,15 +62,20 @@ public abstract class TopScoreDocCollector extends TopDocsCollector<ScoreDoc> {
       final int docBase = context.docBase;
       return new ScorerLeafCollector() {
 
+        private void updateMinCompetitiveScore() {
+          // since we tie-break on doc id and collect in doc id order, we can require
+          // the next float
+          scorer.setMinCompetitiveScore(Math.nextUp(pqTop.score));
+          totalHitsRelation = TotalHits.Relation.GREATER_THAN_OR_EQUAL_TO;
+        }
+
         @Override
         public void setScorer(Scorer scorer) throws IOException {
           super.setScorer(scorer);
-          if (trackTotalHits == false
+          if (totalHits >= totalHitsThreshold
               && pqTop != null
               && pqTop.score != Float.NEGATIVE_INFINITY) {
-            // since we tie-break on doc id and collect in doc id order, we can require
-            // the next float
-            scorer.setMinCompetitiveScore(Math.nextUp(pqTop.score));
+            updateMinCompetitiveScore();
           }
         }
 
@@ -87,6 +88,11 @@ public abstract class TopScoreDocCollector extends TopDocsCollector<ScoreDoc> {
 
           totalHits++;
           if (score <= pqTop.score) {
+            if (totalHitsRelation == TotalHits.Relation.EQUAL_TO && totalHits >= totalHitsThreshold) {
+              // we just reached totalHitsThreshold, we can start setting the min
+              // competitive score now
+              updateMinCompetitiveScore();
+            }
             // Since docs are returned in-order (i.e., increasing doc Id), a document
             // with equal score to pqTop.score cannot compete since HitQueue favors
             // documents with lower doc Ids. Therefore reject those docs too.
@@ -95,10 +101,8 @@ public abstract class TopScoreDocCollector extends TopDocsCollector<ScoreDoc> {
           pqTop.doc = doc + docBase;
           pqTop.score = score;
           pqTop = pq.updateTop();
-          if (trackTotalHits == false && pqTop.score != Float.NEGATIVE_INFINITY) { // -Infinity is the score of sentinels
-            // since we tie-break on doc id and collect in doc id order, we can require
-            // the next float
-            scorer.setMinCompetitiveScore(Math.nextUp(pqTop.score));
+          if (totalHits >= totalHitsThreshold && pqTop.score != Float.NEGATIVE_INFINITY) { // -Infinity is the score of sentinels
+            updateMinCompetitiveScore();
           }
         }
 
@@ -107,7 +111,7 @@ public abstract class TopScoreDocCollector extends TopDocsCollector<ScoreDoc> {
 
     @Override
     public ScoreMode scoreMode() {
-      return trackTotalHits ? ScoreMode.COMPLETE : ScoreMode.TOP_SCORES;
+      return totalHitsThreshold == Integer.MAX_VALUE ? ScoreMode.COMPLETE : ScoreMode.TOP_SCORES;
     }
   }
 
@@ -170,38 +174,51 @@ public abstract class TopScoreDocCollector extends TopDocsCollector<ScoreDoc> {
 
   /**
    * Creates a new {@link TopScoreDocCollector} given the number of hits to
-   * collect.
+   * collect and the number of hits to count accurately.
    *
+   * <p><b>NOTE</b>: If the total hit count of the top docs is less than
+   * {@code totalHitsThreshold} then this value is accurate. On the other hand,
+   * if the {@link TopDocs#totalHits} value is greater than or equal to
+   * {@code totalHitsThreshold} then its value is a lower bound of the hit
+   * count. A value of {@link Integer#MAX_VALUE} will make the hit count
+   * accurate but will also likely make query processing slower.
    * <p><b>NOTE</b>: The instances returned by this method
    * pre-allocate a full array of length
    * <code>numHits</code>, and fill the array with sentinel
    * objects.
    */
-  public static TopScoreDocCollector create(int numHits) {
-    return create(numHits, null, true);
+  public static TopScoreDocCollector create(int numHits, int totalHitsThreshold) {
+    return create(numHits, null, totalHitsThreshold);
   }
 
   /**
    * Creates a new {@link TopScoreDocCollector} given the number of hits to
-   * collect, the bottom of the previous page, and whether the total hit count
-   * is needed.
+   * collect, the bottom of the previous page, and the number of hits to count
+   * accurately.
    *
-   * <p><b>NOTE</b>: If {@code trackTotalHits} is {@code false} then the
-   * {@link TopDocs#totalHits} of the returned {@link TopDocs} will be an
-   * approximation and may be completely off.
+   * <p><b>NOTE</b>: If the total hit count of the top docs is less than
+   * {@code totalHitsThreshold} then this value is accurate. On the other hand,
+   * if the {@link TopDocs#totalHits} value is greater than or equal to
+   * {@code totalHitsThreshold} then its value is a lower bound of the hit
+   * count. A value of {@link Integer#MAX_VALUE} will make the hit count
+   * accurate but will also likely make query processing slower.
    * <p><b>NOTE</b>: The instances returned by this method
    * pre-allocate a full array of length
    * <code>numHits</code>, and fill the array with sentinel
    * objects.
    */
-  public static TopScoreDocCollector create(int numHits, ScoreDoc after, boolean trackTotalHits) {
+  public static TopScoreDocCollector create(int numHits, ScoreDoc after, int totalHitsThreshold) {
 
     if (numHits <= 0) {
       throw new IllegalArgumentException("numHits must be > 0; please use TotalHitCountCollector if you just need the total hit count");
     }
 
+    if (totalHitsThreshold <= 0) {
+      throw new IllegalArgumentException("totalHitsThreshold must be > 0, got " + totalHitsThreshold);
+    }
+
     if (after == null) {
-      return new SimpleTopScoreDocCollector(numHits, trackTotalHits);
+      return new SimpleTopScoreDocCollector(numHits, totalHitsThreshold);
     } else {
       return new PagingTopScoreDocCollector(numHits, after);
     }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/61e89e3c/lucene/core/src/test/org/apache/lucene/index/TestIndexSorting.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/test/org/apache/lucene/index/TestIndexSorting.java b/lucene/core/src/test/org/apache/lucene/index/TestIndexSorting.java
index 2eab9c6..9711a35 100644
--- a/lucene/core/src/test/org/apache/lucene/index/TestIndexSorting.java
+++ b/lucene/core/src/test/org/apache/lucene/index/TestIndexSorting.java
@@ -2324,11 +2324,11 @@ public class TestIndexSorting extends LuceneTestCase {
         System.out.println("TEST: iter=" + iter + " numHits=" + numHits);
       }
 
-      TopFieldCollector c1 = TopFieldCollector.create(sort, numHits, true);
+      TopFieldCollector c1 = TopFieldCollector.create(sort, numHits, Integer.MAX_VALUE);
       s1.search(new MatchAllDocsQuery(), c1);
       TopDocs hits1 = c1.topDocs();
 
-      TopFieldCollector c2 = TopFieldCollector.create(sort, numHits, false);
+      TopFieldCollector c2 = TopFieldCollector.create(sort, numHits, 1);
       s2.search(new MatchAllDocsQuery(), c2);
 
       TopDocs hits2 = c2.topDocs();

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/61e89e3c/lucene/core/src/test/org/apache/lucene/search/TestBoolean2.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/test/org/apache/lucene/search/TestBoolean2.java b/lucene/core/src/test/org/apache/lucene/search/TestBoolean2.java
index cb2d886..e15ba97 100644
--- a/lucene/core/src/test/org/apache/lucene/search/TestBoolean2.java
+++ b/lucene/core/src/test/org/apache/lucene/search/TestBoolean2.java
@@ -237,10 +237,10 @@ public class TestBoolean2 extends LuceneTestCase {
     // The asserting searcher will sometimes return the bulk scorer and
     // sometimes return a default impl around the scorer so that we can
     // compare BS1 and BS2
-    TopScoreDocCollector collector = TopScoreDocCollector.create(topDocsToCheck);
+    TopScoreDocCollector collector = TopScoreDocCollector.create(topDocsToCheck, Integer.MAX_VALUE);
     searcher.search(query, collector);
     ScoreDoc[] hits1 = collector.topDocs().scoreDocs;
-    collector = TopScoreDocCollector.create(topDocsToCheck);
+    collector = TopScoreDocCollector.create(topDocsToCheck, Integer.MAX_VALUE);
     searcher.search(query, collector);
     ScoreDoc[] hits2 = collector.topDocs().scoreDocs; 
 
@@ -248,7 +248,7 @@ public class TestBoolean2 extends LuceneTestCase {
 
     // Since we have no deleted docs, we should also be able to verify identical matches &
     // scores against an single segment copy of our index
-    collector = TopScoreDocCollector.create(topDocsToCheck);
+    collector = TopScoreDocCollector.create(topDocsToCheck, Integer.MAX_VALUE);
     singleSegmentSearcher.search(query, collector);
     hits2 = collector.topDocs().scoreDocs; 
     CheckHits.checkHitsQuery(query, hits1, hits2, expDocNrs);
@@ -258,10 +258,10 @@ public class TestBoolean2 extends LuceneTestCase {
                  bigSearcher.search(query, 1).totalHits.value);
 
     // now check 2 diff scorers from the bigSearcher as well
-    collector = TopScoreDocCollector.create(topDocsToCheck);
+    collector = TopScoreDocCollector.create(topDocsToCheck, Integer.MAX_VALUE);
     bigSearcher.search(query, collector);
     hits1 = collector.topDocs().scoreDocs;
-    collector = TopScoreDocCollector.create(topDocsToCheck);
+    collector = TopScoreDocCollector.create(topDocsToCheck, Integer.MAX_VALUE);
     bigSearcher.search(query, collector);
     hits2 = collector.topDocs().scoreDocs; 
 
@@ -386,10 +386,10 @@ public class TestBoolean2 extends LuceneTestCase {
         }
 
         // check diff (randomized) scorers (from AssertingSearcher) produce the same results
-        TopFieldCollector collector = TopFieldCollector.create(sort, 1000, false);
+        TopFieldCollector collector = TopFieldCollector.create(sort, 1000, 1);
         searcher.search(q1, collector);
         ScoreDoc[] hits1 = collector.topDocs().scoreDocs;
-        collector = TopFieldCollector.create(sort, 1000, false);
+        collector = TopFieldCollector.create(sort, 1000, 1);
         searcher.search(q1, collector);
         ScoreDoc[] hits2 = collector.topDocs().scoreDocs;
         tot+=hits2.length;
@@ -402,10 +402,10 @@ public class TestBoolean2 extends LuceneTestCase {
         assertEquals(mulFactor*collector.totalHits + NUM_EXTRA_DOCS/2, hits4.totalHits.value);
 
         // test diff (randomized) scorers produce the same results on bigSearcher as well
-        collector = TopFieldCollector.create(sort, 1000 * mulFactor, false);
+        collector = TopFieldCollector.create(sort, 1000 * mulFactor, 1);
         bigSearcher.search(q1, collector);
         hits1 = collector.topDocs().scoreDocs;
-        collector = TopFieldCollector.create(sort, 1000 * mulFactor, false);
+        collector = TopFieldCollector.create(sort, 1000 * mulFactor, 1);
         bigSearcher.search(q1, collector);
         hits2 = collector.topDocs().scoreDocs;
         CheckHits.checkEqual(q1, hits1, hits2);

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/61e89e3c/lucene/core/src/test/org/apache/lucene/search/TestBooleanMinShouldMatch.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/test/org/apache/lucene/search/TestBooleanMinShouldMatch.java b/lucene/core/src/test/org/apache/lucene/search/TestBooleanMinShouldMatch.java
index 643b45d..8d0ec05 100644
--- a/lucene/core/src/test/org/apache/lucene/search/TestBooleanMinShouldMatch.java
+++ b/lucene/core/src/test/org/apache/lucene/search/TestBooleanMinShouldMatch.java
@@ -91,7 +91,7 @@ public class TestBooleanMinShouldMatch extends LuceneTestCase {
         assertEquals("result count", expected, h.length);
         //System.out.println("TEST: now check");
         // bs2
-        TopScoreDocCollector collector = TopScoreDocCollector.create(1000);
+        TopScoreDocCollector collector = TopScoreDocCollector.create(1000, Integer.MAX_VALUE);
         s.search(q, collector);
         ScoreDoc[] h2 = collector.topDocs().scoreDocs;
         if (expected != h2.length) {

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/61e89e3c/lucene/core/src/test/org/apache/lucene/search/TestBooleanQuery.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/test/org/apache/lucene/search/TestBooleanQuery.java b/lucene/core/src/test/org/apache/lucene/search/TestBooleanQuery.java
index d07bb7e..37d5557 100644
--- a/lucene/core/src/test/org/apache/lucene/search/TestBooleanQuery.java
+++ b/lucene/core/src/test/org/apache/lucene/search/TestBooleanQuery.java
@@ -394,7 +394,7 @@ public class TestBooleanQuery extends LuceneTestCase {
     SpanQuery sq2 = new SpanTermQuery(new Term(FIELD, "clckwork"));
     query.add(sq1, BooleanClause.Occur.SHOULD);
     query.add(sq2, BooleanClause.Occur.SHOULD);
-    TopScoreDocCollector collector = TopScoreDocCollector.create(1000);
+    TopScoreDocCollector collector = TopScoreDocCollector.create(1000, Integer.MAX_VALUE);
     searcher.search(query.build(), collector);
     hits = collector.topDocs().scoreDocs.length;
     for (ScoreDoc scoreDoc : collector.topDocs().scoreDocs){

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/61e89e3c/lucene/core/src/test/org/apache/lucene/search/TestBooleanQueryVisitSubscorers.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/test/org/apache/lucene/search/TestBooleanQueryVisitSubscorers.java b/lucene/core/src/test/org/apache/lucene/search/TestBooleanQueryVisitSubscorers.java
index e28e090..b207264 100644
--- a/lucene/core/src/test/org/apache/lucene/search/TestBooleanQueryVisitSubscorers.java
+++ b/lucene/core/src/test/org/apache/lucene/search/TestBooleanQueryVisitSubscorers.java
@@ -141,7 +141,7 @@ public class TestBooleanQueryVisitSubscorers extends LuceneTestCase {
     private final Set<Scorer> tqsSet = new HashSet<>();
     
     MyCollector() {
-      super(TopScoreDocCollector.create(10));
+      super(TopScoreDocCollector.create(10, Integer.MAX_VALUE));
     }
 
     public LeafCollector getLeafCollector(LeafReaderContext context)

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/61e89e3c/lucene/core/src/test/org/apache/lucene/search/TestDisjunctionMaxQuery.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/test/org/apache/lucene/search/TestDisjunctionMaxQuery.java b/lucene/core/src/test/org/apache/lucene/search/TestDisjunctionMaxQuery.java
index 98f9426..2d72fc1 100644
--- a/lucene/core/src/test/org/apache/lucene/search/TestDisjunctionMaxQuery.java
+++ b/lucene/core/src/test/org/apache/lucene/search/TestDisjunctionMaxQuery.java
@@ -497,7 +497,7 @@ public class TestDisjunctionMaxQuery extends LuceneTestCase {
             new SpanTermQuery(new Term(FIELD, "clockwork")),
             new SpanTermQuery(new Term(FIELD, "clckwork"))),
         1.0f);
-    TopScoreDocCollector collector = TopScoreDocCollector.create(1000);
+    TopScoreDocCollector collector = TopScoreDocCollector.create(1000, Integer.MAX_VALUE);
     searcher.search(query, collector);
     hits = collector.topDocs().scoreDocs.length;
     for (ScoreDoc scoreDoc : collector.topDocs().scoreDocs){

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/61e89e3c/lucene/core/src/test/org/apache/lucene/search/TestElevationComparator.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/test/org/apache/lucene/search/TestElevationComparator.java b/lucene/core/src/test/org/apache/lucene/search/TestElevationComparator.java
index 337bb36..69d8679 100644
--- a/lucene/core/src/test/org/apache/lucene/search/TestElevationComparator.java
+++ b/lucene/core/src/test/org/apache/lucene/search/TestElevationComparator.java
@@ -86,7 +86,7 @@ public class TestElevationComparator extends LuceneTestCase {
         new SortField(null, SortField.Type.SCORE, reversed)
       );
 
-    TopDocsCollector<Entry> topCollector = TopFieldCollector.create(sort, 50, true);
+    TopDocsCollector<Entry> topCollector = TopFieldCollector.create(sort, 50, Integer.MAX_VALUE);
     searcher.search(newq.build(), topCollector);
 
     TopDocs topDocs = topCollector.topDocs(0, 10);

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/61e89e3c/lucene/core/src/test/org/apache/lucene/search/TestPhraseQuery.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/test/org/apache/lucene/search/TestPhraseQuery.java b/lucene/core/src/test/org/apache/lucene/search/TestPhraseQuery.java
index 9e58e7d..e25a159 100644
--- a/lucene/core/src/test/org/apache/lucene/search/TestPhraseQuery.java
+++ b/lucene/core/src/test/org/apache/lucene/search/TestPhraseQuery.java
@@ -748,10 +748,10 @@ public class TestPhraseQuery extends LuceneTestCase {
         new PhraseQuery("f", "d", "d")  // repeated term
         )) {
       for (int topN = 1; topN <= 2; ++topN) {
-        TopScoreDocCollector collector1 = TopScoreDocCollector.create(topN, null, true);
+        TopScoreDocCollector collector1 = TopScoreDocCollector.create(topN, null, Integer.MAX_VALUE);
         searcher.search(query, collector1);
         ScoreDoc[] hits1 = collector1.topDocs().scoreDocs;
-        TopScoreDocCollector collector2 = TopScoreDocCollector.create(topN, null, false);
+        TopScoreDocCollector collector2 = TopScoreDocCollector.create(topN, null, 1);
         searcher.search(query, collector2);
         ScoreDoc[] hits2 = collector2.topDocs().scoreDocs;
         assertTrue("" + query, hits1.length > 0);

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/61e89e3c/lucene/core/src/test/org/apache/lucene/search/TestPositiveScoresOnlyCollector.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/test/org/apache/lucene/search/TestPositiveScoresOnlyCollector.java b/lucene/core/src/test/org/apache/lucene/search/TestPositiveScoresOnlyCollector.java
index 5860e8f..2213b99 100644
--- a/lucene/core/src/test/org/apache/lucene/search/TestPositiveScoresOnlyCollector.java
+++ b/lucene/core/src/test/org/apache/lucene/search/TestPositiveScoresOnlyCollector.java
@@ -99,7 +99,7 @@ public class TestPositiveScoresOnlyCollector extends LuceneTestCase {
     IndexSearcher searcher = newSearcher(ir);
     Weight fake = new TermQuery(new Term("fake", "weight")).createWeight(searcher, ScoreMode.COMPLETE, 1f);
     Scorer s = new SimpleScorer(fake);
-    TopDocsCollector<ScoreDoc> tdc = TopScoreDocCollector.create(scores.length);
+    TopDocsCollector<ScoreDoc> tdc = TopScoreDocCollector.create(scores.length, Integer.MAX_VALUE);
     Collector c = new PositiveScoresOnlyCollector(tdc);
     LeafCollector ac = c.getLeafCollector(ir.leaves().get(0));
     ac.setScorer(s);

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/61e89e3c/lucene/core/src/test/org/apache/lucene/search/TestReqOptSumScorer.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/test/org/apache/lucene/search/TestReqOptSumScorer.java b/lucene/core/src/test/org/apache/lucene/search/TestReqOptSumScorer.java
index b831c02..f8fc6c2 100644
--- a/lucene/core/src/test/org/apache/lucene/search/TestReqOptSumScorer.java
+++ b/lucene/core/src/test/org/apache/lucene/search/TestReqOptSumScorer.java
@@ -135,7 +135,7 @@ public class TestReqOptSumScorer extends LuceneTestCase {
         .add(shouldTerm, Occur.SHOULD)
         .build();
 
-    TopScoreDocCollector coll = TopScoreDocCollector.create(10, null, true);
+    TopScoreDocCollector coll = TopScoreDocCollector.create(10, null, Integer.MAX_VALUE);
     searcher.search(query, coll);
     ScoreDoc[] expected = coll.topDocs().scoreDocs;
 
@@ -146,7 +146,7 @@ public class TestReqOptSumScorer extends LuceneTestCase {
         .add(new TermQuery(new Term("f", "C")), Occur.FILTER)
         .build();
 
-    coll = TopScoreDocCollector.create(10, null, true);
+    coll = TopScoreDocCollector.create(10, null, Integer.MAX_VALUE);
     searcher.search(query, coll);
     ScoreDoc[] expectedFiltered = coll.topDocs().scoreDocs;
 
@@ -165,7 +165,7 @@ public class TestReqOptSumScorer extends LuceneTestCase {
           .add(should, Occur.SHOULD)
           .build();
 
-      coll = TopScoreDocCollector.create(10, null, false);
+      coll = TopScoreDocCollector.create(10, null, 1);
       searcher.search(query, coll);
       ScoreDoc[] actual = coll.topDocs().scoreDocs;
 
@@ -176,7 +176,7 @@ public class TestReqOptSumScorer extends LuceneTestCase {
           .add(new RandomApproximationQuery(new TermQuery(new Term("f", "C")), random()), Occur.FILTER)
           .build();
 
-      coll = TopScoreDocCollector.create(10, null, false);
+      coll = TopScoreDocCollector.create(10, null, 1);
       searcher.search(query, coll);
       ScoreDoc[] actualFiltered = coll.topDocs().scoreDocs;
 

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/61e89e3c/lucene/core/src/test/org/apache/lucene/search/TestSubScorerFreqs.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/test/org/apache/lucene/search/TestSubScorerFreqs.java b/lucene/core/src/test/org/apache/lucene/search/TestSubScorerFreqs.java
index 699f8b9..b49793e 100644
--- a/lucene/core/src/test/org/apache/lucene/search/TestSubScorerFreqs.java
+++ b/lucene/core/src/test/org/apache/lucene/search/TestSubScorerFreqs.java
@@ -135,7 +135,7 @@ public class TestSubScorerFreqs extends LuceneTestCase {
   @Test
   public void testTermQuery() throws Exception {
     TermQuery q = new TermQuery(new Term("f", "d"));
-    CountingCollector c = new CountingCollector(TopScoreDocCollector.create(10));
+    CountingCollector c = new CountingCollector(TopScoreDocCollector.create(10, Integer.MAX_VALUE));
     s.search(q, c);
     final int maxDocs = s.getIndexReader().maxDoc();
     assertEquals(maxDocs, c.docCounts.size());
@@ -175,7 +175,7 @@ public class TestSubScorerFreqs extends LuceneTestCase {
     
     for (final Set<String> occur : occurList) {
       CountingCollector c = new CountingCollector(TopScoreDocCollector.create(
-          10), occur);
+          10, Integer.MAX_VALUE), occur);
       s.search(query.build(), c);
       final int maxDocs = s.getIndexReader().maxDoc();
       assertEquals(maxDocs, c.docCounts.size());
@@ -205,7 +205,7 @@ public class TestSubScorerFreqs extends LuceneTestCase {
   @Test
   public void testPhraseQuery() throws Exception {
     PhraseQuery q = new PhraseQuery("f", "b", "c");
-    CountingCollector c = new CountingCollector(TopScoreDocCollector.create(10));
+    CountingCollector c = new CountingCollector(TopScoreDocCollector.create(10, Integer.MAX_VALUE));
     s.search(q, c);
     final int maxDocs = s.getIndexReader().maxDoc();
     assertEquals(maxDocs, c.docCounts.size());

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/61e89e3c/lucene/core/src/test/org/apache/lucene/search/TestSynonymQuery.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/test/org/apache/lucene/search/TestSynonymQuery.java b/lucene/core/src/test/org/apache/lucene/search/TestSynonymQuery.java
index 6165a1f..1768254 100644
--- a/lucene/core/src/test/org/apache/lucene/search/TestSynonymQuery.java
+++ b/lucene/core/src/test/org/apache/lucene/search/TestSynonymQuery.java
@@ -66,11 +66,11 @@ public class TestSynonymQuery extends LuceneTestCase {
   }
 
   public void testScores() throws IOException {
-    doTestScores(false);
-    doTestScores(true);
+    doTestScores(2);
+    doTestScores(Integer.MAX_VALUE);
   }
 
-  private void doTestScores(boolean trackTotalHits) throws IOException {
+  private void doTestScores(int totalHitsThreshold) throws IOException {
     Directory dir = newDirectory();
     RandomIndexWriter w = new RandomIndexWriter(random(), dir);
 
@@ -88,11 +88,14 @@ public class TestSynonymQuery extends LuceneTestCase {
     IndexSearcher searcher = newSearcher(reader);
     SynonymQuery query = new SynonymQuery(new Term("f", "a"), new Term("f", "b"));
 
-    TopScoreDocCollector collector = TopScoreDocCollector.create(20, null, trackTotalHits);
+    TopScoreDocCollector collector = TopScoreDocCollector.create(Math.min(reader.numDocs(), totalHitsThreshold), null, totalHitsThreshold);
     searcher.search(query, collector);
     TopDocs topDocs = collector.topDocs();
-    if (trackTotalHits) {
+    if (topDocs.totalHits.value < totalHitsThreshold) {
+      assertEquals(TotalHits.Relation.EQUAL_TO, topDocs.totalHits.relation);
       assertEquals(11, topDocs.totalHits.value);
+    } else {
+      assertEquals(TotalHits.Relation.GREATER_THAN_OR_EQUAL_TO, topDocs.totalHits.relation);
     }
     // All docs must have the same score
     for (int i = 0; i < topDocs.scoreDocs.length; ++i) {
@@ -284,8 +287,8 @@ public class TestSynonymQuery extends LuceneTestCase {
               new Term("foo", Integer.toString(term1)),
               new Term("foo", Integer.toString(term2))});
 
-      TopScoreDocCollector collector1 = TopScoreDocCollector.create(10, null, true); // COMPLETE
-      TopScoreDocCollector collector2 = TopScoreDocCollector.create(10, null, false); // TOP_SCORES
+      TopScoreDocCollector collector1 = TopScoreDocCollector.create(10, null, Integer.MAX_VALUE); // COMPLETE
+      TopScoreDocCollector collector2 = TopScoreDocCollector.create(10, null, 1); // TOP_SCORES
 
       searcher.search(query, collector1);
       searcher.search(query, collector2);
@@ -297,8 +300,8 @@ public class TestSynonymQuery extends LuceneTestCase {
           .add(new TermQuery(new Term("foo", Integer.toString(filterTerm))), Occur.FILTER)
           .build();
 
-      collector1 = TopScoreDocCollector.create(10, null, true); // COMPLETE
-      collector2 = TopScoreDocCollector.create(10, null, false); // TOP_SCORES
+      collector1 = TopScoreDocCollector.create(10, null, Integer.MAX_VALUE); // COMPLETE
+      collector2 = TopScoreDocCollector.create(10, null, 1); // TOP_SCORES
       searcher.search(filteredQuery, collector1);
       searcher.search(filteredQuery, collector2);
       CheckHits.checkEqual(query, collector1.topDocs().scoreDocs, collector2.topDocs().scoreDocs);

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/61e89e3c/lucene/core/src/test/org/apache/lucene/search/TestTermScorer.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/test/org/apache/lucene/search/TestTermScorer.java b/lucene/core/src/test/org/apache/lucene/search/TestTermScorer.java
index b98ae41..f05935c 100644
--- a/lucene/core/src/test/org/apache/lucene/search/TestTermScorer.java
+++ b/lucene/core/src/test/org/apache/lucene/search/TestTermScorer.java
@@ -233,8 +233,8 @@ public class TestTermScorer extends LuceneTestCase {
     for (int iter = 0; iter < 15; ++iter) {
       Query query = new TermQuery(new Term("foo", Integer.toString(iter)));
 
-      TopScoreDocCollector collector1 = TopScoreDocCollector.create(10, null, true); // COMPLETE
-      TopScoreDocCollector collector2 = TopScoreDocCollector.create(10, null, false); // TOP_SCORES
+      TopScoreDocCollector collector1 = TopScoreDocCollector.create(10, null, Integer.MAX_VALUE); // COMPLETE
+      TopScoreDocCollector collector2 = TopScoreDocCollector.create(10, null, 1); // TOP_SCORES
       
       searcher.search(query, collector1);
       searcher.search(query, collector2);
@@ -246,8 +246,8 @@ public class TestTermScorer extends LuceneTestCase {
           .add(new TermQuery(new Term("foo", Integer.toString(filterTerm))), Occur.FILTER)
           .build();
 
-      collector1 = TopScoreDocCollector.create(10, null, true); // COMPLETE
-      collector2 = TopScoreDocCollector.create(10, null, false); // TOP_SCORES
+      collector1 = TopScoreDocCollector.create(10, null, Integer.MAX_VALUE); // COMPLETE
+      collector2 = TopScoreDocCollector.create(10, null, 1); // TOP_SCORES
       searcher.search(filteredQuery, collector1);
       searcher.search(filteredQuery, collector2);
       CheckHits.checkEqual(query, collector1.topDocs().scoreDocs, collector2.topDocs().scoreDocs);

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/61e89e3c/lucene/core/src/test/org/apache/lucene/search/TestTopDocsCollector.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/test/org/apache/lucene/search/TestTopDocsCollector.java b/lucene/core/src/test/org/apache/lucene/search/TestTopDocsCollector.java
index 8311465..9701199 100644
--- a/lucene/core/src/test/org/apache/lucene/search/TestTopDocsCollector.java
+++ b/lucene/core/src/test/org/apache/lucene/search/TestTopDocsCollector.java
@@ -239,7 +239,7 @@ public class TestTopDocsCollector extends LuceneTestCase {
     assertEquals(2, reader.leaves().size());
     w.close();
 
-    TopScoreDocCollector collector = TopScoreDocCollector.create(2, null, false);
+    TopScoreDocCollector collector = TopScoreDocCollector.create(2, null, 1);
     FakeScorer scorer = new FakeScorer();
 
     LeafCollector leafCollector = collector.getLeafCollector(reader.leaves().get(0));
@@ -288,7 +288,7 @@ public class TestTopDocsCollector extends LuceneTestCase {
     dir.close();
   }
 
-  public void testNotTrackTotalHits() throws Exception {
+  public void testTotalHits() throws Exception {
     Directory dir = newDirectory();
     IndexWriter w = new IndexWriter(dir, newIndexWriterConfig().setMergePolicy(NoMergePolicy.INSTANCE));
     Document doc = new Document();
@@ -300,31 +300,37 @@ public class TestTopDocsCollector extends LuceneTestCase {
     assertEquals(2, reader.leaves().size());
     w.close();
 
-    TopScoreDocCollector collector = TopScoreDocCollector.create(2, null, false);
-    FakeScorer scorer = new FakeScorer();
+    for (int totalHitsThreshold = 1; totalHitsThreshold < 20; ++ totalHitsThreshold) {
+      TopScoreDocCollector collector = TopScoreDocCollector.create(2, null, totalHitsThreshold);
+      FakeScorer scorer = new FakeScorer();
 
-    LeafCollector leafCollector = collector.getLeafCollector(reader.leaves().get(0));
-    leafCollector.setScorer(scorer);
+      LeafCollector leafCollector = collector.getLeafCollector(reader.leaves().get(0));
+      leafCollector.setScorer(scorer);
 
-    scorer.doc = 0;
-    scorer.score = 3;
-    leafCollector.collect(0);
+      scorer.doc = 0;
+      scorer.score = 3;
+      leafCollector.collect(0);
 
-    scorer.doc = 1;
-    scorer.score = 3;
-    leafCollector.collect(1);
+      scorer.doc = 1;
+      scorer.score = 3;
+      leafCollector.collect(1);
 
-    leafCollector = collector.getLeafCollector(reader.leaves().get(1));
-    leafCollector.setScorer(scorer);
+      leafCollector = collector.getLeafCollector(reader.leaves().get(1));
+      leafCollector.setScorer(scorer);
 
-    scorer.doc = 1;
-    scorer.score = 3;
-    leafCollector.collect(1);
+      scorer.doc = 1;
+      scorer.score = 3;
+      leafCollector.collect(1);
 
-    TopDocs topDocs = collector.topDocs();
-    // It assumes all docs matched since numHits was 2 and the first 2 collected docs matched
-    assertEquals(3, topDocs.totalHits.value);
-    assertEquals(TotalHits.Relation.GREATER_THAN_OR_EQUAL_TO, topDocs.totalHits.relation);
+      scorer.doc = 5;
+      scorer.score = 4;
+      leafCollector.collect(1);
+
+      TopDocs topDocs = collector.topDocs();
+      assertEquals(4, topDocs.totalHits.value);
+      assertEquals(totalHitsThreshold <= 4, scorer.minCompetitiveScore != null);
+      assertEquals(totalHitsThreshold <= 4 ? TotalHits.Relation.GREATER_THAN_OR_EQUAL_TO : TotalHits.Relation.EQUAL_TO, topDocs.totalHits.relation);
+    }
 
     reader.close();
     dir.close();

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/61e89e3c/lucene/core/src/test/org/apache/lucene/search/TestTopDocsMerge.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/test/org/apache/lucene/search/TestTopDocsMerge.java b/lucene/core/src/test/org/apache/lucene/search/TestTopDocsMerge.java
index 36f5275..bf92642 100644
--- a/lucene/core/src/test/org/apache/lucene/search/TestTopDocsMerge.java
+++ b/lucene/core/src/test/org/apache/lucene/search/TestTopDocsMerge.java
@@ -57,7 +57,7 @@ public class TestTopDocsMerge extends LuceneTestCase {
     }
 
     public TopDocs search(Weight weight, int topN) throws IOException {
-      TopScoreDocCollector collector = TopScoreDocCollector.create(topN);
+      TopScoreDocCollector collector = TopScoreDocCollector.create(topN, Integer.MAX_VALUE);
       search(ctx, weight, collector);
       return collector.topDocs();    }
 
@@ -262,7 +262,7 @@ public class TestTopDocsMerge extends LuceneTestCase {
       final TopDocs topHits;
       if (sort == null) {
         if (useFrom) {
-          TopScoreDocCollector c = TopScoreDocCollector.create(numHits);
+          TopScoreDocCollector c = TopScoreDocCollector.create(numHits, Integer.MAX_VALUE);
           searcher.search(query, c);
           from = TestUtil.nextInt(random(), 0, numHits - 1);
           size = numHits - from;
@@ -281,7 +281,7 @@ public class TestTopDocsMerge extends LuceneTestCase {
           topHits = searcher.search(query, numHits);
         }
       } else {
-        final TopFieldCollector c = TopFieldCollector.create(sort, numHits, true);
+        final TopFieldCollector c = TopFieldCollector.create(sort, numHits, Integer.MAX_VALUE);
         searcher.search(query, c);
         if (useFrom) {
           from = TestUtil.nextInt(random(), 0, numHits - 1);
@@ -330,7 +330,7 @@ public class TestTopDocsMerge extends LuceneTestCase {
         if (sort == null) {
           subHits = subSearcher.search(w, numHits);
         } else {
-          final TopFieldCollector c = TopFieldCollector.create(sort, numHits, true);
+          final TopFieldCollector c = TopFieldCollector.create(sort, numHits, Integer.MAX_VALUE);
           subSearcher.search(w, c);
           subHits = c.topDocs(0, numHits);
         }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/61e89e3c/lucene/core/src/test/org/apache/lucene/search/TestTopFieldCollector.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/test/org/apache/lucene/search/TestTopFieldCollector.java b/lucene/core/src/test/org/apache/lucene/search/TestTopFieldCollector.java
index edcb2d6..2962a2e 100644
--- a/lucene/core/src/test/org/apache/lucene/search/TestTopFieldCollector.java
+++ b/lucene/core/src/test/org/apache/lucene/search/TestTopFieldCollector.java
@@ -26,8 +26,11 @@ import org.apache.lucene.document.Field.Store;
 import org.apache.lucene.document.NumericDocValuesField;
 import org.apache.lucene.document.StringField;
 import org.apache.lucene.document.TextField;
+import org.apache.lucene.index.DirectoryReader;
 import org.apache.lucene.index.IndexReader;
+import org.apache.lucene.index.IndexWriter;
 import org.apache.lucene.index.LeafReaderContext;
+import org.apache.lucene.index.NoMergePolicy;
 import org.apache.lucene.index.RandomIndexWriter;
 import org.apache.lucene.index.Term;
 import org.apache.lucene.search.BooleanClause.Occur;
@@ -73,7 +76,7 @@ public class TestTopFieldCollector extends LuceneTestCase {
     Sort[] sort = new Sort[] { new Sort(SortField.FIELD_DOC), new Sort() };
     for(int i = 0; i < sort.length; i++) {
       Query q = new MatchAllDocsQuery();
-      TopDocsCollector<Entry> tdc = TopFieldCollector.create(sort[i], 10, true);
+      TopDocsCollector<Entry> tdc = TopFieldCollector.create(sort[i], 10, Integer.MAX_VALUE);
       
       is.search(q, tdc);
       
@@ -91,7 +94,7 @@ public class TestTopFieldCollector extends LuceneTestCase {
     Sort[] sort = new Sort[] {new Sort(SortField.FIELD_DOC), new Sort() };
     for(int i = 0; i < sort.length; i++) {
       Query q = new MatchAllDocsQuery();
-      TopDocsCollector<Entry> tdc = TopFieldCollector.create(sort[i], 10, true);
+      TopDocsCollector<Entry> tdc = TopFieldCollector.create(sort[i], 10, Integer.MAX_VALUE);
       
       is.search(q, tdc);
       
@@ -111,10 +114,10 @@ public class TestTopFieldCollector extends LuceneTestCase {
       // the index is not sorted
       TopDocsCollector<Entry> tdc;
       if (i % 2 == 0) {
-        tdc =  TopFieldCollector.create(sort, 10, false);
+        tdc =  TopFieldCollector.create(sort, 10, 1);
       } else {
         FieldDoc fieldDoc = new FieldDoc(1, Float.NaN, new Object[] { 1 });
-        tdc = TopFieldCollector.create(sort, 10, fieldDoc, false);
+        tdc = TopFieldCollector.create(sort, 10, fieldDoc, 1);
       }
 
       is.search(q, tdc);
@@ -127,12 +130,81 @@ public class TestTopFieldCollector extends LuceneTestCase {
     }
   }
 
+  public void testTotalHits() throws Exception {
+    Directory dir = newDirectory();
+    Sort sort = new Sort(new SortField("foo", SortField.Type.LONG));
+    IndexWriter w = new IndexWriter(dir, newIndexWriterConfig()
+        .setMergePolicy(NoMergePolicy.INSTANCE)
+        .setIndexSort(sort));
+    Document doc = new Document();
+    doc.add(new NumericDocValuesField("foo", 3));
+    w.addDocuments(Arrays.asList(doc, doc, doc, doc));
+    w.flush();
+    w.addDocuments(Arrays.asList(doc, doc, doc, doc, doc, doc));
+    w.flush();
+    IndexReader reader = DirectoryReader.open(w);
+    assertEquals(2, reader.leaves().size());
+    w.close();
+
+    for (int totalHitsThreshold = 1; totalHitsThreshold < 20; ++ totalHitsThreshold) {
+      for (FieldDoc after : new FieldDoc[] { null, new FieldDoc(4, Float.NaN, new Object[] { 2L })}) {
+        TopFieldCollector collector = TopFieldCollector.create(sort, 2, after, totalHitsThreshold);
+        FakeScorer scorer = new FakeScorer();
+
+        LeafCollector leafCollector1 = collector.getLeafCollector(reader.leaves().get(0));
+        leafCollector1.setScorer(scorer);
+
+        scorer.doc = 0;
+        scorer.score = 3;
+        leafCollector1.collect(0);
+
+        scorer.doc = 1;
+        scorer.score = 3;
+        leafCollector1.collect(1);
+
+        LeafCollector leafCollector2 = collector.getLeafCollector(reader.leaves().get(1));
+        leafCollector2.setScorer(scorer);
+
+        scorer.doc = 1;
+        scorer.score = 3;
+        if (totalHitsThreshold < 4) {
+          expectThrows(CollectionTerminatedException.class, () -> leafCollector2.collect(1));
+          TopDocs topDocs = collector.topDocs();
+          assertEquals(TotalHits.Relation.GREATER_THAN_OR_EQUAL_TO, topDocs.totalHits.relation);
+          assertEquals(3, topDocs.totalHits.value);
+          continue;
+        } else {
+          leafCollector2.collect(1);
+        }
+
+        scorer.doc = 5;
+        scorer.score = 4;
+        if (totalHitsThreshold == 4) {
+          expectThrows(CollectionTerminatedException.class, () -> leafCollector2.collect(1));
+          TopDocs topDocs = collector.topDocs();
+          assertEquals(TotalHits.Relation.GREATER_THAN_OR_EQUAL_TO, topDocs.totalHits.relation);
+          assertEquals(4, topDocs.totalHits.value);
+          continue;
+        } else {
+          leafCollector2.collect(1);
+        }
+
+        TopDocs topDocs = collector.topDocs();
+        assertEquals(TotalHits.Relation.EQUAL_TO, topDocs.totalHits.relation);
+        assertEquals(4, topDocs.totalHits.value);
+      }
+    }
+
+    reader.close();
+    dir.close();
+  }
+
   public void testSortNoResults() throws Exception {
     
     // Two Sort criteria to instantiate the multi/single comparators.
     Sort[] sort = new Sort[] {new Sort(SortField.FIELD_DOC), new Sort() };
     for(int i = 0; i < sort.length; i++) {
-      TopDocsCollector<Entry> tdc = TopFieldCollector.create(sort[i], 10, true);
+      TopDocsCollector<Entry> tdc = TopFieldCollector.create(sort[i], 10, Integer.MAX_VALUE);
       TopDocs td = tdc.topDocs();
       assertEquals(0, td.totalHits.value);
     }
@@ -164,7 +236,7 @@ public class TestTopFieldCollector extends LuceneTestCase {
         .build();
     final IndexSearcher searcher = new IndexSearcher(reader);
     for (Sort sort : new Sort[] {new Sort(SortField.FIELD_SCORE), new Sort(new SortField("f", SortField.Type.SCORE))}) {
-      final TopFieldCollector topCollector = TopFieldCollector.create(sort, TestUtil.nextInt(random(), 1, 2), true);
+      final TopFieldCollector topCollector = TopFieldCollector.create(sort, TestUtil.nextInt(random(), 1, 2), Integer.MAX_VALUE);
       final Collector assertingCollector = new Collector() {
         @Override
         public LeafCollector getLeafCollector(LeafReaderContext context) throws IOException {

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/61e89e3c/lucene/core/src/test/org/apache/lucene/search/TestTopFieldCollectorEarlyTermination.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/test/org/apache/lucene/search/TestTopFieldCollectorEarlyTermination.java b/lucene/core/src/test/org/apache/lucene/search/TestTopFieldCollectorEarlyTermination.java
index c82f268..b6d33da 100644
--- a/lucene/core/src/test/org/apache/lucene/search/TestTopFieldCollectorEarlyTermination.java
+++ b/lucene/core/src/test/org/apache/lucene/search/TestTopFieldCollectorEarlyTermination.java
@@ -136,8 +136,8 @@ public class TestTopFieldCollectorEarlyTermination extends LuceneTestCase {
         } else {
           after = null;
         }
-        final TopFieldCollector collector1 = TopFieldCollector.create(sort, numHits, after, true);
-        final TopFieldCollector collector2 = TopFieldCollector.create(sort, numHits, after, false);
+        final TopFieldCollector collector1 = TopFieldCollector.create(sort, numHits, after, Integer.MAX_VALUE);
+        final TopFieldCollector collector2 = TopFieldCollector.create(sort, numHits, after, 1);
 
         final Query query;
         if (random().nextBoolean()) {

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/61e89e3c/lucene/facet/src/java/org/apache/lucene/facet/DrillSideways.java
----------------------------------------------------------------------
diff --git a/lucene/facet/src/java/org/apache/lucene/facet/DrillSideways.java b/lucene/facet/src/java/org/apache/lucene/facet/DrillSideways.java
index a2631c3..15df7e3 100644
--- a/lucene/facet/src/java/org/apache/lucene/facet/DrillSideways.java
+++ b/lucene/facet/src/java/org/apache/lucene/facet/DrillSideways.java
@@ -241,7 +241,7 @@ public class DrillSideways {
 
                   @Override
                   public TopFieldCollector newCollector() throws IOException {
-                    return TopFieldCollector.create(sort, fTopN, after, true);
+                    return TopFieldCollector.create(sort, fTopN, after, Integer.MAX_VALUE);
                   }
 
                   @Override
@@ -264,7 +264,7 @@ public class DrillSideways {
       } else {
 
         final TopFieldCollector hitCollector =
-                TopFieldCollector.create(sort, fTopN, after, true);
+                TopFieldCollector.create(sort, fTopN, after, Integer.MAX_VALUE);
         DrillSidewaysResult r = search(query, hitCollector);
         TopFieldDocs topDocs = hitCollector.topDocs();
         if (doDocScores) {
@@ -303,7 +303,7 @@ public class DrillSideways {
 
                 @Override
                 public TopScoreDocCollector newCollector() throws IOException {
-                  return TopScoreDocCollector.create(fTopN, after, true);
+                  return TopScoreDocCollector.create(fTopN, after, Integer.MAX_VALUE);
                 }
 
                 @Override
@@ -321,7 +321,7 @@ public class DrillSideways {
 
     } else {
 
-      TopScoreDocCollector hitCollector = TopScoreDocCollector.create(topN, after, true);
+      TopScoreDocCollector hitCollector = TopScoreDocCollector.create(topN, after, Integer.MAX_VALUE);
       DrillSidewaysResult r = search(query, hitCollector);
       return new DrillSidewaysResult(r.facets, hitCollector.topDocs());
     }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/61e89e3c/lucene/facet/src/java/org/apache/lucene/facet/FacetsCollector.java
----------------------------------------------------------------------
diff --git a/lucene/facet/src/java/org/apache/lucene/facet/FacetsCollector.java b/lucene/facet/src/java/org/apache/lucene/facet/FacetsCollector.java
index 095fd4f..f06527e 100644
--- a/lucene/facet/src/java/org/apache/lucene/facet/FacetsCollector.java
+++ b/lucene/facet/src/java/org/apache/lucene/facet/FacetsCollector.java
@@ -231,9 +231,9 @@ public class FacetsCollector extends SimpleCollector implements Collector {
         }
         hitsCollector = TopFieldCollector.create(sort, n,
                                                  (FieldDoc) after,
-                                                 true); // TODO: can we disable exact hit counts
+                                                 Integer.MAX_VALUE); // TODO: can we disable exact hit counts
       } else {
-        hitsCollector = TopScoreDocCollector.create(n, after, true);
+        hitsCollector = TopScoreDocCollector.create(n, after, Integer.MAX_VALUE);
       }
       searcher.search(q, MultiCollector.wrap(hitsCollector, fc));
     

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/61e89e3c/lucene/grouping/src/java/org/apache/lucene/search/grouping/BlockGroupingCollector.java
----------------------------------------------------------------------
diff --git a/lucene/grouping/src/java/org/apache/lucene/search/grouping/BlockGroupingCollector.java b/lucene/grouping/src/java/org/apache/lucene/search/grouping/BlockGroupingCollector.java
index 58f2232..886ce63 100644
--- a/lucene/grouping/src/java/org/apache/lucene/search/grouping/BlockGroupingCollector.java
+++ b/lucene/grouping/src/java/org/apache/lucene/search/grouping/BlockGroupingCollector.java
@@ -302,10 +302,10 @@ public class BlockGroupingCollector extends SimpleCollector {
         if (!needsScores) {
           throw new IllegalArgumentException("cannot sort by relevance within group: needsScores=false");
         }
-        collector = TopScoreDocCollector.create(maxDocsPerGroup);
+        collector = TopScoreDocCollector.create(maxDocsPerGroup, Integer.MAX_VALUE);
       } else {
         // Sort by fields
-        collector = TopFieldCollector.create(withinGroupSort, maxDocsPerGroup, true); // TODO: disable exact counts?
+        collector = TopFieldCollector.create(withinGroupSort, maxDocsPerGroup, Integer.MAX_VALUE); // TODO: disable exact counts?
       }
 
       float groupMaxScore = needsScores ? Float.NEGATIVE_INFINITY : Float.NaN;

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/61e89e3c/lucene/grouping/src/java/org/apache/lucene/search/grouping/TopGroupsCollector.java
----------------------------------------------------------------------
diff --git a/lucene/grouping/src/java/org/apache/lucene/search/grouping/TopGroupsCollector.java b/lucene/grouping/src/java/org/apache/lucene/search/grouping/TopGroupsCollector.java
index 16dcebb..b2aa9e4 100644
--- a/lucene/grouping/src/java/org/apache/lucene/search/grouping/TopGroupsCollector.java
+++ b/lucene/grouping/src/java/org/apache/lucene/search/grouping/TopGroupsCollector.java
@@ -116,10 +116,10 @@ public class TopGroupsCollector<T> extends SecondPassGroupingCollector<T> {
                    int maxDocsPerGroup, boolean getMaxScores) {
       this.needsScores = getMaxScores || withinGroupSort.needsScores();
       if (withinGroupSort == Sort.RELEVANCE) {
-        supplier = () -> new TopDocsAndMaxScoreCollector(true, TopScoreDocCollector.create(maxDocsPerGroup), null);
+        supplier = () -> new TopDocsAndMaxScoreCollector(true, TopScoreDocCollector.create(maxDocsPerGroup, Integer.MAX_VALUE), null);
       } else {
         supplier = () -> {
-          TopFieldCollector topDocsCollector = TopFieldCollector.create(withinGroupSort, maxDocsPerGroup, true); // TODO: disable exact counts?
+          TopFieldCollector topDocsCollector = TopFieldCollector.create(withinGroupSort, maxDocsPerGroup, Integer.MAX_VALUE); // TODO: disable exact counts?
           MaxScoreCollector maxScoreCollector = getMaxScores ? new MaxScoreCollector() : null;
           return new TopDocsAndMaxScoreCollector(false, topDocsCollector, maxScoreCollector);
         };

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/61e89e3c/lucene/join/src/test/org/apache/lucene/search/join/TestJoinUtil.java
----------------------------------------------------------------------
diff --git a/lucene/join/src/test/org/apache/lucene/search/join/TestJoinUtil.java b/lucene/join/src/test/org/apache/lucene/search/join/TestJoinUtil.java
index 123e998..39e818e 100644
--- a/lucene/join/src/test/org/apache/lucene/search/join/TestJoinUtil.java
+++ b/lucene/join/src/test/org/apache/lucene/search/join/TestJoinUtil.java
@@ -424,7 +424,7 @@ public class TestJoinUtil extends LuceneTestCase {
       }
 
       final BitSet actualResult = new FixedBitSet(indexSearcher.getIndexReader().maxDoc());
-      final TopScoreDocCollector topScoreDocCollector = TopScoreDocCollector.create(10);
+      final TopScoreDocCollector topScoreDocCollector = TopScoreDocCollector.create(10, Integer.MAX_VALUE);
       indexSearcher.search(joinQuery, MultiCollector.wrap(new BitSetCollector(actualResult), topScoreDocCollector));
       assertBitSet(expectedResult, actualResult, indexSearcher);
       TopDocs expectedTopDocs = createExpectedTopDocs(randomValue, from, scoreMode, context);
@@ -1245,7 +1245,7 @@ public class TestJoinUtil extends LuceneTestCase {
 
         // Need to know all documents that have matches. TopDocs doesn't give me that and then I'd be also testing TopDocsCollector...
         final BitSet actualResult = new FixedBitSet(indexSearcher.getIndexReader().maxDoc());
-        final TopScoreDocCollector topScoreDocCollector = TopScoreDocCollector.create(10);
+        final TopScoreDocCollector topScoreDocCollector = TopScoreDocCollector.create(10, Integer.MAX_VALUE);
         indexSearcher.search(joinQuery, MultiCollector.wrap(new BitSetCollector(actualResult), topScoreDocCollector));
         // Asserting bit set...
         assertBitSet(expectedResult, actualResult, indexSearcher);

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/61e89e3c/lucene/suggest/src/java/org/apache/lucene/search/suggest/analyzing/AnalyzingInfixSuggester.java
----------------------------------------------------------------------
diff --git a/lucene/suggest/src/java/org/apache/lucene/search/suggest/analyzing/AnalyzingInfixSuggester.java b/lucene/suggest/src/java/org/apache/lucene/search/suggest/analyzing/AnalyzingInfixSuggester.java
index 07180e3..a8394e0 100644
--- a/lucene/suggest/src/java/org/apache/lucene/search/suggest/analyzing/AnalyzingInfixSuggester.java
+++ b/lucene/suggest/src/java/org/apache/lucene/search/suggest/analyzing/AnalyzingInfixSuggester.java
@@ -647,7 +647,7 @@ public class AnalyzingInfixSuggester extends Lookup implements Closeable {
     //System.out.println("finalQuery=" + finalQuery);
 
     // Sort by weight, descending:
-    TopFieldCollector c = TopFieldCollector.create(SORT, num, false);
+    TopFieldCollector c = TopFieldCollector.create(SORT, num, 1);
     List<LookupResult> results = null;
     SearcherManager mgr;
     IndexSearcher searcher;

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/61e89e3c/lucene/test-framework/src/java/org/apache/lucene/search/CheckHits.java
----------------------------------------------------------------------
diff --git a/lucene/test-framework/src/java/org/apache/lucene/search/CheckHits.java b/lucene/test-framework/src/java/org/apache/lucene/search/CheckHits.java
index 784d3bb..a64ce99 100644
--- a/lucene/test-framework/src/java/org/apache/lucene/search/CheckHits.java
+++ b/lucene/test-framework/src/java/org/apache/lucene/search/CheckHits.java
@@ -583,8 +583,8 @@ public class CheckHits {
   }
 
   private static void doCheckTopScores(Query query, IndexSearcher searcher, int numHits) throws IOException {
-    TopScoreDocCollector collector1 = TopScoreDocCollector.create(numHits, null, true); // COMPLETE
-    TopScoreDocCollector collector2 = TopScoreDocCollector.create(numHits, null, false); // TOP_SCORES
+    TopScoreDocCollector collector1 = TopScoreDocCollector.create(numHits, null, Integer.MAX_VALUE); // COMPLETE
+    TopScoreDocCollector collector2 = TopScoreDocCollector.create(numHits, null, 1); // TOP_SCORES
     searcher.search(query, collector1);
     searcher.search(query, collector2);
     checkEqual(query, collector1.topDocs().scoreDocs, collector2.topDocs().scoreDocs);

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/61e89e3c/solr/core/src/java/org/apache/solr/handler/component/ExpandComponent.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/handler/component/ExpandComponent.java b/solr/core/src/java/org/apache/solr/handler/component/ExpandComponent.java
index 5b5add9..5101e40 100644
--- a/solr/core/src/java/org/apache/solr/handler/component/ExpandComponent.java
+++ b/solr/core/src/java/org/apache/solr/handler/component/ExpandComponent.java
@@ -537,7 +537,7 @@ public class ExpandComponent extends SearchComponent implements PluginInfoInitia
       DocIdSetIterator iterator = new BitSetIterator(groupBits, 0); // cost is not useful here
       int group;
       while ((group = iterator.nextDoc()) != DocIdSetIterator.NO_MORE_DOCS) {
-        Collector collector = (sort == null) ? TopScoreDocCollector.create(limit) : TopFieldCollector.create(sort, limit, true);
+        Collector collector = (sort == null) ? TopScoreDocCollector.create(limit, Integer.MAX_VALUE) : TopFieldCollector.create(sort, limit, Integer.MAX_VALUE);
         groups.put(group, collector);
       }
 
@@ -621,7 +621,7 @@ public class ExpandComponent extends SearchComponent implements PluginInfoInitia
       Iterator<LongCursor> iterator = groupSet.iterator();
       while (iterator.hasNext()) {
         LongCursor cursor = iterator.next();
-        Collector collector = (sort == null) ? TopScoreDocCollector.create(limit) : TopFieldCollector.create(sort, limit, true);
+        Collector collector = (sort == null) ? TopScoreDocCollector.create(limit, Integer.MAX_VALUE) : TopFieldCollector.create(sort, limit, Integer.MAX_VALUE);
         groups.put(cursor.value, collector);
       }
 

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/61e89e3c/solr/core/src/java/org/apache/solr/search/Grouping.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/search/Grouping.java b/solr/core/src/java/org/apache/solr/search/Grouping.java
index 6f40e72..8342bb7 100644
--- a/solr/core/src/java/org/apache/solr/search/Grouping.java
+++ b/solr/core/src/java/org/apache/solr/search/Grouping.java
@@ -861,9 +861,9 @@ public class Grouping {
       int groupDocsToCollect = getMax(groupOffset, docsPerGroup, maxDoc);
       Collector subCollector;
       if (withinGroupSort == null || withinGroupSort.equals(Sort.RELEVANCE)) {
-        subCollector = topCollector = TopScoreDocCollector.create(groupDocsToCollect);
+        subCollector = topCollector = TopScoreDocCollector.create(groupDocsToCollect, Integer.MAX_VALUE);
       } else {
-        topCollector = TopFieldCollector.create(searcher.weightSort(withinGroupSort), groupDocsToCollect, true);
+        topCollector = TopFieldCollector.create(searcher.weightSort(withinGroupSort), groupDocsToCollect, Integer.MAX_VALUE);
         if (needScores) {
           maxScoreCollector = new MaxScoreCollector();
           subCollector = MultiCollector.wrap(topCollector, maxScoreCollector);

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/61e89e3c/solr/core/src/java/org/apache/solr/search/ReRankCollector.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/search/ReRankCollector.java b/solr/core/src/java/org/apache/solr/search/ReRankCollector.java
index ffadb6e..ed917c3 100644
--- a/solr/core/src/java/org/apache/solr/search/ReRankCollector.java
+++ b/solr/core/src/java/org/apache/solr/search/ReRankCollector.java
@@ -68,11 +68,11 @@ public class ReRankCollector extends TopDocsCollector {
     Sort sort = cmd.getSort();
     if(sort == null) {
       this.sort = null;
-      this.mainCollector = TopScoreDocCollector.create(Math.max(this.reRankDocs, length));
+      this.mainCollector = TopScoreDocCollector.create(Math.max(this.reRankDocs, length), Integer.MAX_VALUE);
     } else {
       this.sort = sort = sort.rewrite(searcher);
       //scores are needed for Rescorer (regardless of whether sort needs it)
-      this.mainCollector = TopFieldCollector.create(sort, Math.max(this.reRankDocs, length), true);
+      this.mainCollector = TopFieldCollector.create(sort, Math.max(this.reRankDocs, length), Integer.MAX_VALUE);
     }
     this.searcher = searcher;
     this.reRankQueryRescorer = reRankQueryRescorer;

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/61e89e3c/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java b/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java
index 343d7c4..623bf5c 100644
--- a/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java
+++ b/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java
@@ -1529,14 +1529,14 @@ public class SolrIndexSearcher extends IndexSearcher implements Closeable, SolrI
 
     if (null == cmd.getSort()) {
       assert null == cmd.getCursorMark() : "have cursor but no sort";
-      return TopScoreDocCollector.create(len);
+      return TopScoreDocCollector.create(len, Integer.MAX_VALUE);
     } else {
       // we have a sort
       final Sort weightedSort = weightSort(cmd.getSort());
       final CursorMark cursor = cmd.getCursorMark();
 
       final FieldDoc searchAfter = (null != cursor ? cursor.getSearchAfterFieldDoc() : null);
-      return TopFieldCollector.create(weightedSort, len, searchAfter, true);
+      return TopFieldCollector.create(weightedSort, len, searchAfter, Integer.MAX_VALUE);
     }
   }
 

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/61e89e3c/solr/core/src/java/org/apache/solr/search/grouping/distributed/command/QueryCommand.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/search/grouping/distributed/command/QueryCommand.java b/solr/core/src/java/org/apache/solr/search/grouping/distributed/command/QueryCommand.java
index 93b55b1..6503d86 100644
--- a/solr/core/src/java/org/apache/solr/search/grouping/distributed/command/QueryCommand.java
+++ b/solr/core/src/java/org/apache/solr/search/grouping/distributed/command/QueryCommand.java
@@ -129,9 +129,9 @@ public class QueryCommand implements Command<QueryCommandResult> {
   public List<Collector> create() throws IOException {
     Collector subCollector;
     if (sort == null || sort.equals(Sort.RELEVANCE)) {
-      subCollector = topDocsCollector = TopScoreDocCollector.create(docsToCollect);
+      subCollector = topDocsCollector = TopScoreDocCollector.create(docsToCollect, Integer.MAX_VALUE);
     } else {
-      topDocsCollector = TopFieldCollector.create(sort, docsToCollect, true);
+      topDocsCollector = TopFieldCollector.create(sort, docsToCollect, Integer.MAX_VALUE);
       if (needScores) {
         maxScoreCollector = new MaxScoreCollector();
         subCollector = MultiCollector.wrap(topDocsCollector, maxScoreCollector);

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/61e89e3c/solr/core/src/test/org/apache/solr/search/TestSort.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/search/TestSort.java b/solr/core/src/test/org/apache/solr/search/TestSort.java
index fdb4807..54cc5ea 100644
--- a/solr/core/src/test/org/apache/solr/search/TestSort.java
+++ b/solr/core/src/test/org/apache/solr/search/TestSort.java
@@ -283,7 +283,7 @@ public class TestSort extends SolrTestCaseJ4 {
         final String nullRep2 = luceneSort2 || sortMissingFirst2 && !reverse2 || sortMissingLast2 && reverse2 ? "" : "zzz";
 
         boolean scoreInOrder = r.nextBoolean();
-        final TopFieldCollector topCollector = TopFieldCollector.create(sort, top, true);
+        final TopFieldCollector topCollector = TopFieldCollector.create(sort, top, Integer.MAX_VALUE);
 
         final List<MyDoc> collectedDocs = new ArrayList<>();
         // delegate and collect docs ourselves


Mime
View raw message