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 2026/06/19 09:26:55 UTC

(lucene) branch main updated: Replace search(Query, Collector) deprecated usages in TestJoinUtil (#16262)

This is an automated email from the ASF dual-hosted git repository.

javanna pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/lucene.git


The following commit(s) were added to refs/heads/main by this push:
     new 4965e8d4d96 Replace search(Query, Collector) deprecated usages in TestJoinUtil  (#16262)
4965e8d4d96 is described below

commit 4965e8d4d960445a0522fae512c60c6d8f11fc29
Author: Luca Cavanna <ja...@apache.org>
AuthorDate: Fri Jun 19 11:26:50 2026 +0200

    Replace search(Query, Collector) deprecated usages in TestJoinUtil  (#16262)
    
    Relates to #12892
---
 .../apache/lucene/search/join/TestJoinUtil.java    | 421 +++++++++++++--------
 1 file changed, 265 insertions(+), 156 deletions(-)

diff --git a/lucene/join/src/test/org/apache/lucene/search/join/TestJoinUtil.java b/lucene/join/src/test/org/apache/lucene/search/join/TestJoinUtil.java
index 2f815a8357f..6ec736089ed 100644
--- a/lucene/join/src/test/org/apache/lucene/search/join/TestJoinUtil.java
+++ b/lucene/join/src/test/org/apache/lucene/search/join/TestJoinUtil.java
@@ -21,6 +21,7 @@ import com.carrotsearch.randomizedtesting.generators.RandomPicks;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.EnumSet;
 import java.util.HashMap;
@@ -65,6 +66,7 @@ import org.apache.lucene.index.TermsEnum;
 import org.apache.lucene.search.BooleanClause;
 import org.apache.lucene.search.BooleanQuery;
 import org.apache.lucene.search.BoostQuery;
+import org.apache.lucene.search.CollectorManager;
 import org.apache.lucene.search.DocIdSetIterator;
 import org.apache.lucene.search.Explanation;
 import org.apache.lucene.search.FieldExistsQuery;
@@ -72,7 +74,7 @@ import org.apache.lucene.search.FilterScorer;
 import org.apache.lucene.search.IndexSearcher;
 import org.apache.lucene.search.MatchAllDocsQuery;
 import org.apache.lucene.search.MatchNoDocsQuery;
-import org.apache.lucene.search.MultiCollector;
+import org.apache.lucene.search.MultiCollectorManager;
 import org.apache.lucene.search.Query;
 import org.apache.lucene.search.QueryVisitor;
 import org.apache.lucene.search.Scorable;
@@ -82,7 +84,6 @@ import org.apache.lucene.search.ScorerSupplier;
 import org.apache.lucene.search.SimpleCollector;
 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.search.TotalHits;
 import org.apache.lucene.search.Weight;
@@ -488,14 +489,16 @@ public class TestJoinUtil extends LuceneTestCase {
         System.out.println("joinQuery=" + joinQuery);
       }
 
-      final BitSet actualResult = new FixedBitSet(indexSearcher.getIndexReader().maxDoc());
-      final TopScoreDocCollector topScoreDocCollector =
-          new TopScoreDocCollectorManager(10, null, Integer.MAX_VALUE).newCollector();
-      indexSearcher.search(
-          joinQuery, MultiCollector.wrap(new BitSetCollector(actualResult), topScoreDocCollector));
+      Object[] searchResults =
+          indexSearcher.search(
+              joinQuery,
+              new MultiCollectorManager(
+                  new BitSetCollectorManager(indexSearcher.getIndexReader().maxDoc()),
+                  new TopScoreDocCollectorManager(10, null, Integer.MAX_VALUE)));
+      final BitSet actualResult = (BitSet) searchResults[0];
       assertBitSet(expectedResult, actualResult, indexSearcher);
       TopDocs expectedTopDocs = createExpectedTopDocs(randomValue, from, scoreMode, context);
-      TopDocs actualTopDocs = topScoreDocCollector.topDocs();
+      TopDocs actualTopDocs = (TopDocs) searchResults[1];
       assertTopDocs(expectedTopDocs, actualTopDocs, scoreMode, indexSearcher, joinQuery);
     }
     context.close();
@@ -899,7 +902,8 @@ public class TestJoinUtil extends LuceneTestCase {
     w.addDocument(doc);
 
     w.forceMerge(1);
-
+    // single segment test, that relies on sequential collection, the searcher is also created
+    // without an executor
     IndexSearcher indexSearcher = new IndexSearcher(w.getReader());
     w.close();
 
@@ -919,26 +923,37 @@ public class TestJoinUtil extends LuceneTestCase {
 
     indexSearcher.search(
         bq.build(),
-        new SimpleCollector() {
-          boolean sawFive;
-
+        new CollectorManager<SimpleCollector, Void>() {
           @Override
-          public void collect(int docID) {
-            // Hairy / evil (depends on how BooleanScorer
-            // stores temporarily collected docIDs by
-            // appending to head of linked list):
-            if (docID == 5) {
-              sawFive = true;
-            } else if (docID == 1) {
-              assertFalse(
-                  "optimized bulkScorer was not used for join query embedded in boolean query!",
-                  sawFive);
-            }
+          public SimpleCollector newCollector() {
+            return new SimpleCollector() {
+              boolean sawFive;
+
+              @Override
+              public void collect(int docID) {
+                // Hairy / evil (depends on how BooleanScorer
+                // stores temporarily collected docIDs by
+                // appending to head of linked list):
+                if (docID == 5) {
+                  sawFive = true;
+                } else if (docID == 1) {
+                  assertFalse(
+                      "optimized bulkScorer was not used for join query embedded in boolean query!",
+                      sawFive);
+                }
+              }
+
+              @Override
+              public org.apache.lucene.search.ScoreMode scoreMode() {
+                return org.apache.lucene.search.ScoreMode.COMPLETE_NO_SCORES;
+              }
+            };
           }
 
           @Override
-          public org.apache.lucene.search.ScoreMode scoreMode() {
-            return org.apache.lucene.search.ScoreMode.COMPLETE_NO_SCORES;
+          public Void reduce(Collection<SimpleCollector> collectors) {
+            assert collectors.size() == 1 : "concurrent execution is not supported by this test";
+            return null;
           }
         });
 
@@ -1564,17 +1579,17 @@ public class TestJoinUtil extends LuceneTestCase {
 
         // Need to know all documents that have matches. TopDocs doesn't give me that and then I'd
         // be also testing TopDocsCollector...
-        final BitSet actualResult = new FixedBitSet(indexSearcher.getIndexReader().maxDoc());
-        final TopScoreDocCollector topScoreDocCollector =
-            new TopScoreDocCollectorManager(10, null, Integer.MAX_VALUE).newCollector();
-        indexSearcher.search(
-            joinQuery,
-            MultiCollector.wrap(new BitSetCollector(actualResult), topScoreDocCollector));
+        Object[] searchResults =
+            indexSearcher.search(
+                joinQuery,
+                new MultiCollectorManager(
+                    new BitSetCollectorManager(indexSearcher.getIndexReader().maxDoc()),
+                    new TopScoreDocCollectorManager(10, null, Integer.MAX_VALUE)));
         // Asserting bit set...
-        assertBitSet(expectedResult, actualResult, indexSearcher);
+        assertBitSet(expectedResult, (BitSet) searchResults[0], indexSearcher);
         // Asserting TopDocs...
         TopDocs expectedTopDocs = createExpectedTopDocs(randomValue, from, scoreMode, context);
-        TopDocs actualTopDocs = topScoreDocCollector.topDocs();
+        TopDocs actualTopDocs = (TopDocs) searchResults[1];
         assertTopDocs(expectedTopDocs, actualTopDocs, scoreMode, indexSearcher, joinQuery);
       }
       context.close();
@@ -1787,98 +1802,40 @@ public class TestJoinUtil extends LuceneTestCase {
         toField = "from";
         queryVals = context.toHitsToJoinScore;
       }
-      final Map<BytesRef, JoinScore> joinValueToJoinScores = new HashMap<>();
+      final Map<BytesRef, JoinScore> joinValueToJoinScores;
       if (multipleValuesPerDocument) {
-        searcher.search(
-            new TermQuery(new Term("value", uniqueRandomValue)),
-            new SimpleCollector() {
-
-              private Scorable scorer;
-              private SortedSetDocValues docTermOrds;
-
-              @Override
-              public void collect(int doc) throws IOException {
-                if (doc > docTermOrds.docID()) {
-                  docTermOrds.advance(doc);
-                }
-                if (doc == docTermOrds.docID()) {
-                  long ord;
-                  for (int j = 0; j < docTermOrds.docValueCount(); j++) {
-                    ord = docTermOrds.nextOrd();
-                    final BytesRef joinValue = docTermOrds.lookupOrd(ord);
-                    JoinScore joinScore = joinValueToJoinScores.get(joinValue);
-                    if (joinScore == null) {
-                      joinValueToJoinScores.put(
-                          BytesRef.deepCopyOf(joinValue), joinScore = new JoinScore());
-                    }
-                    joinScore.addScore(scorer.score());
+        joinValueToJoinScores =
+            searcher.search(
+                new TermQuery(new Term("value", uniqueRandomValue)),
+                new CollectorManager<SortedSetJoinScoreCollector, Map<BytesRef, JoinScore>>() {
+                  @Override
+                  public SortedSetJoinScoreCollector newCollector() {
+                    return new SortedSetJoinScoreCollector(fromField);
                   }
-                }
-              }
-
-              @Override
-              protected void doSetNextReader(LeafReaderContext context) throws IOException {
-                docTermOrds = DocValues.getSortedSet(context.reader(), fromField);
-              }
 
-              @Override
-              public void setScorer(Scorable scorer) {
-                this.scorer = scorer;
-              }
-
-              @Override
-              public org.apache.lucene.search.ScoreMode scoreMode() {
-                return org.apache.lucene.search.ScoreMode.COMPLETE;
-              }
-            });
+                  @Override
+                  public Map<BytesRef, JoinScore> reduce(
+                      Collection<SortedSetJoinScoreCollector> collectors) {
+                    return SortedSetJoinScoreCollector.mergeJoinValueMaps(collectors);
+                  }
+                });
       } else {
-        searcher.search(
-            new TermQuery(new Term("value", uniqueRandomValue)),
-            new SimpleCollector() {
-
-              private Scorable scorer;
-              private SortedDocValues terms;
-
-              @Override
-              public void collect(int doc) throws IOException {
-                final BytesRef joinValue;
-                if (terms.advanceExact(doc)) {
-                  joinValue = terms.lookupOrd(terms.ordValue());
-                } else {
-                  // missing;
-                  return;
-                }
-
-                JoinScore joinScore = joinValueToJoinScores.get(joinValue);
-                if (joinScore == null) {
-                  joinValueToJoinScores.put(
-                      BytesRef.deepCopyOf(joinValue), joinScore = new JoinScore());
-                }
-                if (VERBOSE) {
-                  System.out.println(
-                      "expected val="
-                          + joinValue.utf8ToString()
-                          + " expected score="
-                          + scorer.score());
-                }
-                joinScore.addScore(scorer.score());
-              }
-
-              @Override
-              protected void doSetNextReader(LeafReaderContext context) throws IOException {
-                terms = DocValues.getSorted(context.reader(), fromField);
-              }
-
-              @Override
-              public void setScorer(Scorable scorer) {
-                this.scorer = scorer;
-              }
+        joinValueToJoinScores =
+            searcher.search(
+                new TermQuery(new Term("value", uniqueRandomValue)),
+                new CollectorManager<
+                    SortedDocValuesJoinScoreCollector, Map<BytesRef, JoinScore>>() {
+                  @Override
+                  public SortedDocValuesJoinScoreCollector newCollector() {
+                    return new SortedDocValuesJoinScoreCollector(fromField);
+                  }
 
-              @Override
-              public org.apache.lucene.search.ScoreMode scoreMode() {
-                return org.apache.lucene.search.ScoreMode.COMPLETE;
-              }
-            });
+                  @Override
+                  public Map<BytesRef, JoinScore> reduce(
+                      Collection<SortedDocValuesJoinScoreCollector> collectors) {
+                    return SortedDocValuesJoinScoreCollector.mergeJoinValueMaps(collectors);
+                  }
+                });
       }
 
       final Map<Integer, JoinScore> docToJoinScore = new HashMap<>();
@@ -1906,43 +1863,25 @@ public class TestJoinUtil extends LuceneTestCase {
           }
         }
       } else {
-        searcher.search(
-            MatchAllDocsQuery.INSTANCE,
-            new SimpleCollector() {
-
-              private SortedDocValues terms;
-              private int docBase;
-
-              @Override
-              public void collect(int doc) throws IOException {
-                final BytesRef joinValue;
-                if (terms.advanceExact(doc)) {
-                  joinValue = terms.lookupOrd(terms.ordValue());
-                } else {
-                  // missing;
-                  joinValue = new BytesRef(BytesRef.EMPTY_BYTES);
-                }
-                JoinScore joinScore = joinValueToJoinScores.get(joinValue);
-                if (joinScore == null) {
-                  return;
-                }
-                docToJoinScore.put(docBase + doc, joinScore);
-              }
-
-              @Override
-              protected void doSetNextReader(LeafReaderContext context) throws IOException {
-                terms = DocValues.getSorted(context.reader(), toField);
-                docBase = context.docBase;
-              }
-
-              @Override
-              public void setScorer(Scorable scorer) {}
+        docToJoinScore.putAll(
+            searcher.search(
+                MatchAllDocsQuery.INSTANCE,
+                new CollectorManager<DocToJoinScoreCollector, Map<Integer, JoinScore>>() {
+                  @Override
+                  public DocToJoinScoreCollector newCollector() {
+                    return new DocToJoinScoreCollector(toField, joinValueToJoinScores);
+                  }
 
-              @Override
-              public org.apache.lucene.search.ScoreMode scoreMode() {
-                return org.apache.lucene.search.ScoreMode.COMPLETE_NO_SCORES;
-              }
-            });
+                  @Override
+                  public Map<Integer, JoinScore> reduce(
+                      Collection<DocToJoinScoreCollector> collectors) {
+                    Map<Integer, JoinScore> merged = new HashMap<>();
+                    for (DocToJoinScoreCollector c : collectors) {
+                      merged.putAll(c.localMap);
+                    }
+                    return merged;
+                  }
+                }));
       }
       queryVals.put(uniqueRandomValue, docToJoinScore);
     }
@@ -2162,4 +2101,174 @@ public class TestJoinUtil extends LuceneTestCase {
       return org.apache.lucene.search.ScoreMode.COMPLETE_NO_SCORES;
     }
   }
+
+  private abstract static class JoinValueCollector extends SimpleCollector {
+    final Map<BytesRef, JoinScore> localMap = new HashMap<>();
+    final String fromField;
+    Scorable scorer;
+
+    JoinValueCollector(String fromField) {
+      this.fromField = fromField;
+    }
+
+    @Override
+    public final void setScorer(Scorable s) {
+      this.scorer = s;
+    }
+
+    @Override
+    public final org.apache.lucene.search.ScoreMode scoreMode() {
+      return org.apache.lucene.search.ScoreMode.COMPLETE;
+    }
+
+    static Map<BytesRef, JoinScore> mergeJoinValueMaps(
+        Collection<? extends JoinValueCollector> collectors) {
+      Map<BytesRef, JoinScore> merged = new HashMap<>();
+      for (JoinValueCollector c : collectors) {
+        for (Map.Entry<BytesRef, JoinScore> entry : c.localMap.entrySet()) {
+          merged.merge(
+              entry.getKey(),
+              entry.getValue(),
+              (existing, src) -> {
+                if (src.minScore < existing.minScore) existing.minScore = src.minScore;
+                if (src.maxScore > existing.maxScore) existing.maxScore = src.maxScore;
+                existing.total += src.total;
+                existing.count += src.count;
+                return existing;
+              });
+        }
+      }
+      return merged;
+    }
+  }
+
+  private static class SortedSetJoinScoreCollector extends JoinValueCollector {
+    private SortedSetDocValues docTermOrds;
+
+    SortedSetJoinScoreCollector(String fromField) {
+      super(fromField);
+    }
+
+    @Override
+    public void collect(int doc) throws IOException {
+      if (doc > docTermOrds.docID()) {
+        docTermOrds.advance(doc);
+      }
+      if (doc == docTermOrds.docID()) {
+        long ord;
+        for (int j = 0; j < docTermOrds.docValueCount(); j++) {
+          ord = docTermOrds.nextOrd();
+          final BytesRef joinValue = docTermOrds.lookupOrd(ord);
+          JoinScore joinScore = localMap.get(joinValue);
+          if (joinScore == null) {
+            localMap.put(BytesRef.deepCopyOf(joinValue), joinScore = new JoinScore());
+          }
+          joinScore.addScore(scorer.score());
+        }
+      }
+    }
+
+    @Override
+    protected void doSetNextReader(LeafReaderContext ctx) throws IOException {
+      docTermOrds = DocValues.getSortedSet(ctx.reader(), fromField);
+    }
+  }
+
+  private static class SortedDocValuesJoinScoreCollector extends JoinValueCollector {
+    private SortedDocValues terms;
+
+    SortedDocValuesJoinScoreCollector(String fromField) {
+      super(fromField);
+    }
+
+    @Override
+    public void collect(int doc) throws IOException {
+      final BytesRef joinValue;
+      if (terms.advanceExact(doc)) {
+        joinValue = terms.lookupOrd(terms.ordValue());
+      } else {
+        return;
+      }
+      JoinScore joinScore = localMap.get(joinValue);
+      if (joinScore == null) {
+        localMap.put(BytesRef.deepCopyOf(joinValue), joinScore = new JoinScore());
+      }
+      if (LuceneTestCase.VERBOSE) {
+        System.out.println(
+            "expected val=" + joinValue.utf8ToString() + " expected score=" + scorer.score());
+      }
+      joinScore.addScore(scorer.score());
+    }
+
+    @Override
+    protected void doSetNextReader(LeafReaderContext ctx) throws IOException {
+      terms = DocValues.getSorted(ctx.reader(), fromField);
+    }
+  }
+
+  private static class DocToJoinScoreCollector extends SimpleCollector {
+    final Map<Integer, JoinScore> localMap = new HashMap<>();
+    private final String toField;
+    private final Map<BytesRef, JoinScore> joinValueToJoinScores;
+    private SortedDocValues terms;
+    private int docBase;
+
+    DocToJoinScoreCollector(String toField, Map<BytesRef, JoinScore> joinValueToJoinScores) {
+      this.toField = toField;
+      this.joinValueToJoinScores = joinValueToJoinScores;
+    }
+
+    @Override
+    public void collect(int doc) throws IOException {
+      final BytesRef joinValue;
+      if (terms.advanceExact(doc)) {
+        joinValue = terms.lookupOrd(terms.ordValue());
+      } else {
+        joinValue = new BytesRef(BytesRef.EMPTY_BYTES);
+      }
+      JoinScore joinScore = joinValueToJoinScores.get(joinValue);
+      if (joinScore == null) {
+        return;
+      }
+      localMap.put(docBase + doc, joinScore);
+    }
+
+    @Override
+    protected void doSetNextReader(LeafReaderContext ctx) throws IOException {
+      terms = DocValues.getSorted(ctx.reader(), toField);
+      docBase = ctx.docBase;
+    }
+
+    @Override
+    public void setScorer(Scorable scorer) {}
+
+    @Override
+    public org.apache.lucene.search.ScoreMode scoreMode() {
+      return org.apache.lucene.search.ScoreMode.COMPLETE_NO_SCORES;
+    }
+  }
+
+  private static class BitSetCollectorManager
+      implements CollectorManager<BitSetCollector, FixedBitSet> {
+
+    private final int maxDoc;
+
+    BitSetCollectorManager(int maxDoc) {
+      this.maxDoc = maxDoc;
+    }
+
+    @Override
+    public BitSetCollector newCollector() {
+      return new BitSetCollector(new FixedBitSet(maxDoc));
+    }
+
+    @Override
+    public FixedBitSet reduce(Collection<BitSetCollector> collectors) {
+      FixedBitSet result = new FixedBitSet(maxDoc);
+      for (BitSetCollector c : collectors) {
+        result.or((FixedBitSet) c.bitSet);
+      }
+      return result;
+    }
+  }
 }