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:38 UTC

[lucene-solr] branch branch_8x 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 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 5286439  LUCENE-8658: Fix illegal assertion in WANDScorer.
5286439 is described below

commit 5286439fb93cd88ad79181983202c7ac3cff6711
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