You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by ja...@apache.org on 2024/07/30 15:50:20 UTC
(lucene) branch branch_9x updated: Introduce IndexSearcher#searchLeaf(LeafReaderContext, Weight, Collector) method (#13603)
This is an automated email from the ASF dual-hosted git repository.
javanna pushed a commit to branch branch_9x
in repository https://gitbox.apache.org/repos/asf/lucene.git
The following commit(s) were added to refs/heads/branch_9x by this push:
new 539274f4530 Introduce IndexSearcher#searchLeaf(LeafReaderContext, Weight, Collector) method (#13603)
539274f4530 is described below
commit 539274f453097a5201ae1bec6a742e9e98f8d6eb
Author: Luca Cavanna <ja...@apache.org>
AuthorDate: Tue Jul 30 17:50:14 2024 +0200
Introduce IndexSearcher#searchLeaf(LeafReaderContext, Weight, Collector) method (#13603)
There's a couple of places in the codebase where we extend `IndexSearcher` to customize
per leaf behaviour, and in order to do that, we need to override the entire search method
that loops through the leaves. A good example is `ScorerIndexSearcher`.
Adding a `searchLeaf` method that provides the per leaf behaviour makes those cases a little
easier to deal with.
---
lucene/CHANGES.txt | 4 ++
.../org/apache/lucene/search/IndexSearcher.java | 69 ++++++++++++++--------
.../org/apache/lucene/search/TestTopDocsMerge.java | 10 ++--
.../lucene/search/grouping/TestGrouping.java | 8 +--
.../lucene/tests/search/ScorerIndexSearcher.java | 33 +++++------
5 files changed, 71 insertions(+), 53 deletions(-)
diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt
index d4a8343ca1f..6d17ba1d048 100644
--- a/lucene/CHANGES.txt
+++ b/lucene/CHANGES.txt
@@ -14,6 +14,10 @@ API Changes
* GITHUB#13612: Hunspell: add Suggester#proceedPastRep to avoid losing relevant suggestions. (Peter Gromov)
+* GITHUB#13603: Introduced `IndexSearcher#searchLeaf(LeafReaderContext, Weight, Collector)` protected method to
+ facilitate customizing per-leaf behavior of search without requiring to override
+ `search(LeafReaderContext[], Weight, Collector)` which requires overriding the entire loop across the leaves (Luca Cavanna)
+
New Features
---------------------
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 16728675745..9f0d5b71a08 100644
--- a/lucene/core/src/java/org/apache/lucene/search/IndexSearcher.java
+++ b/lucene/core/src/java/org/apache/lucene/search/IndexSearcher.java
@@ -712,7 +712,8 @@ public class IndexSearcher {
/**
* Lower-level search API.
*
- * <p>{@link LeafCollector#collect(int)} is called for every document. <br>
+ * <p>{@link #searchLeaf(LeafReaderContext, Weight, Collector)} is called for every leaf
+ * partition. <br>
*
* <p>NOTE: this method executes the searches on all given leaves exclusively. To search across
* all the searchers leaves use {@link #leafContexts}.
@@ -732,38 +733,54 @@ public class IndexSearcher {
// threaded...? the Collector could be sync'd?
// always use single thread:
for (LeafReaderContext ctx : leaves) { // search each subreader
- final LeafCollector leafCollector;
+ searchLeaf(ctx, weight, collector);
+ }
+ }
+
+ /**
+ * Lower-level search API
+ *
+ * <p>{@link LeafCollector#collect(int)} is called for every document. <br>
+ *
+ * @param ctx the leaf to execute the search against
+ * @param weight to match document
+ * @param collector to receive hits
+ * @throws TooManyClauses If a query would exceed {@link IndexSearcher#getMaxClauseCount()}
+ * clauses.
+ */
+ protected void searchLeaf(LeafReaderContext ctx, Weight weight, Collector collector)
+ throws IOException {
+ final LeafCollector leafCollector;
+ try {
+ leafCollector = collector.getLeafCollector(ctx);
+ } catch (
+ @SuppressWarnings("unused")
+ CollectionTerminatedException e) {
+ // there is no doc of interest in this reader context
+ // continue with the following leaf
+ return;
+ }
+ BulkScorer scorer = weight.bulkScorer(ctx);
+ if (scorer != null) {
+ if (queryTimeout != null) {
+ scorer = new TimeLimitingBulkScorer(scorer, queryTimeout);
+ }
try {
- leafCollector = collector.getLeafCollector(ctx);
+ scorer.score(leafCollector, ctx.reader().getLiveDocs());
} catch (
@SuppressWarnings("unused")
CollectionTerminatedException e) {
- // there is no doc of interest in this reader context
+ // collection was terminated prematurely
// continue with the following leaf
- continue;
- }
- BulkScorer scorer = weight.bulkScorer(ctx);
- if (scorer != null) {
- if (queryTimeout != null) {
- scorer = new TimeLimitingBulkScorer(scorer, queryTimeout);
- }
- try {
- scorer.score(leafCollector, ctx.reader().getLiveDocs());
- } catch (
- @SuppressWarnings("unused")
- CollectionTerminatedException e) {
- // collection was terminated prematurely
- // continue with the following leaf
- } catch (
- @SuppressWarnings("unused")
- TimeLimitingBulkScorer.TimeExceededException e) {
- partialResult = true;
- }
+ } catch (
+ @SuppressWarnings("unused")
+ TimeLimitingBulkScorer.TimeExceededException e) {
+ partialResult = true;
}
- // Note: this is called if collection ran successfully, including the above special cases of
- // CollectionTerminatedException and TimeExceededException, but no other exception.
- leafCollector.finish();
}
+ // Note: this is called if collection ran successfully, including the above special cases of
+ // CollectionTerminatedException and TimeExceededException, but no other exception.
+ leafCollector.finish();
}
/**
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 e683b39c310..1dedbe3d3dc 100644
--- a/lucene/core/src/test/org/apache/lucene/search/TestTopDocsMerge.java
+++ b/lucene/core/src/test/org/apache/lucene/search/TestTopDocsMerge.java
@@ -43,26 +43,26 @@ import org.apache.lucene.util.BytesRef;
public class TestTopDocsMerge extends LuceneTestCase {
private static class ShardSearcher extends IndexSearcher {
- private final List<LeafReaderContext> ctx;
+ private final LeafReaderContext ctx;
public ShardSearcher(LeafReaderContext ctx, IndexReaderContext parent) {
super(parent);
- this.ctx = Collections.singletonList(ctx);
+ this.ctx = ctx;
}
public void search(Weight weight, Collector collector) throws IOException {
- search(ctx, weight, collector);
+ searchLeaf(ctx, weight, collector);
}
public TopDocs search(Weight weight, int topN) throws IOException {
TopScoreDocCollector collector = TopScoreDocCollector.create(topN, Integer.MAX_VALUE);
- search(ctx, weight, collector);
+ searchLeaf(ctx, weight, collector);
return collector.topDocs();
}
@Override
public String toString() {
- return "ShardSearcher(" + ctx.get(0) + ")";
+ return "ShardSearcher(" + ctx + ")";
}
}
diff --git a/lucene/grouping/src/test/org/apache/lucene/search/grouping/TestGrouping.java b/lucene/grouping/src/test/org/apache/lucene/search/grouping/TestGrouping.java
index 436a4ca45a2..38493a01bb6 100644
--- a/lucene/grouping/src/test/org/apache/lucene/search/grouping/TestGrouping.java
+++ b/lucene/grouping/src/test/org/apache/lucene/search/grouping/TestGrouping.java
@@ -1571,20 +1571,20 @@ public class TestGrouping extends LuceneTestCase {
}
private static class ShardSearcher extends IndexSearcher {
- private final List<LeafReaderContext> ctx;
+ private final LeafReaderContext ctx;
public ShardSearcher(LeafReaderContext ctx, IndexReaderContext parent) {
super(parent);
- this.ctx = Collections.singletonList(ctx);
+ this.ctx = ctx;
}
public void search(Weight weight, Collector collector) throws IOException {
- search(ctx, weight, collector);
+ searchLeaf(ctx, weight, collector);
}
@Override
public String toString() {
- return "ShardSearcher(" + ctx.get(0).reader() + ")";
+ return "ShardSearcher(" + ctx.reader() + ")";
}
}
}
diff --git a/lucene/test-framework/src/java/org/apache/lucene/tests/search/ScorerIndexSearcher.java b/lucene/test-framework/src/java/org/apache/lucene/tests/search/ScorerIndexSearcher.java
index d3a414bc988..a77229ef68f 100644
--- a/lucene/test-framework/src/java/org/apache/lucene/tests/search/ScorerIndexSearcher.java
+++ b/lucene/test-framework/src/java/org/apache/lucene/tests/search/ScorerIndexSearcher.java
@@ -17,7 +17,6 @@
package org.apache.lucene.tests.search;
import java.io.IOException;
-import java.util.List;
import java.util.concurrent.Executor;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.LeafReaderContext;
@@ -53,24 +52,22 @@ public class ScorerIndexSearcher extends IndexSearcher {
}
@Override
- protected void search(List<LeafReaderContext> leaves, Weight weight, Collector collector)
+ protected void searchLeaf(LeafReaderContext ctx, Weight weight, Collector collector)
throws IOException {
- for (LeafReaderContext ctx : leaves) { // search each subreader
- // we force the use of Scorer (not BulkScorer) to make sure
- // that the scorer passed to LeafCollector.setScorer supports
- // Scorer.getChildren
- Scorer scorer = weight.scorer(ctx);
- if (scorer != null) {
- final DocIdSetIterator iterator = scorer.iterator();
- final LeafCollector leafCollector = collector.getLeafCollector(ctx);
- leafCollector.setScorer(scorer);
- final Bits liveDocs = ctx.reader().getLiveDocs();
- for (int doc = iterator.nextDoc();
- doc != DocIdSetIterator.NO_MORE_DOCS;
- doc = iterator.nextDoc()) {
- if (liveDocs == null || liveDocs.get(doc)) {
- leafCollector.collect(doc);
- }
+ // we force the use of Scorer (not BulkScorer) to make sure
+ // that the scorer passed to LeafCollector.setScorer supports
+ // Scorer.getChildren
+ Scorer scorer = weight.scorer(ctx);
+ if (scorer != null) {
+ final DocIdSetIterator iterator = scorer.iterator();
+ final LeafCollector leafCollector = collector.getLeafCollector(ctx);
+ leafCollector.setScorer(scorer);
+ final Bits liveDocs = ctx.reader().getLiveDocs();
+ for (int doc = iterator.nextDoc();
+ doc != DocIdSetIterator.NO_MORE_DOCS;
+ doc = iterator.nextDoc()) {
+ if (liveDocs == null || liveDocs.get(doc)) {
+ leafCollector.collect(doc);
}
}
}