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 2018/09/04 12:03:35 UTC
[1/2] lucene-solr:master: LUCENE-8475: Remove deprecated constants
from RamUsageEstimator.
Repository: lucene-solr
Updated Branches:
refs/heads/master 34a85014d -> 2da53c32c
LUCENE-8475: Remove deprecated constants from RamUsageEstimator.
Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/2da53c32
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/2da53c32
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/2da53c32
Branch: refs/heads/master
Commit: 2da53c32cbcf82139d1053b5f3709cf639ec7971
Parents: a9acdfd
Author: Adrien Grand <jp...@gmail.com>
Authored: Tue Sep 4 11:55:51 2018 +0200
Committer: Adrien Grand <jp...@gmail.com>
Committed: Tue Sep 4 14:03:24 2018 +0200
----------------------------------------------------------------------
lucene/CHANGES.txt | 3 ++
.../document/LatLonPointDistanceComparator.java | 3 +-
.../apache/lucene/util/RamUsageEstimator.java | 51 +-------------------
.../org/apache/lucene/util/packed/Direct16.java | 2 +-
.../org/apache/lucene/util/packed/Direct32.java | 2 +-
.../org/apache/lucene/util/packed/Direct64.java | 2 +-
.../org/apache/lucene/util/packed/Direct8.java | 2 +-
.../lucene/util/packed/Packed16ThreeBlocks.java | 2 +-
.../lucene/util/packed/Packed64SingleBlock.java | 2 +-
.../lucene/util/packed/Packed8ThreeBlocks.java | 2 +-
.../directory/DirectoryTaxonomyReader.java | 2 +-
.../taxonomy/directory/TaxonomyIndexArrays.java | 2 +-
12 files changed, 14 insertions(+), 61 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/2da53c32/lucene/CHANGES.txt
----------------------------------------------------------------------
diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt
index 1334294..c81ae61 100644
--- a/lucene/CHANGES.txt
+++ b/lucene/CHANGES.txt
@@ -73,6 +73,9 @@ API Changes
methods from Scorer that should be called from Collectors. LeafCollector.setScorer()
now takes a Scorable rather than a Scorer. (Alan Woodward, Adrien Grand)
+* LUCENE-8475: Deprecated constants have been removed from RamUsageEstimator.
+ (Dimitrios Athanasiou)
+
Changes in Runtime Behavior
* LUCENE-8333: Switch MoreLikeThis.setMaxDocFreqPct to use maxDoc instead of
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/2da53c32/lucene/core/src/java/org/apache/lucene/document/LatLonPointDistanceComparator.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/document/LatLonPointDistanceComparator.java b/lucene/core/src/java/org/apache/lucene/document/LatLonPointDistanceComparator.java
index 7a2c5b0..10566b6 100644
--- a/lucene/core/src/java/org/apache/lucene/document/LatLonPointDistanceComparator.java
+++ b/lucene/core/src/java/org/apache/lucene/document/LatLonPointDistanceComparator.java
@@ -28,7 +28,6 @@ import org.apache.lucene.search.FieldComparator;
import org.apache.lucene.search.LeafFieldComparator;
import org.apache.lucene.search.Scorable;
import org.apache.lucene.util.ArrayUtil;
-import org.apache.lucene.util.RamUsageEstimator;
import org.apache.lucene.util.SloppyMath;
import static org.apache.lucene.geo.GeoEncodingUtils.decodeLatitude;
@@ -124,7 +123,7 @@ class LatLonPointDistanceComparator extends FieldComparator<Double> implements L
valuesDocID = currentDocs.docID();
int count = currentDocs.docValueCount();
if (count > currentValues.length) {
- currentValues = new long[ArrayUtil.oversize(count, RamUsageEstimator.NUM_BYTES_LONG)];
+ currentValues = new long[ArrayUtil.oversize(count, Long.BYTES)];
}
for(int i=0;i<count;i++) {
currentValues[i] = currentDocs.nextValue();
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/2da53c32/lucene/core/src/java/org/apache/lucene/util/RamUsageEstimator.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/util/RamUsageEstimator.java b/lucene/core/src/java/org/apache/lucene/util/RamUsageEstimator.java
index 2765d7f..0d72e5e 100644
--- a/lucene/core/src/java/org/apache/lucene/util/RamUsageEstimator.java
+++ b/lucene/core/src/java/org/apache/lucene/util/RamUsageEstimator.java
@@ -55,56 +55,7 @@ public final class RamUsageEstimator {
/** No instantiation. */
private RamUsageEstimator() {}
- /**
- * Number of bytes used to represent a {@code boolean} in binary form
- * @deprecated use {@code 1} instead.
- */
- @Deprecated
- public final static int NUM_BYTES_BOOLEAN = 1;
- /**
- * Number of bytes used to represent a {@code byte} in binary form
- * @deprecated use {@code 1} instead.
- */
- @Deprecated
- public final static int NUM_BYTES_BYTE = 1;
- /**
- * Number of bytes used to represent a {@code char} in binary form
- * @deprecated use {@link Character#BYTES} instead.
- */
- @Deprecated
- public final static int NUM_BYTES_CHAR = Character.BYTES;
- /**
- * Number of bytes used to represent a {@code short} in binary form
- * @deprecated use {@link Short#BYTES} instead.
- */
- @Deprecated
- public final static int NUM_BYTES_SHORT = Short.BYTES;
- /**
- * Number of bytes used to represent an {@code int} in binary form
- * @deprecated use {@link Integer#BYTES} instead.
- */
- @Deprecated
- public final static int NUM_BYTES_INT = Integer.BYTES;
- /**
- * Number of bytes used to represent a {@code float} in binary form
- * @deprecated use {@link Float#BYTES} instead.
- */
- @Deprecated
- public final static int NUM_BYTES_FLOAT = Float.BYTES;
- /**
- * Number of bytes used to represent a {@code long} in binary form
- * @deprecated use {@link Long#BYTES} instead.
- */
- @Deprecated
- public final static int NUM_BYTES_LONG = Long.BYTES;
- /**
- * Number of bytes used to represent a {@code double} in binary form
- * @deprecated use {@link Double#BYTES} instead.
- */
- @Deprecated
- public final static int NUM_BYTES_DOUBLE = Double.BYTES;
-
- /**
+ /**
* True, iff compressed references (oops) are enabled by this JVM
*/
public final static boolean COMPRESSED_REFS_ENABLED;
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/2da53c32/lucene/core/src/java/org/apache/lucene/util/packed/Direct16.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/util/packed/Direct16.java b/lucene/core/src/java/org/apache/lucene/util/packed/Direct16.java
index 82281a9e..9c2b13d 100644
--- a/lucene/core/src/java/org/apache/lucene/util/packed/Direct16.java
+++ b/lucene/core/src/java/org/apache/lucene/util/packed/Direct16.java
@@ -62,7 +62,7 @@ final class Direct16 extends PackedInts.MutableImpl {
public long ramBytesUsed() {
return RamUsageEstimator.alignObjectSize(
RamUsageEstimator.NUM_BYTES_OBJECT_HEADER
- + 2 * RamUsageEstimator.NUM_BYTES_INT // valueCount,bitsPerValue
+ + 2 * Integer.BYTES // valueCount,bitsPerValue
+ RamUsageEstimator.NUM_BYTES_OBJECT_REF) // values ref
+ RamUsageEstimator.sizeOf(values);
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/2da53c32/lucene/core/src/java/org/apache/lucene/util/packed/Direct32.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/util/packed/Direct32.java b/lucene/core/src/java/org/apache/lucene/util/packed/Direct32.java
index 502aa3f..169e262 100644
--- a/lucene/core/src/java/org/apache/lucene/util/packed/Direct32.java
+++ b/lucene/core/src/java/org/apache/lucene/util/packed/Direct32.java
@@ -62,7 +62,7 @@ final class Direct32 extends PackedInts.MutableImpl {
public long ramBytesUsed() {
return RamUsageEstimator.alignObjectSize(
RamUsageEstimator.NUM_BYTES_OBJECT_HEADER
- + 2 * RamUsageEstimator.NUM_BYTES_INT // valueCount,bitsPerValue
+ + 2 * Integer.BYTES // valueCount,bitsPerValue
+ RamUsageEstimator.NUM_BYTES_OBJECT_REF) // values ref
+ RamUsageEstimator.sizeOf(values);
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/2da53c32/lucene/core/src/java/org/apache/lucene/util/packed/Direct64.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/util/packed/Direct64.java b/lucene/core/src/java/org/apache/lucene/util/packed/Direct64.java
index 106f641..7c6bada 100644
--- a/lucene/core/src/java/org/apache/lucene/util/packed/Direct64.java
+++ b/lucene/core/src/java/org/apache/lucene/util/packed/Direct64.java
@@ -57,7 +57,7 @@ final class Direct64 extends PackedInts.MutableImpl {
public long ramBytesUsed() {
return RamUsageEstimator.alignObjectSize(
RamUsageEstimator.NUM_BYTES_OBJECT_HEADER
- + 2 * RamUsageEstimator.NUM_BYTES_INT // valueCount,bitsPerValue
+ + 2 * Integer.BYTES // valueCount,bitsPerValue
+ RamUsageEstimator.NUM_BYTES_OBJECT_REF) // values ref
+ RamUsageEstimator.sizeOf(values);
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/2da53c32/lucene/core/src/java/org/apache/lucene/util/packed/Direct8.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/util/packed/Direct8.java b/lucene/core/src/java/org/apache/lucene/util/packed/Direct8.java
index 27986c0..fef26c3 100644
--- a/lucene/core/src/java/org/apache/lucene/util/packed/Direct8.java
+++ b/lucene/core/src/java/org/apache/lucene/util/packed/Direct8.java
@@ -60,7 +60,7 @@ final class Direct8 extends PackedInts.MutableImpl {
public long ramBytesUsed() {
return RamUsageEstimator.alignObjectSize(
RamUsageEstimator.NUM_BYTES_OBJECT_HEADER
- + 2 * RamUsageEstimator.NUM_BYTES_INT // valueCount,bitsPerValue
+ + 2 * Integer.BYTES // valueCount,bitsPerValue
+ RamUsageEstimator.NUM_BYTES_OBJECT_REF) // values ref
+ RamUsageEstimator.sizeOf(values);
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/2da53c32/lucene/core/src/java/org/apache/lucene/util/packed/Packed16ThreeBlocks.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/util/packed/Packed16ThreeBlocks.java b/lucene/core/src/java/org/apache/lucene/util/packed/Packed16ThreeBlocks.java
index 8e8e94d..fe425eb 100644
--- a/lucene/core/src/java/org/apache/lucene/util/packed/Packed16ThreeBlocks.java
+++ b/lucene/core/src/java/org/apache/lucene/util/packed/Packed16ThreeBlocks.java
@@ -112,7 +112,7 @@ final class Packed16ThreeBlocks extends PackedInts.MutableImpl {
public long ramBytesUsed() {
return RamUsageEstimator.alignObjectSize(
RamUsageEstimator.NUM_BYTES_OBJECT_HEADER
- + 2 * RamUsageEstimator.NUM_BYTES_INT // valueCount,bitsPerValue
+ + 2 * Integer.BYTES // valueCount,bitsPerValue
+ RamUsageEstimator.NUM_BYTES_OBJECT_REF) // blocks ref
+ RamUsageEstimator.sizeOf(blocks);
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/2da53c32/lucene/core/src/java/org/apache/lucene/util/packed/Packed64SingleBlock.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/util/packed/Packed64SingleBlock.java b/lucene/core/src/java/org/apache/lucene/util/packed/Packed64SingleBlock.java
index a7262b3..128d77f 100644
--- a/lucene/core/src/java/org/apache/lucene/util/packed/Packed64SingleBlock.java
+++ b/lucene/core/src/java/org/apache/lucene/util/packed/Packed64SingleBlock.java
@@ -61,7 +61,7 @@ abstract class Packed64SingleBlock extends PackedInts.MutableImpl {
public long ramBytesUsed() {
return RamUsageEstimator.alignObjectSize(
RamUsageEstimator.NUM_BYTES_OBJECT_HEADER
- + 2 * RamUsageEstimator.NUM_BYTES_INT // valueCount,bitsPerValue
+ + 2 * Integer.BYTES // valueCount,bitsPerValue
+ RamUsageEstimator.NUM_BYTES_OBJECT_REF) // blocks ref
+ RamUsageEstimator.sizeOf(blocks);
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/2da53c32/lucene/core/src/java/org/apache/lucene/util/packed/Packed8ThreeBlocks.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/util/packed/Packed8ThreeBlocks.java b/lucene/core/src/java/org/apache/lucene/util/packed/Packed8ThreeBlocks.java
index 5a85735..93f6497 100644
--- a/lucene/core/src/java/org/apache/lucene/util/packed/Packed8ThreeBlocks.java
+++ b/lucene/core/src/java/org/apache/lucene/util/packed/Packed8ThreeBlocks.java
@@ -110,7 +110,7 @@ final class Packed8ThreeBlocks extends PackedInts.MutableImpl {
public long ramBytesUsed() {
return RamUsageEstimator.alignObjectSize(
RamUsageEstimator.NUM_BYTES_OBJECT_HEADER
- + 2 * RamUsageEstimator.NUM_BYTES_INT // valueCount,bitsPerValue
+ + 2 * Integer.BYTES // valueCount,bitsPerValue
+ RamUsageEstimator.NUM_BYTES_OBJECT_REF) // blocks ref
+ RamUsageEstimator.sizeOf(blocks);
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/2da53c32/lucene/facet/src/java/org/apache/lucene/facet/taxonomy/directory/DirectoryTaxonomyReader.java
----------------------------------------------------------------------
diff --git a/lucene/facet/src/java/org/apache/lucene/facet/taxonomy/directory/DirectoryTaxonomyReader.java b/lucene/facet/src/java/org/apache/lucene/facet/taxonomy/directory/DirectoryTaxonomyReader.java
index 2e4270b..ea02a0a 100644
--- a/lucene/facet/src/java/org/apache/lucene/facet/taxonomy/directory/DirectoryTaxonomyReader.java
+++ b/lucene/facet/src/java/org/apache/lucene/facet/taxonomy/directory/DirectoryTaxonomyReader.java
@@ -65,7 +65,7 @@ public class DirectoryTaxonomyReader extends TaxonomyReader implements Accountab
private static final int DEFAULT_CACHE_VALUE = 4000;
// NOTE: very coarse estimate!
- private static final int BYTES_PER_CACHE_ENTRY = 4 * RamUsageEstimator.NUM_BYTES_OBJECT_REF + 4 * RamUsageEstimator.NUM_BYTES_OBJECT_HEADER + 8 * RamUsageEstimator.NUM_BYTES_CHAR;
+ private static final int BYTES_PER_CACHE_ENTRY = 4 * RamUsageEstimator.NUM_BYTES_OBJECT_REF + 4 * RamUsageEstimator.NUM_BYTES_OBJECT_HEADER + 8 * Character.BYTES;
private final DirectoryTaxonomyWriter taxoWriter;
private final long taxoEpoch; // used in doOpenIfChanged
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/2da53c32/lucene/facet/src/java/org/apache/lucene/facet/taxonomy/directory/TaxonomyIndexArrays.java
----------------------------------------------------------------------
diff --git a/lucene/facet/src/java/org/apache/lucene/facet/taxonomy/directory/TaxonomyIndexArrays.java b/lucene/facet/src/java/org/apache/lucene/facet/taxonomy/directory/TaxonomyIndexArrays.java
index dc4d18a..c39887b 100644
--- a/lucene/facet/src/java/org/apache/lucene/facet/taxonomy/directory/TaxonomyIndexArrays.java
+++ b/lucene/facet/src/java/org/apache/lucene/facet/taxonomy/directory/TaxonomyIndexArrays.java
@@ -223,7 +223,7 @@ class TaxonomyIndexArrays extends ParallelTaxonomyArrays implements Accountable
@Override
public synchronized long ramBytesUsed() {
- long ramBytesUsed = RamUsageEstimator.NUM_BYTES_OBJECT_HEADER + 3 * RamUsageEstimator.NUM_BYTES_OBJECT_REF + RamUsageEstimator.NUM_BYTES_BOOLEAN;
+ long ramBytesUsed = RamUsageEstimator.NUM_BYTES_OBJECT_HEADER + 3 * RamUsageEstimator.NUM_BYTES_OBJECT_REF + 1;
ramBytesUsed += RamUsageEstimator.shallowSizeOf(parents);
if (children != null) {
ramBytesUsed += RamUsageEstimator.shallowSizeOf(children);
[2/2] lucene-solr:master: LUCENE-8340: Recency boosting.
Posted by jp...@apache.org.
LUCENE-8340: Recency boosting.
Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/a9acdfdb
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/a9acdfdb
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/a9acdfdb
Branch: refs/heads/master
Commit: a9acdfdb544cb0f66709a89a9820e8444fe8edef
Parents: 34a8501
Author: Adrien Grand <jp...@gmail.com>
Authored: Tue Sep 4 11:48:25 2018 +0200
Committer: Adrien Grand <jp...@gmail.com>
Committed: Tue Sep 4 14:03:24 2018 +0200
----------------------------------------------------------------------
lucene/CHANGES.txt | 6 +
.../document/LongDistanceFeatureQuery.java | 438 +++++++++++++++++++
.../org/apache/lucene/document/LongPoint.java | 26 ++
.../search/BlockMaxConjunctionScorer.java | 2 +-
.../apache/lucene/search/ConjunctionScorer.java | 2 +-
.../lucene/search/MaxScoreSumPropagator.java | 2 +-
.../org/apache/lucene/search/ReqExclScorer.java | 2 +-
.../apache/lucene/search/ReqOptSumScorer.java | 2 +-
.../java/org/apache/lucene/search/Scorable.java | 2 +-
.../search/ScoreCachingWrappingScorer.java | 2 +-
.../lucene/search/TopScoreDocCollector.java | 2 +-
.../org/apache/lucene/search/WANDScorer.java | 2 +-
.../document/TestLongDistanceFeatureQuery.java | 350 +++++++++++++++
.../apache/lucene/search/AssertingScorable.java | 2 +-
.../apache/lucene/search/AssertingScorer.java | 2 +-
15 files changed, 831 insertions(+), 11 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/a9acdfdb/lucene/CHANGES.txt
----------------------------------------------------------------------
diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt
index f95ce90..1334294 100644
--- a/lucene/CHANGES.txt
+++ b/lucene/CHANGES.txt
@@ -106,6 +106,12 @@ Changes in Runtime Behavior
total hit counts accurately up to 1,000 in order to enable top-hits
optimizations such as block-max WAND (LUCENE-8135). (Adrien Grand)
+New Features
+
+* LUCENE-8340: LongPoint#newDistanceQuery may be used to boost scores based on
+ how close a value of a long field is from an configurable origin. This is
+ typically useful to boost by recency. (Adrien Grand)
+
Improvements
* LUCENE-7997: Add BaseSimilarityTestCase to sanity check similarities.
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/a9acdfdb/lucene/core/src/java/org/apache/lucene/document/LongDistanceFeatureQuery.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/document/LongDistanceFeatureQuery.java b/lucene/core/src/java/org/apache/lucene/document/LongDistanceFeatureQuery.java
new file mode 100644
index 0000000..480cfce
--- /dev/null
+++ b/lucene/core/src/java/org/apache/lucene/document/LongDistanceFeatureQuery.java
@@ -0,0 +1,438 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.document;
+
+import java.io.IOException;
+import java.util.Objects;
+import java.util.Set;
+
+import org.apache.lucene.index.DocValues;
+import org.apache.lucene.index.LeafReaderContext;
+import org.apache.lucene.index.NumericDocValues;
+import org.apache.lucene.index.PointValues;
+import org.apache.lucene.index.PointValues.IntersectVisitor;
+import org.apache.lucene.index.PointValues.Relation;
+import org.apache.lucene.index.SortedNumericDocValues;
+import org.apache.lucene.index.Term;
+import org.apache.lucene.search.DocIdSetIterator;
+import org.apache.lucene.search.Explanation;
+import org.apache.lucene.search.IndexSearcher;
+import org.apache.lucene.search.Query;
+import org.apache.lucene.search.ScoreMode;
+import org.apache.lucene.search.Scorer;
+import org.apache.lucene.search.ScorerSupplier;
+import org.apache.lucene.search.Weight;
+import org.apache.lucene.util.DocIdSetBuilder;
+import org.apache.lucene.util.FutureArrays;
+
+final class LongDistanceFeatureQuery extends Query {
+
+ private final String field;
+ private final long origin;
+ private final long pivotDistance;
+
+ LongDistanceFeatureQuery(String field, long origin, long pivotDistance) {
+ this.field = Objects.requireNonNull(field);
+ this.origin = origin;
+ if (pivotDistance <= 0) {
+ throw new IllegalArgumentException("pivotDistance must be > 0, got " + pivotDistance);
+ }
+ this.pivotDistance = pivotDistance;
+ }
+
+ @Override
+ public final boolean equals(Object o) {
+ return sameClassAs(o) &&
+ equalsTo(getClass().cast(o));
+ }
+
+ private boolean equalsTo(LongDistanceFeatureQuery other) {
+ return Objects.equals(field, other.field) &&
+ origin == other.origin &&
+ pivotDistance == other.pivotDistance;
+ }
+
+ @Override
+ public int hashCode() {
+ int h = classHash();
+ h = 31 * h + field.hashCode();
+ h = 31 * h + Long.hashCode(origin);
+ h = 31 * h + Long.hashCode(pivotDistance);
+ return h;
+ }
+
+ @Override
+ public String toString(String field) {
+ return getClass().getSimpleName() + "(field=" + field + ",origin=" + origin + ",pivotDistance=" + pivotDistance + ")";
+ }
+
+ @Override
+ public Weight createWeight(IndexSearcher searcher, ScoreMode scoreMode, float boost) throws IOException {
+ return new Weight(this) {
+
+ @Override
+ public boolean isCacheable(LeafReaderContext ctx) {
+ return false;
+ }
+
+ @Override
+ public void extractTerms(Set<Term> terms) {}
+
+ @Override
+ public Explanation explain(LeafReaderContext context, int doc) throws IOException {
+ SortedNumericDocValues multiDocValues = DocValues.getSortedNumeric(context.reader(), field);
+ if (multiDocValues.advanceExact(doc) == false) {
+ return Explanation.noMatch("Document " + doc + " doesn't have a value for field " + field);
+ }
+ long value = selectValue(multiDocValues);
+ long distance = Math.max(value, origin) - Math.min(value, origin);
+ if (distance < 0) {
+ // underflow, treat as MAX_VALUE
+ distance = Long.MAX_VALUE;
+ }
+ float score = (float) (boost * (pivotDistance / (pivotDistance + (double) distance)));
+ return Explanation.match(score, "Distance score, computed as weight * pivotDistance / (pivotDistance + abs(value - origin)) from:",
+ Explanation.match(boost, "weight"),
+ Explanation.match(pivotDistance, "pivotDistance"),
+ Explanation.match(origin, "origin"),
+ Explanation.match(value, "current value"));
+ }
+
+ private long selectValue(SortedNumericDocValues multiDocValues) throws IOException {
+ int count = multiDocValues.docValueCount();
+
+ long next = multiDocValues.nextValue();
+ if (count == 1 || next >= origin) {
+ return next;
+ }
+ long previous = next;
+ for (int i = 1; i < count; ++i) {
+ next = multiDocValues.nextValue();
+ if (next >= origin) {
+ // Unsigned comparison because of underflows
+ if (Long.compareUnsigned(origin - previous, next - origin) < 0) {
+ return previous;
+ } else {
+ return next;
+ }
+ }
+ previous = next;
+ }
+
+ assert next < origin;
+ return next;
+ }
+
+ private NumericDocValues selectValues(SortedNumericDocValues multiDocValues) {
+ final NumericDocValues singleton = DocValues.unwrapSingleton(multiDocValues);
+ if (singleton != null) {
+ return singleton;
+ }
+ return new NumericDocValues() {
+
+ long value;
+
+ @Override
+ public long longValue() throws IOException {
+ return value;
+ }
+
+ @Override
+ public boolean advanceExact(int target) throws IOException {
+ if (multiDocValues.advanceExact(target)) {
+ value = selectValue(multiDocValues);
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ @Override
+ public int docID() {
+ return multiDocValues.docID();
+ }
+
+ @Override
+ public int nextDoc() throws IOException {
+ return multiDocValues.nextDoc();
+ }
+
+ @Override
+ public int advance(int target) throws IOException {
+ return multiDocValues.advance(target);
+ }
+
+ @Override
+ public long cost() {
+ return multiDocValues.cost();
+ }
+
+ };
+ }
+
+ @Override
+ public ScorerSupplier scorerSupplier(LeafReaderContext context) throws IOException {
+ PointValues pointValues = context.reader().getPointValues(field);
+ if (pointValues == null) {
+ // No data on this segment
+ return null;
+ }
+ final SortedNumericDocValues multiDocValues = DocValues.getSortedNumeric(context.reader(), field);
+ final NumericDocValues docValues = selectValues(multiDocValues);
+
+ final Weight weight = this;
+ return new ScorerSupplier() {
+
+ @Override
+ public Scorer get(long leadCost) throws IOException {
+ return new DistanceScorer(weight, context.reader().maxDoc(), leadCost, boost, pointValues, docValues);
+ }
+
+ @Override
+ public long cost() {
+ return docValues.cost();
+ }
+ };
+ }
+
+ @Override
+ public Scorer scorer(LeafReaderContext context) throws IOException {
+ ScorerSupplier scorerSupplier = scorerSupplier(context);
+ if (scorerSupplier == null) {
+ return null;
+ }
+ return scorerSupplier.get(Long.MAX_VALUE);
+ }
+
+ };
+ }
+
+ private class DistanceScorer extends Scorer {
+
+ private final int maxDoc;
+ private DocIdSetIterator it;
+ private int doc = -1;
+ private final long leadCost;
+ private final float boost;
+ private final PointValues pointValues;
+ private final NumericDocValues docValues;
+ private long maxDistance = Long.MAX_VALUE;
+
+ protected DistanceScorer(Weight weight, int maxDoc, long leadCost, float boost,
+ PointValues pointValues, NumericDocValues docValues) {
+ super(weight);
+ this.maxDoc = maxDoc;
+ this.leadCost = leadCost;
+ this.boost = boost;
+ this.pointValues = pointValues;
+ this.docValues = docValues;
+ // initially use doc values in order to iterate all documents that have
+ // a value for this field
+ this.it = docValues;
+ }
+
+ @Override
+ public int docID() {
+ return doc;
+ }
+
+ private float score(double distance) {
+ return (float) (boost * (pivotDistance / (pivotDistance + distance)));
+ }
+
+ /**
+ * Inverting the score computation is very hard due to all potential
+ * rounding errors, so we binary search the maximum distance.
+ */
+ private long computeMaxDistance(float minScore, long previousMaxDistance) {
+ assert score(0) >= minScore;
+ if (score(previousMaxDistance) >= minScore) {
+ // minScore did not decrease enough to require an update to the max distance
+ return previousMaxDistance;
+ }
+ assert score(previousMaxDistance) < minScore;
+ long min = 0, max = previousMaxDistance;
+ // invariant: score(min) >= minScore && score(max) < minScore
+ while (max - min > 1) {
+ long mid = (min + max) >>> 1;
+ float score = score(mid);
+ if (score >= minScore) {
+ min = mid;
+ } else {
+ max = mid;
+ }
+ }
+ assert score(min) >= minScore;
+ assert min == Long.MAX_VALUE || score(min + 1) < minScore;
+ return min;
+ }
+
+ @Override
+ public float score() throws IOException {
+ if (docValues.advanceExact(docID()) == false) {
+ return 0;
+ }
+ long v = docValues.longValue();
+ // note: distance is unsigned
+ long distance = Math.max(v, origin) - Math.min(v, origin);
+ if (distance < 0) {
+ // underflow
+ // treat distances that are greater than MAX_VALUE as MAX_VALUE
+ distance = Long.MAX_VALUE;
+ }
+ return score(distance);
+ }
+
+ @Override
+ public DocIdSetIterator iterator() {
+ // add indirection so that if 'it' is updated then it will
+ // be taken into account
+ return new DocIdSetIterator() {
+
+ @Override
+ public int nextDoc() throws IOException {
+ return doc = it.nextDoc();
+ }
+
+ @Override
+ public int docID() {
+ return doc;
+ }
+
+ @Override
+ public long cost() {
+ return it.cost();
+ }
+
+ @Override
+ public int advance(int target) throws IOException {
+ return doc = it.advance(target);
+ }
+ };
+ }
+
+ @Override
+ public float getMaxScore(int upTo) {
+ return boost;
+ }
+
+ private int setMinCompetitiveScoreCounter = 0;
+
+ @Override
+ public void setMinCompetitiveScore(float minScore) throws IOException {
+ if (minScore > boost) {
+ it = DocIdSetIterator.empty();
+ return;
+ }
+
+ // Start sampling if we get called too much
+ setMinCompetitiveScoreCounter++;
+ if (setMinCompetitiveScoreCounter > 256 && (setMinCompetitiveScoreCounter & 0x1f) != 0x1f) {
+ return;
+ }
+
+ long previousMaxDistance = maxDistance;
+ maxDistance = computeMaxDistance(minScore, maxDistance);
+ if (maxDistance == previousMaxDistance) {
+ // nothing to update
+ return;
+ }
+ long minValue = origin - maxDistance;
+ if (minValue > origin) {
+ // underflow
+ minValue = Long.MIN_VALUE;
+ }
+ long maxValue = origin + maxDistance;
+ if (maxValue < origin) {
+ // overflow
+ maxValue = Long.MAX_VALUE;
+ }
+
+ final byte[] minValueAsBytes = new byte[Long.BYTES];
+ LongPoint.encodeDimension(minValue, minValueAsBytes, 0);
+ final byte[] maxValueAsBytes = new byte[Long.BYTES];
+ LongPoint.encodeDimension(maxValue, maxValueAsBytes, 0);
+
+ DocIdSetBuilder result = new DocIdSetBuilder(maxDoc);
+ final int doc = docID();
+ IntersectVisitor visitor = new IntersectVisitor() {
+
+ DocIdSetBuilder.BulkAdder adder;
+
+ @Override
+ public void grow(int count) {
+ adder = result.grow(count);
+ }
+
+ @Override
+ public void visit(int docID) {
+ if (docID <= doc) {
+ // Already visited or skipped
+ return;
+ }
+ adder.add(docID);
+ }
+
+ @Override
+ public void visit(int docID, byte[] packedValue) {
+ if (docID <= doc) {
+ // Already visited or skipped
+ return;
+ }
+ if (FutureArrays.compareUnsigned(packedValue, 0, Long.BYTES, minValueAsBytes, 0, Long.BYTES) < 0) {
+ // Doc's value is too low, in this dimension
+ return;
+ }
+ if (FutureArrays.compareUnsigned(packedValue, 0, Long.BYTES, maxValueAsBytes, 0, Long.BYTES) > 0) {
+ // Doc's value is too high, in this dimension
+ return;
+ }
+
+ // Doc is in-bounds
+ adder.add(docID);
+ }
+
+ @Override
+ public Relation compare(byte[] minPackedValue, byte[] maxPackedValue) {
+ if (FutureArrays.compareUnsigned(minPackedValue, 0, Long.BYTES, maxValueAsBytes, 0, Long.BYTES) > 0 ||
+ FutureArrays.compareUnsigned(maxPackedValue, 0, Long.BYTES, minValueAsBytes, 0, Long.BYTES) < 0) {
+ return Relation.CELL_OUTSIDE_QUERY;
+ }
+
+ if (FutureArrays.compareUnsigned(minPackedValue, 0, Long.BYTES, minValueAsBytes, 0, Long.BYTES) < 0 ||
+ FutureArrays.compareUnsigned(maxPackedValue, 0, Long.BYTES, maxValueAsBytes, 0, Long.BYTES) > 0) {
+ return Relation.CELL_CROSSES_QUERY;
+ }
+
+ return Relation.CELL_INSIDE_QUERY;
+ }
+ };
+
+ final long currentQueryCost = Math.min(leadCost, it.cost());
+ final long threshold = currentQueryCost >>> 3;
+ long estimatedNumberOfMatches = pointValues.estimatePointCount(visitor); // runs in O(log(numPoints))
+ // TODO: what is the right factor compared to the current disi? Is 8 optimal?
+ if (estimatedNumberOfMatches >= threshold) {
+ // the new range is not selective enough to be worth materializing
+ return;
+ }
+ pointValues.intersect(visitor);
+ it = result.build().iterator();
+ }
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/a9acdfdb/lucene/core/src/java/org/apache/lucene/document/LongPoint.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/document/LongPoint.java b/lucene/core/src/java/org/apache/lucene/document/LongPoint.java
index 686086c..5311114 100644
--- a/lucene/core/src/java/org/apache/lucene/document/LongPoint.java
+++ b/lucene/core/src/java/org/apache/lucene/document/LongPoint.java
@@ -20,9 +20,12 @@ import java.util.Arrays;
import java.util.Collection;
import org.apache.lucene.index.PointValues;
+import org.apache.lucene.search.BooleanQuery;
+import org.apache.lucene.search.BoostQuery;
import org.apache.lucene.search.PointInSetQuery;
import org.apache.lucene.search.PointRangeQuery;
import org.apache.lucene.search.Query;
+import org.apache.lucene.search.BooleanClause.Occur;
import org.apache.lucene.util.BytesRef;
import org.apache.lucene.util.NumericUtils;
@@ -256,4 +259,27 @@ public final class LongPoint extends Field {
}
return newSetQuery(field, unboxed);
}
+
+ /**
+ * Given a field that indexes the same long values into a {@link LongPoint}
+ * and doc values (either {@link NumericDocValuesField} or
+ * {@link SortedNumericDocValuesField}), this returns a query that scores
+ * documents based on their distance to {@code origin}:
+ * {@code score = weight * pivotDistance / (pivotDistance + distance)}, ie.
+ * score is in the {@code [0, weight]} range, is equal to {@code weight} when
+ * the document's value is equal to {@code origin} and is equal to
+ * {@code weight/2} when the document's value is distant of
+ * {@code pivotDistance} from {@code origin}.
+ * In case of multi-valued fields, only the closest point to {@code origin}
+ * will be considered.
+ * This query is typically useful to boost results based on recency by adding
+ * this query to a {@link Occur#SHOULD} clause of a {@link BooleanQuery}.
+ */
+ public static Query newDistanceFeatureQuery(String field, float weight, long origin, long pivotDistance) {
+ Query query = new LongDistanceFeatureQuery(field, origin, pivotDistance);
+ if (weight != 1f) {
+ query = new BoostQuery(query, weight);
+ }
+ return query;
+ }
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/a9acdfdb/lucene/core/src/java/org/apache/lucene/search/BlockMaxConjunctionScorer.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/search/BlockMaxConjunctionScorer.java b/lucene/core/src/java/org/apache/lucene/search/BlockMaxConjunctionScorer.java
index fa3743f..91fe76c 100644
--- a/lucene/core/src/java/org/apache/lucene/search/BlockMaxConjunctionScorer.java
+++ b/lucene/core/src/java/org/apache/lucene/search/BlockMaxConjunctionScorer.java
@@ -244,7 +244,7 @@ final class BlockMaxConjunctionScorer extends Scorer {
}
@Override
- public void setMinCompetitiveScore(float score) {
+ public void setMinCompetitiveScore(float score) throws IOException {
minScore = score;
maxScorePropagator.setMinCompetitiveScore(score);
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/a9acdfdb/lucene/core/src/java/org/apache/lucene/search/ConjunctionScorer.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/search/ConjunctionScorer.java b/lucene/core/src/java/org/apache/lucene/search/ConjunctionScorer.java
index eafc57f..7ba4aa3 100644
--- a/lucene/core/src/java/org/apache/lucene/search/ConjunctionScorer.java
+++ b/lucene/core/src/java/org/apache/lucene/search/ConjunctionScorer.java
@@ -83,7 +83,7 @@ class ConjunctionScorer extends Scorer {
}
@Override
- public void setMinCompetitiveScore(float minScore) {
+ public void setMinCompetitiveScore(float minScore) throws IOException {
// This scorer is only used for TOP_SCORES when there is a single scoring clause
if (scorers.length == 1) {
scorers[0].setMinCompetitiveScore(minScore);
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/a9acdfdb/lucene/core/src/java/org/apache/lucene/search/MaxScoreSumPropagator.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/search/MaxScoreSumPropagator.java b/lucene/core/src/java/org/apache/lucene/search/MaxScoreSumPropagator.java
index 331754c..1a4b3b5 100644
--- a/lucene/core/src/java/org/apache/lucene/search/MaxScoreSumPropagator.java
+++ b/lucene/core/src/java/org/apache/lucene/search/MaxScoreSumPropagator.java
@@ -110,7 +110,7 @@ final class MaxScoreSumPropagator {
return scoreSumUpperBound(maxScore);
}
- void setMinCompetitiveScore(float minScore) {
+ void setMinCompetitiveScore(float minScore) throws IOException {
if (minScore == 0) {
return ;
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/a9acdfdb/lucene/core/src/java/org/apache/lucene/search/ReqExclScorer.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/search/ReqExclScorer.java b/lucene/core/src/java/org/apache/lucene/search/ReqExclScorer.java
index d5c114a..90b11aa 100644
--- a/lucene/core/src/java/org/apache/lucene/search/ReqExclScorer.java
+++ b/lucene/core/src/java/org/apache/lucene/search/ReqExclScorer.java
@@ -87,7 +87,7 @@ class ReqExclScorer extends Scorer {
}
@Override
- public void setMinCompetitiveScore(float score) {
+ public void setMinCompetitiveScore(float score) throws IOException {
// The score of this scorer is the same as the score of 'reqScorer'.
reqScorer.setMinCompetitiveScore(score);
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/a9acdfdb/lucene/core/src/java/org/apache/lucene/search/ReqOptSumScorer.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/search/ReqOptSumScorer.java b/lucene/core/src/java/org/apache/lucene/search/ReqOptSumScorer.java
index 22df0af..fe9afc0 100644
--- a/lucene/core/src/java/org/apache/lucene/search/ReqOptSumScorer.java
+++ b/lucene/core/src/java/org/apache/lucene/search/ReqOptSumScorer.java
@@ -290,7 +290,7 @@ class ReqOptSumScorer extends Scorer {
}
@Override
- public void setMinCompetitiveScore(float minScore) {
+ public void setMinCompetitiveScore(float minScore) throws IOException {
this.minScore = minScore;
// Potentially move to a conjunction
if (reqMaxScore < minScore) {
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/a9acdfdb/lucene/core/src/java/org/apache/lucene/search/Scorable.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/search/Scorable.java b/lucene/core/src/java/org/apache/lucene/search/Scorable.java
index 5102949..1fdda0d 100644
--- a/lucene/core/src/java/org/apache/lucene/search/Scorable.java
+++ b/lucene/core/src/java/org/apache/lucene/search/Scorable.java
@@ -45,7 +45,7 @@ public abstract class Scorable {
* {@link ScoreMode#TOP_SCORES}, and successive calls may only set increasing
* values of {@code minScore}.
*/
- public void setMinCompetitiveScore(float minScore) {
+ public void setMinCompetitiveScore(float minScore) throws IOException {
// no-op by default
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/a9acdfdb/lucene/core/src/java/org/apache/lucene/search/ScoreCachingWrappingScorer.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/search/ScoreCachingWrappingScorer.java b/lucene/core/src/java/org/apache/lucene/search/ScoreCachingWrappingScorer.java
index 0f11609..f68f25d 100644
--- a/lucene/core/src/java/org/apache/lucene/search/ScoreCachingWrappingScorer.java
+++ b/lucene/core/src/java/org/apache/lucene/search/ScoreCachingWrappingScorer.java
@@ -55,7 +55,7 @@ public final class ScoreCachingWrappingScorer extends Scorable {
}
@Override
- public void setMinCompetitiveScore(float minScore) {
+ public void setMinCompetitiveScore(float minScore) throws IOException {
in.setMinCompetitiveScore(minScore);
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/a9acdfdb/lucene/core/src/java/org/apache/lucene/search/TopScoreDocCollector.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/search/TopScoreDocCollector.java b/lucene/core/src/java/org/apache/lucene/search/TopScoreDocCollector.java
index 9a24406..eb8236c 100644
--- a/lucene/core/src/java/org/apache/lucene/search/TopScoreDocCollector.java
+++ b/lucene/core/src/java/org/apache/lucene/search/TopScoreDocCollector.java
@@ -62,7 +62,7 @@ public abstract class TopScoreDocCollector extends TopDocsCollector<ScoreDoc> {
final int docBase = context.docBase;
return new ScorerLeafCollector() {
- private void updateMinCompetitiveScore() {
+ private void updateMinCompetitiveScore() throws IOException {
// since we tie-break on doc id and collect in doc id order, we can require
// the next float
scorer.setMinCompetitiveScore(Math.nextUp(pqTop.score));
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/a9acdfdb/lucene/core/src/java/org/apache/lucene/search/WANDScorer.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/search/WANDScorer.java b/lucene/core/src/java/org/apache/lucene/search/WANDScorer.java
index c6a5528..c9a6746 100644
--- a/lucene/core/src/java/org/apache/lucene/search/WANDScorer.java
+++ b/lucene/core/src/java/org/apache/lucene/search/WANDScorer.java
@@ -186,7 +186,7 @@ final class WANDScorer extends Scorer {
}
@Override
- public void setMinCompetitiveScore(float minScore) {
+ public void setMinCompetitiveScore(float minScore) throws IOException {
// Let this disjunction know about the new min score so that it can skip
// over clauses that produce low scores.
assert minScore >= 0;
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/a9acdfdb/lucene/core/src/test/org/apache/lucene/document/TestLongDistanceFeatureQuery.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/test/org/apache/lucene/document/TestLongDistanceFeatureQuery.java b/lucene/core/src/test/org/apache/lucene/document/TestLongDistanceFeatureQuery.java
new file mode 100644
index 0000000..d8ae66a
--- /dev/null
+++ b/lucene/core/src/test/org/apache/lucene/document/TestLongDistanceFeatureQuery.java
@@ -0,0 +1,350 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.document;
+
+import java.io.IOException;
+
+import org.apache.lucene.index.DirectoryReader;
+import org.apache.lucene.index.IndexReader;
+import org.apache.lucene.index.IndexWriter;
+import org.apache.lucene.index.MultiReader;
+import org.apache.lucene.index.RandomIndexWriter;
+import org.apache.lucene.search.CheckHits;
+import org.apache.lucene.search.IndexSearcher;
+import org.apache.lucene.search.Query;
+import org.apache.lucene.search.QueryUtils;
+import org.apache.lucene.search.ScoreDoc;
+import org.apache.lucene.search.TopDocs;
+import org.apache.lucene.search.TopScoreDocCollector;
+import org.apache.lucene.store.Directory;
+import org.apache.lucene.util.LuceneTestCase;
+
+public class TestLongDistanceFeatureQuery extends LuceneTestCase {
+
+ public void testEqualsAndHashcode() {
+ Query q1 = LongPoint.newDistanceFeatureQuery("foo", 3, 10, 5);
+ Query q2 = LongPoint.newDistanceFeatureQuery("foo", 3, 10, 5);
+ QueryUtils.checkEqual(q1, q2);
+
+ Query q3 = LongPoint.newDistanceFeatureQuery("bar", 3, 10, 5);
+ QueryUtils.checkUnequal(q1, q3);
+
+ Query q4 = LongPoint.newDistanceFeatureQuery("foo", 4, 10, 5);
+ QueryUtils.checkUnequal(q1, q4);
+
+ Query q5 = LongPoint.newDistanceFeatureQuery("foo", 3, 9, 5);
+ QueryUtils.checkUnequal(q1, q5);
+
+ Query q6 = LongPoint.newDistanceFeatureQuery("foo", 3, 10, 6);
+ QueryUtils.checkUnequal(q1, q6);
+ }
+
+ public void testBasics() throws IOException {
+ Directory dir = newDirectory();
+ RandomIndexWriter w = new RandomIndexWriter(random(), dir, newIndexWriterConfig()
+ .setMergePolicy(newLogMergePolicy(random().nextBoolean())));
+ Document doc = new Document();
+ LongPoint point = new LongPoint("foo", 0L);
+ doc.add(point);
+ NumericDocValuesField docValue = new NumericDocValuesField("foo", 0L);
+ doc.add(docValue);
+
+ point.setLongValue(3);
+ docValue.setLongValue(3);
+ w.addDocument(doc);
+
+ point.setLongValue(12);
+ docValue.setLongValue(12);
+ w.addDocument(doc);
+
+ point.setLongValue(8);
+ docValue.setLongValue(8);
+ w.addDocument(doc);
+
+ point.setLongValue(-1);
+ docValue.setLongValue(-1);
+ w.addDocument(doc);
+
+ point.setLongValue(7);
+ docValue.setLongValue(7);
+ w.addDocument(doc);
+
+ DirectoryReader reader = w.getReader();
+ IndexSearcher searcher = newSearcher(reader);
+
+ Query q = LongPoint.newDistanceFeatureQuery("foo", 3, 10, 5);
+ TopScoreDocCollector collector = TopScoreDocCollector.create(2, null, 1);
+ searcher.search(q, collector);
+ TopDocs topHits = collector.topDocs();
+ assertEquals(2, topHits.scoreDocs.length);
+
+ CheckHits.checkEqual(q,
+ new ScoreDoc[] {
+ new ScoreDoc(1, (float) (3f * (5. / (5. + 2.)))),
+ new ScoreDoc(2, (float) (3f * (5. / (5. + 2.))))
+ },
+ topHits.scoreDocs);
+
+ q = LongPoint.newDistanceFeatureQuery("foo", 3, 7, 5);
+ collector = TopScoreDocCollector.create(2, null, 1);
+ searcher.search(q, collector);
+ topHits = collector.topDocs();
+ assertEquals(2, topHits.scoreDocs.length);
+ CheckHits.checkExplanations(q, "", searcher);
+
+ CheckHits.checkEqual(q,
+ new ScoreDoc[] {
+ new ScoreDoc(4, (float) (3f * (5. / (5. + 0.)))),
+ new ScoreDoc(2, (float) (3f * (5. / (5. + 1.))))
+ },
+ topHits.scoreDocs);
+
+ reader.close();
+ w.close();
+ dir.close();
+ }
+
+ public void testOverUnderFlow() throws IOException {
+ Directory dir = newDirectory();
+ RandomIndexWriter w = new RandomIndexWriter(random(), dir, newIndexWriterConfig()
+ .setMergePolicy(newLogMergePolicy(random().nextBoolean())));
+ Document doc = new Document();
+ LongPoint point = new LongPoint("foo", 0L);
+ doc.add(point);
+ NumericDocValuesField docValue = new NumericDocValuesField("foo", 0L);
+ doc.add(docValue);
+
+ point.setLongValue(3);
+ docValue.setLongValue(3);
+ w.addDocument(doc);
+
+ point.setLongValue(12);
+ docValue.setLongValue(12);
+ w.addDocument(doc);
+
+ point.setLongValue(-10);
+ docValue.setLongValue(-10);
+ w.addDocument(doc);
+
+ point.setLongValue(Long.MAX_VALUE);
+ docValue.setLongValue(Long.MAX_VALUE);
+ w.addDocument(doc);
+
+ point.setLongValue(Long.MIN_VALUE);
+ docValue.setLongValue(Long.MIN_VALUE);
+ w.addDocument(doc);
+
+ DirectoryReader reader = w.getReader();
+ IndexSearcher searcher = newSearcher(reader);
+
+ Query q = LongPoint.newDistanceFeatureQuery("foo", 3, Long.MAX_VALUE - 1, 100);
+ TopScoreDocCollector collector = TopScoreDocCollector.create(2, null, 1);
+ searcher.search(q, collector);
+ TopDocs topHits = collector.topDocs();
+ assertEquals(2, topHits.scoreDocs.length);
+
+ CheckHits.checkEqual(q,
+ new ScoreDoc[] {
+ new ScoreDoc(3, (float) (3f * (100. / (100. + 1.)))),
+ new ScoreDoc(0, (float) (3f * (100. / (100. + Long.MAX_VALUE)))) // rounding makes the distance treated as if it was MAX_VALUE
+ },
+ topHits.scoreDocs);
+
+ q = LongPoint.newDistanceFeatureQuery("foo", 3, Long.MIN_VALUE + 1, 100);
+ collector = TopScoreDocCollector.create(2, null, 1);
+ searcher.search(q, collector);
+ topHits = collector.topDocs();
+ assertEquals(2, topHits.scoreDocs.length);
+ CheckHits.checkExplanations(q, "", searcher);
+
+ CheckHits.checkEqual(q,
+ new ScoreDoc[] {
+ new ScoreDoc(4, (float) (3f * (100. / (100. + 1.)))),
+ new ScoreDoc(0, (float) (3f * (100. / (100. + Long.MAX_VALUE)))) // rounding makes the distance treated as if it was MAX_VALUE
+ },
+ topHits.scoreDocs);
+
+ reader.close();
+ w.close();
+ dir.close();
+ }
+
+ public void testMissingField() throws IOException {
+ IndexReader reader = new MultiReader();
+ IndexSearcher searcher = newSearcher(reader);
+
+ Query q = LongPoint.newDistanceFeatureQuery("foo", 3, 10, 5);
+ TopDocs topHits = searcher.search(q, 2);
+ assertEquals(0, topHits.totalHits.value);
+ }
+
+ public void testMissingValue() throws IOException {
+ Directory dir = newDirectory();
+ RandomIndexWriter w = new RandomIndexWriter(random(), dir, newIndexWriterConfig()
+ .setMergePolicy(newLogMergePolicy(random().nextBoolean())));
+ Document doc = new Document();
+ LongPoint point = new LongPoint("foo", 0L);
+ doc.add(point);
+ NumericDocValuesField docValue = new NumericDocValuesField("foo", 0L);
+ doc.add(docValue);
+
+ point.setLongValue(3);
+ docValue.setLongValue(3);
+ w.addDocument(doc);
+
+ w.addDocument(new Document());
+
+ point.setLongValue(7);
+ docValue.setLongValue(7);
+ w.addDocument(doc);
+
+ DirectoryReader reader = w.getReader();
+ IndexSearcher searcher = newSearcher(reader);
+
+ Query q = LongPoint.newDistanceFeatureQuery("foo", 3, 10, 5);
+ TopScoreDocCollector collector = TopScoreDocCollector.create(3, null, 1);
+ searcher.search(q, collector);
+ TopDocs topHits = collector.topDocs();
+ assertEquals(2, topHits.scoreDocs.length);
+
+ CheckHits.checkEqual(q,
+ new ScoreDoc[] {
+ new ScoreDoc(2, (float) (3f * (5. / (5. + 3.)))),
+ new ScoreDoc(0, (float) (3f * (5. / (5. + 7.))))
+ },
+ topHits.scoreDocs);
+
+ CheckHits.checkExplanations(q, "", searcher);
+
+ reader.close();
+ w.close();
+ dir.close();
+ }
+
+ public void testMultiValued() throws IOException {
+ Directory dir = newDirectory();
+ RandomIndexWriter w = new RandomIndexWriter(random(), dir, newIndexWriterConfig()
+ .setMergePolicy(newLogMergePolicy(random().nextBoolean())));
+
+ Document doc = new Document();
+ for (long v : new long[] {3, 1000, Long.MAX_VALUE}) {
+ doc.add(new LongPoint("foo", v));
+ doc.add(new SortedNumericDocValuesField("foo", v));
+ }
+ w.addDocument(doc);
+
+ doc = new Document();
+ for (long v : new long[] {-100, 12, 999}) {
+ doc.add(new LongPoint("foo", v));
+ doc.add(new SortedNumericDocValuesField("foo", v));
+ }
+ w.addDocument(doc);
+
+ doc = new Document();
+ for (long v : new long[] {Long.MIN_VALUE, -1000, 8}) {
+ doc.add(new LongPoint("foo", v));
+ doc.add(new SortedNumericDocValuesField("foo", v));
+ }
+ w.addDocument(doc);
+
+ doc = new Document();
+ for (long v : new long[] { -1 }) {
+ doc.add(new LongPoint("foo", v));
+ doc.add(new SortedNumericDocValuesField("foo", v));
+ }
+ w.addDocument(doc);
+
+ doc = new Document();
+ for (long v : new long[] {Long.MIN_VALUE, 7}) {
+ doc.add(new LongPoint("foo", v));
+ doc.add(new SortedNumericDocValuesField("foo", v));
+ }
+ w.addDocument(doc);
+
+ DirectoryReader reader = w.getReader();
+ IndexSearcher searcher = newSearcher(reader);
+
+ Query q = LongPoint.newDistanceFeatureQuery("foo", 3, 10, 5);
+ TopScoreDocCollector collector = TopScoreDocCollector.create(2, null, 1);
+ searcher.search(q, collector);
+ TopDocs topHits = collector.topDocs();
+ assertEquals(2, topHits.scoreDocs.length);
+
+ CheckHits.checkEqual(q,
+ new ScoreDoc[] {
+ new ScoreDoc(1, (float) (3f * (5. / (5. + 2.)))),
+ new ScoreDoc(2, (float) (3f * (5. / (5. + 2.))))
+ },
+ topHits.scoreDocs);
+
+ q = LongPoint.newDistanceFeatureQuery("foo", 3, 7, 5);
+ collector = TopScoreDocCollector.create(2, null, 1);
+ searcher.search(q, collector);
+ topHits = collector.topDocs();
+ assertEquals(2, topHits.scoreDocs.length);
+ CheckHits.checkExplanations(q, "", searcher);
+
+ CheckHits.checkEqual(q,
+ new ScoreDoc[] {
+ new ScoreDoc(4, (float) (3f * (5. / (5. + 0.)))),
+ new ScoreDoc(2, (float) (3f * (5. / (5. + 1.))))
+ },
+ topHits.scoreDocs);
+
+ reader.close();
+ w.close();
+ dir.close();
+ }
+
+ public void testRandom() throws IOException {
+ Directory dir = newDirectory();
+ IndexWriter w = new IndexWriter(dir, newIndexWriterConfig()
+ .setMergePolicy(newLogMergePolicy(random().nextBoolean())));
+ Document doc = new Document();
+ LongPoint point = new LongPoint("foo", 0L);
+ doc.add(point);
+ NumericDocValuesField docValue = new NumericDocValuesField("foo", 0L);
+ doc.add(docValue);
+
+ int numDocs = atLeast(10000);
+ for (int i = 0; i < numDocs; ++i) {
+ long v = random().nextLong();
+ point.setLongValue(v);
+ docValue.setLongValue(v);
+ w.addDocument(doc);
+ }
+
+ IndexReader reader = DirectoryReader.open(w);
+ IndexSearcher searcher = newSearcher(reader);
+
+ for (int iter = 0; iter < 10; ++iter) {
+ long origin = random().nextLong();
+ long pivotDistance;
+ do {
+ pivotDistance = random().nextLong();
+ } while (pivotDistance <= 0);
+ float boost = (1 + random().nextInt(10)) / 3f;
+ Query q = LongPoint.newDistanceFeatureQuery("foo", boost, origin, pivotDistance);
+
+ CheckHits.checkTopScores(random(), q, searcher);
+ }
+
+ reader.close();
+ w.close();
+ dir.close();
+ }
+}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/a9acdfdb/lucene/test-framework/src/java/org/apache/lucene/search/AssertingScorable.java
----------------------------------------------------------------------
diff --git a/lucene/test-framework/src/java/org/apache/lucene/search/AssertingScorable.java b/lucene/test-framework/src/java/org/apache/lucene/search/AssertingScorable.java
index f69fe60..208eb4b 100644
--- a/lucene/test-framework/src/java/org/apache/lucene/search/AssertingScorable.java
+++ b/lucene/test-framework/src/java/org/apache/lucene/search/AssertingScorable.java
@@ -39,7 +39,7 @@ public class AssertingScorable extends FilterScorable {
}
@Override
- public void setMinCompetitiveScore(float minScore) {
+ public void setMinCompetitiveScore(float minScore) throws IOException {
in.setMinCompetitiveScore(minScore);
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/a9acdfdb/lucene/test-framework/src/java/org/apache/lucene/search/AssertingScorer.java
----------------------------------------------------------------------
diff --git a/lucene/test-framework/src/java/org/apache/lucene/search/AssertingScorer.java b/lucene/test-framework/src/java/org/apache/lucene/search/AssertingScorer.java
index 0319ce9..01477f3 100644
--- a/lucene/test-framework/src/java/org/apache/lucene/search/AssertingScorer.java
+++ b/lucene/test-framework/src/java/org/apache/lucene/search/AssertingScorer.java
@@ -66,7 +66,7 @@ public class AssertingScorer extends Scorer {
}
@Override
- public void setMinCompetitiveScore(float score) {
+ public void setMinCompetitiveScore(float score) throws IOException {
assert scoreMode == ScoreMode.TOP_SCORES;
assert Float.isNaN(score) == false;
assert score >= minCompetitiveScore;