diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt index 1fd049270541..e4c01252f54c 100644 --- a/lucene/CHANGES.txt +++ b/lucene/CHANGES.txt @@ -61,6 +61,10 @@ API Changes * GITHUB#12599: Add RandomAccessInput#readBytes method to the RandomAccessInput interface. (Ignacio Vera) +* GITHUB#11041: Deprecate IndexSearch#search(Query, Collector) in favor of + IndexSearcher#search(Query, CollectorManager) for TopFieldCollectorManager + and TopScoreDocCollectorManager. (Zach Chen, Adrien Grand, Michael McCandless, Greg Miller, Luca Cavanna) + New Features --------------------- @@ -172,6 +176,8 @@ API Changes * GITHUB#12799: Make TaskExecutor constructor public and use TaskExecutor for concurrent HNSW graph build. (Shubham Chaudhary) +* + New Features --------------------- 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 405305d50a1e..58cf8e79efae 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 @@ -30,8 +30,8 @@ import org.apache.lucene.search.ScoreDoc; import org.apache.lucene.search.Sort; import org.apache.lucene.search.TopDocs; -import org.apache.lucene.search.TopFieldCollector; -import org.apache.lucene.search.TopScoreDocCollector; +import org.apache.lucene.search.TopFieldCollectorManager; +import org.apache.lucene.search.TopScoreDocCollectorManager; import org.apache.lucene.store.Directory; import org.apache.lucene.util.Bits; @@ -110,15 +110,17 @@ public int doLogic() throws Exception { // the IndexSearcher search methods that take // Weight public again, we can go back to // pulling the Weight ourselves: - TopFieldCollector collector = - TopFieldCollector.create(sort, numHits, withTotalHits() ? Integer.MAX_VALUE : 1); - searcher.search(q, collector); - hits = collector.topDocs(); + int totalHitsThreshold = withTotalHits() ? Integer.MAX_VALUE : 1; + TopFieldCollectorManager collectorManager = + new TopFieldCollectorManager( + sort, numHits, null, totalHitsThreshold, searcher.getSlices().length > 1); + hits = searcher.search(q, collectorManager); } else { hits = searcher.search(q, numHits); } } else { Collector collector = createCollector(); + searcher.search(q, collector); // hits = collector.topDocs(); } @@ -183,7 +185,8 @@ protected int withTopDocs(IndexSearcher searcher, Query q, TopDocs hits) throws } protected Collector createCollector() throws Exception { - return TopScoreDocCollector.create(numHits(), withTotalHits() ? Integer.MAX_VALUE : 1); + return new TopScoreDocCollectorManager(numHits(), withTotalHits() ? Integer.MAX_VALUE : 1) + .newCollector(); } protected Document retrieveDoc(StoredFields storedFields, int id) throws IOException { 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 50f20876e47e..45d436bbf411 100644 --- a/lucene/core/src/java/org/apache/lucene/search/IndexSearcher.java +++ b/lucene/core/src/java/org/apache/lucene/search/IndexSearcher.java @@ -19,7 +19,6 @@ import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.List; @@ -62,9 +61,9 @@ * match lots of documents, counting the number of hits may take much longer than computing the top * hits so this trade-off allows to get some minimal information about the hit count without slowing * down search too much. The {@link TopDocs#scoreDocs} array is always accurate however. If this - * behavior doesn't suit your needs, you should create collectors manually with either {@link - * TopScoreDocCollector#create} or {@link TopFieldCollector#create} and call {@link #search(Query, - * Collector)}. + * behavior doesn't suit your needs, you should create collectorManagers manually with either {@link + * TopScoreDocCollectorManager} or {@link TopFieldCollectorManager} and call {@link #search(Query, + * CollectorManager)}. * *

