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 2025/03/15 21:18:40 UTC

(lucene) branch main updated: Avoid unnecessary evaluations and skipping documents (#14301)

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 565d0e743a6 Avoid unnecessary evaluations and skipping documents (#14301)
565d0e743a6 is described below

commit 565d0e743a69e009809fdd8e58fdd96c092b0e5a
Author: hanbj <ha...@163.com>
AuthorDate: Sun Mar 16 05:18:34 2025 +0800

    Avoid unnecessary evaluations and skipping documents (#14301)
---
 lucene/CHANGES.txt                                 |  2 ++
 .../lucene/document/LongDistanceFeatureQuery.java  | 29 +++++++++++++++++++++-
 2 files changed, 30 insertions(+), 1 deletion(-)

diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt
index 374ebef954d..9603ab872e8 100644
--- a/lucene/CHANGES.txt
+++ b/lucene/CHANGES.txt
@@ -176,6 +176,8 @@ Optimizations
 
 * GITHUB#14338: Deduplicate BKDConfig records in BKDReader. (Ignacio Vera)
 
+* GITHUB#14301: Avoid unnecessary evaluations and skipping documents. (hanbj)
+
 Bug Fixes
 ---------------------
 
diff --git a/lucene/core/src/java/org/apache/lucene/document/LongDistanceFeatureQuery.java b/lucene/core/src/java/org/apache/lucene/document/LongDistanceFeatureQuery.java
index 788ded4909b..2f1fd0c8ccc 100644
--- a/lucene/core/src/java/org/apache/lucene/document/LongDistanceFeatureQuery.java
+++ b/lucene/core/src/java/org/apache/lucene/document/LongDistanceFeatureQuery.java
@@ -39,6 +39,9 @@ import org.apache.lucene.util.IntsRef;
 import org.apache.lucene.util.NumericUtils;
 
 final class LongDistanceFeatureQuery extends Query {
+  // MIN_SKIP_INTERVAL and MAX_SKIP_INTERVAL both should be powers of 2
+  private static final int MIN_SKIP_INTERVAL = 32;
+  private static final int MAX_SKIP_INTERVAL = 8192;
 
   private final String field;
   private final long origin;
@@ -234,6 +237,10 @@ final class LongDistanceFeatureQuery extends Query {
     private final NumericDocValues docValues;
     private long maxDistance = Long.MAX_VALUE;
 
+    private int currentSkipInterval = MIN_SKIP_INTERVAL;
+    // helps to be conservative about increasing the sampling interval
+    private int tryUpdateFailCount = 0;
+
     protected DistanceScorer(
         int maxDoc,
         long leadCost,
@@ -346,7 +353,9 @@ final class LongDistanceFeatureQuery extends Query {
 
       // Start sampling if we get called too much
       setMinCompetitiveScoreCounter++;
-      if (setMinCompetitiveScoreCounter > 256 && (setMinCompetitiveScoreCounter & 0x1f) != 0x1f) {
+      if (setMinCompetitiveScoreCounter > 256
+          && (setMinCompetitiveScoreCounter & (currentSkipInterval - 1))
+              != currentSkipInterval - 1) {
         return;
       }
 
@@ -444,10 +453,28 @@ final class LongDistanceFeatureQuery extends Query {
       if (PointValues.isEstimatedPointCountGreaterThanOrEqualTo(
           visitor, pointValues.getPointTree(), threshold)) {
         // the new range is not selective enough to be worth materializing
+        updateSkipInterval(false);
         return;
       }
       pointValues.intersect(visitor);
       it = result.build().iterator();
+      updateSkipInterval(true);
+    }
+
+    private void updateSkipInterval(boolean success) {
+      if (setMinCompetitiveScoreCounter > 256) {
+        if (success) {
+          currentSkipInterval = Math.max(currentSkipInterval / 2, MIN_SKIP_INTERVAL);
+          tryUpdateFailCount = 0;
+        } else {
+          if (tryUpdateFailCount >= 3) {
+            currentSkipInterval = Math.min(currentSkipInterval * 2, MAX_SKIP_INTERVAL);
+            tryUpdateFailCount = 0;
+          } else {
+            tryUpdateFailCount++;
+          }
+        }
+      }
     }
   }
 }