You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by jp...@apache.org on 2018/08/30 14:45:29 UTC

[3/4] lucene-solr:master: LUCENE-8432: TopFieldComparator stops calling the comparator when only counting hits.

LUCENE-8432: TopFieldComparator stops calling the comparator when only counting hits.


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

Branch: refs/heads/master
Commit: ba83c5a26a9e789617bf8c4a0113fe62f9f56f66
Parents: a30eeae
Author: Adrien Grand <jp...@gmail.com>
Authored: Thu Aug 30 12:00:21 2018 +0200
Committer: Adrien Grand <jp...@gmail.com>
Committed: Thu Aug 30 16:44:56 2018 +0200

----------------------------------------------------------------------
 lucene/CHANGES.txt                              |  4 ++
 .../apache/lucene/search/TopFieldCollector.java | 41 ++++++++++++--------
 2 files changed, 29 insertions(+), 16 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/ba83c5a2/lucene/CHANGES.txt
----------------------------------------------------------------------
diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt
index a9f93b9..5120f28 100644
--- a/lucene/CHANGES.txt
+++ b/lucene/CHANGES.txt
@@ -274,6 +274,10 @@ Improvements
 
 * LUCENE-8460: Better argument validation in StoredField. (Namgyu Kim)
 
+* LUCENE-8432: TopFieldComparator stops comparing documents if the index is
+  sorted, even if hits still need to be visited to compute the hit count.
+  (Nikolay Khitrin)
+
 Other:
 
 * LUCENE-8366: Upgrade to ICU 62.1. Emoji handling now uses Unicode 11's

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/ba83c5a2/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 8f0e059..90c4555 100644
--- a/lucene/core/src/java/org/apache/lucene/search/TopFieldCollector.java
+++ b/lucene/core/src/java/org/apache/lucene/search/TopFieldCollector.java
@@ -107,21 +107,25 @@ public abstract class TopFieldCollector extends TopDocsCollector<Entry> {
 
       return new MultiComparatorLeafCollector(comparators, reverseMul) {
 
+        boolean collectedAllCompetitiveHits = false;
+
         @Override
         public void collect(int doc) throws IOException {
           ++totalHits;
           if (queueFull) {
-            if (reverseMul * comparator.compareBottom(doc) <= 0) {
+            if (collectedAllCompetitiveHits || reverseMul * comparator.compareBottom(doc) <= 0) {
               // 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 && totalHits >= totalHitsThreshold) {
-                totalHitsRelation = Relation.GREATER_THAN_OR_EQUAL_TO;
-                throw new CollectionTerminatedException();
-              } else {
-                // just move to the next doc
-                return;
+              if (canEarlyTerminate) {
+                if (totalHits >= totalHitsThreshold) {
+                  totalHitsRelation = Relation.GREATER_THAN_OR_EQUAL_TO;
+                  throw new CollectionTerminatedException();
+                } else {
+                  collectedAllCompetitiveHits = true;
+                }
               }
+              return;
             }
 
             // This hit is competitive - replace bottom element in queue & adjustTop
@@ -183,6 +187,8 @@ public abstract class TopFieldCollector extends TopDocsCollector<Entry> {
           canEarlyTerminate(sort, indexSort);
       return new MultiComparatorLeafCollector(queue.getComparators(context), queue.getReverseMul()) {
 
+        boolean collectedAllCompetitiveHits = false;
+
         @Override
         public void collect(int doc) throws IOException {
           //System.out.println("  collect doc=" + doc);
@@ -192,16 +198,19 @@ public abstract class TopFieldCollector extends TopDocsCollector<Entry> {
           if (queueFull) {
             // Fastmatch: return if this hit is no better than
             // the worst hit currently in the queue:
-            final int cmp = reverseMul * comparator.compareBottom(doc);
-            if (cmp <= 0) {
-              // not competitive since documents are visited in doc id order
-              if (canEarlyTerminate && totalHits >= totalHitsThreshold) {
-                totalHitsRelation = Relation.GREATER_THAN_OR_EQUAL_TO;
-                throw new CollectionTerminatedException();
-              } else {
-                // just move to the next doc
-                return;
+            if (collectedAllCompetitiveHits || reverseMul * comparator.compareBottom(doc) <= 0) {
+              // 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 (totalHits >= totalHitsThreshold) {
+                  totalHitsRelation = Relation.GREATER_THAN_OR_EQUAL_TO;
+                  throw new CollectionTerminatedException();
+                } else {
+                  collectedAllCompetitiveHits = true;
+                }
               }
+              return;
             }
           }