You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by ds...@apache.org on 2020/08/24 04:50:57 UTC

[lucene-solr] branch branch_8x updated: LUCENE-9373: FunctionMatchQuery: add "matchCost" param

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

dsmiley pushed a commit to branch branch_8x
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git


The following commit(s) were added to refs/heads/branch_8x by this push:
     new 654ee3b  LUCENE-9373: FunctionMatchQuery: add "matchCost" param
654ee3b is described below

commit 654ee3bee4f567d5e3043b2f2ae0873714ea5fd3
Author: David Smiley <ds...@salesforce.com>
AuthorDate: Mon Aug 24 00:07:55 2020 -0400

    LUCENE-9373: FunctionMatchQuery: add "matchCost" param
    
    (cherry picked from commit e1392c74400d74366982ccb796063ffdcef08047)
---
 lucene/CHANGES.txt                                 |  4 +++-
 .../queries/function/FunctionMatchQuery.java       | 19 ++++++++++++++--
 .../queries/function/TestFunctionMatchQuery.java   | 26 +++++++++++++++++++++-
 3 files changed, 45 insertions(+), 4 deletions(-)

diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt
index 93f14d3..66a52a3 100644
--- a/lucene/CHANGES.txt
+++ b/lucene/CHANGES.txt
@@ -7,7 +7,6 @@ http://s.apache.org/luceneversions
 
 API Changes
 ---------------------
-(No changes)
 
 * LUCENE-9437: Lucene's facet module's DocValuesOrdinalsReader.decode method
   is now public, making it easier for applications to decode facet
@@ -40,6 +39,9 @@ Optimizations
 * LUCENE-9395: ConstantValuesSource now shares a single DoubleValues
   instance across all segments (Tony Xu)
 
+* LUCENE-9373: FunctionMatchQuery now accepts a "matchCost" optimization hint.
+  (Maxim Glazkov, David Smiley)
+
 Bug Fixes
 ---------------------
 
diff --git a/lucene/queries/src/java/org/apache/lucene/queries/function/FunctionMatchQuery.java b/lucene/queries/src/java/org/apache/lucene/queries/function/FunctionMatchQuery.java
index 39a51c1..bd2c2f5 100644
--- a/lucene/queries/src/java/org/apache/lucene/queries/function/FunctionMatchQuery.java
+++ b/lucene/queries/src/java/org/apache/lucene/queries/function/FunctionMatchQuery.java
@@ -44,17 +44,32 @@ import org.apache.lucene.search.Weight;
  */
 public final class FunctionMatchQuery extends Query {
 
+  static final float DEFAULT_MATCH_COST = 100;
+
   private final DoubleValuesSource source;
   private final DoublePredicate filter;
+  private final float matchCost; // not used in equals/hashCode
 
   /**
-   * Create a FunctionMatchQuery
+   * Create a FunctionMatchQuery with default TwoPhaseIterator matchCost -
+   * {@link #DEFAULT_MATCH_COST} = {@value #DEFAULT_MATCH_COST}
    * @param source  a {@link DoubleValuesSource} to use for values
    * @param filter  the predicate to match against
    */
   public FunctionMatchQuery(DoubleValuesSource source, DoublePredicate filter) {
+    this(source, filter, DEFAULT_MATCH_COST);
+  }
+
+  /**
+   * Create a FunctionMatchQuery
+   * @param source     a {@link DoubleValuesSource} to use for values
+   * @param filter     the predicate to match against
+   * @param matchCost  to be returned by {@link TwoPhaseIterator#matchCost()}
+   */
+  public FunctionMatchQuery(DoubleValuesSource source, DoublePredicate filter, float matchCost) {
     this.source = source;
     this.filter = filter;
+    this.matchCost = matchCost;
   }
 
   @Override
@@ -83,7 +98,7 @@ public final class FunctionMatchQuery extends Query {
 
           @Override
           public float matchCost() {
-            return 100; // TODO maybe DoubleValuesSource should have a matchCost?
+            return matchCost; // TODO maybe DoubleValuesSource should have a matchCost?
           }
         };
         return new ConstantScoreScorer(this, score(), scoreMode, twoPhase);
diff --git a/lucene/queries/src/test/org/apache/lucene/queries/function/TestFunctionMatchQuery.java b/lucene/queries/src/test/org/apache/lucene/queries/function/TestFunctionMatchQuery.java
index 38d8d8a..95bdada 100644
--- a/lucene/queries/src/test/org/apache/lucene/queries/function/TestFunctionMatchQuery.java
+++ b/lucene/queries/src/test/org/apache/lucene/queries/function/TestFunctionMatchQuery.java
@@ -18,20 +18,26 @@
 package org.apache.lucene.queries.function;
 
 import java.io.IOException;
+import java.util.function.DoublePredicate;
 
 import org.apache.lucene.index.DirectoryReader;
 import org.apache.lucene.index.IndexReader;
+import org.apache.lucene.index.LeafReaderContext;
 import org.apache.lucene.search.DoubleValuesSource;
 import org.apache.lucene.search.IndexSearcher;
 import org.apache.lucene.search.QueryUtils;
+import org.apache.lucene.search.ScoreMode;
 import org.apache.lucene.search.TopDocs;
 import org.junit.AfterClass;
 import org.junit.BeforeClass;
 
+import static org.apache.lucene.queries.function.FunctionMatchQuery.DEFAULT_MATCH_COST;
+
 public class TestFunctionMatchQuery extends FunctionTestSetup {
 
   static IndexReader reader;
   static IndexSearcher searcher;
+  private static final DoubleValuesSource in = DoubleValuesSource.fromFloatField(FLOAT_FIELD);
 
   @BeforeClass
   public static void beforeClass() throws Exception {
@@ -46,7 +52,6 @@ public class TestFunctionMatchQuery extends FunctionTestSetup {
   }
 
   public void testRangeMatching() throws IOException {
-    DoubleValuesSource in = DoubleValuesSource.fromFloatField(FLOAT_FIELD);
     FunctionMatchQuery fmq = new FunctionMatchQuery(in, d -> d >= 2 && d < 4);
     TopDocs docs = searcher.search(fmq, 10);
 
@@ -58,4 +63,23 @@ public class TestFunctionMatchQuery extends FunctionTestSetup {
 
   }
 
+  public void testTwoPhaseIteratorMatchCost() throws IOException {
+    DoublePredicate predicate = d -> true;
+
+    // should use default match cost
+    FunctionMatchQuery fmq = new FunctionMatchQuery(in, predicate);
+    assertEquals(DEFAULT_MATCH_COST, getMatchCost(fmq), 0.1);
+
+    // should use client defined match cost
+    fmq = new FunctionMatchQuery(in, predicate, 200);
+    assertEquals(200, getMatchCost(fmq), 0.1);
+  }
+
+  private static float getMatchCost(FunctionMatchQuery fmq) throws IOException {
+    LeafReaderContext ctx = reader.leaves().get(0);
+    return fmq.createWeight(searcher, ScoreMode.TOP_DOCS, 1)
+      .scorer(ctx)
+      .twoPhaseIterator()
+      .matchCost();
+  }
 }