You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by kr...@apache.org on 2022/05/02 17:13:49 UTC

[lucene] branch main updated: LUCENE-10534: MinFloatFunction / MaxFloatFunction calls exists twice (#837)

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

krisden 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 7efac761f4d LUCENE-10534: MinFloatFunction / MaxFloatFunction calls exists twice (#837)
7efac761f4d is described below

commit 7efac761f4d0d85328cb6ddddd03100110109887
Author: Kevin Risden <ri...@users.noreply.github.com>
AuthorDate: Mon May 2 13:13:45 2022 -0400

    LUCENE-10534: MinFloatFunction / MaxFloatFunction calls exists twice (#837)
---
 lucene/CHANGES.txt                                 |  2 ++
 .../function/valuesource/MaxFloatFunction.java     |  7 ++--
 .../function/valuesource/MinFloatFunction.java     |  7 ++--
 .../lucene/queries/function/TestValueSources.java  | 42 +++++++++++++++++-----
 4 files changed, 45 insertions(+), 13 deletions(-)

diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt
index 91a13b44580..b0ec21201f4 100644
--- a/lucene/CHANGES.txt
+++ b/lucene/CHANGES.txt
@@ -130,6 +130,8 @@ Optimizations
 
 * LUCENE-10542: FieldSource exists implementations can avoid value retrieval (Kevin Risden)
 
+* LUCENE-10534: MinFloatFunction / MaxFloatFunction exists check can be slow (Kevin Risden)
+
 Bug Fixes
 ---------------------
 * LUCENE-10477: Highlighter: WeightedSpanTermExtractor.extractWeightedSpanTerms to Query#rewrite
diff --git a/lucene/queries/src/java/org/apache/lucene/queries/function/valuesource/MaxFloatFunction.java b/lucene/queries/src/java/org/apache/lucene/queries/function/valuesource/MaxFloatFunction.java
index d88658f131a..9ab07c793a6 100644
--- a/lucene/queries/src/java/org/apache/lucene/queries/function/valuesource/MaxFloatFunction.java
+++ b/lucene/queries/src/java/org/apache/lucene/queries/function/valuesource/MaxFloatFunction.java
@@ -33,14 +33,17 @@ public class MaxFloatFunction extends MultiFloatFunction {
 
   @Override
   protected float func(int doc, FunctionValues[] valsArr) throws IOException {
-    if (!exists(doc, valsArr)) return 0.0f;
-
+    boolean noneFound = true;
     float val = Float.NEGATIVE_INFINITY;
     for (FunctionValues vals : valsArr) {
       if (vals.exists(doc)) {
+        noneFound = false;
         val = Math.max(vals.floatVal(doc), val);
       }
     }
+    if (noneFound) {
+      return 0.0f;
+    }
     return val;
   }
 
diff --git a/lucene/queries/src/java/org/apache/lucene/queries/function/valuesource/MinFloatFunction.java b/lucene/queries/src/java/org/apache/lucene/queries/function/valuesource/MinFloatFunction.java
index 2561c46cd7f..189917a6c4f 100644
--- a/lucene/queries/src/java/org/apache/lucene/queries/function/valuesource/MinFloatFunction.java
+++ b/lucene/queries/src/java/org/apache/lucene/queries/function/valuesource/MinFloatFunction.java
@@ -33,14 +33,17 @@ public class MinFloatFunction extends MultiFloatFunction {
 
   @Override
   protected float func(int doc, FunctionValues[] valsArr) throws IOException {
-    if (!exists(doc, valsArr)) return 0.0f;
-
+    boolean noneFound = true;
     float val = Float.POSITIVE_INFINITY;
     for (FunctionValues vals : valsArr) {
       if (vals.exists(doc)) {
+        noneFound = false;
         val = Math.min(vals.floatVal(doc), val);
       }
     }
+    if (noneFound) {
+      return 0.0f;
+    }
     return val;
   }
 
diff --git a/lucene/queries/src/test/org/apache/lucene/queries/function/TestValueSources.java b/lucene/queries/src/test/org/apache/lucene/queries/function/TestValueSources.java
index 75c2103c046..933c8e7e257 100644
--- a/lucene/queries/src/test/org/apache/lucene/queries/function/TestValueSources.java
+++ b/lucene/queries/src/test/org/apache/lucene/queries/function/TestValueSources.java
@@ -380,42 +380,66 @@ public class TestValueSources extends LuceneTestCase {
     ValueSource vs =
         new MaxFloatFunction(
             new ValueSource[] {new ConstValueSource(1f), new ConstValueSource(2f)});
-
-    assertHits(new FunctionQuery(vs), new float[] {2f, 2f});
     assertAllExist(vs);
+    assertHits(new FunctionQuery(vs), new float[] {2f, 2f});
 
     // as long as one value exists, then max exists
-    vs = new MaxFloatFunction(new ValueSource[] {BOGUS_FLOAT_VS, new ConstValueSource(2F)});
+    vs = new MaxFloatFunction(new ValueSource[] {BOGUS_FLOAT_VS, new ConstValueSource(2f)});
     assertAllExist(vs);
+    assertHits(new FunctionQuery(vs), new float[] {2f, 2f});
+
     vs =
         new MaxFloatFunction(
-            new ValueSource[] {BOGUS_FLOAT_VS, new ConstValueSource(2F), BOGUS_DOUBLE_VS});
+            new ValueSource[] {BOGUS_FLOAT_VS, new ConstValueSource(2f), BOGUS_DOUBLE_VS});
     assertAllExist(vs);
+    assertHits(new FunctionQuery(vs), new float[] {2f, 2f});
+
     // if none exist, then max doesn't exist
     vs = new MaxFloatFunction(new ValueSource[] {BOGUS_FLOAT_VS, BOGUS_INT_VS, BOGUS_DOUBLE_VS});
     assertNoneExist(vs);
+    assertHits(new FunctionQuery(vs), new float[] {0f, 0f});
+
+    // if no values exist should return 0f even if value returned is non zero
+    vs =
+        new MaxFloatFunction(
+            new ValueSource[] {
+              new SumFloatFunction(new ValueSource[] {BOGUS_FLOAT_VS, new ConstValueSource(42)})
+            });
+    assertNoneExist(vs);
+    assertHits(new FunctionQuery(vs), new float[] {0f, 0f});
   }
 
   public void testMinFloat() throws Exception {
     ValueSource vs =
         new MinFloatFunction(
             new ValueSource[] {new ConstValueSource(1f), new ConstValueSource(2f)});
-
-    assertHits(new FunctionQuery(vs), new float[] {1f, 1f});
     assertAllExist(vs);
+    assertHits(new FunctionQuery(vs), new float[] {1f, 1f});
 
     // as long as one value exists, then min exists
-    vs = new MinFloatFunction(new ValueSource[] {BOGUS_FLOAT_VS, new ConstValueSource(2F)});
-    assertHits(new FunctionQuery(vs), new float[] {2F, 2F});
+    vs = new MinFloatFunction(new ValueSource[] {BOGUS_FLOAT_VS, new ConstValueSource(2f)});
     assertAllExist(vs);
+    assertHits(new FunctionQuery(vs), new float[] {2f, 2f});
+
     vs =
         new MinFloatFunction(
-            new ValueSource[] {BOGUS_FLOAT_VS, new ConstValueSource(2F), BOGUS_DOUBLE_VS});
+            new ValueSource[] {BOGUS_FLOAT_VS, new ConstValueSource(2f), BOGUS_DOUBLE_VS});
     assertAllExist(vs);
+    assertHits(new FunctionQuery(vs), new float[] {2f, 2f});
 
     // if none exist, then min doesn't exist
     vs = new MinFloatFunction(new ValueSource[] {BOGUS_FLOAT_VS, BOGUS_INT_VS, BOGUS_DOUBLE_VS});
     assertNoneExist(vs);
+    assertHits(new FunctionQuery(vs), new float[] {0f, 0f});
+
+    // if no values exist should return 0f even if value returned is non zero
+    vs =
+        new MinFloatFunction(
+            new ValueSource[] {
+              new SumFloatFunction(new ValueSource[] {BOGUS_FLOAT_VS, new ConstValueSource(42)})
+            });
+    assertNoneExist(vs);
+    assertHits(new FunctionQuery(vs), new float[] {0f, 0f});
   }
 
   public void testNorm() throws Exception {