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 2019/01/25 08:16:39 UTC
[lucene-solr] branch master updated: LUCENE-8658: Fix illegal
assertion in WANDScorer.
This is an automated email from the ASF dual-hosted git repository.
jpountz pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git
The following commit(s) were added to refs/heads/master by this push:
new ef47582 LUCENE-8658: Fix illegal assertion in WANDScorer.
ef47582 is described below
commit ef47582fd5fcf0f444a925106b7ea354f8edbcfc
Author: Adrien Grand <jp...@gmail.com>
AuthorDate: Fri Jan 25 07:20:31 2019 +0100
LUCENE-8658: Fix illegal assertion in WANDScorer.
---
.../java/org/apache/lucene/search/WANDScorer.java | 16 +++++++----
.../org/apache/lucene/search/TestWANDScorer.java | 33 +++++++++++++++++-----
2 files changed, 36 insertions(+), 13 deletions(-)
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 c9a6746..a633f08 100644
--- a/lucene/core/src/java/org/apache/lucene/search/WANDScorer.java
+++ b/lucene/core/src/java/org/apache/lucene/search/WANDScorer.java
@@ -52,7 +52,7 @@ final class WANDScorer extends Scorer {
*/
static int scalingFactor(float f) {
if (f < 0) {
- throw new IllegalArgumentException("");
+ throw new IllegalArgumentException("Scores must be positive or null");
} else if (f == 0) {
return scalingFactor(Float.MIN_VALUE) - 1;
} else if (Float.isInfinite(f)) {
@@ -76,14 +76,18 @@ final class WANDScorer extends Scorer {
assert Float.isNaN(maxScore) == false;
assert maxScore >= 0;
- if (Float.isInfinite(maxScore)) {
- return (1L << 32) - 1; // means +Infinity in practice for this scorer
- }
-
// NOTE: because doubles have more amplitude than floats for the
// exponent, the scalb call produces an accurate value.
double scaled = Math.scalb((double) maxScore, scalingFactor);
- assert scaled <= 1 << 16 : scaled + " " + maxScore; // regular values of max_score go into 0..2^16
+
+ if (scaled > 1 << 16) {
+ // This happens if either maxScore is +Infty, or we have a scorer that
+ // returned +Infty as its maximum score over the whole range of doc IDs
+ // when computing the scaling factor in the constructor, and now returned
+ // a finite maximum score for a smaller range of doc IDs.
+ return (1L << 32) - 1; // means +Infinity in practice for this scorer
+ }
+
return (long) Math.ceil(scaled); // round up, cast is accurate since value is <= 2^16
}
diff --git a/lucene/core/src/test/org/apache/lucene/search/TestWANDScorer.java b/lucene/core/src/test/org/apache/lucene/search/TestWANDScorer.java
index 03285bd..7d1b2cb 100644
--- a/lucene/core/src/test/org/apache/lucene/search/TestWANDScorer.java
+++ b/lucene/core/src/test/org/apache/lucene/search/TestWANDScorer.java
@@ -270,7 +270,7 @@ public class TestWANDScorer extends LuceneTestCase {
for (int i = 0; i < numClauses; ++i) {
Query query = new TermQuery(new Term("foo", Integer.toString(start + i)));
if (random().nextBoolean()) {
- query = new InfiniteMaxScoreWrapperQuery(query);
+ query = new InfiniteMaxScoreWrapperQuery(query, numDocs / TestUtil.nextInt(random(), 1, 100));
}
builder.add(query, Occur.SHOULD);
}
@@ -292,13 +292,26 @@ public class TestWANDScorer extends LuceneTestCase {
private static class InfiniteMaxScoreWrapperScorer extends FilterScorer {
- InfiniteMaxScoreWrapperScorer(Scorer scorer) {
+ private final int maxRange;
+ private int lastShallowTarget = -1;
+
+ InfiniteMaxScoreWrapperScorer(Scorer scorer, int maxRange) {
super(scorer);
+ this.maxRange = maxRange;
+ }
+
+ @Override
+ public int advanceShallow(int target) throws IOException {
+ lastShallowTarget = target;
+ return in.advanceShallow(target);
}
@Override
public float getMaxScore(int upTo) throws IOException {
- return Float.POSITIVE_INFINITY;
+ if (upTo - Math.max(docID(), lastShallowTarget) >= maxRange) {
+ return Float.POSITIVE_INFINITY;
+ }
+ return in.getMaxScore(upTo);
}
}
@@ -306,9 +319,15 @@ public class TestWANDScorer extends LuceneTestCase {
private static class InfiniteMaxScoreWrapperQuery extends Query {
private final Query query;
+ private final int maxRange;
- InfiniteMaxScoreWrapperQuery(Query query) {
+ /**
+ * If asked for the maximum score over a range of doc IDs that is greater
+ * than or equal to maxRange, this query will return a maximum score of +Infty
+ */
+ InfiniteMaxScoreWrapperQuery(Query query, int maxRange) {
this.query = query;
+ this.maxRange = maxRange;
}
@Override
@@ -330,7 +349,7 @@ public class TestWANDScorer extends LuceneTestCase {
public Query rewrite(IndexReader reader) throws IOException {
Query rewritten = query.rewrite(reader);
if (rewritten != query) {
- return new InfiniteMaxScoreWrapperQuery(rewritten);
+ return new InfiniteMaxScoreWrapperQuery(rewritten, maxRange);
}
return super.rewrite(reader);
}
@@ -344,7 +363,7 @@ public class TestWANDScorer extends LuceneTestCase {
if (scorer == null) {
return null;
} else {
- return new InfiniteMaxScoreWrapperScorer(scorer);
+ return new InfiniteMaxScoreWrapperScorer(scorer, maxRange);
}
}
@@ -358,7 +377,7 @@ public class TestWANDScorer extends LuceneTestCase {
@Override
public Scorer get(long leadCost) throws IOException {
- return new InfiniteMaxScoreWrapperScorer(supplier.get(leadCost));
+ return new InfiniteMaxScoreWrapperScorer(supplier.get(leadCost), maxRange);
}
@Override