You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by mi...@apache.org on 2016/04/08 00:46:36 UTC

lucene-solr:master: LUCENE-7168: use center value on decode

Repository: lucene-solr
Updated Branches:
  refs/heads/master 5e4777346 -> 1848477bd


LUCENE-7168: use center value on decode


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

Branch: refs/heads/master
Commit: 1848477bd83ca3f45ffda0d15a2eee901adb90b6
Parents: 5e47773
Author: Mike McCandless <mi...@apache.org>
Authored: Thu Apr 7 18:48:47 2016 -0400
Committer: Mike McCandless <mi...@apache.org>
Committed: Thu Apr 7 18:48:47 2016 -0400

----------------------------------------------------------------------
 .../org/apache/lucene/spatial3d/Geo3DUtil.java  | 44 ++++++--------------
 .../apache/lucene/spatial3d/TestGeo3DPoint.java | 21 +---------
 2 files changed, 13 insertions(+), 52 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/1848477b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/Geo3DUtil.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/Geo3DUtil.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/Geo3DUtil.java
index 1ff56a7..f91a6f6 100644
--- a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/Geo3DUtil.java
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/Geo3DUtil.java
@@ -23,7 +23,7 @@ class Geo3DUtil {
   private static final double MAX_VALUE = PlanetModel.WGS84.getMaximumMagnitude();
   private static final int BITS = 32;
   private static final double MUL = (0x1L<<BITS)/(2*MAX_VALUE);
-  static final double DECODE = getNextSafeDouble(1/MUL);
+  static final double DECODE = 1/MUL;
   private static final int MIN_ENCODED_VALUE = encodeValue(-MAX_VALUE);
 
   public static int encodeValue(double x) {
@@ -33,6 +33,10 @@ class Geo3DUtil {
     if (x < -MAX_VALUE) {
       throw new IllegalArgumentException("value=" + x + " is out-of-bounds (less than than WGS84's -planetMax=" + -MAX_VALUE + ")");
     }
+    // the maximum possible value cannot be encoded without overflow
+    if (x == MAX_VALUE) {
+      x = Math.nextDown(x);
+    }
     long result = (long) Math.floor(x / DECODE);
     //System.out.println("    enc: " + x + " -> " + result);
     assert result >= Integer.MIN_VALUE;
@@ -41,35 +45,8 @@ class Geo3DUtil {
   }
 
   public static double decodeValue(int x) {
-    double result;
-    if (x == MIN_ENCODED_VALUE) {
-      // We must special case this, because -MAX_VALUE is not guaranteed to land precisely at a floor value, and we don't ever want to
-      // return a value outside of the planet's range (I think?).  The max value is "safe" because we floor during encode:
-      result = -MAX_VALUE;
-    } else {
-      result = x * DECODE;
-    }
-    assert result >= -MAX_VALUE && result <= MAX_VALUE;
-    return result;
-  }
-
-  /** Returns a double value >= x such that if you multiply that value by an int, and then
-   *  divide it by that int again, you get precisely the same value back */
-  private static double getNextSafeDouble(double x) {
-
-    // Move to double space:
-    long bits = Double.doubleToLongBits(x);
-
-    // Make sure we are beyond the actual maximum value:
-    bits += Integer.MAX_VALUE;
-
-    // Clear the bottom 32 bits:
-    bits &= ~((long) Integer.MAX_VALUE);
-
-    // Convert back to double:
-    double result = Double.longBitsToDouble(bits);
-    assert result > x;
-    return result;
+    // We decode to the center value; this keeps the encoding stable
+    return (x+0.5) * DECODE;
   }
 
   /** Returns smallest double that would encode to int x. */
@@ -81,7 +58,10 @@ class Geo3DUtil {
   /** Returns largest double that would encode to int x. */
   // NOTE: keep this package private!!
   static double decodeValueCeil(int x) {
-    assert x < Integer.MAX_VALUE;
-    return Math.nextDown((x+1) * DECODE);
+    if (x == Integer.MAX_VALUE) {
+      return MAX_VALUE;
+    } else {
+      return Math.nextDown((x+1) * DECODE);
+    }
   }
 }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/1848477b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/TestGeo3DPoint.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/TestGeo3DPoint.java b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/TestGeo3DPoint.java
index 5aaa835..14f749b 100644
--- a/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/TestGeo3DPoint.java
+++ b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/TestGeo3DPoint.java
@@ -728,7 +728,7 @@ public class TestGeo3DPoint extends LuceneTestCase {
 
   public void testToString() {
     Geo3DPoint point = new Geo3DPoint("point", 44.244272, 7.769736);
-    assertEquals("Geo3DPoint <point: x=0.7094263127744131 y=0.09679758888428691 z=0.6973564619016113>", point.toString());
+    assertEquals("Geo3DPoint <point: x=0.7094263130517758 y=0.09679758927665334 z=0.6973564618592686>", point.toString());
   }
 
   public void testShapeQueryToString() {
@@ -1078,25 +1078,6 @@ public class TestGeo3DPoint extends LuceneTestCase {
     }
   }
 
-  // Takes ~35 seconds on modern-ish 2015 dev box:
-  @Nightly
-  public void testEncodeIsStableFromIntSide() throws Exception {
-    double max = PlanetModel.WGS84.getMaximumMagnitude();
-
-    // We can't test the full space of ints (Integer.MIN_VALUE to Integer.MAX_VALUE) because not all ints are allowed:
-    int start = Geo3DUtil.encodeValue(-max);
-    int end = Geo3DUtil.encodeValue(max);
-    // This prints: 99.99997175764292
-    //System.out.println("PCTG INT SPACE USED: " + 100.*(((long) end)-(long) start)/(1L<<32));
-    for (int i=start;i<=end;i++) {
-      double x = Geo3DUtil.decodeValue(i);
-      assertEquals(i, Geo3DUtil.encodeValue(x));
-      if (i > start+1) {
-        assertEquals(Geo3DUtil.DECODE, x - Geo3DUtil.decodeValue(i-1), 0.0d);
-      }
-    }
-  }
-
   /** Clips the incoming value to the allowed min/max range before encoding, instead of throwing an exception. */
   private static int encodeValueLenient(double x) {
     double planetMax = PlanetModel.WGS84.getMaximumMagnitude();