diff --git a/opengrok-indexer/src/main/java/org/opengrok/indexer/search/SearchEngine.java b/opengrok-indexer/src/main/java/org/opengrok/indexer/search/SearchEngine.java index e12ad247142..3aa27c9d2c4 100644 --- a/opengrok-indexer/src/main/java/org/opengrok/indexer/search/SearchEngine.java +++ b/opengrok-indexer/src/main/java/org/opengrok/indexer/search/SearchEngine.java @@ -48,7 +48,7 @@ import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.Query; import org.apache.lucene.search.ScoreDoc; -import org.apache.lucene.search.TopScoreDocCollector; +import org.apache.lucene.search.TopScoreDocCollectorManager; import org.apache.lucene.util.Version; import org.opengrok.indexer.analysis.AbstractAnalyzer; import org.opengrok.indexer.analysis.CompatibleAnalyser; @@ -132,7 +132,7 @@ public class SearchEngine { int cachePages = RuntimeEnvironment.getInstance().getCachePages(); int totalHits = 0; private ScoreDoc[] hits; - private TopScoreDocCollector collector; + private TopScoreDocCollectorManager collectorManager; private IndexSearcher searcher; boolean allCollected; private final ArrayList searcherList = new ArrayList<>(); @@ -205,18 +205,17 @@ private void searchMultiDatabase(List projectList, boolean paging) thro } private void searchIndex(IndexSearcher searcher, boolean paging) throws IOException { - collector = TopScoreDocCollector.create(hitsPerPage * cachePages, Short.MAX_VALUE); + collectorManager = new TopScoreDocCollectorManager(hitsPerPage * cachePages, Short.MAX_VALUE); Statistics stat = new Statistics(); - searcher.search(query, collector); - totalHits = collector.getTotalHits(); + hits = searcher.search(query, collectorManager).scoreDocs; + totalHits = searcher.count(query); stat.report(LOGGER, Level.FINEST, "search via SearchEngine done", "search.latency", new String[]{"category", "engine", "outcome", totalHits > 0 ? "success" : "empty"}); if (!paging && totalHits > 0) { - collector = TopScoreDocCollector.create(totalHits, Short.MAX_VALUE); - searcher.search(query, collector); + collectorManager = new TopScoreDocCollectorManager(totalHits, Short.MAX_VALUE); + hits = searcher.search(query, collectorManager).scoreDocs; } - hits = collector.topDocs().scoreDocs; StoredFields storedFields = searcher.storedFields(); for (ScoreDoc hit : hits) { int docId = hit.doc; @@ -412,14 +411,13 @@ public void results(int start, int end, List ret) { // TODO check if below fits for if end=old hits.length, or it should include it if (end > hits.length && !allCollected) { //do the requery, we want more than 5 pages - collector = TopScoreDocCollector.create(totalHits, Short.MAX_VALUE); + collectorManager = new TopScoreDocCollectorManager(totalHits, Short.MAX_VALUE); try { - searcher.search(query, collector); + hits = searcher.search(query, collectorManager).scoreDocs; } catch (Exception e) { // this exception should never be hit, since search() will hit this before LOGGER.log( Level.WARNING, SEARCH_EXCEPTION_MSG, e); } - hits = collector.topDocs().scoreDocs; StoredFields storedFields = null; try { storedFields = searcher.storedFields(); diff --git a/pom.xml b/pom.xml index 731c2530b88..1b84f001d0d 100644 --- a/pom.xml +++ b/pom.xml @@ -60,7 +60,7 @@ Portions Copyright (c) 2018, 2020, Chris Fraire . - 9.9.2 + 9.12.3 3.6.0 17 UTF-8 diff --git a/suggester/src/main/java/org/opengrok/suggest/SuggestResultCollector.java b/suggester/src/main/java/org/opengrok/suggest/SuggestResultCollector.java index aefff246b3c..e93eb857d85 100644 --- a/suggester/src/main/java/org/opengrok/suggest/SuggestResultCollector.java +++ b/suggester/src/main/java/org/opengrok/suggest/SuggestResultCollector.java @@ -27,6 +27,7 @@ import org.apache.lucene.index.StoredFields; import org.apache.lucene.search.CollectionTerminatedException; import org.apache.lucene.search.Collector; +import org.apache.lucene.search.CollectorManager; import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.LeafCollector; import org.apache.lucene.search.Scorable; @@ -35,6 +36,7 @@ import org.opengrok.suggest.query.data.BitIntsHolder; import java.io.IOException; +import java.util.Collection; /** * Collects Suggester query results. @@ -62,6 +64,29 @@ public LeafCollector getLeafCollector(LeafReaderContext context) throws IOExcept return new SuggesterLeafCollector(context); } + /** + * Creates a {@link CollectorManager} that can concurrently collect matching docs in a {@link + * BitIntsHolder}. + */ + public static CollectorManager createManager(LeafReaderContext leafReaderContext, ComplexQueryData data, + BitIntsHolder documentIds) { + return new CollectorManager<>() { + @Override + public SuggestResultCollector newCollector() { + return new SuggestResultCollector(leafReaderContext, data, documentIds); + } + + @Override + public BitIntsHolder reduce(Collection collectors) { + BitIntsHolder reduced = documentIds; + for (SuggestResultCollector collector : collectors) { + documentIds.or(collector.documentIds); //TODO fix as per https://github.com/apache/lucene/pull/766/files + } + return reduced; + } + }; + } + /** * Indicates what features are required from the scorer. */ diff --git a/suggester/src/main/java/org/opengrok/suggest/SuggesterSearcher.java b/suggester/src/main/java/org/opengrok/suggest/SuggesterSearcher.java index f02eefe6a9f..3ac4b3eb4ed 100644 --- a/suggester/src/main/java/org/opengrok/suggest/SuggesterSearcher.java +++ b/suggester/src/main/java/org/opengrok/suggest/SuggesterSearcher.java @@ -238,7 +238,7 @@ private ComplexQueryData getComplexQueryData(final Query query, final LeafReader BitIntsHolder documentIds = new BitIntsHolder(); try { - search(query, new SuggestResultCollector(leafReaderContext, data, documentIds)); + search(query, SuggestResultCollector.createManager(leafReaderContext, data, documentIds)); } catch (IOException e) { if (Thread.currentThread().isInterrupted()) { interrupted = true;