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 2016/12/21 19:45:17 UTC

[2/3] lucene-solr:master: LUCENE-7594: Fixed point range queries on floating-point types to recommend using helpers for exclusive bounds that are consistent with Double.compare.

LUCENE-7594: Fixed point range queries on floating-point types to recommend using helpers for exclusive bounds that are consistent with Double.compare.


Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/18d53a43
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/18d53a43
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/18d53a43

Branch: refs/heads/master
Commit: 18d53a43f7b4536572ef98a94ec1d9b529084d1b
Parents: 5020ea2
Author: Adrien Grand <jp...@gmail.com>
Authored: Wed Dec 21 19:33:52 2016 +0100
Committer: Adrien Grand <jp...@gmail.com>
Committed: Wed Dec 21 20:44:56 2016 +0100

----------------------------------------------------------------------
 lucene/CHANGES.txt                              |  4 +++
 .../org/apache/lucene/document/DoublePoint.java | 30 ++++++++++++++++++--
 .../org/apache/lucene/document/FloatPoint.java  | 30 ++++++++++++++++++--
 .../apache/lucene/search/TestPointQueries.java  | 28 ++++++++++++++++++
 .../lucene/document/TestHalfFloatPoint.java     |  2 ++
 5 files changed, 90 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/18d53a43/lucene/CHANGES.txt
----------------------------------------------------------------------
diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt
index 2e2f9ab..912974d 100644
--- a/lucene/CHANGES.txt
+++ b/lucene/CHANGES.txt
@@ -109,6 +109,10 @@ Bug Fixes
   there are too many merges running and one of the merges hits a
   tragic exception (Joey Echeverria via Mike McCandless)
 