* @@ -455,35 +454,10 @@ public TopDocs searchAfter(ScoreDoc after, Query query, int numHits) throws IOEx } final int cappedNumHits = Math.min(numHits, limit); - - final LeafSlice[] leafSlices = getSlices(); - final CollectorManager manager = - new CollectorManager() { - - private final HitsThresholdChecker hitsThresholdChecker = - leafSlices.length <= 1 - ? HitsThresholdChecker.create(Math.max(TOTAL_HITS_THRESHOLD, numHits)) - : HitsThresholdChecker.createShared(Math.max(TOTAL_HITS_THRESHOLD, numHits)); - - private final MaxScoreAccumulator minScoreAcc = - leafSlices.length <= 1 ? null : new MaxScoreAccumulator(); - - @Override - public TopScoreDocCollector newCollector() throws IOException { - return TopScoreDocCollector.create( - cappedNumHits, after, hitsThresholdChecker, minScoreAcc); - } - - @Override - public TopDocs reduce(Collection collectors) throws IOException { - final TopDocs[] topDocs = new TopDocs[collectors.size()]; - int i = 0; - for (TopScoreDocCollector collector : collectors) { - topDocs[i++] = collector.topDocs(); - } - return TopDocs.merge(0, cappedNumHits, topDocs); - } - }; + final boolean supportsConcurrency = getSlices().length > 1; + CollectorManager manager = + new TopScoreDocCollectorManager( + cappedNumHits, after, TOTAL_HITS_THRESHOLD, supportsConcurrency); return search(query, manager); } @@ -510,7 +484,10 @@ public TopDocs search(Query query, int n) throws IOException { * * @throws TooManyClauses If a query would exceed {@link IndexSearcher#getMaxClauseCount()} * clauses. + * @deprecated This method is being deprecated in favor of {@link IndexSearcher#search(Query, + * CollectorManager)} due to its support for concurrency in IndexSearcher */ + @Deprecated public void search(Query query, Collector results) throws IOException { query = rewrite(query, results.scoreMode().needsScores()); search(leafContexts, createWeight(query, results.scoreMode(), 1), results); @@ -602,34 +579,10 @@ private TopFieldDocs searchAfter( final Sort rewrittenSort = sort.rewrite(this); final LeafSlice[] leafSlices = getSlices(); + final boolean supportsConcurrency = leafSlices.length > 1; final CollectorManager manager = - new CollectorManager<>() { - - private final HitsThresholdChecker hitsThresholdChecker = - leafSlices.length <= 1 - ? HitsThresholdChecker.create(Math.max(TOTAL_HITS_THRESHOLD, numHits)) - : HitsThresholdChecker.createShared(Math.max(TOTAL_HITS_THRESHOLD, numHits)); - - private final MaxScoreAccumulator minScoreAcc = - leafSlices.length <= 1 ? null : new MaxScoreAccumulator(); - - @Override - public TopFieldCollector newCollector() throws IOException { - // TODO: don't pay the price for accurate hit counts by default - return TopFieldCollector.create( - rewrittenSort, cappedNumHits, after, hitsThresholdChecker, minScoreAcc); - } - - @Override - public TopFieldDocs reduce(Collection collectors) throws IOException { - final TopFieldDocs[] topDocs = new TopFieldDocs[collectors.size()]; - int i = 0; - for (TopFieldCollector collector : collectors) { - topDocs[i++] = collector.topDocs(); - } - return TopDocs.merge(rewrittenSort, 0, cappedNumHits, topDocs); - } - }; + new TopFieldCollectorManager( + rewrittenSort, cappedNumHits, after, TOTAL_HITS_THRESHOLD, supportsConcurrency); TopFieldDocs topDocs = search(query, manager); if (doDocScores) { 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 fce33a030d50..68c45bb2c668 100644 --- a/lucene/core/src/java/org/apache/lucene/search/SortRescorer.java +++ b/lucene/core/src/java/org/apache/lucene/search/SortRescorer.java @@ -45,7 +45,10 @@ public TopDocs rescore(IndexSearcher searcher, TopDocs firstPassTopDocs, int top List leaves = searcher.getIndexReader().leaves(); - TopFieldCollector collector = TopFieldCollector.create(sort, topN, Integer.MAX_VALUE); + TopFieldCollector collector = + new TopFieldCollectorManager( + sort, topN, null, Integer.MAX_VALUE, searcher.getSlices().length > 1) + .newCollector(); // Now merge sort docIDs from hits, with reader's leaves: int hitUpto = 0; diff --git a/lucene/core/src/java/org/apache/lucene/search/TopDocs.java b/lucene/core/src/java/org/apache/lucene/search/TopDocs.java index 9b95f27fd6fa..08b25a505549 100644 --- a/lucene/core/src/java/org/apache/lucene/search/TopDocs.java +++ b/lucene/core/src/java/org/apache/lucene/search/TopDocs.java @@ -232,8 +232,7 @@ public static TopDocs merge( /** * Returns a new TopFieldDocs, containing topN results across the provided TopFieldDocs, sorting * by the specified {@link Sort}. Each of the TopDocs must have been sorted by the same Sort, and - * sort field values must have been filled (ie, fillFields=true must be passed to - * {@link TopFieldCollector#create}). + * sort field values must have been filled. * * @see #merge(Sort, int, int, TopFieldDocs[]) * @lucene.experimental 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 d9e32ff08584..fcb14e1feef4 100644 --- a/lucene/core/src/java/org/apache/lucene/search/TopFieldCollector.java +++ b/lucene/core/src/java/org/apache/lucene/search/TopFieldCollector.java @@ -18,7 +18,6 @@ import java.io.IOException; import java.util.Arrays; -import java.util.Collection; import java.util.Comparator; import java.util.List; import java.util.Objects; @@ -174,7 +173,7 @@ private static boolean canEarlyTerminateOnPrefix(Sort searchSort, Sort indexSort * Implements a TopFieldCollector over one SortField criteria, with tracking * document scores and maxScore. */ - private static class SimpleFieldCollector extends TopFieldCollector { + static class SimpleFieldCollector extends TopFieldCollector { final Sort sort; final FieldValueHitQueue queue; @@ -225,7 +224,7 @@ public void collect(int doc) throws IOException { /* * Implements a TopFieldCollector when after != null. */ - private static final class PagingFieldCollector extends TopFieldCollector { + static final class PagingFieldCollector extends TopFieldCollector { final Sort sort; int collectedHits; @@ -405,9 +404,13 @@ protected void updateMinCompetitiveScore(Scorable scorer) throws IOException { * 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. + * @deprecated This method is deprecated in favor of the constructor of {@link + * TopFieldCollectorManager} due to its support for concurrency in IndexSearcher */ + @Deprecated public static TopFieldCollector create(Sort sort, int numHits, int totalHitsThreshold) { - return create(sort, numHits, null, totalHitsThreshold); + return new TopFieldCollectorManager(sort, numHits, null, totalHitsThreshold, false) + .newCollector(); } /** @@ -429,106 +432,29 @@ public static TopFieldCollector create(Sort sort, int numHits, int totalHitsThre * field is indexed both with doc values and points. In this case, there is an assumption that * the same data is stored in these points and doc values. * @return a {@link TopFieldCollector} instance which will sort the results by the sort criteria. + * @deprecated This method is deprecated in favor of the constructor of {@link + * TopFieldCollectorManager} due to its support for concurrency in IndexSearcher */ + @Deprecated public static TopFieldCollector create( Sort sort, int numHits, FieldDoc after, int totalHitsThreshold) { - if (totalHitsThreshold < 0) { - throw new IllegalArgumentException( - "totalHitsThreshold must be >= 0, got " + totalHitsThreshold); - } - - return create( - sort, - numHits, - after, - HitsThresholdChecker.create(Math.max(totalHitsThreshold, numHits)), - null /* bottomValueChecker */); - } - - /** - * Same as above with additional parameters to allow passing in the threshold checker and the max - * score accumulator. - */ - static TopFieldCollector create( - Sort sort, - int numHits, - FieldDoc after, - HitsThresholdChecker hitsThresholdChecker, - MaxScoreAccumulator minScoreAcc) { - - if (sort.getSort().length == 0) { - throw new IllegalArgumentException("Sort must contain at least one field"); - } - - if (numHits <= 0) { - throw new IllegalArgumentException( - "numHits must be > 0; please use TotalHitCountCollector if you just need the total hit count"); - } - - if (hitsThresholdChecker == null) { - throw new IllegalArgumentException("hitsThresholdChecker should not be null"); - } - - FieldValueHitQueue queue = FieldValueHitQueue.create(sort.getSort(), numHits); - - if (after == null) { - // inform a comparator that sort is based on this single field - // to enable some optimizations for skipping over non-competitive documents - // We can't set single sort when the `after` parameter is non-null as it's - // an implicit sort over the document id. - if (queue.comparators.length == 1) { - queue.comparators[0].setSingleSort(); - } - return new SimpleFieldCollector(sort, queue, numHits, hitsThresholdChecker, minScoreAcc); - } else { - if (after.fields == null) { - throw new IllegalArgumentException( - "after.fields wasn't set; you must pass fillFields=true for the previous search"); - } - - if (after.fields.length != sort.getSort().length) { - throw new IllegalArgumentException( - "after.fields has " - + after.fields.length - + " values but sort has " - + sort.getSort().length); - } - - return new PagingFieldCollector( - sort, queue, after, numHits, hitsThresholdChecker, minScoreAcc); - } + return new TopFieldCollectorManager(sort, numHits, after, totalHitsThreshold, false) + .newCollector(); } /** * Create a CollectorManager which uses a shared hit counter to maintain number of hits and a * shared {@link MaxScoreAccumulator} to propagate the minimum score accross segments if the * primary sort is by relevancy. + * + * @deprecated This method is deprecated in favor of the constructor of {@link + * TopFieldCollectorManager} due to its support for concurrency in IndexSearcher */ + @Deprecated public static CollectorManager createSharedManager( Sort sort, int numHits, FieldDoc after, int totalHitsThreshold) { - int totalHitsMax = Math.max(totalHitsThreshold, numHits); - return new CollectorManager<>() { - private final HitsThresholdChecker hitsThresholdChecker = - HitsThresholdChecker.createShared(totalHitsMax); - private final MaxScoreAccumulator minScoreAcc = - totalHitsMax == Integer.MAX_VALUE ? null : new MaxScoreAccumulator(); - - @Override - public TopFieldCollector newCollector() throws IOException { - return create(sort, numHits, after, hitsThresholdChecker, minScoreAcc); - } - - @Override - public TopFieldDocs reduce(Collection collectors) throws IOException { - final TopFieldDocs[] topDocs = new TopFieldDocs[collectors.size()]; - int i = 0; - for (TopFieldCollector collector : collectors) { - topDocs[i++] = collector.topDocs(); - } - return TopDocs.merge(sort, 0, numHits, topDocs); - } - }; + return new TopFieldCollectorManager(sort, numHits, after, totalHitsThreshold, true); } /** diff --git a/lucene/core/src/java/org/apache/lucene/search/TopFieldCollectorManager.java b/lucene/core/src/java/org/apache/lucene/search/TopFieldCollectorManager.java new file mode 100644 index 000000000000..d09a589be975 --- /dev/null +++ b/lucene/core/src/java/org/apache/lucene/search/TopFieldCollectorManager.java @@ -0,0 +1,198 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.lucene.search; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +/** + * Create a TopFieldCollectorManager which uses a shared hit counter to maintain number of hits and + * a shared {@link MaxScoreAccumulator} to propagate the minimum score across segments if the + * primary sort is by relevancy. + * + *

Note that a new collectorManager should be created for each search due to its internal states. + */ +public class TopFieldCollectorManager implements CollectorManager { + private final Sort sort; + private final int numHits; + private final FieldDoc after; + private final HitsThresholdChecker hitsThresholdChecker; + private final MaxScoreAccumulator minScoreAcc; + private final List collectors; + private final boolean supportsConcurrency; + private boolean collectorCreated; + + /** + * Creates a new {@link TopFieldCollectorManager} from the given arguments. + * + *

NOTE: The instances returned by this method pre-allocate a full array of length + * numHits. + * + * @param sort the sort criteria (SortFields). + * @param numHits the number of results to collect. + * @param after the previous doc after which matching docs will be collected. + * @param totalHitsThreshold the number of docs to count accurately. If the query matches more + * than {@code totalHitsThreshold} hits then its hit count will be a lower bound. On the other + * hand if the query matches less than or exactly {@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. + * @param supportsConcurrency to use thread-safe and slower internal states for count tracking. + */ + public TopFieldCollectorManager( + Sort sort, int numHits, FieldDoc after, int totalHitsThreshold, boolean supportsConcurrency) { + if (totalHitsThreshold < 0) { + throw new IllegalArgumentException( + "totalHitsThreshold must be >= 0, got " + totalHitsThreshold); + } + + if (numHits <= 0) { + throw new IllegalArgumentException( + "numHits must be > 0; please use TotalHitCountCollector if you just need the total hit count"); + } + + if (sort.getSort().length == 0) { + throw new IllegalArgumentException("Sort must contain at least one field"); + } + + if (after != null) { + if (after.fields == null) { + throw new IllegalArgumentException( + "after.fields wasn't set; you must pass fillFields=true for the previous search"); + } + + if (after.fields.length != sort.getSort().length) { + throw new IllegalArgumentException( + "after.fields has " + + after.fields.length + + " values but sort has " + + sort.getSort().length); + } + } + + this.sort = sort; + this.numHits = numHits; + this.after = after; + this.supportsConcurrency = supportsConcurrency; + this.hitsThresholdChecker = + supportsConcurrency + ? HitsThresholdChecker.createShared(Math.max(totalHitsThreshold, numHits)) + : HitsThresholdChecker.create(Math.max(totalHitsThreshold, numHits)); + this.minScoreAcc = supportsConcurrency ? new MaxScoreAccumulator() : null; + this.collectors = new ArrayList<>(); + } + + /** + * Creates a new {@link TopFieldCollectorManager} from the given arguments, with thread-safe + * internal states. + * + *

NOTE: The instances returned by this method pre-allocate a full array of length + * numHits. + * + * @param sort the sort criteria (SortFields). + * @param numHits the number of results to collect. + * @param after the previous doc after which matching docs will be collected. + * @param totalHitsThreshold the number of docs to count accurately. If the query matches more + * than {@code totalHitsThreshold} hits then its hit count will be a lower bound. On the other + * hand if the query matches less than or exactly {@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. + */ + public TopFieldCollectorManager(Sort sort, int numHits, FieldDoc after, int totalHitsThreshold) { + this(sort, numHits, after, totalHitsThreshold, true); + } + + /** + * Creates a new {@link TopFieldCollectorManager} from the given arguments, with thread-safe + * internal states. + * + *

NOTE: The instances returned by this method pre-allocate a full array of length + * numHits. + * + * @param sort the sort criteria (SortFields). + * @param numHits the number of results to collect. + * @param totalHitsThreshold the number of docs to count accurately. If the query matches more + * than {@code totalHitsThreshold} hits then its hit count will be a lower bound. On the other + * hand if the query matches less than or exactly {@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. + */ + public TopFieldCollectorManager(Sort sort, int numHits, int totalHitsThreshold) { + this(sort, numHits, null, totalHitsThreshold, true); + } + + @Override + public TopFieldCollector newCollector() { + if (collectorCreated && supportsConcurrency == false) { + throw new IllegalStateException( + "This TopFieldCollectorManager was created without concurrency (supportsConcurrency=false), but multiple collectors are being created"); + } else { + collectorCreated = true; + } + + FieldValueHitQueue queue = + FieldValueHitQueue.create(sort.getSort(), numHits); + + TopFieldCollector collector; + if (after == null) { + // inform a comparator that sort is based on this single field + // to enable some optimizations for skipping over non-competitive documents + // We can't set single sort when the `after` parameter is non-null as it's + // an implicit sort over the document id. + if (queue.comparators.length == 1) { + queue.comparators[0].setSingleSort(); + } + collector = + new TopFieldCollector.SimpleFieldCollector( + sort, queue, numHits, hitsThresholdChecker, minScoreAcc); + } else { + if (after.fields == null) { + throw new IllegalArgumentException( + "after.fields wasn't set; you must pass fillFields=true for the previous search"); + } + + if (after.fields.length != sort.getSort().length) { + throw new IllegalArgumentException( + "after.fields has " + + after.fields.length + + " values but sort has " + + sort.getSort().length); + } + collector = + new TopFieldCollector.PagingFieldCollector( + sort, queue, after, numHits, hitsThresholdChecker, minScoreAcc); + } + + collectors.add(collector); + return collector; + } + + @Override + public TopFieldDocs reduce(Collection collectors) throws IOException { + final TopFieldDocs[] topDocs = new TopFieldDocs[collectors.size()]; + int i = 0; + for (TopFieldCollector collector : collectors) { + topDocs[i++] = collector.topDocs(); + } + return TopDocs.merge(sort, 0, numHits, topDocs); + } + + public List getCollectors() { + return collectors; + } +} 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 a6de5ac3c13f..304eff2f11a0 100644 --- a/lucene/core/src/java/org/apache/lucene/search/TopScoreDocCollector.java +++ b/lucene/core/src/java/org/apache/lucene/search/TopScoreDocCollector.java @@ -17,7 +17,6 @@ package org.apache.lucene.search; import java.io.IOException; -import java.util.Collection; import org.apache.lucene.index.LeafReaderContext; import org.apache.lucene.search.MaxScoreAccumulator.DocAndScore; @@ -44,7 +43,7 @@ public void setScorer(Scorable scorer) throws IOException { } } - private static class SimpleTopScoreDocCollector extends TopScoreDocCollector { + static class SimpleTopScoreDocCollector extends TopScoreDocCollector { SimpleTopScoreDocCollector( int numHits, HitsThresholdChecker hitsThresholdChecker, MaxScoreAccumulator minScoreAcc) { @@ -102,7 +101,7 @@ public void collect(int doc) throws IOException { } } - private static class PagingTopScoreDocCollector extends TopScoreDocCollector { + static class PagingTopScoreDocCollector extends TopScoreDocCollector { private final ScoreDoc after; private int collectedHits; @@ -204,9 +203,13 @@ public void collect(int doc) throws IOException { * *

NOTE: The instances returned by this method pre-allocate a full array of length * numHits, and fill the array with sentinel objects. + * + * @deprecated This method is deprecated in favor of the constructor of {@link + * TopScoreDocCollectorManager} due to its support for concurrency in IndexSearcher */ + @Deprecated public static TopScoreDocCollector create(int numHits, int totalHitsThreshold) { - return create(numHits, null, totalHitsThreshold); + return new TopScoreDocCollectorManager(numHits, null, totalHitsThreshold, false).newCollector(); } /** @@ -221,64 +224,27 @@ public static TopScoreDocCollector create(int numHits, int totalHitsThreshold) { * *

NOTE: The instances returned by this method pre-allocate a full array of length * numHits, and fill the array with sentinel objects. + * + * @deprecated This method is deprecated in favor of the constructor of {@link + * TopScoreDocCollectorManager} due to its support for concurrency in IndexSearcher */ + @Deprecated public static TopScoreDocCollector create(int numHits, ScoreDoc after, int totalHitsThreshold) { - return create( - numHits, after, HitsThresholdChecker.create(Math.max(totalHitsThreshold, numHits)), null); - } - - static TopScoreDocCollector create( - int numHits, - ScoreDoc after, - HitsThresholdChecker hitsThresholdChecker, - MaxScoreAccumulator minScoreAcc) { - - if (numHits <= 0) { - throw new IllegalArgumentException( - "numHits must be > 0; please use TotalHitCountCollector if you just need the total hit count"); - } - - if (hitsThresholdChecker == null) { - throw new IllegalArgumentException("hitsThresholdChecker must be non null"); - } - - if (after == null) { - return new SimpleTopScoreDocCollector(numHits, hitsThresholdChecker, minScoreAcc); - } else { - return new PagingTopScoreDocCollector(numHits, after, hitsThresholdChecker, minScoreAcc); - } + return new TopScoreDocCollectorManager(numHits, after, totalHitsThreshold, false) + .newCollector(); } /** * Create a CollectorManager which uses a shared hit counter to maintain number of hits and a * shared {@link MaxScoreAccumulator} to propagate the minimum score accross segments + * + * @deprecated This method is deprecated in favor of the constructor of {@link + * TopScoreDocCollectorManager} due to its support for concurrency in IndexSearcher */ + @Deprecated public static CollectorManager createSharedManager( int numHits, ScoreDoc after, int totalHitsThreshold) { - - int totalHitsMax = Math.max(totalHitsThreshold, numHits); - return new CollectorManager<>() { - - private final HitsThresholdChecker hitsThresholdChecker = - HitsThresholdChecker.createShared(totalHitsMax); - private final MaxScoreAccumulator minScoreAcc = - totalHitsMax == Integer.MAX_VALUE ? null : new MaxScoreAccumulator(); - - @Override - public TopScoreDocCollector newCollector() throws IOException { - return TopScoreDocCollector.create(numHits, after, hitsThresholdChecker, minScoreAcc); - } - - @Override - public TopDocs reduce(Collection collectors) throws IOException { - final TopDocs[] topDocs = new TopDocs[collectors.size()]; - int i = 0; - for (TopScoreDocCollector collector : collectors) { - topDocs[i++] = collector.topDocs(); - } - return TopDocs.merge(0, numHits, topDocs); - } - }; + return new TopScoreDocCollectorManager(numHits, after, totalHitsThreshold, true); } int docBase; diff --git a/lucene/core/src/java/org/apache/lucene/search/TopScoreDocCollectorManager.java b/lucene/core/src/java/org/apache/lucene/search/TopScoreDocCollectorManager.java new file mode 100644 index 000000000000..4e3181abdf7c --- /dev/null +++ b/lucene/core/src/java/org/apache/lucene/search/TopScoreDocCollectorManager.java @@ -0,0 +1,157 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.lucene.search; + +import java.io.IOException; +import java.util.Collection; + +/** + * Create a TopScoreDocCollectorManager which uses a shared hit counter to maintain number of hits + * and a shared {@link MaxScoreAccumulator} to propagate the minimum score across segments + * + *

Note that a new collectorManager should be created for each search due to its internal states. + */ +public class TopScoreDocCollectorManager + implements CollectorManager { + private final int numHits; + private final ScoreDoc after; + private final HitsThresholdChecker hitsThresholdChecker; + private final MaxScoreAccumulator minScoreAcc; + private final boolean supportsConcurrency; + private boolean collectorCreated; + + /** + * Creates a new {@link TopScoreDocCollectorManager} given the number of hits to collect and the + * number of hits to count accurately. + * + *

NOTE: If the total hit count of the top docs is less than or exactly {@code + * totalHitsThreshold} then this value is accurate. On the other hand, if the {@link + * TopDocs#totalHits} value is greater than {@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. + * + *

NOTE: The instances returned by this method pre-allocate a full array of length + * numHits, and fill the array with sentinel objects. + * + * @param numHits the number of results to collect. + * @param after the previous doc after which matching docs will be collected. + * @param totalHitsThreshold the number of docs to count accurately. If the query matches more + * than {@code totalHitsThreshold} hits then its hit count will be a lower bound. On the other + * hand if the query matches less than or exactly {@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. + * @param supportsConcurrency to use thread-safe and slower internal states for count tracking. + */ + public TopScoreDocCollectorManager( + int numHits, ScoreDoc after, int totalHitsThreshold, boolean supportsConcurrency) { + if (totalHitsThreshold < 0) { + throw new IllegalArgumentException( + "totalHitsThreshold must be >= 0, got " + totalHitsThreshold); + } + + if (numHits <= 0) { + throw new IllegalArgumentException( + "numHits must be > 0; please use TotalHitCountCollectorManager if you just need the total hit count"); + } + + this.numHits = numHits; + this.after = after; + this.supportsConcurrency = supportsConcurrency; + this.hitsThresholdChecker = + supportsConcurrency + ? HitsThresholdChecker.createShared(Math.max(totalHitsThreshold, numHits)) + : HitsThresholdChecker.create(Math.max(totalHitsThreshold, numHits)); + this.minScoreAcc = supportsConcurrency ? new MaxScoreAccumulator() : null; + } + + /** + * Creates a new {@link TopScoreDocCollectorManager} given the number of hits to collect and the + * number of hits to count accurately, with thread-safe internal states. + * + *

NOTE: If the total hit count of the top docs is less than or exactly {@code + * totalHitsThreshold} then this value is accurate. On the other hand, if the {@link + * TopDocs#totalHits} value is greater than {@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. + * + *

NOTE: The instances returned by this method pre-allocate a full array of length + * numHits, and fill the array with sentinel objects. + * + * @param numHits the number of results to collect. + * @param after the previous doc after which matching docs will be collected. + * @param totalHitsThreshold the number of docs to count accurately. If the query matches more + * than {@code totalHitsThreshold} hits then its hit count will be a lower bound. On the other + * hand if the query matches less than or exactly {@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. + */ + public TopScoreDocCollectorManager(int numHits, ScoreDoc after, int totalHitsThreshold) { + this(numHits, after, totalHitsThreshold, true); + } + + /** + * Creates a new {@link TopScoreDocCollectorManager} given the number of hits to collect and the + * number of hits to count accurately, with thread-safe internal states. + * + *

NOTE: If the total hit count of the top docs is less than or exactly {@code + * totalHitsThreshold} then this value is accurate. On the other hand, if the {@link + * TopDocs#totalHits} value is greater than {@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. + * + *

NOTE: The instances returned by this method pre-allocate a full array of length + * numHits, and fill the array with sentinel objects. + * + * @param numHits the number of results to collect. + * @param totalHitsThreshold the number of docs to count accurately. If the query matches more + * than {@code totalHitsThreshold} hits then its hit count will be a lower bound. On the other + * hand if the query matches less than or exactly {@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. + */ + public TopScoreDocCollectorManager(int numHits, int totalHitsThreshold) { + this(numHits, null, totalHitsThreshold, true); + } + + @Override + public TopScoreDocCollector newCollector() { + if (collectorCreated && supportsConcurrency == false) { + throw new IllegalStateException( + "This TopScoreDocCollectorManager was created without concurrency (supportsConcurrency=false), but multiple collectors are being created"); + } else { + collectorCreated = true; + } + + if (after == null) { + return new TopScoreDocCollector.SimpleTopScoreDocCollector( + numHits, hitsThresholdChecker, minScoreAcc); + } else { + return new TopScoreDocCollector.PagingTopScoreDocCollector( + numHits, after, hitsThresholdChecker, minScoreAcc); + } + } + + @Override + public TopDocs reduce(Collection collectors) throws IOException { + final TopDocs[] topDocs = new TopDocs[collectors.size()]; + int i = 0; + for (TopScoreDocCollector collector : collectors) { + topDocs[i++] = collector.topDocs(); + } + return TopDocs.merge(0, numHits, topDocs); + } +} diff --git a/lucene/core/src/test/org/apache/lucene/document/TestLatLonPointDistanceFeatureQuery.java b/lucene/core/src/test/org/apache/lucene/document/TestLatLonPointDistanceFeatureQuery.java index 881196f90a3a..76ed1b5bab34 100644 --- a/lucene/core/src/test/org/apache/lucene/document/TestLatLonPointDistanceFeatureQuery.java +++ b/lucene/core/src/test/org/apache/lucene/document/TestLatLonPointDistanceFeatureQuery.java @@ -23,7 +23,6 @@ import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.MultiReader; -import org.apache.lucene.search.CollectorManager; import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.MatchAllDocsQuery; import org.apache.lucene.search.Query; @@ -31,7 +30,7 @@ import org.apache.lucene.search.Sort; import org.apache.lucene.search.SortField; import org.apache.lucene.search.TopDocs; -import org.apache.lucene.search.TopScoreDocCollector; +import org.apache.lucene.search.TopScoreDocCollectorManager; import org.apache.lucene.store.Directory; import org.apache.lucene.tests.index.RandomIndexWriter; import org.apache.lucene.tests.search.CheckHits; @@ -101,9 +100,8 @@ public void testBasics() throws IOException { IndexSearcher searcher = newSearcher(reader); Query q = LatLonPoint.newDistanceFeatureQuery("foo", 3, 10, 10, pivotDistance); - CollectorManager manager = - TopScoreDocCollector.createSharedManager(2, null, 1); - TopDocs topHits = searcher.search(q, manager); + TopScoreDocCollectorManager collectorManager = new TopScoreDocCollectorManager(2, null, 1); + TopDocs topHits = searcher.search(q, collectorManager); assertEquals(2, topHits.scoreDocs.length); double distance1 = @@ -141,8 +139,8 @@ public void testBasics() throws IOException { 9); q = LatLonPoint.newDistanceFeatureQuery("foo", 3, 9, 9, pivotDistance); - manager = TopScoreDocCollector.createSharedManager(2, null, 1); - topHits = searcher.search(q, manager); + collectorManager = new TopScoreDocCollectorManager(2, 1); + topHits = searcher.search(q, collectorManager); assertEquals(2, topHits.scoreDocs.length); CheckHits.checkExplanations(q, "", searcher); @@ -198,9 +196,8 @@ public void testCrossesDateLine() throws IOException { IndexSearcher searcher = newSearcher(reader); Query q = LatLonPoint.newDistanceFeatureQuery("foo", 3, 0, 179, pivotDistance); - CollectorManager manager = - TopScoreDocCollector.createSharedManager(2, null, 1); - TopDocs topHits = searcher.search(q, manager); + TopScoreDocCollectorManager collectorManager = new TopScoreDocCollectorManager(2, 1); + TopDocs topHits = searcher.search(q, collectorManager); assertEquals(2, topHits.scoreDocs.length); double distance1 = @@ -265,9 +262,8 @@ public void testMissingValue() throws IOException { IndexSearcher searcher = newSearcher(reader); Query q = LatLonPoint.newDistanceFeatureQuery("foo", 3, 10, 10, 5); - CollectorManager manager = - TopScoreDocCollector.createSharedManager(3, null, 1); - TopDocs topHits = searcher.search(q, manager); + TopScoreDocCollectorManager collectorManager = new TopScoreDocCollectorManager(3, 1); + TopDocs topHits = searcher.search(q, collectorManager); assertEquals(2, topHits.scoreDocs.length); double distance1 = @@ -345,9 +341,8 @@ public void testMultiValued() throws IOException { IndexSearcher searcher = newSearcher(reader); Query q = LatLonPoint.newDistanceFeatureQuery("foo", 3, 0, 0, 200); - CollectorManager manager = - TopScoreDocCollector.createSharedManager(2, null, 1); - TopDocs topHits = searcher.search(q, manager); + TopScoreDocCollectorManager collectorManager = new TopScoreDocCollectorManager(2, 1); + TopDocs topHits = searcher.search(q, collectorManager); assertEquals(2, topHits.scoreDocs.length); double distance1 = @@ -372,8 +367,8 @@ public void testMultiValued() throws IOException { topHits.scoreDocs); q = LatLonPoint.newDistanceFeatureQuery("foo", 3, -90, 0, 10000.); - manager = TopScoreDocCollector.createSharedManager(2, null, 1); - topHits = searcher.search(q, manager); + collectorManager = new TopScoreDocCollectorManager(2, 1); + topHits = searcher.search(q, collectorManager); assertEquals(2, topHits.scoreDocs.length); CheckHits.checkExplanations(q, "", searcher); diff --git a/lucene/core/src/test/org/apache/lucene/document/TestLongDistanceFeatureQuery.java b/lucene/core/src/test/org/apache/lucene/document/TestLongDistanceFeatureQuery.java index 2f35024c220a..2ea6e161435f 100644 --- a/lucene/core/src/test/org/apache/lucene/document/TestLongDistanceFeatureQuery.java +++ b/lucene/core/src/test/org/apache/lucene/document/TestLongDistanceFeatureQuery.java @@ -22,12 +22,11 @@ import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.MultiReader; -import org.apache.lucene.search.CollectorManager; import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.Query; import org.apache.lucene.search.ScoreDoc; import org.apache.lucene.search.TopDocs; -import org.apache.lucene.search.TopScoreDocCollector; +import org.apache.lucene.search.TopScoreDocCollectorManager; import org.apache.lucene.store.Directory; import org.apache.lucene.tests.index.RandomIndexWriter; import org.apache.lucene.tests.search.CheckHits; @@ -84,9 +83,8 @@ public void testBasics() throws IOException { IndexSearcher searcher = newSearcher(reader); Query q = LongField.newDistanceFeatureQuery("foo", 3, 10, 5); - CollectorManager manager = - TopScoreDocCollector.createSharedManager(2, null, 1); - TopDocs topHits = searcher.search(q, manager); + TopScoreDocCollectorManager collectorManager = new TopScoreDocCollectorManager(2, 1); + TopDocs topHits = searcher.search(q, collectorManager); assertEquals(2, topHits.scoreDocs.length); CheckHits.checkEqual( @@ -98,8 +96,8 @@ public void testBasics() throws IOException { topHits.scoreDocs); q = LongField.newDistanceFeatureQuery("foo", 3, 7, 5); - manager = TopScoreDocCollector.createSharedManager(2, null, 1); - topHits = searcher.search(q, manager); + collectorManager = new TopScoreDocCollectorManager(2, 1); + topHits = searcher.search(q, collectorManager); assertEquals(2, topHits.scoreDocs.length); CheckHits.checkExplanations(q, "", searcher); @@ -146,9 +144,8 @@ public void testOverUnderFlow() throws IOException { IndexSearcher searcher = newSearcher(reader); Query q = LongField.newDistanceFeatureQuery("foo", 3, Long.MAX_VALUE - 1, 100); - CollectorManager manager = - TopScoreDocCollector.createSharedManager(2, null, 1); - TopDocs topHits = searcher.search(q, manager); + TopScoreDocCollectorManager collectorManager = new TopScoreDocCollectorManager(2, 1); + TopDocs topHits = searcher.search(q, collectorManager); assertEquals(2, topHits.scoreDocs.length); CheckHits.checkEqual( @@ -168,7 +165,8 @@ public void testOverUnderFlow() throws IOException { topHits.scoreDocs); q = LongField.newDistanceFeatureQuery("foo", 3, Long.MIN_VALUE + 1, 100); - topHits = searcher.search(q, manager); + topHits = searcher.search(q, collectorManager); + assertEquals(2, topHits.scoreDocs.length); CheckHits.checkExplanations(q, "", searcher); @@ -225,9 +223,8 @@ public void testMissingValue() throws IOException { IndexSearcher searcher = newSearcher(reader); Query q = LongField.newDistanceFeatureQuery("foo", 3, 10, 5); - CollectorManager manager = - TopScoreDocCollector.createSharedManager(3, null, 1); - TopDocs topHits = searcher.search(q, manager); + TopScoreDocCollectorManager collectorManager = new TopScoreDocCollectorManager(3, 1); + TopDocs topHits = searcher.search(q, collectorManager); assertEquals(2, topHits.scoreDocs.length); CheckHits.checkEqual( @@ -287,9 +284,8 @@ public void testMultiValued() throws IOException { IndexSearcher searcher = newSearcher(reader); Query q = LongField.newDistanceFeatureQuery("foo", 3, 10, 5); - CollectorManager manager = - TopScoreDocCollector.createSharedManager(2, null, 1); - TopDocs topHits = searcher.search(q, manager); + TopScoreDocCollectorManager collectorManager = new TopScoreDocCollectorManager(2, 1); + TopDocs topHits = searcher.search(q, collectorManager); assertEquals(2, topHits.scoreDocs.length); CheckHits.checkEqual( @@ -301,8 +297,8 @@ public void testMultiValued() throws IOException { topHits.scoreDocs); q = LongField.newDistanceFeatureQuery("foo", 3, 7, 5); - manager = TopScoreDocCollector.createSharedManager(2, null, 1); - topHits = searcher.search(q, manager); + collectorManager = new TopScoreDocCollectorManager(2, 1); + topHits = searcher.search(q, collectorManager); assertEquals(2, topHits.scoreDocs.length); CheckHits.checkExplanations(q, "", searcher); 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 df051f3244b4..e54e76875103 100644 --- a/lucene/core/src/test/org/apache/lucene/index/TestIndexSorting.java +++ b/lucene/core/src/test/org/apache/lucene/index/TestIndexSorting.java @@ -75,7 +75,7 @@ import org.apache.lucene.search.TermQuery; import org.apache.lucene.search.TermStatistics; import org.apache.lucene.search.TopDocs; -import org.apache.lucene.search.TopFieldCollector; +import org.apache.lucene.search.TopFieldCollectorManager; import org.apache.lucene.search.similarities.Similarity; import org.apache.lucene.store.Directory; import org.apache.lucene.tests.analysis.MockAnalyzer; @@ -2651,11 +2651,9 @@ public void testRandom3() throws Exception { TopDocs hits1 = s1.search( new MatchAllDocsQuery(), - TopFieldCollector.createSharedManager(sort, numHits, null, Integer.MAX_VALUE)); + new TopFieldCollectorManager(sort, numHits, Integer.MAX_VALUE)); TopDocs hits2 = - s2.search( - new MatchAllDocsQuery(), - TopFieldCollector.createSharedManager(sort, numHits, null, 1)); + s2.search(new MatchAllDocsQuery(), new TopFieldCollectorManager(sort, numHits, 1)); if (VERBOSE) { System.out.println(" topDocs query-time sort: totalHits=" + hits1.totalHits.value); diff --git a/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterMaxDocs.java b/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterMaxDocs.java index 5fd575762586..102d1786e5be 100644 --- a/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterMaxDocs.java +++ b/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterMaxDocs.java @@ -23,13 +23,12 @@ import java.util.concurrent.CountDownLatch; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; -import org.apache.lucene.search.CollectorManager; import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.Sort; import org.apache.lucene.search.SortField; import org.apache.lucene.search.TermQuery; import org.apache.lucene.search.TopDocs; -import org.apache.lucene.search.TopScoreDocCollector; +import org.apache.lucene.search.TopScoreDocCollectorManager; import org.apache.lucene.store.Directory; import org.apache.lucene.store.FilterDirectory; import org.apache.lucene.store.NoLockFactory; @@ -67,9 +66,9 @@ public void testExactlyAtTrueLimit() throws Exception { assertEquals(IndexWriter.MAX_DOCS, ir.maxDoc()); assertEquals(IndexWriter.MAX_DOCS, ir.numDocs()); IndexSearcher searcher = new IndexSearcher(ir); - CollectorManager manager = - TopScoreDocCollector.createSharedManager(10, null, Integer.MAX_VALUE); - TopDocs hits = searcher.search(new TermQuery(new Term("field", "text")), manager); + TopScoreDocCollectorManager collectorManager = + new TopScoreDocCollectorManager(10, null, Integer.MAX_VALUE, true); + TopDocs hits = searcher.search(new TermQuery(new Term("field", "text")), collectorManager); assertEquals(IndexWriter.MAX_DOCS, hits.totalHits.value); // Sort by docID reversed: 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 2413e1b9e23f..77883626b2d7 100644 --- a/lucene/core/src/test/org/apache/lucene/search/TestBoolean2.java +++ b/lucene/core/src/test/org/apache/lucene/search/TestBoolean2.java @@ -239,18 +239,18 @@ public void queriesTest(Query query, int[] expDocNrs) throws Exception { // 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 - CollectorManager manager = - TopScoreDocCollector.createSharedManager(topDocsToCheck, null, Integer.MAX_VALUE); - ScoreDoc[] hits1 = searcher.search(query, manager).scoreDocs; - manager = TopScoreDocCollector.createSharedManager(topDocsToCheck, null, Integer.MAX_VALUE); - ScoreDoc[] hits2 = searcher.search(query, manager).scoreDocs; + TopScoreDocCollectorManager collectorManager = + new TopScoreDocCollectorManager(topDocsToCheck, Integer.MAX_VALUE); + ScoreDoc[] hits1 = searcher.search(query, collectorManager).scoreDocs; + collectorManager = new TopScoreDocCollectorManager(topDocsToCheck, Integer.MAX_VALUE); + ScoreDoc[] hits2 = searcher.search(query, collectorManager).scoreDocs; CheckHits.checkHitsQuery(query, hits1, hits2, expDocNrs); // Since we have no deleted docs, we should also be able to verify identical matches & // scores against an single segment copy of our index - manager = TopScoreDocCollector.createSharedManager(topDocsToCheck, null, Integer.MAX_VALUE); - TopDocs topDocs = singleSegmentSearcher.search(query, manager); + collectorManager = new TopScoreDocCollectorManager(topDocsToCheck, Integer.MAX_VALUE); + TopDocs topDocs = singleSegmentSearcher.search(query, collectorManager); hits2 = topDocs.scoreDocs; CheckHits.checkHitsQuery(query, hits1, hits2, expDocNrs); @@ -258,10 +258,10 @@ public void queriesTest(Query query, int[] expDocNrs) throws Exception { assertEquals(mulFactor * topDocs.totalHits.value, bigSearcher.count(query)); // now check 2 diff scorers from the bigSearcher as well - manager = TopScoreDocCollector.createSharedManager(topDocsToCheck, null, Integer.MAX_VALUE); - hits1 = bigSearcher.search(query, manager).scoreDocs; - manager = TopScoreDocCollector.createSharedManager(topDocsToCheck, null, Integer.MAX_VALUE); - hits2 = bigSearcher.search(query, manager).scoreDocs; + collectorManager = new TopScoreDocCollectorManager(topDocsToCheck, Integer.MAX_VALUE); + hits1 = bigSearcher.search(query, collectorManager).scoreDocs; + collectorManager = new TopScoreDocCollectorManager(topDocsToCheck, Integer.MAX_VALUE); + hits2 = bigSearcher.search(query, collectorManager).scoreDocs; // NOTE: just comparing results, not vetting against expDocNrs // since we have dups in bigSearcher @@ -390,10 +390,8 @@ public void testRandomQueries() throws Exception { // check diff (randomized) scorers (from AssertingSearcher) produce the same results ScoreDoc[] hits1 = - searcher.search(q1, TopFieldCollector.createSharedManager(sort, 1000, null, 1)) - .scoreDocs; - TopDocs topDocs = - searcher.search(q1, TopFieldCollector.createSharedManager(sort, 1000, null, 1)); + searcher.search(q1, new TopFieldCollectorManager(sort, 1000, 1)).scoreDocs; + TopDocs topDocs = searcher.search(q1, new TopFieldCollectorManager(sort, 1000, 1)); ScoreDoc[] hits2 = topDocs.scoreDocs; CheckHits.checkEqual(q1, hits1, hits2); @@ -406,12 +404,10 @@ public void testRandomQueries() throws Exception { // test diff (randomized) scorers produce the same results on bigSearcher as well hits1 = - bigSearcher.search( - q1, TopFieldCollector.createSharedManager(sort, 1000 * mulFactor, null, 1)) + bigSearcher.search(q1, new TopFieldCollectorManager(sort, 1000 * mulFactor, 1)) .scoreDocs; hits2 = - bigSearcher.search( - q1, TopFieldCollector.createSharedManager(sort, 1000 * mulFactor, null, 1)) + bigSearcher.search(q1, new TopFieldCollectorManager(sort, 1000 * mulFactor, 1)) .scoreDocs; CheckHits.checkEqual(q1, hits1, hits2); } 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 90eff45832bb..159ba4f21536 100644 --- a/lucene/core/src/test/org/apache/lucene/search/TestBooleanMinShouldMatch.java +++ b/lucene/core/src/test/org/apache/lucene/search/TestBooleanMinShouldMatch.java @@ -93,9 +93,9 @@ public void verifyNrHits(Query q, int expected) throws Exception { assertEquals("result count", expected, h.length); // System.out.println("TEST: now check"); // bs2 - CollectorManager manager = - TopScoreDocCollector.createSharedManager(1000, null, Integer.MAX_VALUE); - ScoreDoc[] h2 = s.search(q, manager).scoreDocs; + TopScoreDocCollectorManager collectorManager = + new TopScoreDocCollectorManager(1000, Integer.MAX_VALUE); + ScoreDoc[] h2 = s.search(q, collectorManager).scoreDocs; if (expected != h2.length) { printHits(getTestName(), h2, s); } 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 2af33bc10b76..c65e5af8e780 100644 --- a/lucene/core/src/test/org/apache/lucene/search/TestBooleanQuery.java +++ b/lucene/core/src/test/org/apache/lucene/search/TestBooleanQuery.java @@ -523,6 +523,7 @@ public Void reduce(Collection collectors) { return null; } }); + assertTrue(matched.get()); } diff --git a/lucene/core/src/test/org/apache/lucene/search/TestConstantScoreScorer.java b/lucene/core/src/test/org/apache/lucene/search/TestConstantScoreScorer.java index 495b28f11506..12333e97374b 100644 --- a/lucene/core/src/test/org/apache/lucene/search/TestConstantScoreScorer.java +++ b/lucene/core/src/test/org/apache/lucene/search/TestConstantScoreScorer.java @@ -241,20 +241,18 @@ public void testEarlyTermination() throws IOException { // Don't use threads so that we can assert on the number of visited hits IndexSearcher is = newSearcher(ir, true, true, false); - CollectorManager manager = - TopScoreDocCollector.createSharedManager(10, null, 10); - TopDocs topDocs = - is.search(new ConstantScoreQuery(new TermQuery(new Term("key", "foo"))), manager); + TopScoreDocCollectorManager c = new TopScoreDocCollectorManager(10, 10); + TopDocs topDocs = is.search(new ConstantScoreQuery(new TermQuery(new Term("key", "foo"))), c); assertEquals(11, topDocs.totalHits.value); assertEquals(TotalHits.Relation.GREATER_THAN_OR_EQUAL_TO, topDocs.totalHits.relation); - manager = TopScoreDocCollector.createSharedManager(10, null, 10); + c = new TopScoreDocCollectorManager(10, 10); Query query = new BooleanQuery.Builder() .add(new ConstantScoreQuery(new TermQuery(new Term("key", "foo"))), Occur.SHOULD) .add(new ConstantScoreQuery(new TermQuery(new Term("key", "bar"))), Occur.FILTER) .build(); - topDocs = is.search(query, manager); + topDocs = is.search(query, c); assertEquals(11, topDocs.totalHits.value); assertEquals(TotalHits.Relation.GREATER_THAN_OR_EQUAL_TO, topDocs.totalHits.relation); diff --git a/lucene/core/src/test/org/apache/lucene/search/TestMatchAllDocsQuery.java b/lucene/core/src/test/org/apache/lucene/search/TestMatchAllDocsQuery.java index 245ee9d57aa0..dca7ff8c815a 100644 --- a/lucene/core/src/test/org/apache/lucene/search/TestMatchAllDocsQuery.java +++ b/lucene/core/src/test/org/apache/lucene/search/TestMatchAllDocsQuery.java @@ -117,15 +117,17 @@ public void testEarlyTermination() throws IOException { IndexSearcher singleThreadedSearcher = newSearcher(ir, true, true, false); final int totalHitsThreshold = 200; - CollectorManager manager = - TopScoreDocCollector.createSharedManager(10, null, totalHitsThreshold); - TopDocs topDocs = singleThreadedSearcher.search(new MatchAllDocsQuery(), manager); + TopScoreDocCollectorManager collectorManager = + new TopScoreDocCollectorManager(10, totalHitsThreshold); + + TopDocs topDocs = singleThreadedSearcher.search(new MatchAllDocsQuery(), collectorManager); assertEquals(totalHitsThreshold + 1, topDocs.totalHits.value); assertEquals(TotalHits.Relation.GREATER_THAN_OR_EQUAL_TO, topDocs.totalHits.relation); IndexSearcher is = newSearcher(ir); - manager = TopScoreDocCollector.createSharedManager(10, null, numDocs); - topDocs = is.search(new MatchAllDocsQuery(), manager); + collectorManager = new TopScoreDocCollectorManager(10, numDocs); + + topDocs = is.search(new MatchAllDocsQuery(), collectorManager); assertEquals(numDocs, topDocs.totalHits.value); assertEquals(TotalHits.Relation.EQUAL_TO, topDocs.totalHits.relation); 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 f721f5e4fe21..05cb9df5397a 100644 --- a/lucene/core/src/test/org/apache/lucene/search/TestPhraseQuery.java +++ b/lucene/core/src/test/org/apache/lucene/search/TestPhraseQuery.java @@ -772,13 +772,14 @@ public void testTopPhrases() throws IOException { new PhraseQuery("f", "d", "d") // repeated term )) { for (int topN = 1; topN <= 2; ++topN) { - CollectorManager manager = - TopScoreDocCollector.createSharedManager(topN, null, Integer.MAX_VALUE); - TopDocs topDocs = searcher.search(query, manager); - ScoreDoc[] hits1 = topDocs.scoreDocs; - manager = TopScoreDocCollector.createSharedManager(topN, null, 1); - topDocs = searcher.search(query, manager); - ScoreDoc[] hits2 = topDocs.scoreDocs; + TopScoreDocCollectorManager collectorManager = + new TopScoreDocCollectorManager(topN, Integer.MAX_VALUE); + ScoreDoc[] hits1 = searcher.search(query, collectorManager).scoreDocs; + + collectorManager = new TopScoreDocCollectorManager(topN, 1); + TopDocs topDocs2 = searcher.search(query, collectorManager); + ScoreDoc[] hits2 = topDocs2.scoreDocs; + assertTrue("" + query, hits1.length > 0); CheckHits.checkEqual(query, hits1, hits2); } @@ -1029,10 +1030,10 @@ public void testRandomTopDocs() throws IOException { for (String secondTerm : new String[] {"a", "b", "c"}) { Query query = new PhraseQuery("foo", newBytesRef(firstTerm), newBytesRef(secondTerm)); - CollectorManager completeManager = - TopScoreDocCollector.createSharedManager(10, null, Integer.MAX_VALUE); // COMPLETE - CollectorManager topScoresManager = - TopScoreDocCollector.createSharedManager(10, null, 10); // TOP_SCORES + TopScoreDocCollectorManager completeManager = + new TopScoreDocCollectorManager(10, Integer.MAX_VALUE); // COMPLETE + TopScoreDocCollectorManager topScoresManager = + new TopScoreDocCollectorManager(10, 10); // TOP_SCORES TopDocs complete = searcher.search(query, completeManager); TopDocs topScores = searcher.search(query, topScoresManager); @@ -1044,9 +1045,9 @@ public void testRandomTopDocs() throws IOException { .add(new TermQuery(new Term("foo", "b")), Occur.FILTER) .build(); - completeManager = - TopScoreDocCollector.createSharedManager(10, null, Integer.MAX_VALUE); // COMPLETE - topScoresManager = TopScoreDocCollector.createSharedManager(10, null, 10); // TOP_SCORES + completeManager = new TopScoreDocCollectorManager(10, Integer.MAX_VALUE); // COMPLETE + topScoresManager = new TopScoreDocCollectorManager(10, 10); // TOP_SCORES + complete = searcher.search(filteredQuery, completeManager); topScores = searcher.search(filteredQuery, topScoresManager); CheckHits.checkEqual(query, complete.scoreDocs, topScores.scoreDocs); 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 5d99816037ec..cccc765cab9b 100644 --- a/lucene/core/src/test/org/apache/lucene/search/TestReqOptSumScorer.java +++ b/lucene/core/src/test/org/apache/lucene/search/TestReqOptSumScorer.java @@ -271,9 +271,9 @@ private void doTestRandom(double optFreq) throws IOException { Query query = new BooleanQuery.Builder().add(mustTerm, Occur.MUST).add(shouldTerm, Occur.SHOULD).build(); - CollectorManager manager = - TopScoreDocCollector.createSharedManager(10, null, Integer.MAX_VALUE); - TopDocs topDocs = searcher.search(query, manager); + TopScoreDocCollectorManager collectorManager = + new TopScoreDocCollectorManager(10, Integer.MAX_VALUE); + TopDocs topDocs = searcher.search(query, collectorManager); ScoreDoc[] expected = topDocs.scoreDocs; // Also test a filtered query, since it does not compute the score on all @@ -284,8 +284,8 @@ private void doTestRandom(double optFreq) throws IOException { .add(new TermQuery(new Term("f", "C")), Occur.FILTER) .build(); - manager = TopScoreDocCollector.createSharedManager(10, null, Integer.MAX_VALUE); - topDocs = searcher.search(query, manager); + collectorManager = new TopScoreDocCollectorManager(10, Integer.MAX_VALUE); + topDocs = searcher.search(query, collectorManager); ScoreDoc[] expectedFiltered = topDocs.scoreDocs; CheckHits.checkTopScores(random(), query, searcher); @@ -297,8 +297,8 @@ private void doTestRandom(double optFreq) throws IOException { .add(shouldTerm, Occur.SHOULD) .build(); - manager = TopScoreDocCollector.createSharedManager(10, null, 1); - topDocs = searcher.search(q, manager); + collectorManager = new TopScoreDocCollectorManager(10, 1); + topDocs = searcher.search(q, collectorManager); ScoreDoc[] actual = topDocs.scoreDocs; CheckHits.checkEqual(query, expected, actual); @@ -307,8 +307,8 @@ private void doTestRandom(double optFreq) throws IOException { .add(mustTerm, Occur.MUST) .add(new RandomApproximationQuery(shouldTerm, random()), Occur.SHOULD) .build(); - manager = TopScoreDocCollector.createSharedManager(10, null, 1); - topDocs = searcher.search(q, manager); + collectorManager = new TopScoreDocCollectorManager(10, 1); + topDocs = searcher.search(q, collectorManager); actual = topDocs.scoreDocs; CheckHits.checkEqual(q, expected, actual); @@ -317,8 +317,8 @@ private void doTestRandom(double optFreq) throws IOException { .add(new RandomApproximationQuery(mustTerm, random()), Occur.MUST) .add(new RandomApproximationQuery(shouldTerm, random()), Occur.SHOULD) .build(); - manager = TopScoreDocCollector.createSharedManager(10, null, 1); - topDocs = searcher.search(q, manager); + collectorManager = new TopScoreDocCollectorManager(10, 1); + topDocs = searcher.search(q, collectorManager); actual = topDocs.scoreDocs; CheckHits.checkEqual(q, expected, actual); } @@ -339,8 +339,8 @@ private void doTestRandom(double optFreq) throws IOException { Occur.FILTER) .build(); - manager = TopScoreDocCollector.createSharedManager(10, null, 1); - topDocs = searcher.search(nestedQ, manager); + collectorManager = new TopScoreDocCollectorManager(10, 1); + topDocs = searcher.search(nestedQ, collectorManager); ScoreDoc[] actualFiltered = topDocs.scoreDocs; CheckHits.checkEqual(nestedQ, expectedFiltered, actualFiltered); } diff --git a/lucene/core/src/test/org/apache/lucene/search/TestSloppyPhraseQuery.java b/lucene/core/src/test/org/apache/lucene/search/TestSloppyPhraseQuery.java index 67c1aadefa59..8b69510f7354 100644 --- a/lucene/core/src/test/org/apache/lucene/search/TestSloppyPhraseQuery.java +++ b/lucene/core/src/test/org/apache/lucene/search/TestSloppyPhraseQuery.java @@ -270,6 +270,7 @@ public Void reduce(Collection collectors) { return null; } }); + QueryUtils.check(random(), pq, searcher); } diff --git a/lucene/core/src/test/org/apache/lucene/search/TestSortOptimization.java b/lucene/core/src/test/org/apache/lucene/search/TestSortOptimization.java index 3cf6b2efd311..765c355e534e 100644 --- a/lucene/core/src/test/org/apache/lucene/search/TestSortOptimization.java +++ b/lucene/core/src/test/org/apache/lucene/search/TestSortOptimization.java @@ -91,9 +91,11 @@ public void testLongSortOptimization() throws IOException { final int totalHitsThreshold = 3; { // simple sort - CollectorManager manager = - TopFieldCollector.createSharedManager(sort, numHits, null, totalHitsThreshold); - TopDocs topDocs = searcher.search(new MatchAllDocsQuery(), manager); + final TopFieldCollectorManager collectorManager = + new TopFieldCollectorManager(sort, numHits, totalHitsThreshold); + + TopDocs topDocs = searcher.search(new MatchAllDocsQuery(), collectorManager); + assertEquals(topDocs.scoreDocs.length, numHits); for (int i = 0; i < numHits; i++) { FieldDoc fieldDoc = (FieldDoc) topDocs.scoreDocs[i]; @@ -106,9 +108,9 @@ public void testLongSortOptimization() throws IOException { { // paging sort with after long afterValue = 2; FieldDoc after = new FieldDoc(2, Float.NaN, new Long[] {afterValue}); - CollectorManager manager = - TopFieldCollector.createSharedManager(sort, numHits, after, totalHitsThreshold); - TopDocs topDocs = searcher.search(new MatchAllDocsQuery(), manager); + final TopFieldCollectorManager collectorManager = + new TopFieldCollectorManager(sort, numHits, after, totalHitsThreshold); + TopDocs topDocs = searcher.search(new MatchAllDocsQuery(), collectorManager); assertEquals(topDocs.scoreDocs.length, numHits); for (int i = 0; i < numHits; i++) { FieldDoc fieldDoc = (FieldDoc) topDocs.scoreDocs[i]; @@ -119,10 +121,10 @@ public void testLongSortOptimization() throws IOException { } { // test that if there is the secondary sort on _score, scores are filled correctly - CollectorManager manager = - TopFieldCollector.createSharedManager( - new Sort(sortField, FIELD_SCORE), numHits, null, totalHitsThreshold); - TopDocs topDocs = searcher.search(new MatchAllDocsQuery(), manager); + final TopFieldCollectorManager collectorManager = + new TopFieldCollectorManager( + new Sort(sortField, FIELD_SCORE), numHits, totalHitsThreshold); + TopDocs topDocs = searcher.search(new MatchAllDocsQuery(), collectorManager); assertEquals(topDocs.scoreDocs.length, numHits); for (int i = 0; i < numHits; i++) { FieldDoc fieldDoc = (FieldDoc) topDocs.scoreDocs[i]; @@ -135,10 +137,10 @@ public void testLongSortOptimization() throws IOException { } { // test that if numeric field is a secondary sort, no optimization is run - CollectorManager manager = - TopFieldCollector.createSharedManager( - new Sort(FIELD_SCORE, sortField), numHits, null, totalHitsThreshold); - TopDocs topDocs = searcher.search(new MatchAllDocsQuery(), manager); + final TopFieldCollectorManager collectorManager = + new TopFieldCollectorManager( + new Sort(FIELD_SCORE, sortField), numHits, totalHitsThreshold); + TopDocs topDocs = searcher.search(new MatchAllDocsQuery(), collectorManager); assertEquals(topDocs.scoreDocs.length, numHits); assertEquals( topDocs.totalHits.value, @@ -173,9 +175,9 @@ public void testLongSortOptimizationOnFieldNotIndexedWithPoints() throws IOExcep final int numHits = 3; final int totalHitsThreshold = 3; - CollectorManager manager = - TopFieldCollector.createSharedManager(sort, numHits, null, totalHitsThreshold); - TopDocs topDocs = searcher.search(new MatchAllDocsQuery(), manager); + final TopFieldCollectorManager collectorManager = + new TopFieldCollectorManager(sort, numHits, totalHitsThreshold); + TopDocs topDocs = searcher.search(new MatchAllDocsQuery(), collectorManager); assertEquals( topDocs.scoreDocs.length, numHits); // sort still works and returns expected number of docs for (int i = 0; i < numHits; i++) { @@ -221,9 +223,9 @@ public void testSortOptimizationWithMissingValues() throws IOException { final SortField sortField = new SortField("my_field", SortField.Type.LONG); sortField.setMissingValue(0L); // set a competitive missing value final Sort sort = new Sort(sortField); - CollectorManager manager = - TopFieldCollector.createSharedManager(sort, numHits, null, totalHitsThreshold); - TopDocs topDocs = searcher.search(new MatchAllDocsQuery(), manager); + final TopFieldCollectorManager collectorManager = + new TopFieldCollectorManager(sort, numHits, totalHitsThreshold); + TopDocs topDocs = searcher.search(new MatchAllDocsQuery(), collectorManager); assertEquals(topDocs.scoreDocs.length, numHits); assertNonCompetitiveHitsAreSkipped(topDocs.totalHits.value, numDocs); } @@ -246,9 +248,9 @@ public void testSortOptimizationWithMissingValues() throws IOException { final SortField sortField = new SortField("my_field", SortField.Type.LONG); sortField.setMissingValue(100L); // set a NON competitive missing value final Sort sort = new Sort(sortField); - CollectorManager manager = - TopFieldCollector.createSharedManager(sort, numHits, null, totalHitsThreshold); - TopDocs topDocs = searcher.search(new MatchAllDocsQuery(), manager); + final TopFieldCollectorManager collectorManager = + new TopFieldCollectorManager(sort, numHits, totalHitsThreshold); + TopDocs topDocs = searcher.search(new MatchAllDocsQuery(), collectorManager); assertEquals(topDocs.scoreDocs.length, numHits); assertNonCompetitiveHitsAreSkipped(topDocs.totalHits.value, numDocs); } @@ -398,9 +400,9 @@ public void testSortOptimizationEqualValues() throws IOException { // GREATER_THAN_OR_EQUAL_TO final SortField sortField = new SortField("my_field1", SortField.Type.INT); final Sort sort = new Sort(sortField); - CollectorManager manager = - TopFieldCollector.createSharedManager(sort, numHits, null, totalHitsThreshold); - TopDocs topDocs = searcher.search(new MatchAllDocsQuery(), manager); + final TopFieldCollectorManager collectorManager = + new TopFieldCollectorManager(sort, numHits, totalHitsThreshold); + TopDocs topDocs = searcher.search(new MatchAllDocsQuery(), collectorManager); assertEquals(topDocs.scoreDocs.length, numHits); for (int i = 0; i < numHits; i++) { FieldDoc fieldDoc = (FieldDoc) topDocs.scoreDocs[i]; @@ -419,10 +421,10 @@ public void testSortOptimizationEqualValues() throws IOException { final int afterDocID = 10 + random().nextInt(1000); final SortField sortField = new SortField("my_field1", SortField.Type.INT); final Sort sort = new Sort(sortField); - FieldDoc after = new FieldDoc(afterDocID, Float.NaN, new Integer[] {afterValue}); - CollectorManager manager = - TopFieldCollector.createSharedManager(sort, numHits, after, totalHitsThreshold); - TopDocs topDocs = searcher.search(new MatchAllDocsQuery(), manager); + final FieldDoc after = new FieldDoc(afterDocID, Float.NaN, new Integer[] {afterValue}); + final TopFieldCollectorManager collectorManager = + new TopFieldCollectorManager(sort, numHits, after, totalHitsThreshold); + TopDocs topDocs = searcher.search(new MatchAllDocsQuery(), collectorManager); assertEquals(topDocs.scoreDocs.length, numHits); for (int i = 0; i < numHits; i++) { FieldDoc fieldDoc = (FieldDoc) topDocs.scoreDocs[i]; @@ -437,9 +439,9 @@ public void testSortOptimizationEqualValues() throws IOException { final SortField sortField1 = new SortField("my_field1", SortField.Type.INT); final SortField sortField2 = new SortField("my_field2", SortField.Type.INT); final Sort sort = new Sort(sortField1, sortField2); - CollectorManager manager = - TopFieldCollector.createSharedManager(sort, numHits, null, totalHitsThreshold); - TopDocs topDocs = searcher.search(new MatchAllDocsQuery(), manager); + final TopFieldCollectorManager collectorManager = + new TopFieldCollectorManager(sort, numHits, totalHitsThreshold); + TopDocs topDocs = searcher.search(new MatchAllDocsQuery(), collectorManager); assertEquals(topDocs.scoreDocs.length, numHits); for (int i = 0; i < numHits; i++) { FieldDoc fieldDoc = (FieldDoc) topDocs.scoreDocs[i]; @@ -478,9 +480,10 @@ public void testFloatSortOptimization() throws IOException { final int totalHitsThreshold = 3; { // simple sort - CollectorManager manager = - TopFieldCollector.createSharedManager(sort, numHits, null, totalHitsThreshold); - TopDocs topDocs = searcher.search(new MatchAllDocsQuery(), manager); + final TopFieldCollectorManager collectorManager = + new TopFieldCollectorManager(sort, numHits, totalHitsThreshold); + + TopDocs topDocs = searcher.search(new MatchAllDocsQuery(), collectorManager); assertEquals(topDocs.scoreDocs.length, numHits); for (int i = 0; i < numHits; i++) { FieldDoc fieldDoc = (FieldDoc) topDocs.scoreDocs[i]; @@ -535,9 +538,9 @@ public void testDocSortOptimizationMultipleIndices() throws IOException { // single threaded so totalHits is deterministic IndexSearcher searcher = newSearcher(readers[i], random().nextBoolean(), random().nextBoolean(), false); - CollectorManager manager = - TopFieldCollector.createSharedManager(sort, size, after, totalHitsThreshold); - topDocs[i] = searcher.search(new MatchAllDocsQuery(), manager); + final TopFieldCollectorManager collectorManager = + new TopFieldCollectorManager(sort, size, after, totalHitsThreshold); + topDocs[i] = searcher.search(new MatchAllDocsQuery(), collectorManager); for (int docID = 0; docID < topDocs[i].scoreDocs.length; docID++) { topDocs[i].scoreDocs[docID].shardIndex = i; } @@ -587,9 +590,9 @@ public void testDocSortOptimizationWithAfter() throws IOException { { final Sort sort = new Sort(FIELD_DOC); FieldDoc after = new FieldDoc(searchAfter, Float.NaN, new Integer[] {searchAfter}); - CollectorManager manager = - TopFieldCollector.createSharedManager(sort, numHits, after, totalHitsThreshold); - TopDocs topDocs = searcher.search(new MatchAllDocsQuery(), manager); + final TopFieldCollectorManager collectorManager = + new TopFieldCollectorManager(sort, numHits, after, totalHitsThreshold); + TopDocs topDocs = searcher.search(new MatchAllDocsQuery(), collectorManager); int expNumHits = (searchAfter >= (numDocs - numHits)) ? (numDocs - searchAfter - 1) : numHits; assertEquals(expNumHits, topDocs.scoreDocs.length); @@ -605,9 +608,9 @@ public void testDocSortOptimizationWithAfter() throws IOException { { final Sort sort = new Sort(FIELD_DOC, FIELD_SCORE); FieldDoc after = new FieldDoc(searchAfter, Float.NaN, new Object[] {searchAfter, 1.0f}); - CollectorManager manager = - TopFieldCollector.createSharedManager(sort, numHits, after, totalHitsThreshold); - TopDocs topDocs = searcher.search(new MatchAllDocsQuery(), manager); + final TopFieldCollectorManager collectorManager = + new TopFieldCollectorManager(sort, numHits, after, totalHitsThreshold); + TopDocs topDocs = searcher.search(new MatchAllDocsQuery(), collectorManager); int expNumHits = (searchAfter >= (numDocs - numHits)) ? (numDocs - searchAfter - 1) : numHits; assertEquals(expNumHits, topDocs.scoreDocs.length); @@ -623,9 +626,9 @@ public void testDocSortOptimizationWithAfter() throws IOException { { final Sort sort = new Sort(new SortField(null, SortField.Type.DOC, true)); FieldDoc after = new FieldDoc(searchAfter, Float.NaN, new Integer[] {searchAfter}); - CollectorManager manager = - TopFieldCollector.createSharedManager(sort, numHits, after, totalHitsThreshold); - TopDocs topDocs = searcher.search(new MatchAllDocsQuery(), manager); + final TopFieldCollectorManager collectorManager = + new TopFieldCollectorManager(sort, numHits, after, totalHitsThreshold); + TopDocs topDocs = searcher.search(new MatchAllDocsQuery(), collectorManager); int expNumHits = (searchAfter < numHits) ? searchAfter : numHits; assertEquals(expNumHits, topDocs.scoreDocs.length); for (int i = 0; i < topDocs.scoreDocs.length; i++) { @@ -705,9 +708,9 @@ public void testDocSortOptimization() throws IOException { // sort by _doc should skip all non-competitive documents { - CollectorManager manager = - TopFieldCollector.createSharedManager(sort, numHits, null, totalHitsThreshold); - TopDocs topDocs = searcher.search(new MatchAllDocsQuery(), manager); + final TopFieldCollectorManager collectorManager = + new TopFieldCollectorManager(sort, numHits, totalHitsThreshold); + TopDocs topDocs = searcher.search(new MatchAllDocsQuery(), collectorManager); assertEquals(numHits, topDocs.scoreDocs.length); for (int i = 0; i < numHits; i++) { assertEquals(i, topDocs.scoreDocs[i].doc); @@ -718,14 +721,14 @@ public void testDocSortOptimization() throws IOException { // sort by _doc with a bool query should skip all non-competitive documents { - CollectorManager manager = - TopFieldCollector.createSharedManager(sort, numHits, null, totalHitsThreshold); + final TopFieldCollectorManager collectorManager = + new TopFieldCollectorManager(sort, numHits, totalHitsThreshold); int lowerRange = 40; BooleanQuery.Builder bq = new BooleanQuery.Builder(); bq.add(LongPoint.newRangeQuery("lf", lowerRange, Long.MAX_VALUE), BooleanClause.Occur.MUST); bq.add(new TermQuery(new Term("tf", "seg1")), BooleanClause.Occur.MUST); - TopDocs topDocs = searcher.search(bq.build(), manager); + TopDocs topDocs = searcher.search(bq.build(), collectorManager); assertEquals(numHits, topDocs.scoreDocs.length); StoredFields storedFields = searcher.storedFields(); for (int i = 0; i < numHits; i++) { @@ -770,12 +773,12 @@ public void testDocSort() throws IOException { final Sort sort = new Sort(FIELD_DOC); { - CollectorManager manager = - TopFieldCollector.createSharedManager(sort, numHits, null, totalHitsThreshold); + final TopFieldCollectorManager collectorManager = + new TopFieldCollectorManager(sort, numHits, totalHitsThreshold); BooleanQuery.Builder bq = new BooleanQuery.Builder(); bq.add(LongPoint.newExactQuery("lf", 1), BooleanClause.Occur.MUST); bq.add(new TermQuery(new Term("id", "id3")), BooleanClause.Occur.MUST_NOT); - TopDocs topDocs = searcher.search(bq.build(), manager); + TopDocs topDocs = searcher.search(bq.build(), collectorManager); assertEquals(2, topDocs.scoreDocs.length); } 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 ae026a87367f..f366debb9ce5 100644 --- a/lucene/core/src/test/org/apache/lucene/search/TestSynonymQuery.java +++ b/lucene/core/src/test/org/apache/lucene/search/TestSynonymQuery.java @@ -185,10 +185,10 @@ private void doTestScores(int totalHitsThreshold) throws IOException { .addTerm(new Term("f", "b"), boost == 0 ? 1f : boost) .build(); - CollectorManager manager = - TopScoreDocCollector.createSharedManager( - Math.min(reader.numDocs(), totalHitsThreshold), null, totalHitsThreshold); - TopDocs topDocs = searcher.search(query, manager); + TopScoreDocCollectorManager collectorManager = + new TopScoreDocCollectorManager( + Math.min(reader.numDocs(), totalHitsThreshold), totalHitsThreshold); + TopDocs topDocs = searcher.search(query, collectorManager); if (topDocs.totalHits.value < totalHitsThreshold) { assertEquals(new TotalHits(11, TotalHits.Relation.EQUAL_TO), topDocs.totalHits); } else { @@ -244,10 +244,10 @@ public void doTestBoosts(int totalHitsThreshold) throws IOException { .addTerm(new Term("f", "c")) .build(); - CollectorManager manager = - TopScoreDocCollector.createSharedManager( - Math.min(reader.numDocs(), totalHitsThreshold), null, totalHitsThreshold); - TopDocs topDocs = searcher.search(query, manager); + TopScoreDocCollectorManager collectorManager = + new TopScoreDocCollectorManager( + Math.min(reader.numDocs(), totalHitsThreshold), totalHitsThreshold); + TopDocs topDocs = searcher.search(query, collectorManager); if (topDocs.totalHits.value < totalHitsThreshold) { assertEquals(TotalHits.Relation.EQUAL_TO, topDocs.totalHits.relation); assertEquals(22, topDocs.totalHits.value); @@ -461,10 +461,10 @@ public void testRandomTopDocs() throws IOException { .addTerm(new Term("foo", Integer.toString(term2)), boost2) .build(); - CollectorManager completeManager = - TopScoreDocCollector.createSharedManager(10, null, Integer.MAX_VALUE); - CollectorManager topScoresManager = - TopScoreDocCollector.createSharedManager(10, null, 1); + TopScoreDocCollectorManager completeManager = + new TopScoreDocCollectorManager(10, Integer.MAX_VALUE); // COMPLETE + TopScoreDocCollectorManager topScoresManager = + new TopScoreDocCollectorManager(10, 1); // TOP_SCORES TopDocs complete = searcher.search(query, completeManager); TopDocs topScores = searcher.search(query, topScoresManager); @@ -477,8 +477,9 @@ public void testRandomTopDocs() throws IOException { .add(new TermQuery(new Term("foo", Integer.toString(filterTerm))), Occur.FILTER) .build(); - completeManager = TopScoreDocCollector.createSharedManager(10, null, Integer.MAX_VALUE); - topScoresManager = TopScoreDocCollector.createSharedManager(10, null, 1); + completeManager = new TopScoreDocCollectorManager(10, Integer.MAX_VALUE); // COMPLETE + topScoresManager = new TopScoreDocCollectorManager(10, 1); // TOP_SCORES + complete = searcher.search(filteredQuery, completeManager); topScores = searcher.search(filteredQuery, topScoresManager); CheckHits.checkEqual(query, complete.scoreDocs, topScores.scoreDocs); 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 6ddb6999c620..314bc7a5d68f 100644 --- a/lucene/core/src/test/org/apache/lucene/search/TestTermScorer.java +++ b/lucene/core/src/test/org/apache/lucene/search/TestTermScorer.java @@ -242,10 +242,10 @@ public void testRandomTopDocs() throws IOException { for (int iter = 0; iter < 15; ++iter) { Query query = new TermQuery(new Term("foo", Integer.toString(iter))); - CollectorManager completeManager = - TopScoreDocCollector.createSharedManager(10, null, Integer.MAX_VALUE); - CollectorManager topScoresManager = - TopScoreDocCollector.createSharedManager(10, null, 1); + TopScoreDocCollectorManager completeManager = + new TopScoreDocCollectorManager(10, Integer.MAX_VALUE); // COMPLETE + TopScoreDocCollectorManager topScoresManager = + new TopScoreDocCollectorManager(10, 1); // TOP_SCORES TopDocs complete = searcher.search(query, completeManager); TopDocs topScores = searcher.search(query, topScoresManager); @@ -258,8 +258,8 @@ public void testRandomTopDocs() throws IOException { .add(new TermQuery(new Term("foo", Integer.toString(filterTerm))), Occur.FILTER) .build(); - completeManager = TopScoreDocCollector.createSharedManager(10, null, Integer.MAX_VALUE); - topScoresManager = TopScoreDocCollector.createSharedManager(10, null, 1); + completeManager = new TopScoreDocCollectorManager(10, Integer.MAX_VALUE); // COMPLETE + topScoresManager = new TopScoreDocCollectorManager(10, 1); // TOP_SCORES complete = searcher.search(filteredQuery, completeManager); topScores = searcher.search(filteredQuery, topScoresManager); CheckHits.checkEqual(query, complete.scoreDocs, topScores.scoreDocs); 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 b3d9a9b8c933..e28be104ac0c 100644 --- a/lucene/core/src/test/org/apache/lucene/search/TestTopDocsCollector.java +++ b/lucene/core/src/test/org/apache/lucene/search/TestTopDocsCollector.java @@ -135,19 +135,21 @@ private TopDocsCollector doSearch(int numResults, Query q) throws IOEx return tdc; } - private static TopDocs doSearchWithThreshold( + private TopDocs doSearchWithThreshold( int numResults, int thresHold, Query q, IndexReader indexReader) throws IOException { IndexSearcher searcher = newSearcher(indexReader, true, true, false); - CollectorManager manager = - TopScoreDocCollector.createSharedManager(numResults, null, thresHold); - return searcher.search(q, manager); + TopScoreDocCollectorManager collectorManager = + new TopScoreDocCollectorManager( + numResults, null, thresHold, searcher.getSlices().length > 1); + return searcher.search(q, collectorManager); } private static TopDocs doConcurrentSearchWithThreshold( int numResults, int threshold, Query q, IndexReader indexReader) throws IOException { IndexSearcher searcher = newSearcher(indexReader, true, true, true); - CollectorManager collectorManager = - TopScoreDocCollector.createSharedManager(numResults, null, threshold); + TopScoreDocCollectorManager collectorManager = + new TopScoreDocCollectorManager( + numResults, null, threshold, searcher.getSlices().length > 1); return searcher.search(q, collectorManager); } @@ -308,7 +310,8 @@ public void testSetMinCompetitiveScore() throws Exception { assertEquals(2, reader.leaves().size()); w.close(); - TopScoreDocCollector collector = TopScoreDocCollector.create(2, null, 2); + TopScoreDocCollectorManager collectorManager = new TopScoreDocCollectorManager(2, 2); + TopScoreDocCollector collector = collectorManager.newCollector(); Score scorer = new Score(); LeafCollector leafCollector = collector.getLeafCollector(reader.leaves().get(0)); @@ -369,8 +372,8 @@ public void testSharedCountCollectorManager() throws Exception { assertEquals(2, reader.leaves().size()); w.close(); - TopDocs tdc2 = doSearchWithThreshold(5, 10, q, reader); TopDocs tdc = doConcurrentSearchWithThreshold(5, 10, q, reader); + TopDocs tdc2 = doSearchWithThreshold(5, 10, q, reader); CheckHits.checkEqual(q, tdc.scoreDocs, tdc2.scoreDocs); @@ -392,7 +395,9 @@ public void testTotalHits() throws Exception { w.close(); for (int totalHitsThreshold = 0; totalHitsThreshold < 20; ++totalHitsThreshold) { - TopScoreDocCollector collector = TopScoreDocCollector.create(2, null, totalHitsThreshold); + TopScoreDocCollectorManager collectorManager = + new TopScoreDocCollectorManager(2, totalHitsThreshold); + TopScoreDocCollector collector = collectorManager.newCollector(); Score scorer = new Score(); LeafCollector leafCollector = collector.getLeafCollector(reader.leaves().get(0)); @@ -442,19 +447,18 @@ public void testRelationVsTopDocsCount() throws Exception { try (IndexReader reader = DirectoryReader.open(w)) { IndexSearcher searcher = new IndexSearcher(reader); - CollectorManager manager = - TopScoreDocCollector.createSharedManager(2, null, 10); - TopDocs topDocs = searcher.search(new TermQuery(new Term("f", "foo")), manager); + TopScoreDocCollectorManager collectorManager = new TopScoreDocCollectorManager(2, 10); + TopDocs topDocs = searcher.search(new TermQuery(new Term("f", "foo")), collectorManager); assertEquals(10, topDocs.totalHits.value); assertEquals(TotalHits.Relation.EQUAL_TO, topDocs.totalHits.relation); - manager = TopScoreDocCollector.createSharedManager(2, null, 2); - topDocs = searcher.search(new TermQuery(new Term("f", "foo")), manager); + collectorManager = new TopScoreDocCollectorManager(2, 2); + topDocs = searcher.search(new TermQuery(new Term("f", "foo")), collectorManager); assertTrue(10 >= topDocs.totalHits.value); assertEquals(TotalHits.Relation.GREATER_THAN_OR_EQUAL_TO, topDocs.totalHits.relation); - manager = TopScoreDocCollector.createSharedManager(10, null, 2); - topDocs = searcher.search(new TermQuery(new Term("f", "foo")), manager); + collectorManager = new TopScoreDocCollectorManager(10, 2); + topDocs = searcher.search(new TermQuery(new Term("f", "foo")), collectorManager); assertEquals(10, topDocs.totalHits.value); assertEquals(TotalHits.Relation.EQUAL_TO, topDocs.totalHits.relation); } @@ -476,8 +480,7 @@ public void testConcurrentMinScore() throws Exception { assertEquals(3, reader.leaves().size()); w.close(); - CollectorManager manager = - TopScoreDocCollector.createSharedManager(2, null, 0); + CollectorManager manager = new TopScoreDocCollectorManager(2, 0); TopScoreDocCollector collector = manager.newCollector(); TopScoreDocCollector collector2 = manager.newCollector(); assertTrue(collector.minScoreAcc == collector2.minScoreAcc); @@ -609,8 +612,8 @@ public void testRandomMinCompetitiveScore() throws Exception { .build() }; for (Query query : queries) { - TopDocs tdc2 = doSearchWithThreshold(5, 0, query, indexReader); TopDocs tdc = doConcurrentSearchWithThreshold(5, 0, query, indexReader); + TopDocs tdc2 = doSearchWithThreshold(5, 0, query, indexReader); assertTrue(tdc.totalHits.value > 0); assertTrue(tdc2.totalHits.value > 0); @@ -650,8 +653,8 @@ public void testRealisticConcurrentMinimumScore() throws Exception { BytesRef term = BytesRef.deepCopyOf(termsEnum.term()); Query query = new TermQuery(new Term("body", term)); - TopDocs tdc2 = doSearchWithThreshold(5, 0, query, reader); TopDocs tdc = doConcurrentSearchWithThreshold(5, 0, query, reader); + TopDocs tdc2 = doSearchWithThreshold(5, 0, query, reader); CheckHits.checkEqual(query, tdc.scoreDocs, tdc2.scoreDocs); } 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 38af05fcc0c8..6bc0931fe636 100644 --- a/lucene/core/src/test/org/apache/lucene/search/TestTopDocsMerge.java +++ b/lucene/core/src/test/org/apache/lucene/search/TestTopDocsMerge.java @@ -271,11 +271,11 @@ void testSort(boolean useFrom) throws Exception { final TopDocs topHits; if (sort == null) { if (useFrom) { - TopScoreDocCollector c = TopScoreDocCollector.create(numHits, Integer.MAX_VALUE); - searcher.search(query, c); + from = TestUtil.nextInt(random(), 0, numHits - 1); size = numHits - from; - TopDocs tempTopHits = c.topDocs(); + TopDocs tempTopHits = + searcher.search(query, new TopScoreDocCollectorManager(numHits, Integer.MAX_VALUE)); if (from < tempTopHits.scoreDocs.length) { // Can't use TopDocs#topDocs(start, howMany), since it has different behaviour when // start >= hitCount 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 11d9c1c3301b..960e63415c74 100644 --- a/lucene/core/src/test/org/apache/lucene/search/TestTopFieldCollector.java +++ b/lucene/core/src/test/org/apache/lucene/search/TestTopFieldCollector.java @@ -73,8 +73,9 @@ private static TopDocs doSearchWithThreshold( int numResults, int thresHold, Query q, Sort sort, IndexReader indexReader) throws IOException { IndexSearcher searcher = newSearcher(indexReader); - CollectorManager manager = - TopFieldCollector.createSharedManager(sort, numResults, null, thresHold); + TopFieldCollectorManager manager = + new TopFieldCollectorManager( + sort, numResults, null, thresHold, searcher.getSlices().length > 1); return searcher.search(q, manager); } @@ -83,12 +84,13 @@ private static TopDocs doConcurrentSearchWithThreshold( throws IOException { IndexSearcher searcher = newSearcher(indexReader, true, true, true); - CollectorManager collectorManager = - TopFieldCollector.createSharedManager(sort, numResults, null, threshold); + TopFieldCollectorManager collectorManager = + new TopFieldCollectorManager( + sort, numResults, null, threshold, searcher.getSlices().length > 1); - TopDocs tdc = searcher.search(q, collectorManager); + TopDocs topDoc = searcher.search(q, collectorManager); - return tdc; + return topDoc; } public void testSortWithoutFillFields() throws Exception { @@ -101,10 +103,10 @@ public void testSortWithoutFillFields() throws Exception { Sort[] sort = new Sort[] {new Sort(SortField.FIELD_DOC), new Sort()}; for (int i = 0; i < sort.length; i++) { Query q = new MatchAllDocsQuery(); + TopFieldCollectorManager collectorManager = + new TopFieldCollectorManager(sort[i], 10, Integer.MAX_VALUE); - ScoreDoc[] sd = - is.search(q, TopFieldCollector.createSharedManager(sort[i], 10, null, Integer.MAX_VALUE)) - .scoreDocs; + ScoreDoc[] sd = is.search(q, collectorManager).scoreDocs; for (int j = 1; j < sd.length; j++) { assertTrue(sd[j].doc != sd[j - 1].doc); } @@ -117,10 +119,10 @@ public void testSort() throws Exception { Sort[] sort = new Sort[] {new Sort(SortField.FIELD_DOC), new Sort()}; for (int i = 0; i < sort.length; i++) { Query q = new MatchAllDocsQuery(); - - ScoreDoc[] sd = - is.search(q, TopFieldCollector.createSharedManager(sort[i], 10, null, Integer.MAX_VALUE)) - .scoreDocs; + TopFieldCollectorManager tdc = + new TopFieldCollectorManager(sort[i], 10, null, Integer.MAX_VALUE, false); + TopDocs td = is.search(q, tdc); + ScoreDoc[] sd = td.scoreDocs; for (int j = 0; j < sd.length; j++) { assertTrue(Float.isNaN(sd[j].score)); } @@ -135,15 +137,12 @@ public void testSharedHitcountCollector() throws Exception { Sort[] sort = new Sort[] {new Sort(SortField.FIELD_DOC), new Sort()}; for (int i = 0; i < sort.length; i++) { Query q = new MatchAllDocsQuery(); + TopFieldCollectorManager tdc = new TopFieldCollectorManager(sort[i], 10, Integer.MAX_VALUE); + TopDocs td = singleThreadedSearcher.search(q, tdc); - TopDocs td = - singleThreadedSearcher.search( - q, TopFieldCollector.createSharedManager(sort[i], 10, null, Integer.MAX_VALUE)); - - CollectorManager tsdc = - TopFieldCollector.createSharedManager(sort[i], 10, null, Integer.MAX_VALUE); - + TopFieldCollectorManager tsdc = new TopFieldCollectorManager(sort[i], 10, Integer.MAX_VALUE); TopDocs td2 = concurrentSearcher.search(q, tsdc); + ScoreDoc[] sd = td.scoreDocs; for (int j = 0; j < sd.length; j++) { assertTrue(Float.isNaN(sd[j].score)); @@ -159,16 +158,15 @@ public void testSortWithoutTotalHitTracking() throws Exception { Query q = new MatchAllDocsQuery(); // check that setting trackTotalHits to false does not throw an NPE because // the index is not sorted - CollectorManager manager; + TopFieldCollectorManager manager; if (i % 2 == 0) { - manager = TopFieldCollector.createSharedManager(sort, 10, null, 1); + manager = new TopFieldCollectorManager(sort, 10, 1); } else { FieldDoc fieldDoc = new FieldDoc(1, Float.NaN, new Object[] {1}); - manager = TopFieldCollector.createSharedManager(sort, 10, fieldDoc, 1); + manager = new TopFieldCollectorManager(sort, 10, fieldDoc, 1); } TopDocs td = is.search(q, manager); - ScoreDoc[] sd = td.scoreDocs; for (int j = 0; j < sd.length; j++) { assertTrue(Float.isNaN(sd[j].score)); @@ -194,7 +192,8 @@ public void testTotalHits() throws Exception { for (int totalHitsThreshold = 0; 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); + TopFieldCollector collector = + new TopFieldCollectorManager(sort, 2, after, totalHitsThreshold).newCollector(); Score scorer = new Score(); LeafCollector leafCollector1 = collector.getLeafCollector(reader.leaves().get(0)); @@ -269,7 +268,7 @@ public void testSetMinCompetitiveScore() throws Exception { w.close(); Sort sort = new Sort(FIELD_SCORE, new SortField("foo", SortField.Type.LONG)); - TopFieldCollector collector = TopFieldCollector.create(sort, 2, null, 2); + TopFieldCollector collector = new TopFieldCollectorManager(sort, 2, 2).newCollector(); Score scorer = new Score(); LeafCollector leafCollector = collector.getLeafCollector(reader.leaves().get(0)); @@ -331,7 +330,8 @@ public void testTotalHitsWithScore() throws Exception { for (int totalHitsThreshold = 0; totalHitsThreshold < 20; ++totalHitsThreshold) { Sort sort = new Sort(FIELD_SCORE, new SortField("foo", SortField.Type.LONG)); - TopFieldCollector collector = TopFieldCollector.create(sort, 2, null, totalHitsThreshold); + TopFieldCollector collector = + new TopFieldCollectorManager(sort, 2, totalHitsThreshold).newCollector(); Score scorer = new Score(); LeafCollector leafCollector = collector.getLeafCollector(reader.leaves().get(0)); @@ -372,7 +372,8 @@ 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 tdc = TopFieldCollector.create(sort[i], 10, Integer.MAX_VALUE); + TopDocsCollector tdc = + new TopFieldCollectorManager(sort[i], 10, null, Integer.MAX_VALUE, false).newCollector(); TopDocs td = tdc.topDocs(); assertEquals(0, td.totalHits.value); } @@ -406,22 +407,22 @@ public void testComputeScoresOnlyOnce() throws Exception { final IndexSearcher searcher = newSearcher(reader); for (Sort sort : new Sort[] {new Sort(FIELD_SCORE), new Sort(new SortField("f", SortField.Type.SCORE))}) { - int numHits = TestUtil.nextInt(random(), 1, 2); searcher.search( query, - new CollectorManager() { + new CollectorManager<>() { + TopFieldCollectorManager topFieldCollectorManager = + new TopFieldCollectorManager( + sort, TestUtil.nextInt(random(), 1, 2), Integer.MAX_VALUE); + @Override - public Collector newCollector() { + public Collector newCollector() throws IOException { + TopFieldCollector topCollector = topFieldCollectorManager.newCollector(); return new Collector() { - final TopFieldCollector topCollector = - TopFieldCollector.create(sort, numHits, Integer.MAX_VALUE); - @Override public LeafCollector getLeafCollector(LeafReaderContext context) throws IOException { final LeafCollector in = topCollector.getLeafCollector(context); return new FilterLeafCollector(in) { - int currentDoc = -1; @Override @@ -547,7 +548,7 @@ public void testConcurrentMinScore() throws Exception { Sort sort = new Sort(SortField.FIELD_SCORE, SortField.FIELD_DOC); CollectorManager manager = - TopFieldCollector.createSharedManager(sort, 2, null, 0); + new TopFieldCollectorManager(sort, 2, 0); TopFieldCollector collector = manager.newCollector(); TopFieldCollector collector2 = manager.newCollector(); assertTrue(collector.minScoreAcc == collector2.minScoreAcc); @@ -680,8 +681,8 @@ public void testRandomMinCompetitiveScore() throws Exception { }; for (Query query : queries) { Sort sort = new Sort(new SortField[] {SortField.FIELD_SCORE, SortField.FIELD_DOC}); - TopDocs tdc2 = doSearchWithThreshold(5, 0, query, sort, indexReader); TopDocs tdc = doConcurrentSearchWithThreshold(5, 0, query, sort, indexReader); + TopDocs tdc2 = doSearchWithThreshold(5, 0, query, sort, indexReader); assertTrue(tdc.totalHits.value > 0); assertTrue(tdc2.totalHits.value > 0); @@ -706,24 +707,19 @@ public void testRelationVsTopDocsCount() throws Exception { try (IndexReader reader = DirectoryReader.open(w)) { IndexSearcher searcher = new IndexSearcher(reader); - TopFieldDocs topDocs = - searcher.search( - new TermQuery(new Term("f", "foo")), - TopFieldCollector.createSharedManager(sort, 2, null, 10)); + TopFieldCollectorManager collectorManager = + new TopFieldCollectorManager(sort, 2, null, 10, true); + TopDocs topDocs = searcher.search(new TermQuery(new Term("f", "foo")), collectorManager); assertEquals(10, topDocs.totalHits.value); assertEquals(TotalHits.Relation.EQUAL_TO, topDocs.totalHits.relation); - topDocs = - searcher.search( - new TermQuery(new Term("f", "foo")), - TopFieldCollector.createSharedManager(sort, 2, null, 2)); + collectorManager = new TopFieldCollectorManager(sort, 2, null, 2, true); + topDocs = searcher.search(new TermQuery(new Term("f", "foo")), collectorManager); assertTrue(10 >= topDocs.totalHits.value); assertEquals(TotalHits.Relation.GREATER_THAN_OR_EQUAL_TO, topDocs.totalHits.relation); - topDocs = - searcher.search( - new TermQuery(new Term("f", "foo")), - TopFieldCollector.createSharedManager(sort, 10, null, 2)); + collectorManager = new TopFieldCollectorManager(sort, 10, null, 2, true); + topDocs = searcher.search(new TermQuery(new Term("f", "foo")), collectorManager); assertEquals(10, topDocs.totalHits.value); assertEquals(TotalHits.Relation.EQUAL_TO, topDocs.totalHits.relation); } 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 91fa39446797..4c788492becf 100644 --- a/lucene/core/src/test/org/apache/lucene/search/TestTopFieldCollectorEarlyTermination.java +++ b/lucene/core/src/test/org/apache/lucene/search/TestTopFieldCollectorEarlyTermination.java @@ -134,10 +134,10 @@ private void doTestEarlyTermination(boolean paging) throws IOException { } else { after = null; } - CollectorManager manager1 = - TopFieldCollector.createSharedManager(sort, numHits, after, Integer.MAX_VALUE); - CollectorManager manager2 = - TopFieldCollector.createSharedManager(sort, numHits, after, 1); + final TopFieldCollectorManager manager1 = + new TopFieldCollectorManager(sort, numHits, after, Integer.MAX_VALUE); + final TopFieldCollectorManager manager2 = + new TopFieldCollectorManager(sort, numHits, after, 1); final Query query; if (random().nextBoolean()) { 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 372ac4ade0c5..02f506fbca09 100644 --- a/lucene/facet/src/java/org/apache/lucene/facet/DrillSideways.java +++ b/lucene/facet/src/java/org/apache/lucene/facet/DrillSideways.java @@ -40,8 +40,9 @@ import org.apache.lucene.search.Sort; import org.apache.lucene.search.TopDocs; import org.apache.lucene.search.TopFieldCollector; +import org.apache.lucene.search.TopFieldCollectorManager; import org.apache.lucene.search.TopFieldDocs; -import org.apache.lucene.search.TopScoreDocCollector; +import org.apache.lucene.search.TopScoreDocCollectorManager; import org.apache.lucene.util.ThreadInterruptedException; /** @@ -195,12 +196,12 @@ public DrillSidewaysResult search( limit = 1; // the collector does not alow numHits = 0 } final int fTopN = Math.min(topN, limit); - - final CollectorManager collectorManager = - TopFieldCollector.createSharedManager(sort, fTopN, after, Integer.MAX_VALUE); + final boolean supportsConcurrency = searcher.getSlices().length > 1; + final TopFieldCollectorManager collectorManager = + new TopFieldCollectorManager(sort, fTopN, after, Integer.MAX_VALUE, supportsConcurrency); final ConcurrentDrillSidewaysResult r = search(query, collectorManager); - TopFieldDocs topDocs = r.collectorResult; + if (doDocScores) { TopFieldCollector.populateScores(topDocs.scoreDocs, searcher, query); } @@ -228,9 +229,9 @@ public DrillSidewaysResult search(ScoreDoc after, DrillDownQuery query, int topN limit = 1; // the collector does not alow numHits = 0 } final int fTopN = Math.min(topN, limit); - - final CollectorManager collectorManager = - TopScoreDocCollector.createSharedManager(fTopN, after, Integer.MAX_VALUE); + final boolean supportsConcurrency = searcher.getSlices().length > 1; + final TopScoreDocCollectorManager collectorManager = + new TopScoreDocCollectorManager(fTopN, after, Integer.MAX_VALUE, supportsConcurrency); final ConcurrentDrillSidewaysResult r = search(query, collectorManager); return new DrillSidewaysResult( r.facets, diff --git a/lucene/facet/src/test/org/apache/lucene/facet/taxonomy/TestTaxonomyFacetValueSource.java b/lucene/facet/src/test/org/apache/lucene/facet/taxonomy/TestTaxonomyFacetValueSource.java index 2e454554317f..a95c7db5d030 100644 --- a/lucene/facet/src/test/org/apache/lucene/facet/taxonomy/TestTaxonomyFacetValueSource.java +++ b/lucene/facet/src/test/org/apache/lucene/facet/taxonomy/TestTaxonomyFacetValueSource.java @@ -475,7 +475,6 @@ public void testRollupValues() throws Exception { FacetsCollector sfc = newSearcher(r).search(new MatchAllDocsQuery(), new FacetsCollectorManager()); - // Test SUM: Facets facets = new TaxonomyFacetFloatAssociations( diff --git a/lucene/luke/src/java/org/apache/lucene/luke/models/search/SearchImpl.java b/lucene/luke/src/java/org/apache/lucene/luke/models/search/SearchImpl.java index fa552e65d3f0..cd2fb8769747 100644 --- a/lucene/luke/src/java/org/apache/lucene/luke/models/search/SearchImpl.java +++ b/lucene/luke/src/java/org/apache/lucene/luke/models/search/SearchImpl.java @@ -57,7 +57,7 @@ import org.apache.lucene.search.SortedNumericSortField; import org.apache.lucene.search.SortedSetSortField; import org.apache.lucene.search.TopDocs; -import org.apache.lucene.search.TopScoreDocCollector; +import org.apache.lucene.search.TopScoreDocCollectorManager; import org.apache.lucene.search.TotalHits; import org.apache.lucene.search.similarities.BM25Similarity; import org.apache.lucene.search.similarities.ClassicSimilarity; @@ -314,9 +314,10 @@ private SearchResults search() throws IOException { topDocs = searcher.searchAfter(after, query, pageSize, sort); } else { int hitsThreshold = exactHitsCount ? Integer.MAX_VALUE : DEFAULT_TOTAL_HITS_THRESHOLD; - TopScoreDocCollector collector = TopScoreDocCollector.create(pageSize, after, hitsThreshold); - searcher.search(query, collector); - topDocs = collector.topDocs(); + TopScoreDocCollectorManager collectorManager = + new TopScoreDocCollectorManager( + pageSize, after, hitsThreshold, searcher.getSlices().length > 1); + topDocs = searcher.search(query, collectorManager); } // reset total hits for the current query diff --git a/lucene/queries/src/test/org/apache/lucene/queries/spans/TestBasics.java b/lucene/queries/src/test/org/apache/lucene/queries/spans/TestBasics.java index f53313a1bda7..a35d68e29c46 100644 --- a/lucene/queries/src/test/org/apache/lucene/queries/spans/TestBasics.java +++ b/lucene/queries/src/test/org/apache/lucene/queries/spans/TestBasics.java @@ -37,7 +37,6 @@ import org.apache.lucene.index.Term; import org.apache.lucene.search.BooleanClause; import org.apache.lucene.search.BooleanQuery; -import org.apache.lucene.search.CollectorManager; import org.apache.lucene.search.DisjunctionMaxQuery; import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.PhraseQuery; @@ -45,7 +44,7 @@ import org.apache.lucene.search.ScoreDoc; import org.apache.lucene.search.TermQuery; import org.apache.lucene.search.TopDocs; -import org.apache.lucene.search.TopScoreDocCollector; +import org.apache.lucene.search.TopScoreDocCollectorManager; import org.apache.lucene.store.Directory; import org.apache.lucene.tests.analysis.MockAnalyzer; import org.apache.lucene.tests.analysis.MockTokenizer; @@ -518,9 +517,9 @@ public void testBooleanSpanQuery() throws Exception { SpanQuery sq2 = new SpanTermQuery(new Term(FIELD, "clckwork")); query.add(sq1, BooleanClause.Occur.SHOULD); query.add(sq2, BooleanClause.Occur.SHOULD); - CollectorManager manager = - TopScoreDocCollector.createSharedManager(1000, null, Integer.MAX_VALUE); - TopDocs topDocs = searcher.search(query.build(), manager); + TopScoreDocCollectorManager collectorManager = + new TopScoreDocCollectorManager(1000, Integer.MAX_VALUE); + TopDocs topDocs = searcher.search(query.build(), collectorManager); hits = topDocs.scoreDocs.length; for (ScoreDoc scoreDoc : topDocs.scoreDocs) { System.out.println(scoreDoc.doc); @@ -554,9 +553,9 @@ public void testDismaxSpanQuery() throws Exception { new SpanTermQuery(new Term(FIELD, "clockwork")), new SpanTermQuery(new Term(FIELD, "clckwork"))), 1.0f); - CollectorManager manager = - TopScoreDocCollector.createSharedManager(1000, null, Integer.MAX_VALUE); - TopDocs topDocs = searcher.search(query, manager); + TopScoreDocCollectorManager collectorManager = + new TopScoreDocCollectorManager(1000, Integer.MAX_VALUE); + TopDocs topDocs = searcher.search(query, collectorManager); hits = topDocs.scoreDocs.length; for (ScoreDoc scoreDoc : topDocs.scoreDocs) { System.out.println(scoreDoc.doc); diff --git a/lucene/sandbox/src/test/org/apache/lucene/sandbox/search/TestCombinedFieldQuery.java b/lucene/sandbox/src/test/org/apache/lucene/sandbox/search/TestCombinedFieldQuery.java index 739c9b85323d..c2e6eefd5337 100644 --- a/lucene/sandbox/src/test/org/apache/lucene/sandbox/search/TestCombinedFieldQuery.java +++ b/lucene/sandbox/src/test/org/apache/lucene/sandbox/search/TestCombinedFieldQuery.java @@ -40,6 +40,7 @@ import org.apache.lucene.search.TermStatistics; import org.apache.lucene.search.TopDocs; import org.apache.lucene.search.TopScoreDocCollector; +import org.apache.lucene.search.TopScoreDocCollectorManager; import org.apache.lucene.search.TotalHits; import org.apache.lucene.search.similarities.BM25Similarity; import org.apache.lucene.search.similarities.BooleanSimilarity; @@ -153,10 +154,10 @@ public void testSameScore() throws IOException { .addField("g", 1f) .addTerm(new BytesRef("a")) .build(); - CollectorManager manager = - TopScoreDocCollector.createSharedManager( - Math.min(reader.numDocs(), Integer.MAX_VALUE), null, Integer.MAX_VALUE); - TopDocs topDocs = searcher.search(query, manager); + TopScoreDocCollectorManager collectorManager = + new TopScoreDocCollectorManager( + Math.min(reader.numDocs(), Integer.MAX_VALUE), Integer.MAX_VALUE); + TopDocs topDocs = searcher.search(query, collectorManager); assertEquals(new TotalHits(11, TotalHits.Relation.EQUAL_TO), topDocs.totalHits); // All docs must have the same score for (int i = 0; i < topDocs.scoreDocs.length; ++i) { @@ -234,7 +235,8 @@ public void testScoringWithMultipleFieldTermsMatch() throws IOException { .build(); CollectorManager completeManager = - TopScoreDocCollector.createSharedManager(numHits, null, Integer.MAX_VALUE); + new TopScoreDocCollectorManager(numHits, Integer.MAX_VALUE); + searcher.search(query, completeManager); reader.close(); @@ -267,8 +269,7 @@ public void testNormsDisabled() throws IOException { Similarity searchSimilarity = randomCompatibleSimilarity(); searcher.setSimilarity(searchSimilarity); - CollectorManager manager = - TopScoreDocCollector.createSharedManager(10, null, 10); + TopScoreDocCollectorManager collectorManager = new TopScoreDocCollectorManager(10, 10); CombinedFieldQuery query = new CombinedFieldQuery.Builder() @@ -276,7 +277,7 @@ public void testNormsDisabled() throws IOException { .addField("b", 1.0f) .addTerm(new BytesRef("value")) .build(); - TopDocs topDocs = searcher.search(query, manager); + TopDocs topDocs = searcher.search(query, collectorManager); assertEquals(new TotalHits(2, TotalHits.Relation.EQUAL_TO), topDocs.totalHits); CombinedFieldQuery invalidQuery = @@ -286,7 +287,8 @@ public void testNormsDisabled() throws IOException { .addTerm(new BytesRef("value")) .build(); IllegalArgumentException e = - expectThrows(IllegalArgumentException.class, () -> searcher.search(invalidQuery, manager)); + expectThrows( + IllegalArgumentException.class, () -> searcher.search(invalidQuery, collectorManager)); assertTrue(e.getMessage().contains("requires norms to be consistent across fields")); reader.close(); @@ -498,14 +500,14 @@ private static Similarity randomCompatibleSimilarity() { private void checkExpectedHits( IndexSearcher searcher, int numHits, Query firstQuery, Query secondQuery) throws IOException { - CollectorManager firstManager = - TopScoreDocCollector.createSharedManager(numHits, null, Integer.MAX_VALUE); - TopDocs firstTopDocs = searcher.search(firstQuery, firstManager); + TopScoreDocCollectorManager collectorManager = + new TopScoreDocCollectorManager(numHits, Integer.MAX_VALUE); + + TopDocs firstTopDocs = searcher.search(firstQuery, collectorManager); assertEquals(numHits, firstTopDocs.totalHits.value); - CollectorManager secondManager = - TopScoreDocCollector.createSharedManager(numHits, null, Integer.MAX_VALUE); - TopDocs secondTopDocs = searcher.search(secondQuery, secondManager); + collectorManager = new TopScoreDocCollectorManager(numHits, Integer.MAX_VALUE); + TopDocs secondTopDocs = searcher.search(secondQuery, collectorManager); CheckHits.checkEqual(firstQuery, secondTopDocs.scoreDocs, firstTopDocs.scoreDocs); } diff --git a/lucene/sandbox/src/test/org/apache/lucene/sandbox/search/TestLargeNumHitsTopDocsCollector.java b/lucene/sandbox/src/test/org/apache/lucene/sandbox/search/TestLargeNumHitsTopDocsCollector.java index 2df90ea749b6..42cd7e71b6b7 100644 --- a/lucene/sandbox/src/test/org/apache/lucene/sandbox/search/TestLargeNumHitsTopDocsCollector.java +++ b/lucene/sandbox/src/test/org/apache/lucene/sandbox/search/TestLargeNumHitsTopDocsCollector.java @@ -24,14 +24,13 @@ import org.apache.lucene.index.Term; import org.apache.lucene.search.BooleanClause; import org.apache.lucene.search.BooleanQuery; -import org.apache.lucene.search.CollectorManager; import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.MatchAllDocsQuery; import org.apache.lucene.search.Query; import org.apache.lucene.search.ScoreDoc; import org.apache.lucene.search.TermQuery; import org.apache.lucene.search.TopDocs; -import org.apache.lucene.search.TopScoreDocCollector; +import org.apache.lucene.search.TopScoreDocCollectorManager; import org.apache.lucene.store.Directory; import org.apache.lucene.tests.index.RandomIndexWriter; import org.apache.lucene.tests.search.CheckHits; @@ -84,13 +83,13 @@ public void testRequestLessHitsThanCollected() throws Exception { public void testIllegalArguments() throws IOException { IndexSearcher searcher = newSearcher(reader); LargeNumHitsTopDocsCollector largeCollector = new LargeNumHitsTopDocsCollector(15); - CollectorManager regularManager = - TopScoreDocCollector.createSharedManager(15, null, Integer.MAX_VALUE); + TopScoreDocCollectorManager regularCollectorManager = + new TopScoreDocCollectorManager(15, Integer.MAX_VALUE); searcher.search(testQuery, largeCollector); - TopDocs regular = searcher.search(testQuery, regularManager); + TopDocs topDocs = searcher.search(testQuery, regularCollectorManager); - assertEquals(largeCollector.totalHits, regular.totalHits.value); + assertEquals(largeCollector.totalHits, topDocs.totalHits.value); IllegalArgumentException expected = expectThrows( @@ -105,13 +104,13 @@ public void testIllegalArguments() throws IOException { public void testNoPQBuild() throws IOException { IndexSearcher searcher = newSearcher(reader); LargeNumHitsTopDocsCollector largeCollector = new LargeNumHitsTopDocsCollector(250_000); - CollectorManager regularManager = - TopScoreDocCollector.createSharedManager(250_000, null, Integer.MAX_VALUE); + TopScoreDocCollectorManager regularCollectorManager = + new TopScoreDocCollectorManager(250_000, Integer.MAX_VALUE); searcher.search(testQuery, largeCollector); - TopDocs regular = searcher.search(testQuery, regularManager); + TopDocs topDocs = searcher.search(testQuery, regularCollectorManager); - assertEquals(largeCollector.totalHits, regular.totalHits.value); + assertEquals(largeCollector.totalHits, topDocs.totalHits.value); assertNull(largeCollector.pq); assertNull(largeCollector.pqTop); @@ -120,13 +119,13 @@ public void testNoPQBuild() throws IOException { public void testPQBuild() throws IOException { IndexSearcher searcher = newSearcher(reader); LargeNumHitsTopDocsCollector largeCollector = new LargeNumHitsTopDocsCollector(50); - CollectorManager regularManager = - TopScoreDocCollector.createSharedManager(50, null, Integer.MAX_VALUE); + TopScoreDocCollectorManager regularCollectorManager = + new TopScoreDocCollectorManager(50, Integer.MAX_VALUE); searcher.search(testQuery, largeCollector); - TopDocs regular = searcher.search(testQuery, regularManager); + TopDocs topDocs = searcher.search(testQuery, regularCollectorManager); - assertEquals(largeCollector.totalHits, regular.totalHits.value); + assertEquals(largeCollector.totalHits, topDocs.totalHits.value); assertNotNull(largeCollector.pq); assertNotNull(largeCollector.pqTop); @@ -135,18 +134,18 @@ public void testPQBuild() throws IOException { public void testNoPQHitsOrder() throws IOException { IndexSearcher searcher = newSearcher(reader); LargeNumHitsTopDocsCollector largeCollector = new LargeNumHitsTopDocsCollector(250_000); - CollectorManager regularManager = - TopScoreDocCollector.createSharedManager(250_000, null, Integer.MAX_VALUE); + TopScoreDocCollectorManager regularCollectorManager = + new TopScoreDocCollectorManager(250_000, Integer.MAX_VALUE); searcher.search(testQuery, largeCollector); - TopDocs regular = searcher.search(testQuery, regularManager); + TopDocs topDocs = searcher.search(testQuery, regularCollectorManager); - assertEquals(largeCollector.totalHits, regular.totalHits.value); + assertEquals(largeCollector.totalHits, topDocs.totalHits.value); assertNull(largeCollector.pq); assertNull(largeCollector.pqTop); - TopDocs topDocs = largeCollector.topDocs(); + topDocs = largeCollector.topDocs(); if (topDocs.scoreDocs.length > 0) { float preScore = topDocs.scoreDocs[0].score; @@ -160,18 +159,16 @@ public void testNoPQHitsOrder() throws IOException { private void runNumHits(int numHits) throws IOException { IndexSearcher searcher = newSearcher(reader); LargeNumHitsTopDocsCollector largeCollector = new LargeNumHitsTopDocsCollector(numHits); - CollectorManager regularManager = - TopScoreDocCollector.createSharedManager(numHits, null, Integer.MAX_VALUE); + TopScoreDocCollectorManager regularCollectorManager = + new TopScoreDocCollectorManager(numHits, Integer.MAX_VALUE); searcher.search(testQuery, largeCollector); - TopDocs secondTopDocs = searcher.search(testQuery, regularManager); - - assertEquals(largeCollector.totalHits, secondTopDocs.totalHits.value); TopDocs firstTopDocs = largeCollector.topDocs(); + TopDocs secondTopDocs = searcher.search(testQuery, regularCollectorManager); + assertEquals(largeCollector.totalHits, secondTopDocs.totalHits.value); assertEquals(firstTopDocs.scoreDocs.length, secondTopDocs.scoreDocs.length); - CheckHits.checkEqual(testQuery, firstTopDocs.scoreDocs, secondTopDocs.scoreDocs); } } 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 26a434f8291e..e1772102098b 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 @@ -64,7 +64,7 @@ import org.apache.lucene.search.Sort; import org.apache.lucene.search.SortField; import org.apache.lucene.search.TermQuery; -import org.apache.lucene.search.TopFieldCollector; +import org.apache.lucene.search.TopFieldCollectorManager; import org.apache.lucene.search.TopFieldDocs; import org.apache.lucene.search.suggest.InputIterator; import org.apache.lucene.search.suggest.Lookup; @@ -728,7 +728,6 @@ public List lookup( // System.out.println("finalQuery=" + finalQuery); // Sort by weight, descending: - TopFieldCollector c = TopFieldCollector.create(SORT, num, 1); List results = null; SearcherManager mgr; IndexSearcher searcher; @@ -740,10 +739,10 @@ public List lookup( searcherMgrReadLock.unlock(); } try { + TopFieldCollectorManager c = + new TopFieldCollectorManager(SORT, num, null, 1, searcher.getSlices().length > 1); // System.out.println("got searcher=" + searcher); - searcher.search(finalQuery, c); - - TopFieldDocs hits = c.topDocs(); + TopFieldDocs hits = searcher.search(finalQuery, c); // Slower way if postings are not pre-sorted by weight: // hits = searcher.search(query, null, num, SORT); diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/search/CheckHits.java b/lucene/test-framework/src/java/org/apache/lucene/tests/search/CheckHits.java index 668c308dd0ab..a7b0a61549a9 100644 --- a/lucene/test-framework/src/java/org/apache/lucene/tests/search/CheckHits.java +++ b/lucene/test-framework/src/java/org/apache/lucene/tests/search/CheckHits.java @@ -49,7 +49,7 @@ import org.apache.lucene.search.Sort; import org.apache.lucene.search.TopDocs; import org.apache.lucene.search.TopFieldDocs; -import org.apache.lucene.search.TopScoreDocCollector; +import org.apache.lucene.search.TopScoreDocCollectorManager; import org.apache.lucene.search.TwoPhaseIterator; import org.apache.lucene.search.Weight; import org.apache.lucene.tests.util.LuceneTestCase; @@ -700,13 +700,15 @@ public static void checkTopScores(Random random, Query query, IndexSearcher sear private static void doCheckTopScores(Query query, IndexSearcher searcher, int numHits) throws IOException { - CollectorManager complete = - TopScoreDocCollector.createSharedManager(numHits, null, Integer.MAX_VALUE); - ScoreDoc[] completeScoreDocs = searcher.search(query, complete).scoreDocs; - CollectorManager topScores = - TopScoreDocCollector.createSharedManager(numHits, null, 1); - ScoreDoc[] topScoresScoreDocs = searcher.search(query, topScores).scoreDocs; - checkEqual(query, completeScoreDocs, topScoresScoreDocs); + boolean supportsConcurrency = searcher.getSlices().length > 1; + TopScoreDocCollectorManager complete = + new TopScoreDocCollectorManager( + numHits, null, Integer.MAX_VALUE, supportsConcurrency); // COMPLETE + TopScoreDocCollectorManager topScores = + new TopScoreDocCollectorManager(numHits, null, 1, supportsConcurrency); // TOP_SCORES + TopDocs completeTopDocs = searcher.search(query, complete); + TopDocs topScoresTopDocs = searcher.search(query, topScores); + checkEqual(query, completeTopDocs.scoreDocs, topScoresTopDocs.scoreDocs); } private static void doCheckMaxScores(Random random, Query query, IndexSearcher searcher)