You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by jp...@apache.org on 2023/06/30 13:14:39 UTC

[lucene] branch main updated: Assign a dummy simScorer in TermsWeight if score is not needed (#12383)

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

jpountz 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 40ee6e583e1 Assign a dummy simScorer in TermsWeight if score is not needed (#12383)
40ee6e583e1 is described below

commit 40ee6e583e18c0744295926c8ca6590206f07853
Author: Sagar <99...@users.noreply.github.com>
AuthorDate: Fri Jun 30 06:14:33 2023 -0700

    Assign a dummy simScorer in TermsWeight if score is not needed (#12383)
---
 lucene/CHANGES.txt                                 |  2 +
 .../java/org/apache/lucene/search/TermQuery.java   | 17 +++++++-
 .../org/apache/lucene/search/TestTermQuery.java    | 51 ++++++++++++++++++++++
 3 files changed, 69 insertions(+), 1 deletion(-)

diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt
index 42ea9730f0d..9c04ce90c5e 100644
--- a/lucene/CHANGES.txt
+++ b/lucene/CHANGES.txt
@@ -136,6 +136,8 @@ Optimizations
 * GITHUB#12361: Faster top-level disjunctions sorted by descending score.
   (Adrien Grand)
 
+* GITHUB#12383: Assign a dummy simScorer in TermsWeight if score is not needed. (Sagar Upadhyaya)
+
 * GITHUB#12372: Reduce allocation during HNSW construction (Jonathan Ellis)
 
 * GITHUB#12385: Restore parallel knn query rewrite across segments rather than slices (Luca Cavanna)
diff --git a/lucene/core/src/java/org/apache/lucene/search/TermQuery.java b/lucene/core/src/java/org/apache/lucene/search/TermQuery.java
index f08855abe5c..c7d5ac325b9 100644
--- a/lucene/core/src/java/org/apache/lucene/search/TermQuery.java
+++ b/lucene/core/src/java/org/apache/lucene/search/TermQuery.java
@@ -72,7 +72,22 @@ public class TermQuery extends Query {
       if (termStats == null) {
         this.simScorer = null; // term doesn't exist in any segment, we won't use similarity at all
       } else {
-        this.simScorer = similarity.scorer(boost, collectionStats, termStats);
+        // Assigning a dummy simScorer in case score is not needed to avoid unnecessary float[]
+        // allocations in case default BM25Scorer is used.
+        // See: https://github.com/apache/lucene/issues/12297
+        if (scoreMode.needsScores()) {
+          this.simScorer = similarity.scorer(boost, collectionStats, termStats);
+        } else {
+          // Assigning a dummy scorer as this is not expected to be called since scores are not
+          // needed.
+          this.simScorer =
+              new Similarity.SimScorer() {
+                @Override
+                public float score(float freq, long norm) {
+                  return 0f;
+                }
+              };
+        }
       }
     }
 
diff --git a/lucene/core/src/test/org/apache/lucene/search/TestTermQuery.java b/lucene/core/src/test/org/apache/lucene/search/TestTermQuery.java
index 9a6f39de726..473f6c9a8f0 100644
--- a/lucene/core/src/test/org/apache/lucene/search/TestTermQuery.java
+++ b/lucene/core/src/test/org/apache/lucene/search/TestTermQuery.java
@@ -17,11 +17,14 @@
 package org.apache.lucene.search;
 
 import java.io.IOException;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicReference;
 import org.apache.lucene.document.Document;
 import org.apache.lucene.document.Field.Store;
 import org.apache.lucene.document.StringField;
 import org.apache.lucene.index.CompositeReaderContext;
 import org.apache.lucene.index.DirectoryReader;
+import org.apache.lucene.index.FieldInvertState;
 import org.apache.lucene.index.FilterDirectoryReader;
 import org.apache.lucene.index.FilterLeafReader;
 import org.apache.lucene.index.LeafReader;
@@ -32,6 +35,7 @@ import org.apache.lucene.index.TermState;
 import org.apache.lucene.index.TermStates;
 import org.apache.lucene.index.Terms;
 import org.apache.lucene.index.TermsEnum;
+import org.apache.lucene.search.similarities.Similarity;
 import org.apache.lucene.store.Directory;
 import org.apache.lucene.tests.index.RandomIndexWriter;
 import org.apache.lucene.tests.search.DummyTotalHitCountCollector;
@@ -164,6 +168,53 @@ public class TestTermQuery extends LuceneTestCase {
     IOUtils.close(reader, w, dir);
   }
 
+  public void testWithWithDifferentScoreModes() throws Exception {
+    Directory dir = newDirectory();
+    RandomIndexWriter w =
+        new RandomIndexWriter(
+            random(), dir, newIndexWriterConfig().setMergePolicy(NoMergePolicy.INSTANCE));
+    // segment that contains the term
+    Document doc = new Document();
+    doc.add(new StringField("foo", "bar", Store.NO));
+    w.addDocument(doc);
+    w.getReader().close();
+    DirectoryReader reader = w.getReader();
+    IndexSearcher searcher = new IndexSearcher(reader);
+    Similarity existingSimilarity = searcher.getSimilarity();
+
+    for (ScoreMode scoreMode : ScoreMode.values()) {
+      final AtomicReference<ScoreMode> scoreModeInWeight = new AtomicReference<ScoreMode>();
+      final AtomicBoolean scorerCalled = new AtomicBoolean();
+      searcher.setSimilarity(
+          new Similarity() { // Wrapping existing similarity for testing
+            @Override
+            public long computeNorm(FieldInvertState state) {
+              return existingSimilarity.computeNorm(state);
+            }
+
+            @Override
+            public SimScorer scorer(
+                float boost, CollectionStatistics collectionStats, TermStatistics... termStats) {
+              scorerCalled.set(true);
+              return existingSimilarity.scorer(boost, collectionStats, termStats);
+            }
+          });
+      TermQuery termQuery =
+          new TermQuery(new Term("foo", "bar")) {
+            @Override
+            public Weight createWeight(IndexSearcher searcher, ScoreMode scoreMode, float boost)
+                throws IOException {
+              scoreModeInWeight.set(scoreMode);
+              return super.createWeight(searcher, scoreMode, boost);
+            }
+          };
+      termQuery.createWeight(searcher, scoreMode, 1f);
+      assertEquals(scoreMode, scoreModeInWeight.get());
+      assertEquals(scoreMode.needsScores(), scorerCalled.get());
+    }
+    IOUtils.close(reader, w, dir);
+  }
+
   private static class NoSeekDirectoryReader extends FilterDirectoryReader {
 
     public NoSeekDirectoryReader(DirectoryReader in) throws IOException {