mirror of https://github.com/apache/lucene.git
LUCENE-8463: TopFieldCollector can now early-terminates queries when sorting by SortField.DOC.
Signed-off-by: Jim Ferenczi <jimczi@apache.org>
This commit is contained in:
parent
b4449c73e4
commit
cd61a926fb
|
@ -212,6 +212,11 @@ New Features
|
||||||
IndexWriterConfig#setIndexCreatedVersionMajor. This is an expert feature.
|
IndexWriterConfig#setIndexCreatedVersionMajor. This is an expert feature.
|
||||||
(Adrien Grand)
|
(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 =======================
|
======================= Lucene 7.6.0 =======================
|
||||||
|
|
||||||
Build
|
Build
|
||||||
|
|
|
@ -68,6 +68,17 @@ public abstract class TopFieldCollector extends TopDocsCollector<Entry> {
|
||||||
}
|
}
|
||||||
|
|
||||||
static boolean canEarlyTerminate(Sort searchSort, Sort indexSort) {
|
static boolean canEarlyTerminate(Sort searchSort, Sort indexSort) {
|
||||||
|
return canEarlyTerminateOnDocId(searchSort) ||
|
||||||
|
canEarlyTerminateOnPrefix(searchSort, indexSort);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean canEarlyTerminateOnDocId(Sort searchSort) {
|
||||||
|
final SortField[] fields1 = searchSort.getSort();
|
||||||
|
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[] fields1 = searchSort.getSort();
|
||||||
final SortField[] fields2 = indexSort.getSort();
|
final SortField[] fields2 = indexSort.getSort();
|
||||||
// early termination is possible if fields1 is a prefix of fields2
|
// early termination is possible if fields1 is a prefix of fields2
|
||||||
|
@ -75,6 +86,9 @@ public abstract class TopFieldCollector extends TopDocsCollector<Entry> {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return Arrays.asList(fields1).equals(Arrays.asList(fields2).subList(0, fields1.length));
|
return Arrays.asList(fields1).equals(Arrays.asList(fields2).subList(0, fields1.length));
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -99,8 +113,7 @@ public abstract class TopFieldCollector extends TopDocsCollector<Entry> {
|
||||||
final LeafFieldComparator[] comparators = queue.getComparators(context);
|
final LeafFieldComparator[] comparators = queue.getComparators(context);
|
||||||
final int[] reverseMul = queue.getReverseMul();
|
final int[] reverseMul = queue.getReverseMul();
|
||||||
final Sort indexSort = context.reader().getMetaData().getSort();
|
final Sort indexSort = context.reader().getMetaData().getSort();
|
||||||
final boolean canEarlyTerminate = indexSort != null &&
|
final boolean canEarlyTerminate = canEarlyTerminate(sort, indexSort);
|
||||||
canEarlyTerminate(sort, indexSort);
|
|
||||||
|
|
||||||
return new MultiComparatorLeafCollector(comparators, reverseMul) {
|
return new MultiComparatorLeafCollector(comparators, reverseMul) {
|
||||||
|
|
||||||
|
@ -192,8 +205,7 @@ public abstract class TopFieldCollector extends TopDocsCollector<Entry> {
|
||||||
docBase = context.docBase;
|
docBase = context.docBase;
|
||||||
final int afterDoc = after.doc - docBase;
|
final int afterDoc = after.doc - docBase;
|
||||||
final Sort indexSort = context.reader().getMetaData().getSort();
|
final Sort indexSort = context.reader().getMetaData().getSort();
|
||||||
final boolean canEarlyTerminate = indexSort != null &&
|
final boolean canEarlyTerminate = canEarlyTerminate(sort, indexSort);
|
||||||
canEarlyTerminate(sort, indexSort);
|
|
||||||
return new MultiComparatorLeafCollector(queue.getComparators(context), queue.getReverseMul()) {
|
return new MultiComparatorLeafCollector(queue.getComparators(context), queue.getReverseMul()) {
|
||||||
|
|
||||||
boolean collectedAllCompetitiveHits = false;
|
boolean collectedAllCompetitiveHits = false;
|
||||||
|
|
|
@ -23,6 +23,7 @@ import java.util.List;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import com.carrotsearch.randomizedtesting.generators.RandomPicks;
|
||||||
import org.apache.lucene.analysis.MockAnalyzer;
|
import org.apache.lucene.analysis.MockAnalyzer;
|
||||||
import org.apache.lucene.document.Document;
|
import org.apache.lucene.document.Document;
|
||||||
import org.apache.lucene.document.Field.Store;
|
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.LuceneTestCase;
|
||||||
import org.apache.lucene.util.TestUtil;
|
import org.apache.lucene.util.TestUtil;
|
||||||
|
|
||||||
import com.carrotsearch.randomizedtesting.generators.RandomPicks;
|
|
||||||
|
|
||||||
public class TestTopFieldCollectorEarlyTermination extends LuceneTestCase {
|
public class TestTopFieldCollectorEarlyTermination extends LuceneTestCase {
|
||||||
|
|
||||||
private int numDocs;
|
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(
|
assertTrue(TopFieldCollector.canEarlyTerminate(
|
||||||
new Sort(new SortField("a", SortField.Type.LONG)),
|
new Sort(new SortField("a", SortField.Type.LONG)),
|
||||||
new Sort(new SortField("a", SortField.Type.LONG))));
|
new Sort(new SortField("a", SortField.Type.LONG))));
|
||||||
|
@ -180,6 +213,10 @@ public class TestTopFieldCollectorEarlyTermination extends LuceneTestCase {
|
||||||
new Sort(new SortField("a", SortField.Type.LONG)),
|
new Sort(new SortField("a", SortField.Type.LONG)),
|
||||||
new Sort(new SortField("a", SortField.Type.LONG), new SortField("b", SortField.Type.STRING))));
|
new Sort(new SortField("a", SortField.Type.LONG), new SortField("b", SortField.Type.STRING))));
|
||||||
|
|
||||||
|
assertFalse(TopFieldCollector.canEarlyTerminate(
|
||||||
|
new Sort(new SortField("a", SortField.Type.LONG, true)),
|
||||||
|
null));
|
||||||
|
|
||||||
assertFalse(TopFieldCollector.canEarlyTerminate(
|
assertFalse(TopFieldCollector.canEarlyTerminate(
|
||||||
new Sort(new SortField("a", SortField.Type.LONG, true)),
|
new Sort(new SortField("a", SortField.Type.LONG, true)),
|
||||||
new Sort(new SortField("a", SortField.Type.LONG, false))));
|
new Sort(new SortField("a", SortField.Type.LONG, false))));
|
||||||
|
|
Loading…
Reference in New Issue