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

lucene-solr:master: LUCENE-8463: TopFieldCollector can now early-terminates queries when sorting by SortField.DOC.

Repository: lucene-solr
Updated Branches:
  refs/heads/master b4449c73e -> cd61a926f


LUCENE-8463: TopFieldCollector can now early-terminates queries when sorting by SortField.DOC.

Signed-off-by: Jim Ferenczi <ji...@apache.org>


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

Branch: refs/heads/master
Commit: cd61a926fb0787823360d22c0a9accd9e4579ceb
Parents: b4449c7
Author: Christophe Bismuth <ch...@gmail.com>
Authored: Mon Nov 12 11:00:20 2018 +0100
Committer: Jim Ferenczi <ji...@apache.org>
Committed: Fri Nov 16 19:13:29 2018 +0100

----------------------------------------------------------------------
 lucene/CHANGES.txt                              |  5 +++
 .../apache/lucene/search/TopFieldCollector.java | 28 +++++++++----
 .../TestTopFieldCollectorEarlyTermination.java  | 43 ++++++++++++++++++--
 3 files changed, 65 insertions(+), 11 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/cd61a926/lucene/CHANGES.txt
----------------------------------------------------------------------
diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt
index 611cb20..ca87bfe 100644
--- a/lucene/CHANGES.txt
+++ b/lucene/CHANGES.txt
@@ -212,6 +212,11 @@ New Features
   IndexWriterConfig#setIndexCreatedVersionMajor. This is an expert feature.
   (Adrien Grand)
 
+Improvements:
+
+* LUCENE-8463: TopFieldCollector can now early-terminates queries when sorting by SortField.DOC.
+  (Christophe Bismuth via Jim Ferenczi)
+
 ======================= Lucene 7.6.0 =======================
 
 Build

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/cd61a926/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 ff2307c..f3a2a3b 100644
--- a/lucene/core/src/java/org/apache/lucene/search/TopFieldCollector.java
+++ b/lucene/core/src/java/org/apache/lucene/search/TopFieldCollector.java
@@ -68,13 +68,27 @@ public abstract class TopFieldCollector extends TopDocsCollector<Entry> {
   }
 
   static boolean canEarlyTerminate(Sort searchSort, Sort indexSort) {
+    return canEarlyTerminateOnDocId(searchSort) ||
+           canEarlyTerminateOnPrefix(searchSort, indexSort);
+  }
+
+  private static boolean canEarlyTerminateOnDocId(Sort searchSort) {
     final SortField[] fields1 = searchSort.getSort();
-    final SortField[] fields2 = indexSort.getSort();
-    // early termination is possible if fields1 is a prefix of fields2
-    if (fields1.length > fields2.length) {
+    return SortField.FIELD_DOC.equals(fields1[0]);
+  }
+
+  private static boolean canEarlyTerminateOnPrefix(Sort searchSort, Sort indexSort) {
+    if (indexSort != null) {
+      final SortField[] fields1 = searchSort.getSort();
+      final SortField[] fields2 = indexSort.getSort();
+      // early termination is possible if fields1 is a prefix of fields2
+      if (fields1.length > fields2.length) {
+        return false;
+      }
+      return Arrays.asList(fields1).equals(Arrays.asList(fields2).subList(0, fields1.length));
+    } else {
       return false;
     }
-    return Arrays.asList(fields1).equals(Arrays.asList(fields2).subList(0, fields1.length));
   }
 
   /*
@@ -99,8 +113,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 = indexSort != null &&
-          canEarlyTerminate(sort, indexSort);
+      final boolean canEarlyTerminate = canEarlyTerminate(sort, indexSort);
 
       return new MultiComparatorLeafCollector(comparators, reverseMul) {
 
@@ -192,8 +205,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 = indexSort != null &&
-          canEarlyTerminate(sort, indexSort);
+      final boolean canEarlyTerminate = canEarlyTerminate(sort, indexSort);
       return new MultiComparatorLeafCollector(queue.getComparators(context), queue.getReverseMul()) {
 
         boolean collectedAllCompetitiveHits = false;

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/cd61a926/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 b6d33da..a92a100 100644
--- a/lucene/core/src/test/org/apache/lucene/search/TestTopFieldCollectorEarlyTermination.java
+++ b/lucene/core/src/test/org/apache/lucene/search/TestTopFieldCollectorEarlyTermination.java
@@ -23,6 +23,7 @@ import java.util.List;
 import java.util.Random;
 import java.util.Set;
 
+import com.carrotsearch.randomizedtesting.generators.RandomPicks;
 import org.apache.lucene.analysis.MockAnalyzer;
 import org.apache.lucene.document.Document;
 import org.apache.lucene.document.Field.Store;
@@ -39,8 +40,6 @@ import org.apache.lucene.store.Directory;
 import org.apache.lucene.util.LuceneTestCase;
 import org.apache.lucene.util.TestUtil;
 
-import com.carrotsearch.randomizedtesting.generators.RandomPicks;
-
 public class TestTopFieldCollectorEarlyTermination extends LuceneTestCase {
 
   private int numDocs;
@@ -167,7 +166,41 @@ public class TestTopFieldCollectorEarlyTermination extends LuceneTestCase {
     }
   }
   
-  public void testCanEarlyTerminate() {
+  public void testCanEarlyTerminateOnDocId() {
+    assertTrue(TopFieldCollector.canEarlyTerminate(
+        new Sort(SortField.FIELD_DOC),
+        new Sort(SortField.FIELD_DOC)));
+    
+    assertTrue(TopFieldCollector.canEarlyTerminate(
+        new Sort(SortField.FIELD_DOC),
+        null));
+
+    assertFalse(TopFieldCollector.canEarlyTerminate(
+        new Sort(new SortField("a", SortField.Type.LONG)),
+        null));
+
+    assertFalse(TopFieldCollector.canEarlyTerminate(
+        new Sort(new SortField("a", SortField.Type.LONG)),
+        new Sort(new SortField("b", SortField.Type.LONG))));
+
+    assertTrue(TopFieldCollector.canEarlyTerminate(
+        new Sort(SortField.FIELD_DOC),
+        new Sort(new SortField("b", SortField.Type.LONG))));
+
+    assertTrue(TopFieldCollector.canEarlyTerminate(
+        new Sort(SortField.FIELD_DOC),
+        new Sort(new SortField("b", SortField.Type.LONG), SortField.FIELD_DOC)));
+
+    assertFalse(TopFieldCollector.canEarlyTerminate(
+        new Sort(new SortField("a", SortField.Type.LONG)),
+        new Sort(SortField.FIELD_DOC)));
+
+    assertFalse(TopFieldCollector.canEarlyTerminate(
+        new Sort(new SortField("a", SortField.Type.LONG), SortField.FIELD_DOC),
+        new Sort(SortField.FIELD_DOC)));
+  }
+
+  public void testCanEarlyTerminateOnPrefix() {
     assertTrue(TopFieldCollector.canEarlyTerminate(
         new Sort(new SortField("a", SortField.Type.LONG)),
         new Sort(new SortField("a", SortField.Type.LONG))));
@@ -182,6 +215,10 @@ public class TestTopFieldCollectorEarlyTermination extends LuceneTestCase {
 
     assertFalse(TopFieldCollector.canEarlyTerminate(
         new Sort(new SortField("a", SortField.Type.LONG, true)),
+        null));
+    
+    assertFalse(TopFieldCollector.canEarlyTerminate(
+        new Sort(new SortField("a", SortField.Type.LONG, true)),
         new Sort(new SortField("a", SortField.Type.LONG, false))));
 
     assertFalse(TopFieldCollector.canEarlyTerminate(