| diff --git a/lucene/core/src/java/org/apache/lucene/search/DoubleValuesSource.java b/lucene/core/src/java/org/apache/lucene/search/DoubleValuesSource.java |
| index 929441d..342c08b 100644 |
| --- a/lucene/core/src/java/org/apache/lucene/search/DoubleValuesSource.java |
| +++ b/lucene/core/src/java/org/apache/lucene/search/DoubleValuesSource.java |
| @@ -20,9 +20,7 @@ package org.apache.lucene.search; |
| import java.io.IOException; |
| import java.util.Objects; |
| import java.util.function.DoubleToLongFunction; |
| -import java.util.function.DoubleUnaryOperator; |
| import java.util.function.LongToDoubleFunction; |
| -import java.util.function.ToDoubleBiFunction; |
| |
| import org.apache.lucene.index.DocValues; |
| import org.apache.lucene.index.LeafReaderContext; |
| @@ -76,14 +74,33 @@ public abstract class DoubleValuesSource { |
| return new DoubleValuesSortField(this, reverse); |
| } |
| |
| + @Override |
| + public abstract int hashCode(); |
| + |
| + @Override |
| + public abstract boolean equals(Object obj); |
| + |
| + @Override |
| + public abstract String toString(); |
| + |
| /** |
| * Convert to a LongValuesSource by casting the double values to longs |
| */ |
| public final LongValuesSource toLongValuesSource() { |
| - return new LongValuesSource() { |
| - @Override |
| + return new LongDoubleValuesSource(this); |
| + } |
| + |
| + private static class LongDoubleValuesSource extends LongValuesSource { |
| + |
| + private final DoubleValuesSource inner; |
| + |
| + private LongDoubleValuesSource(DoubleValuesSource inner) { |
| + this.inner = inner; |
| + } |
| + |
| + @Override |
| public LongValues getValues(LeafReaderContext ctx, DoubleValues scores) throws IOException { |
| - DoubleValues in = DoubleValuesSource.this.getValues(ctx, scores); |
| + DoubleValues in = inner.getValues(ctx, scores); |
| return new LongValues() { |
| @Override |
| public long longValue() throws IOException { |
| @@ -99,9 +116,27 @@ public abstract class DoubleValuesSource { |
| |
| @Override |
| public boolean needsScores() { |
| - return DoubleValuesSource.this.needsScores(); |
| + return inner.needsScores(); |
| } |
| - }; |
| + |
| + @Override |
| + public boolean equals(Object o) { |
| + if (this == o) return true; |
| + if (o == null || getClass() != o.getClass()) return false; |
| + LongDoubleValuesSource that = (LongDoubleValuesSource) o; |
| + return Objects.equals(inner, that.inner); |
| + } |
| + |
| + @Override |
| + public int hashCode() { |
| + return Objects.hash(inner); |
| + } |
| + |
| + @Override |
| + public String toString() { |
| + return "long(" + inner.toString() + ")"; |
| + } |
| + |
| } |
| |
| /** |
| @@ -164,115 +199,80 @@ public abstract class DoubleValuesSource { |
| public Explanation explain(LeafReaderContext ctx, int docId, Explanation scoreExplanation) { |
| return scoreExplanation; |
| } |
| + |
| + @Override |
| + public int hashCode() { |
| + return 0; |
| + } |
| + |
| + @Override |
| + public boolean equals(Object obj) { |
| + return obj == this; |
| + } |
| + |
| + @Override |
| + public String toString() { |
| + return "scores"; |
| + } |
| }; |
| |
| /** |
| * Creates a DoubleValuesSource that always returns a constant value |
| */ |
| public static DoubleValuesSource constant(double value) { |
| - return new DoubleValuesSource() { |
| - @Override |
| - public DoubleValues getValues(LeafReaderContext ctx, DoubleValues scores) throws IOException { |
| - return new DoubleValues() { |
| - @Override |
| - public double doubleValue() throws IOException { |
| - return value; |
| - } |
| - |
| - @Override |
| - public boolean advanceExact(int doc) throws IOException { |
| - return true; |
| - } |
| - }; |
| - } |
| - |
| - @Override |
| - public boolean needsScores() { |
| - return false; |
| - } |
| + return new ConstantValuesSource(value); |
| + } |
| |
| - @Override |
| - public Explanation explain(LeafReaderContext ctx, int docId, Explanation scoreExplanation) { |
| - return Explanation.match((float) value, "constant(" + value + ")"); |
| - } |
| + private static class ConstantValuesSource extends DoubleValuesSource { |
| |
| - @Override |
| - public String toString() { |
| - return "constant(" + value + ")"; |
| - } |
| - }; |
| - } |
| + private final double value; |
| |
| - /** |
| - * Creates a DoubleValuesSource that is a function of another DoubleValuesSource |
| - */ |
| - public static DoubleValuesSource function(DoubleValuesSource in, String description, DoubleUnaryOperator function) { |
| - return new DoubleValuesSource() { |
| - @Override |
| - public DoubleValues getValues(LeafReaderContext ctx, DoubleValues scores) throws IOException { |
| - DoubleValues inputs = in.getValues(ctx, scores); |
| - return new DoubleValues() { |
| - @Override |
| - public double doubleValue() throws IOException { |
| - return function.applyAsDouble(inputs.doubleValue()); |
| - } |
| + private ConstantValuesSource(double value) { |
| + this.value = value; |
| + } |
| |
| - @Override |
| - public boolean advanceExact(int doc) throws IOException { |
| - return inputs.advanceExact(doc); |
| - } |
| - }; |
| - } |
| + @Override |
| + public DoubleValues getValues(LeafReaderContext ctx, DoubleValues scores) throws IOException { |
| + return new DoubleValues() { |
| + @Override |
| + public double doubleValue() throws IOException { |
| + return value; |
| + } |
| |
| - @Override |
| - public boolean needsScores() { |
| - return in.needsScores(); |
| - } |
| + @Override |
| + public boolean advanceExact(int doc) throws IOException { |
| + return true; |
| + } |
| + }; |
| + } |
| |
| - @Override |
| - public Explanation explain(LeafReaderContext ctx, int docId, Explanation scoreExplanation) throws IOException { |
| - Explanation inner = in.explain(ctx, docId, scoreExplanation); |
| - return Explanation.match((float) function.applyAsDouble(inner.getValue()), description + ", computed from:", inner, scoreExplanation); |
| - } |
| - }; |
| - } |
| + @Override |
| + public boolean needsScores() { |
| + return false; |
| + } |
| |
| - /** |
| - * Creates a DoubleValuesSource that is a function of another DoubleValuesSource and a score |
| - * @param in the DoubleValuesSource to use as an input |
| - * @param description a description of the function |
| - * @param function a function of the form (source, score) == result |
| - */ |
| - public static DoubleValuesSource scoringFunction(DoubleValuesSource in, String description, ToDoubleBiFunction<Double, Double> function) { |
| - return new DoubleValuesSource() { |
| - @Override |
| - public DoubleValues getValues(LeafReaderContext ctx, DoubleValues scores) throws IOException { |
| - DoubleValues inputs = in.getValues(ctx, scores); |
| - return new DoubleValues() { |
| - @Override |
| - public double doubleValue() throws IOException { |
| - return function.applyAsDouble(inputs.doubleValue(), scores.doubleValue()); |
| - } |
| + @Override |
| + public Explanation explain(LeafReaderContext ctx, int docId, Explanation scoreExplanation) { |
| + return Explanation.match((float) value, "constant(" + value + ")"); |
| + } |
| |
| - @Override |
| - public boolean advanceExact(int doc) throws IOException { |
| - return inputs.advanceExact(doc); |
| - } |
| - }; |
| - } |
| + @Override |
| + public int hashCode() { |
| + return Objects.hash(value); |
| + } |
| |
| - @Override |
| - public boolean needsScores() { |
| - return true; |
| - } |
| + @Override |
| + public boolean equals(Object o) { |
| + if (this == o) return true; |
| + if (o == null || getClass() != o.getClass()) return false; |
| + ConstantValuesSource that = (ConstantValuesSource) o; |
| + return Double.compare(that.value, value) == 0; |
| + } |
| |
| - @Override |
| - public Explanation explain(LeafReaderContext ctx, int docId, Explanation scoreExplanation) throws IOException { |
| - Explanation inner = in.explain(ctx, docId, scoreExplanation); |
| - return Explanation.match((float) function.applyAsDouble((double)inner.getValue(), (double)scoreExplanation.getValue()), |
| - description + ", computed from:", inner, scoreExplanation); |
| - } |
| - }; |
| + @Override |
| + public String toString() { |
| + return "constant(" + value + ")"; |
| + } |
| } |
| |
| /** |
| @@ -313,6 +313,11 @@ public abstract class DoubleValuesSource { |
| } |
| |
| @Override |
| + public String toString() { |
| + return "double(" + field + ")"; |
| + } |
| + |
| + @Override |
| public int hashCode() { |
| return Objects.hash(field, decoder); |
| } |
| @@ -342,9 +347,9 @@ public abstract class DoubleValuesSource { |
| public Explanation explain(LeafReaderContext ctx, int docId, Explanation scoreExplanation) throws IOException { |
| DoubleValues values = getValues(ctx, null); |
| if (values.advanceExact(docId)) |
| - return Explanation.match((float)values.doubleValue(), "double(" + field + ")"); |
| + return Explanation.match((float)values.doubleValue(), this.toString()); |
| else |
| - return Explanation.noMatch("double(" + field + ")"); |
| + return Explanation.noMatch(this.toString()); |
| } |
| } |
| |
| diff --git a/lucene/core/src/java/org/apache/lucene/search/LongValuesSource.java b/lucene/core/src/java/org/apache/lucene/search/LongValuesSource.java |
| index 9a23cab..975a905 100644 |
| --- a/lucene/core/src/java/org/apache/lucene/search/LongValuesSource.java |
| +++ b/lucene/core/src/java/org/apache/lucene/search/LongValuesSource.java |
| @@ -52,6 +52,15 @@ public abstract class LongValuesSource { |
| */ |
| public abstract boolean needsScores(); |
| |
| + @Override |
| + public abstract int hashCode(); |
| + |
| + @Override |
| + public abstract boolean equals(Object obj); |
| + |
| + @Override |
| + public abstract String toString(); |
| + |
| /** |
| * Create a sort field based on the value of this producer |
| * @param reverse true if the sort should be decreasing |
| @@ -78,27 +87,55 @@ public abstract class LongValuesSource { |
| * Creates a LongValuesSource that always returns a constant value |
| */ |
| public static LongValuesSource constant(long value) { |
| - return new LongValuesSource() { |
| - @Override |
| - public LongValues getValues(LeafReaderContext ctx, DoubleValues scores) throws IOException { |
| - return new LongValues() { |
| - @Override |
| - public long longValue() throws IOException { |
| - return value; |
| - } |
| - |
| - @Override |
| - public boolean advanceExact(int doc) throws IOException { |
| - return true; |
| - } |
| - }; |
| - } |
| + return new ConstantLongValuesSource(value); |
| + } |
| + |
| + private static class ConstantLongValuesSource extends LongValuesSource { |
| + |
| + private final long value; |
| + |
| + private ConstantLongValuesSource(long value) { |
| + this.value = value; |
| + } |
| + |
| + @Override |
| + public LongValues getValues(LeafReaderContext ctx, DoubleValues scores) throws IOException { |
| + return new LongValues() { |
| + @Override |
| + public long longValue() throws IOException { |
| + return value; |
| + } |
| + |
| + @Override |
| + public boolean advanceExact(int doc) throws IOException { |
| + return true; |
| + } |
| + }; |
| + } |
| + |
| + @Override |
| + public boolean needsScores() { |
| + return false; |
| + } |
| + |
| + @Override |
| + public int hashCode() { |
| + return Objects.hash(value); |
| + } |
| + |
| + @Override |
| + public boolean equals(Object o) { |
| + if (this == o) return true; |
| + if (o == null || getClass() != o.getClass()) return false; |
| + ConstantLongValuesSource that = (ConstantLongValuesSource) o; |
| + return value == that.value; |
| + } |
| + |
| + @Override |
| + public String toString() { |
| + return "constant(" + value + ")"; |
| + } |
| |
| - @Override |
| - public boolean needsScores() { |
| - return false; |
| - } |
| - }; |
| } |
| |
| private static class FieldValuesSource extends LongValuesSource { |
| @@ -118,6 +155,11 @@ public abstract class LongValuesSource { |
| } |
| |
| @Override |
| + public String toString() { |
| + return "long(" + field + ")"; |
| + } |
| + |
| + @Override |
| public int hashCode() { |
| return Objects.hash(field); |
| } |
| diff --git a/lucene/core/src/test/org/apache/lucene/search/TestDoubleValuesSource.java b/lucene/core/src/test/org/apache/lucene/search/TestDoubleValuesSource.java |
| index 54501e6..de2479c 100644 |
| --- a/lucene/core/src/test/org/apache/lucene/search/TestDoubleValuesSource.java |
| +++ b/lucene/core/src/test/org/apache/lucene/search/TestDoubleValuesSource.java |
| @@ -92,6 +92,14 @@ public class TestDoubleValuesSource extends LuceneTestCase { |
| assertEquals(vs1.hashCode(), vs2.hashCode()); |
| DoubleValuesSource v3 = DoubleValuesSource.fromLongField("long"); |
| assertFalse(vs1.equals(v3)); |
| + |
| + assertEquals(DoubleValuesSource.constant(5), DoubleValuesSource.constant(5)); |
| + assertEquals(DoubleValuesSource.constant(5).hashCode(), DoubleValuesSource.constant(5).hashCode()); |
| + assertFalse((DoubleValuesSource.constant(5).equals(DoubleValuesSource.constant(6)))); |
| + |
| + assertEquals(DoubleValuesSource.SCORES, DoubleValuesSource.SCORES); |
| + assertFalse(DoubleValuesSource.constant(5).equals(DoubleValuesSource.SCORES)); |
| + |
| } |
| |
| public void testSimpleFieldSortables() throws Exception { |
| @@ -184,13 +192,6 @@ public class TestDoubleValuesSource extends LuceneTestCase { |
| testExplanations(q, DoubleValuesSource.fromDoubleField("double")); |
| testExplanations(q, DoubleValuesSource.fromDoubleField("onefield")); |
| testExplanations(q, DoubleValuesSource.constant(5.45)); |
| - testExplanations(q, DoubleValuesSource.function( |
| - DoubleValuesSource.fromDoubleField("double"), "v * 4 + 73", |
| - v -> v * 4 + 73 |
| - )); |
| - testExplanations(q, DoubleValuesSource.scoringFunction( |
| - DoubleValuesSource.fromDoubleField("double"), "v * score", (v, s) -> v * s |
| - )); |
| } |
| } |
| |
| @@ -227,4 +228,5 @@ public class TestDoubleValuesSource extends LuceneTestCase { |
| } |
| }); |
| } |
| + |
| } |
| diff --git a/lucene/facet/src/test/org/apache/lucene/facet/range/TestRangeFacetCounts.java b/lucene/facet/src/test/org/apache/lucene/facet/range/TestRangeFacetCounts.java |
| index 06bd2e5..5a80c3b 100644 |
| --- a/lucene/facet/src/test/org/apache/lucene/facet/range/TestRangeFacetCounts.java |
| +++ b/lucene/facet/src/test/org/apache/lucene/facet/range/TestRangeFacetCounts.java |
| @@ -706,6 +706,51 @@ public class TestRangeFacetCounts extends FacetTestCase { |
| |
| } |
| |
| + private static class PlusOneValuesSource extends DoubleValuesSource { |
| + |
| + @Override |
| + public DoubleValues getValues(LeafReaderContext ctx, DoubleValues scores) throws IOException { |
| + return new DoubleValues() { |
| + int doc = -1; |
| + @Override |
| + public double doubleValue() throws IOException { |
| + return doc + 1; |
| + } |
| + |
| + @Override |
| + public boolean advanceExact(int doc) throws IOException { |
| + this.doc = doc; |
| + return true; |
| + } |
| + }; |
| + } |
| + |
| + @Override |
| + public boolean needsScores() { |
| + return false; |
| + } |
| + |
| + @Override |
| + public Explanation explain(LeafReaderContext ctx, int docId, Explanation scoreExplanation) throws IOException { |
| + return Explanation.match(docId + 1, ""); |
| + } |
| + |
| + @Override |
| + public int hashCode() { |
| + return 0; |
| + } |
| + |
| + @Override |
| + public boolean equals(Object obj) { |
| + return obj.getClass() == PlusOneValuesSource.class; |
| + } |
| + |
| + @Override |
| + public String toString() { |
| + return null; |
| + } |
| + } |
| + |
| public void testCustomDoubleValuesSource() throws Exception { |
| Directory dir = newDirectory(); |
| RandomIndexWriter writer = new RandomIndexWriter(random(), dir); |
| @@ -718,35 +763,7 @@ public class TestRangeFacetCounts extends FacetTestCase { |
| // Test wants 3 docs in one segment: |
| writer.forceMerge(1); |
| |
| - final DoubleValuesSource vs = new DoubleValuesSource() { |
| - |
| - @Override |
| - public DoubleValues getValues(LeafReaderContext ctx, DoubleValues scores) throws IOException { |
| - return new DoubleValues() { |
| - int doc = -1; |
| - @Override |
| - public double doubleValue() throws IOException { |
| - return doc + 1; |
| - } |
| - |
| - @Override |
| - public boolean advanceExact(int doc) throws IOException { |
| - this.doc = doc; |
| - return true; |
| - } |
| - }; |
| - } |
| - |
| - @Override |
| - public boolean needsScores() { |
| - return false; |
| - } |
| - |
| - @Override |
| - public Explanation explain(LeafReaderContext ctx, int docId, Explanation scoreExplanation) throws IOException { |
| - return Explanation.match(docId + 1, ""); |
| - } |
| - }; |
| + final DoubleValuesSource vs = new PlusOneValuesSource(); |
| |
| FacetsConfig config = new FacetsConfig(); |
| |
| diff --git a/lucene/queries/src/java/org/apache/lucene/queries/function/ValueSource.java b/lucene/queries/src/java/org/apache/lucene/queries/function/ValueSource.java |
| index e49c823..cb3faa3 100644 |
| --- a/lucene/queries/src/java/org/apache/lucene/queries/function/ValueSource.java |
| +++ b/lucene/queries/src/java/org/apache/lucene/queries/function/ValueSource.java |
| @@ -20,6 +20,7 @@ import java.io.IOException; |
| import java.util.HashMap; |
| import java.util.IdentityHashMap; |
| import java.util.Map; |
| +import java.util.Objects; |
| |
| import org.apache.lucene.index.LeafReaderContext; |
| import org.apache.lucene.search.DocIdSetIterator; |
| @@ -120,85 +121,141 @@ public abstract class ValueSource { |
| * Expose this ValueSource as a LongValuesSource |
| */ |
| public LongValuesSource asLongValuesSource() { |
| - return new LongValuesSource() { |
| - @Override |
| - public LongValues getValues(LeafReaderContext ctx, DoubleValues scores) throws IOException { |
| - Map context = new IdentityHashMap<>(); |
| - FakeScorer scorer = new FakeScorer(); |
| - context.put("scorer", scorer); |
| - final FunctionValues fv = ValueSource.this.getValues(context, ctx); |
| - return new LongValues() { |
| - |
| - @Override |
| - public long longValue() throws IOException { |
| - return fv.longVal(scorer.current); |
| - } |
| + return new WrappedLongValuesSource(this); |
| + } |
| + |
| + private static class WrappedLongValuesSource extends LongValuesSource { |
| + |
| + private final ValueSource in; |
| + |
| + private WrappedLongValuesSource(ValueSource in) { |
| + this.in = in; |
| + } |
| + |
| + @Override |
| + public LongValues getValues(LeafReaderContext ctx, DoubleValues scores) throws IOException { |
| + Map context = new IdentityHashMap<>(); |
| + FakeScorer scorer = new FakeScorer(); |
| + context.put("scorer", scorer); |
| + final FunctionValues fv = in.getValues(context, ctx); |
| + return new LongValues() { |
| + |
| + @Override |
| + public long longValue() throws IOException { |
| + return fv.longVal(scorer.current); |
| + } |
| + |
| + @Override |
| + public boolean advanceExact(int doc) throws IOException { |
| + scorer.current = doc; |
| + if (scores != null && scores.advanceExact(doc)) |
| + scorer.score = (float) scores.doubleValue(); |
| + else |
| + scorer.score = 0; |
| + return fv.exists(doc); |
| + } |
| + }; |
| + } |
| + |
| + @Override |
| + public boolean needsScores() { |
| + return false; |
| + } |
| + |
| + @Override |
| + public boolean equals(Object o) { |
| + if (this == o) return true; |
| + if (o == null || getClass() != o.getClass()) return false; |
| + WrappedLongValuesSource that = (WrappedLongValuesSource) o; |
| + return Objects.equals(in, that.in); |
| + } |
| + |
| + @Override |
| + public int hashCode() { |
| + return Objects.hash(in); |
| + } |
| + |
| + @Override |
| + public String toString() { |
| + return in.toString(); |
| + } |
| |
| - @Override |
| - public boolean advanceExact(int doc) throws IOException { |
| - scorer.current = doc; |
| - if (scores != null && scores.advanceExact(doc)) |
| - scorer.score = (float) scores.doubleValue(); |
| - else |
| - scorer.score = 0; |
| - return fv.exists(doc); |
| - } |
| - }; |
| - } |
| - |
| - @Override |
| - public boolean needsScores() { |
| - return false; |
| - } |
| - }; |
| } |
| |
| /** |
| * Expose this ValueSource as a DoubleValuesSource |
| */ |
| public DoubleValuesSource asDoubleValuesSource() { |
| - return new DoubleValuesSource() { |
| - @Override |
| - public DoubleValues getValues(LeafReaderContext ctx, DoubleValues scores) throws IOException { |
| - Map context = new HashMap<>(); |
| - FakeScorer scorer = new FakeScorer(); |
| - context.put("scorer", scorer); |
| - FunctionValues fv = ValueSource.this.getValues(context, ctx); |
| - return new DoubleValues() { |
| - |
| - @Override |
| - public double doubleValue() throws IOException { |
| - return fv.doubleVal(scorer.current); |
| - } |
| + return new WrappedDoubleValuesSource(this); |
| + } |
| + |
| + private static class WrappedDoubleValuesSource extends DoubleValuesSource { |
| + |
| + private final ValueSource in; |
| |
| - @Override |
| - public boolean advanceExact(int doc) throws IOException { |
| - scorer.current = doc; |
| - if (scores != null && scores.advanceExact(doc)) { |
| - scorer.score = (float) scores.doubleValue(); |
| - } |
| - else |
| - scorer.score = 0; |
| - return fv.exists(doc); |
| + private WrappedDoubleValuesSource(ValueSource in) { |
| + this.in = in; |
| + } |
| + |
| + @Override |
| + public DoubleValues getValues(LeafReaderContext ctx, DoubleValues scores) throws IOException { |
| + Map context = new HashMap<>(); |
| + FakeScorer scorer = new FakeScorer(); |
| + context.put("scorer", scorer); |
| + FunctionValues fv = in.getValues(context, ctx); |
| + return new DoubleValues() { |
| + |
| + @Override |
| + public double doubleValue() throws IOException { |
| + return fv.doubleVal(scorer.current); |
| + } |
| + |
| + @Override |
| + public boolean advanceExact(int doc) throws IOException { |
| + scorer.current = doc; |
| + if (scores != null && scores.advanceExact(doc)) { |
| + scorer.score = (float) scores.doubleValue(); |
| } |
| - }; |
| - } |
| - |
| - @Override |
| - public boolean needsScores() { |
| - return true; // be on the safe side |
| - } |
| - |
| - @Override |
| - public Explanation explain(LeafReaderContext ctx, int docId, Explanation scoreExplanation) throws IOException { |
| - Map context = new HashMap<>(); |
| - FakeScorer scorer = new FakeScorer(); |
| - scorer.score = scoreExplanation.getValue(); |
| - context.put("scorer", scorer); |
| - FunctionValues fv = ValueSource.this.getValues(context, ctx); |
| - return fv.explain(docId); |
| - } |
| - }; |
| + else |
| + scorer.score = 0; |
| + return fv.exists(doc); |
| + } |
| + }; |
| + } |
| + |
| + @Override |
| + public boolean needsScores() { |
| + return true; // be on the safe side |
| + } |
| + |
| + @Override |
| + public Explanation explain(LeafReaderContext ctx, int docId, Explanation scoreExplanation) throws IOException { |
| + Map context = new HashMap<>(); |
| + FakeScorer scorer = new FakeScorer(); |
| + scorer.score = scoreExplanation.getValue(); |
| + context.put("scorer", scorer); |
| + FunctionValues fv = in.getValues(context, ctx); |
| + return fv.explain(docId); |
| + } |
| + |
| + @Override |
| + public boolean equals(Object o) { |
| + if (this == o) return true; |
| + if (o == null || getClass() != o.getClass()) return false; |
| + WrappedDoubleValuesSource that = (WrappedDoubleValuesSource) o; |
| + return Objects.equals(in, that.in); |
| + } |
| + |
| + @Override |
| + public int hashCode() { |
| + return Objects.hash(in); |
| + } |
| + |
| + @Override |
| + public String toString() { |
| + return in.toString(); |
| + } |
| + |
| } |
| |
| // |
| diff --git a/lucene/queries/src/test/org/apache/lucene/queries/function/TestFunctionScoreExplanations.java b/lucene/queries/src/test/org/apache/lucene/queries/function/TestFunctionScoreExplanations.java |
| index bc8dbc1..2ed9d72 100644 |
| --- a/lucene/queries/src/test/org/apache/lucene/queries/function/TestFunctionScoreExplanations.java |
| +++ b/lucene/queries/src/test/org/apache/lucene/queries/function/TestFunctionScoreExplanations.java |
| @@ -59,19 +59,15 @@ public class TestFunctionScoreExplanations extends BaseExplanationTestCase { |
| |
| public void testExplanationsIncludingScore() throws Exception { |
| |
| - DoubleValuesSource scores = DoubleValuesSource.function(DoubleValuesSource.SCORES, "v * 2", v -> v * 2); |
| - |
| Query q = new TermQuery(new Term(FIELD, "w1")); |
| - FunctionScoreQuery csq = new FunctionScoreQuery(q, scores); |
| + FunctionScoreQuery csq = new FunctionScoreQuery(q, DoubleValuesSource.SCORES); |
| |
| qtest(csq, new int[] { 0, 1, 2, 3 }); |
| |
| Explanation e1 = searcher.explain(q, 0); |
| Explanation e = searcher.explain(csq, 0); |
| |
| - assertEquals(e.getDetails().length, 2); |
| - |
| - assertEquals(e1.getValue() * 2, e.getValue(), 0.00001); |
| + assertEquals(e, e1); |
| } |
| |
| public void testSubExplanations() throws IOException { |
| diff --git a/lucene/queries/src/test/org/apache/lucene/queries/function/TestFunctionScoreQuery.java b/lucene/queries/src/test/org/apache/lucene/queries/function/TestFunctionScoreQuery.java |
| index de5ad88..139e961 100644 |
| --- a/lucene/queries/src/test/org/apache/lucene/queries/function/TestFunctionScoreQuery.java |
| +++ b/lucene/queries/src/test/org/apache/lucene/queries/function/TestFunctionScoreQuery.java |
| @@ -17,13 +17,20 @@ |
| |
| package org.apache.lucene.queries.function; |
| |
| +import java.io.IOException; |
| +import java.util.function.DoubleUnaryOperator; |
| +import java.util.function.ToDoubleBiFunction; |
| + |
| import org.apache.lucene.index.DirectoryReader; |
| import org.apache.lucene.index.IndexReader; |
| +import org.apache.lucene.index.LeafReaderContext; |
| import org.apache.lucene.index.Term; |
| import org.apache.lucene.search.BooleanClause; |
| import org.apache.lucene.search.BooleanQuery; |
| import org.apache.lucene.search.BoostQuery; |
| +import org.apache.lucene.search.DoubleValues; |
| import org.apache.lucene.search.DoubleValuesSource; |
| +import org.apache.lucene.search.Explanation; |
| import org.apache.lucene.search.IndexSearcher; |
| import org.apache.lucene.search.Query; |
| import org.apache.lucene.search.QueryUtils; |
| @@ -70,7 +77,7 @@ public class TestFunctionScoreQuery extends FunctionTestSetup { |
| public void testScoreModifyingSource() throws Exception { |
| |
| DoubleValuesSource iii = DoubleValuesSource.fromIntField("iii"); |
| - DoubleValuesSource score = DoubleValuesSource.scoringFunction(iii, "v * s", (v, s) -> v * s); |
| + DoubleValuesSource score = scoringFunction(iii, (v, s) -> v * s); |
| |
| BooleanQuery bq = new BooleanQuery.Builder() |
| .add(new TermQuery(new Term(TEXT_FIELD, "first")), BooleanClause.Occur.SHOULD) |
| @@ -95,8 +102,7 @@ public class TestFunctionScoreQuery extends FunctionTestSetup { |
| // check boosts with non-distributive score source |
| public void testBoostsAreAppliedLast() throws Exception { |
| |
| - DoubleValuesSource scores |
| - = DoubleValuesSource.function(DoubleValuesSource.SCORES, "ln(v + 4)", v -> Math.log(v + 4)); |
| + DoubleValuesSource scores = function(DoubleValuesSource.SCORES, v -> Math.log(v + 4)); |
| |
| Query q1 = new FunctionScoreQuery(new TermQuery(new Term(TEXT_FIELD, "text")), scores); |
| TopDocs plain = searcher.search(q1, 5); |
| @@ -111,4 +117,94 @@ public class TestFunctionScoreQuery extends FunctionTestSetup { |
| |
| } |
| |
| + public static DoubleValuesSource function(DoubleValuesSource in, DoubleUnaryOperator function) { |
| + return new DoubleValuesSource() { |
| + @Override |
| + public DoubleValues getValues(LeafReaderContext ctx, DoubleValues scores) throws IOException { |
| + DoubleValues v = in.getValues(ctx, scores); |
| + return new DoubleValues() { |
| + @Override |
| + public double doubleValue() throws IOException { |
| + return function.applyAsDouble(v.doubleValue()); |
| + } |
| + |
| + @Override |
| + public boolean advanceExact(int doc) throws IOException { |
| + return v.advanceExact(doc); |
| + } |
| + }; |
| + } |
| + |
| + @Override |
| + public boolean needsScores() { |
| + return in.needsScores(); |
| + } |
| + |
| + @Override |
| + public Explanation explain(LeafReaderContext ctx, int docId, Explanation scoreExplanation) throws IOException { |
| + return null; |
| + } |
| + |
| + @Override |
| + public int hashCode() { |
| + return 0; |
| + } |
| + |
| + @Override |
| + public boolean equals(Object obj) { |
| + return false; |
| + } |
| + |
| + @Override |
| + public String toString() { |
| + return null; |
| + } |
| + }; |
| + } |
| + |
| + private static DoubleValuesSource scoringFunction(DoubleValuesSource in, ToDoubleBiFunction<Double, Double> function) { |
| + return new DoubleValuesSource() { |
| + @Override |
| + public DoubleValues getValues(LeafReaderContext ctx, DoubleValues scores) throws IOException { |
| + DoubleValues v = in.getValues(ctx, scores); |
| + return new DoubleValues() { |
| + @Override |
| + public double doubleValue() throws IOException { |
| + return function.applyAsDouble(v.doubleValue(), scores.doubleValue()); |
| + } |
| + |
| + @Override |
| + public boolean advanceExact(int doc) throws IOException { |
| + return v.advanceExact(doc); |
| + } |
| + }; |
| + } |
| + |
| + @Override |
| + public boolean needsScores() { |
| + return true; |
| + } |
| + |
| + @Override |
| + public Explanation explain(LeafReaderContext ctx, int docId, Explanation scoreExplanation) throws IOException { |
| + return null; |
| + } |
| + |
| + @Override |
| + public int hashCode() { |
| + return 0; |
| + } |
| + |
| + @Override |
| + public boolean equals(Object obj) { |
| + return false; |
| + } |
| + |
| + @Override |
| + public String toString() { |
| + return null; |
| + } |
| + }; |
| + } |
| + |
| } |
| diff --git a/lucene/suggest/src/test/org/apache/lucene/search/suggest/DocumentValueSourceDictionaryTest.java b/lucene/suggest/src/test/org/apache/lucene/search/suggest/DocumentValueSourceDictionaryTest.java |
| index 55970e4..fb91e20 100644 |
| --- a/lucene/suggest/src/test/org/apache/lucene/search/suggest/DocumentValueSourceDictionaryTest.java |
| +++ b/lucene/suggest/src/test/org/apache/lucene/search/suggest/DocumentValueSourceDictionaryTest.java |
| @@ -171,6 +171,21 @@ public class DocumentValueSourceDictionaryTest extends LuceneTestCase { |
| public boolean needsScores() { |
| return false; |
| } |
| + |
| + @Override |
| + public int hashCode() { |
| + return 0; |
| + } |
| + |
| + @Override |
| + public boolean equals(Object obj) { |
| + return false; |
| + } |
| + |
| + @Override |
| + public String toString() { |
| + return null; |
| + } |
| }; |
| } |
| |