+* LUCENE-7594: Fixed point range queries on floating-point types to recommend
+  using helpers for exclusive bounds that are consistent with Double.compare.
+  (Adrien Grand, Dawid Weiss)
+
 Improvements
 
 * LUCENE-6824: TermAutomatonQuery now rewrites to TermQuery,

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/18d53a43/lucene/core/src/java/org/apache/lucene/document/DoublePoint.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/document/DoublePoint.java b/lucene/core/src/java/org/apache/lucene/document/DoublePoint.java
index 9a383a4..6547402 100644
--- a/lucene/core/src/java/org/apache/lucene/document/DoublePoint.java
+++ b/lucene/core/src/java/org/apache/lucene/document/DoublePoint.java
@@ -45,6 +45,32 @@ import org.apache.lucene.util.NumericUtils;
  */
 public final class DoublePoint extends Field {
 
+  /**
+   * Return the least double that compares greater than {@code d} consistently
+   * with {@link Double#compare}. The only difference with
+   * {@link Math#nextUp(double)} is that this method returns {@code +0d} when
+   * the argument is {@code -0d}.
+   */
+  public static double nextUp(double d) {
+    if (Double.doubleToLongBits(d) == 0x8000_0000_0000_0000L) { // -0d
+      return +0d;
+    }
+    return Math.nextUp(d);
+  }
+
+  /**
+   * Return the greatest double that compares less than {@code d} consistently
+   * with {@link Double#compare}. The only difference with
+   * {@link Math#nextDown(double)} is that this method returns {@code -0d} when
+   * the argument is {@code +0d}.
+   */
+  public static double nextDown(double d) {
+    if (Double.doubleToLongBits(d) == 0L) { // +0d
+      return -0f;
+    }
+    return Math.nextDown(d);
+  }
+
   private static FieldType getType(int numDims) {
     FieldType type = new FieldType();
     type.setDimensions(numDims, Double.BYTES);
@@ -164,8 +190,8 @@ public final class DoublePoint extends Field {
    * <p>
    * You can have half-open ranges (which are in fact &lt;/&le; or &gt;/&ge; queries)
    * by setting {@code lowerValue = Double.NEGATIVE_INFINITY} or {@code upperValue = Double.POSITIVE_INFINITY}.
-   * <p> Ranges are inclusive. For exclusive ranges, pass {@code Math#nextUp(lowerValue)}
-   * or {@code Math.nextDown(upperValue)}.
+   * <p> Ranges are inclusive. For exclusive ranges, pass {@link #nextUp(double) nextUp(lowerValue)}
+   * or {@link #nextUp(double) nextDown(upperValue)}.
    * <p>
    * Range comparisons are consistent with {@link Double#compareTo(Double)}.
    *

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/18d53a43/lucene/core/src/java/org/apache/lucene/document/FloatPoint.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/document/FloatPoint.java b/lucene/core/src/java/org/apache/lucene/document/FloatPoint.java
index 8d84269..0ec67fd 100644
--- a/lucene/core/src/java/org/apache/lucene/document/FloatPoint.java
+++ b/lucene/core/src/java/org/apache/lucene/document/FloatPoint.java
@@ -45,6 +45,32 @@ import org.apache.lucene.util.NumericUtils;
  */
 public final class FloatPoint extends Field {
 
+  /**
+   * Return the least float that compares greater than {@code f} consistently
+   * with {@link Float#compare}. The only difference with
+   * {@link Math#nextUp(float)} is that this method returns {@code +0f} when
+   * the argument is {@code -0f}.
+   */
+  public static float nextUp(float f) {
+    if (Float.floatToIntBits(f) == 0x8000_0000) { // -0f
+      return +0f;
+    }
+    return Math.nextUp(f);
+  }
+
+  /**
+   * Return the greatest float that compares less than {@code f} consistently
+   * with {@link Float#compare}. The only difference with
+   * {@link Math#nextDown(float)} is that this method returns {@code -0f} when
+   * the argument is {@code +0f}.
+   */
+  public static float nextDown(float f) {
+    if (Float.floatToIntBits(f) == 0) { // +0f
+      return -0f;
+    }
+    return Math.nextDown(f);
+  }
+
   private static FieldType getType(int numDims) {
     FieldType type = new FieldType();
     type.setDimensions(numDims, Float.BYTES);
@@ -164,8 +190,8 @@ public final class FloatPoint extends Field {
    * <p>
    * You can have half-open ranges (which are in fact &lt;/&le; or &gt;/&ge; queries)
    * by setting {@code lowerValue = Float.NEGATIVE_INFINITY} or {@code upperValue = Float.POSITIVE_INFINITY}.
-   * <p> Ranges are inclusive. For exclusive ranges, pass {@code Math#nextUp(lowerValue)}
-   * or {@code Math.nextDown(upperValue)}.
+   * <p> Ranges are inclusive. For exclusive ranges, pass {@link #nextUp(float) nextUp(lowerValue)}
+   * or {@link #nextUp(float) nextDown(upperValue)}.
    * <p>
    * Range comparisons are consistent with {@link Float#compareTo(Float)}.
    *

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/18d53a43/lucene/core/src/test/org/apache/lucene/search/TestPointQueries.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/test/org/apache/lucene/search/TestPointQueries.java b/lucene/core/src/test/org/apache/lucene/search/TestPointQueries.java
index 73b2813..5c66478 100644
--- a/lucene/core/src/test/org/apache/lucene/search/TestPointQueries.java
+++ b/lucene/core/src/test/org/apache/lucene/search/TestPointQueries.java
@@ -2052,4 +2052,32 @@ public class TestPointQueries extends LuceneTestCase {
                                               });
     assertEquals("lowerPoint has length=4 but upperPoint has different length=8", e.getMessage());
   }
+
+  public void testNextUp() {
+    assertTrue(Double.compare(0d, DoublePoint.nextUp(-0d)) == 0);
+    assertTrue(Double.compare(Double.MIN_VALUE, DoublePoint.nextUp(0d)) == 0);
+    assertTrue(Double.compare(Double.POSITIVE_INFINITY, DoublePoint.nextUp(Double.MAX_VALUE)) == 0);
+    assertTrue(Double.compare(Double.POSITIVE_INFINITY, DoublePoint.nextUp(Double.POSITIVE_INFINITY)) == 0);
+    assertTrue(Double.compare(-Double.MAX_VALUE, DoublePoint.nextUp(Double.NEGATIVE_INFINITY)) == 0);
+
+    assertTrue(Float.compare(0f, FloatPoint.nextUp(-0f)) == 0);
+    assertTrue(Float.compare(Float.MIN_VALUE, FloatPoint.nextUp(0f)) == 0);
+    assertTrue(Float.compare(Float.POSITIVE_INFINITY, FloatPoint.nextUp(Float.MAX_VALUE)) == 0);
+    assertTrue(Float.compare(Float.POSITIVE_INFINITY, FloatPoint.nextUp(Float.POSITIVE_INFINITY)) == 0);
+    assertTrue(Float.compare(-Float.MAX_VALUE, FloatPoint.nextUp(Float.NEGATIVE_INFINITY)) == 0);
+  }
+
+  public void testNextDown() {
+    assertTrue(Double.compare(-0d, DoublePoint.nextDown(0d)) == 0);
+    assertTrue(Double.compare(-Double.MIN_VALUE, DoublePoint.nextDown(-0d)) == 0);
+    assertTrue(Double.compare(Double.NEGATIVE_INFINITY, DoublePoint.nextDown(-Double.MAX_VALUE)) == 0);
+    assertTrue(Double.compare(Double.NEGATIVE_INFINITY, DoublePoint.nextDown(Double.NEGATIVE_INFINITY)) == 0);
+    assertTrue(Double.compare(Double.MAX_VALUE, DoublePoint.nextDown(Double.POSITIVE_INFINITY)) == 0);
+
+    assertTrue(Float.compare(-0f, FloatPoint.nextDown(0f)) == 0);
+    assertTrue(Float.compare(-Float.MIN_VALUE, FloatPoint.nextDown(-0f)) == 0);
+    assertTrue(Float.compare(Float.NEGATIVE_INFINITY, FloatPoint.nextDown(-Float.MAX_VALUE)) == 0);
+    assertTrue(Float.compare(Float.NEGATIVE_INFINITY, FloatPoint.nextDown(Float.NEGATIVE_INFINITY)) == 0);
+    assertTrue(Float.compare(Float.MAX_VALUE, FloatPoint.nextDown(Float.POSITIVE_INFINITY)) == 0);
+  }
 }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/18d53a43/lucene/sandbox/src/test/org/apache/lucene/document/TestHalfFloatPoint.java
----------------------------------------------------------------------
diff --git a/lucene/sandbox/src/test/org/apache/lucene/document/TestHalfFloatPoint.java b/lucene/sandbox/src/test/org/apache/lucene/document/TestHalfFloatPoint.java
index a24d992..0bcb3f8 100644
--- a/lucene/sandbox/src/test/org/apache/lucene/document/TestHalfFloatPoint.java
+++ b/lucene/sandbox/src/test/org/apache/lucene/document/TestHalfFloatPoint.java
@@ -229,6 +229,7 @@ public class TestHalfFloatPoint extends LuceneTestCase {
     // values that cannot be exactly represented as a half float
     assertEquals(HalfFloatPoint.nextUp(0f), HalfFloatPoint.nextUp(Float.MIN_VALUE), 0f);
     assertEquals(Float.floatToIntBits(-0f), Float.floatToIntBits(HalfFloatPoint.nextUp(-Float.MIN_VALUE)));
+    assertEquals(Float.floatToIntBits(0f), Float.floatToIntBits(HalfFloatPoint.nextUp(-0f)));
   }
 
   public void testNextDown() {
@@ -239,5 +240,6 @@ public class TestHalfFloatPoint extends LuceneTestCase {
     // values that cannot be exactly represented as a half float
     assertEquals(Float.floatToIntBits(0f), Float.floatToIntBits(HalfFloatPoint.nextDown(Float.MIN_VALUE)));
     assertEquals(HalfFloatPoint.nextDown(-0f), HalfFloatPoint.nextDown(-Float.MIN_VALUE), 0f);
+    assertEquals(Float.floatToIntBits(-0f), Float.floatToIntBits(HalfFloatPoint.nextDown(+0f)));
   }
 }