diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt index b9173f8756f4..c4d54b528afa 100644 --- a/lucene/CHANGES.txt +++ b/lucene/CHANGES.txt @@ -306,6 +306,9 @@ API Changes * GITHUB#13568: Add DrillSideways#search method that supports any CollectorManagers for drill-sideways dimensions or drill-down. (Egor Potemkin) +* GITHUB#13735: Add CollectorManager#forSequentialExecution to make CollectorManager creation more convenient + for users of the deprecated IndexSearcher#search(Query, Collector). (Greg Miller) + New Features --------------------- @@ -348,6 +351,9 @@ Improvements * GITHUB#13201: Better cost estimation on MultiTermQuery over few terms. (Michael Froh) +* GITHUB#13735: Migrate monitor package usage of deprecated IndexSearcher#search(Query, Collector) + to IndexSearcher#search(Query, CollectorManager). (Greg Miller) + Optimizations --------------------- diff --git a/lucene/core/src/java/org/apache/lucene/search/CollectorManager.java b/lucene/core/src/java/org/apache/lucene/search/CollectorManager.java index 3c87a94e36d9..c33712b13218 100644 --- a/lucene/core/src/java/org/apache/lucene/search/CollectorManager.java +++ b/lucene/core/src/java/org/apache/lucene/search/CollectorManager.java @@ -18,6 +18,8 @@ import java.io.IOException; import java.util.Collection; +import java.util.concurrent.Executor; +import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.LeafReaderContext; /** @@ -53,4 +55,36 @@ public interface CollectorManager { * called after collection is finished on all provided collectors. */ T reduce(Collection collectors) throws IOException; + + /** + * Wrap a provided {@link Collector} with a thin {@code CollectorManager} wrapper for use with + * {@link IndexSearcher#search(Query, CollectorManager)} when doing single-threaded searching. The + * wrapping {@code CollectorManager} provides no {@link CollectorManager#reduce(Collection)} + * implementation, so the wrapped {@code Collector} needs to do all relevant work while + * collecting. + * + *

Note: This is only safe to use when {@code IndexSearcher} is created with no executor (see: + * {@link IndexSearcher#IndexSearcher(IndexReader, Executor)}). + */ + static CollectorManager forSequentialExecution(C in) { + return new CollectorManager() { + private boolean newCollectorInvoked; + + @Override + public C newCollector() { + if (newCollectorInvoked) { + throw new IllegalStateException( + "newCollector should be invoked at most once. Ensure your IndexSearcher has been created without an Executor."); + } + newCollectorInvoked = true; + return in; + } + + @Override + public Void reduce(Collection collectors) { + assert collectors.size() == 1 : "collectors should contain exactly one collector instance"; + return null; + } + }; + } } diff --git a/lucene/monitor/src/java/org/apache/lucene/monitor/CollectingMatcher.java b/lucene/monitor/src/java/org/apache/lucene/monitor/CollectingMatcher.java index b6300dafa755..6175fec5ca33 100644 --- a/lucene/monitor/src/java/org/apache/lucene/monitor/CollectingMatcher.java +++ b/lucene/monitor/src/java/org/apache/lucene/monitor/CollectingMatcher.java @@ -19,6 +19,7 @@ import java.io.IOException; import java.util.Map; +import org.apache.lucene.search.CollectorManager; import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.Query; import org.apache.lucene.search.Scorable; @@ -37,7 +38,9 @@ abstract class CollectingMatcher extends CandidateMatcher< @Override public void matchQuery(final String queryId, Query matchQuery, Map metadata) throws IOException { - searcher.search(matchQuery, new MatchCollector(queryId, scoreMode)); + searcher.search( + matchQuery, + CollectorManager.forSequentialExecution(new MatchCollector(queryId, scoreMode))); } /**