From 8143fe3b638b5a6b60ee717d98046856a2d2f547 Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Wed, 10 Jul 2013 09:30:37 -0700 Subject: vecmath: introduce hash mixing helpers rather than a different float/double to bits helper Signed-off-by: Harvey Harrison --- src/javax/vecmath/AxisAngle4d.java | 10 ++--- src/javax/vecmath/AxisAngle4f.java | 10 ++--- src/javax/vecmath/GMatrix.java | 12 +++--- src/javax/vecmath/GVector.java | 4 +- src/javax/vecmath/Matrix3d.java | 20 ++++----- src/javax/vecmath/Matrix3f.java | 20 ++++----- src/javax/vecmath/Matrix4d.java | 34 +++++++-------- src/javax/vecmath/Matrix4f.java | 34 +++++++-------- src/javax/vecmath/Tuple2d.java | 6 +-- src/javax/vecmath/Tuple2f.java | 6 +-- src/javax/vecmath/Tuple3d.java | 8 ++-- src/javax/vecmath/Tuple3f.java | 8 ++-- src/javax/vecmath/Tuple4d.java | 10 ++--- src/javax/vecmath/Tuple4f.java | 10 ++--- src/javax/vecmath/VecMathUtil.java | 88 +++++++++++++------------------------- 15 files changed, 125 insertions(+), 155 deletions(-) (limited to 'src') diff --git a/src/javax/vecmath/AxisAngle4d.java b/src/javax/vecmath/AxisAngle4d.java index db59914..bd33ab0 100644 --- a/src/javax/vecmath/AxisAngle4d.java +++ b/src/javax/vecmath/AxisAngle4d.java @@ -524,11 +524,11 @@ public class AxisAngle4d implements java.io.Serializable, Cloneable { @Override public int hashCode() { long bits = 1L; - bits = 31L * bits + VecMathUtil.doubleToLongBits(x); - bits = 31L * bits + VecMathUtil.doubleToLongBits(y); - bits = 31L * bits + VecMathUtil.doubleToLongBits(z); - bits = 31L * bits + VecMathUtil.doubleToLongBits(angle); - return (int) (bits ^ (bits >> 32)); + bits = VecMathUtil.hashDoubleBits(bits, x); + bits = VecMathUtil.hashDoubleBits(bits, y); + bits = VecMathUtil.hashDoubleBits(bits, z); + bits = VecMathUtil.hashDoubleBits(bits, angle); + return VecMathUtil.hashFinish(bits); } /** diff --git a/src/javax/vecmath/AxisAngle4f.java b/src/javax/vecmath/AxisAngle4f.java index eb16fb4..5da30ab 100644 --- a/src/javax/vecmath/AxisAngle4f.java +++ b/src/javax/vecmath/AxisAngle4f.java @@ -520,11 +520,11 @@ public class AxisAngle4f implements java.io.Serializable, Cloneable { @Override public int hashCode() { long bits = 1L; - bits = 31L * bits + (long)VecMathUtil.floatToIntBits(x); - bits = 31L * bits + (long)VecMathUtil.floatToIntBits(y); - bits = 31L * bits + (long)VecMathUtil.floatToIntBits(z); - bits = 31L * bits + (long)VecMathUtil.floatToIntBits(angle); - return (int) (bits ^ (bits >> 32)); + bits = VecMathUtil.hashFloatBits(bits, x); + bits = VecMathUtil.hashFloatBits(bits, y); + bits = VecMathUtil.hashFloatBits(bits, z); + bits = VecMathUtil.hashFloatBits(bits, angle); + return VecMathUtil.hashFinish(bits); } /** diff --git a/src/javax/vecmath/GMatrix.java b/src/javax/vecmath/GMatrix.java index a38d6a4..8b6a1cc 100644 --- a/src/javax/vecmath/GMatrix.java +++ b/src/javax/vecmath/GMatrix.java @@ -1388,16 +1388,16 @@ public class GMatrix implements java.io.Serializable, Cloneable { public int hashCode() { long bits = 1L; - bits = 31L * bits + (long)nRow; - bits = 31L * bits + (long)nCol; + bits = VecMathUtil.hashLongBits(bits, nRow); + bits = VecMathUtil.hashLongBits(bits, nCol); for (int i = 0; i < nRow; i++) { - for (int j = 0; j < nCol; j++) { - bits = 31L * bits + VecMathUtil.doubleToLongBits(values[i][j]); - } + for (int j = 0; j < nCol; j++) { + bits = VecMathUtil.hashDoubleBits(bits, values[i][j]); + } } - return (int) (bits ^ (bits >> 32)); + return VecMathUtil.hashFinish(bits); } diff --git a/src/javax/vecmath/GVector.java b/src/javax/vecmath/GVector.java index f28db87..9cd1412 100644 --- a/src/javax/vecmath/GVector.java +++ b/src/javax/vecmath/GVector.java @@ -663,10 +663,10 @@ public class GVector implements java.io.Serializable, Cloneable { long bits = 1L; for (int i = 0; i < length; i++) { - bits = 31L * bits + VecMathUtil.doubleToLongBits(values[i]); + bits = VecMathUtil.hashDoubleBits(bits, values[i]); } - return (int) (bits ^ (bits >> 32)); + return VecMathUtil.hashFinish(bits); } diff --git a/src/javax/vecmath/Matrix3d.java b/src/javax/vecmath/Matrix3d.java index ad77c09..f0852aa 100644 --- a/src/javax/vecmath/Matrix3d.java +++ b/src/javax/vecmath/Matrix3d.java @@ -1986,16 +1986,16 @@ public class Matrix3d implements java.io.Serializable, Cloneable { @Override public int hashCode() { long bits = 1L; - bits = 31L * bits + VecMathUtil.doubleToLongBits(m00); - bits = 31L * bits + VecMathUtil.doubleToLongBits(m01); - bits = 31L * bits + VecMathUtil.doubleToLongBits(m02); - bits = 31L * bits + VecMathUtil.doubleToLongBits(m10); - bits = 31L * bits + VecMathUtil.doubleToLongBits(m11); - bits = 31L * bits + VecMathUtil.doubleToLongBits(m12); - bits = 31L * bits + VecMathUtil.doubleToLongBits(m20); - bits = 31L * bits + VecMathUtil.doubleToLongBits(m21); - bits = 31L * bits + VecMathUtil.doubleToLongBits(m22); - return (int) (bits ^ (bits >> 32)); + bits = VecMathUtil.hashDoubleBits(bits, m00); + bits = VecMathUtil.hashDoubleBits(bits, m01); + bits = VecMathUtil.hashDoubleBits(bits, m02); + bits = VecMathUtil.hashDoubleBits(bits, m10); + bits = VecMathUtil.hashDoubleBits(bits, m11); + bits = VecMathUtil.hashDoubleBits(bits, m12); + bits = VecMathUtil.hashDoubleBits(bits, m20); + bits = VecMathUtil.hashDoubleBits(bits, m21); + bits = VecMathUtil.hashDoubleBits(bits, m22); + return VecMathUtil.hashFinish(bits); } diff --git a/src/javax/vecmath/Matrix3f.java b/src/javax/vecmath/Matrix3f.java index 4f27128..c5f51db 100644 --- a/src/javax/vecmath/Matrix3f.java +++ b/src/javax/vecmath/Matrix3f.java @@ -1969,16 +1969,16 @@ public class Matrix3f implements java.io.Serializable, Cloneable { @Override public int hashCode() { long bits = 1L; - bits = 31L * bits + (long)VecMathUtil.floatToIntBits(m00); - bits = 31L * bits + (long)VecMathUtil.floatToIntBits(m01); - bits = 31L * bits + (long)VecMathUtil.floatToIntBits(m02); - bits = 31L * bits + (long)VecMathUtil.floatToIntBits(m10); - bits = 31L * bits + (long)VecMathUtil.floatToIntBits(m11); - bits = 31L * bits + (long)VecMathUtil.floatToIntBits(m12); - bits = 31L * bits + (long)VecMathUtil.floatToIntBits(m20); - bits = 31L * bits + (long)VecMathUtil.floatToIntBits(m21); - bits = 31L * bits + (long)VecMathUtil.floatToIntBits(m22); - return (int) (bits ^ (bits >> 32)); + bits = VecMathUtil.hashFloatBits(bits, m00); + bits = VecMathUtil.hashFloatBits(bits, m01); + bits = VecMathUtil.hashFloatBits(bits, m02); + bits = VecMathUtil.hashFloatBits(bits, m10); + bits = VecMathUtil.hashFloatBits(bits, m11); + bits = VecMathUtil.hashFloatBits(bits, m12); + bits = VecMathUtil.hashFloatBits(bits, m20); + bits = VecMathUtil.hashFloatBits(bits, m21); + bits = VecMathUtil.hashFloatBits(bits, m22); + return VecMathUtil.hashFinish(bits); } diff --git a/src/javax/vecmath/Matrix4d.java b/src/javax/vecmath/Matrix4d.java index 783b30c..1e191f8 100644 --- a/src/javax/vecmath/Matrix4d.java +++ b/src/javax/vecmath/Matrix4d.java @@ -3076,23 +3076,23 @@ public class Matrix4d implements java.io.Serializable, Cloneable { @Override public int hashCode() { long bits = 1L; - bits = 31L * bits + VecMathUtil.doubleToLongBits(m00); - bits = 31L * bits + VecMathUtil.doubleToLongBits(m01); - bits = 31L * bits + VecMathUtil.doubleToLongBits(m02); - bits = 31L * bits + VecMathUtil.doubleToLongBits(m03); - bits = 31L * bits + VecMathUtil.doubleToLongBits(m10); - bits = 31L * bits + VecMathUtil.doubleToLongBits(m11); - bits = 31L * bits + VecMathUtil.doubleToLongBits(m12); - bits = 31L * bits + VecMathUtil.doubleToLongBits(m13); - bits = 31L * bits + VecMathUtil.doubleToLongBits(m20); - bits = 31L * bits + VecMathUtil.doubleToLongBits(m21); - bits = 31L * bits + VecMathUtil.doubleToLongBits(m22); - bits = 31L * bits + VecMathUtil.doubleToLongBits(m23); - bits = 31L * bits + VecMathUtil.doubleToLongBits(m30); - bits = 31L * bits + VecMathUtil.doubleToLongBits(m31); - bits = 31L * bits + VecMathUtil.doubleToLongBits(m32); - bits = 31L * bits + VecMathUtil.doubleToLongBits(m33); - return (int) (bits ^ (bits >> 32)); + bits = VecMathUtil.hashDoubleBits(bits, m00); + bits = VecMathUtil.hashDoubleBits(bits, m01); + bits = VecMathUtil.hashDoubleBits(bits, m02); + bits = VecMathUtil.hashDoubleBits(bits, m03); + bits = VecMathUtil.hashDoubleBits(bits, m10); + bits = VecMathUtil.hashDoubleBits(bits, m11); + bits = VecMathUtil.hashDoubleBits(bits, m12); + bits = VecMathUtil.hashDoubleBits(bits, m13); + bits = VecMathUtil.hashDoubleBits(bits, m20); + bits = VecMathUtil.hashDoubleBits(bits, m21); + bits = VecMathUtil.hashDoubleBits(bits, m22); + bits = VecMathUtil.hashDoubleBits(bits, m23); + bits = VecMathUtil.hashDoubleBits(bits, m30); + bits = VecMathUtil.hashDoubleBits(bits, m31); + bits = VecMathUtil.hashDoubleBits(bits, m32); + bits = VecMathUtil.hashDoubleBits(bits, m33); + return VecMathUtil.hashFinish(bits); } diff --git a/src/javax/vecmath/Matrix4f.java b/src/javax/vecmath/Matrix4f.java index 5d29c81..3a54909 100644 --- a/src/javax/vecmath/Matrix4f.java +++ b/src/javax/vecmath/Matrix4f.java @@ -2836,23 +2836,23 @@ public class Matrix4f implements java.io.Serializable, Cloneable { @Override public int hashCode() { long bits = 1L; - bits = 31L * bits + (long)VecMathUtil.floatToIntBits(m00); - bits = 31L * bits + (long)VecMathUtil.floatToIntBits(m01); - bits = 31L * bits + (long)VecMathUtil.floatToIntBits(m02); - bits = 31L * bits + (long)VecMathUtil.floatToIntBits(m03); - bits = 31L * bits + (long)VecMathUtil.floatToIntBits(m10); - bits = 31L * bits + (long)VecMathUtil.floatToIntBits(m11); - bits = 31L * bits + (long)VecMathUtil.floatToIntBits(m12); - bits = 31L * bits + (long)VecMathUtil.floatToIntBits(m13); - bits = 31L * bits + (long)VecMathUtil.floatToIntBits(m20); - bits = 31L * bits + (long)VecMathUtil.floatToIntBits(m21); - bits = 31L * bits + (long)VecMathUtil.floatToIntBits(m22); - bits = 31L * bits + (long)VecMathUtil.floatToIntBits(m23); - bits = 31L * bits + (long)VecMathUtil.floatToIntBits(m30); - bits = 31L * bits + (long)VecMathUtil.floatToIntBits(m31); - bits = 31L * bits + (long)VecMathUtil.floatToIntBits(m32); - bits = 31L * bits + (long)VecMathUtil.floatToIntBits(m33); - return (int) (bits ^ (bits >> 32)); + bits = VecMathUtil.hashFloatBits(bits, m00); + bits = VecMathUtil.hashFloatBits(bits, m01); + bits = VecMathUtil.hashFloatBits(bits, m02); + bits = VecMathUtil.hashFloatBits(bits, m03); + bits = VecMathUtil.hashFloatBits(bits, m10); + bits = VecMathUtil.hashFloatBits(bits, m11); + bits = VecMathUtil.hashFloatBits(bits, m12); + bits = VecMathUtil.hashFloatBits(bits, m13); + bits = VecMathUtil.hashFloatBits(bits, m20); + bits = VecMathUtil.hashFloatBits(bits, m21); + bits = VecMathUtil.hashFloatBits(bits, m22); + bits = VecMathUtil.hashFloatBits(bits, m23); + bits = VecMathUtil.hashFloatBits(bits, m30); + bits = VecMathUtil.hashFloatBits(bits, m31); + bits = VecMathUtil.hashFloatBits(bits, m32); + bits = VecMathUtil.hashFloatBits(bits, m33); + return VecMathUtil.hashFinish(bits); } diff --git a/src/javax/vecmath/Tuple2d.java b/src/javax/vecmath/Tuple2d.java index 2b60b2a..673bfb2 100644 --- a/src/javax/vecmath/Tuple2d.java +++ b/src/javax/vecmath/Tuple2d.java @@ -290,9 +290,9 @@ public abstract class Tuple2d implements java.io.Serializable, Cloneable { @Override public int hashCode() { long bits = 1L; - bits = 31L * bits + VecMathUtil.doubleToLongBits(x); - bits = 31L * bits + VecMathUtil.doubleToLongBits(y); - return (int) (bits ^ (bits >> 32)); + bits = VecMathUtil.hashDoubleBits(bits, x); + bits = VecMathUtil.hashDoubleBits(bits, y); + return VecMathUtil.hashFinish(bits); } diff --git a/src/javax/vecmath/Tuple2f.java b/src/javax/vecmath/Tuple2f.java index 3071485..d5b72d8 100644 --- a/src/javax/vecmath/Tuple2f.java +++ b/src/javax/vecmath/Tuple2f.java @@ -292,9 +292,9 @@ public abstract class Tuple2f implements java.io.Serializable, Cloneable { @Override public int hashCode() { long bits = 1L; - bits = 31L * bits + (long)VecMathUtil.floatToIntBits(x); - bits = 31L * bits + (long)VecMathUtil.floatToIntBits(y); - return (int) (bits ^ (bits >> 32)); + bits = VecMathUtil.hashFloatBits(bits, x); + bits = VecMathUtil.hashFloatBits(bits, y); + return VecMathUtil.hashFinish(bits); } diff --git a/src/javax/vecmath/Tuple3d.java b/src/javax/vecmath/Tuple3d.java index bf87e60..c02eed1 100644 --- a/src/javax/vecmath/Tuple3d.java +++ b/src/javax/vecmath/Tuple3d.java @@ -339,10 +339,10 @@ public abstract class Tuple3d implements java.io.Serializable, Cloneable { @Override public int hashCode() { long bits = 1L; - bits = 31L * bits + VecMathUtil.doubleToLongBits(x); - bits = 31L * bits + VecMathUtil.doubleToLongBits(y); - bits = 31L * bits + VecMathUtil.doubleToLongBits(z); - return (int) (bits ^ (bits >> 32)); + bits = VecMathUtil.hashDoubleBits(bits, x); + bits = VecMathUtil.hashDoubleBits(bits, y); + bits = VecMathUtil.hashDoubleBits(bits, z); + return VecMathUtil.hashFinish(bits); } diff --git a/src/javax/vecmath/Tuple3f.java b/src/javax/vecmath/Tuple3f.java index d4be6a9..28943ee 100644 --- a/src/javax/vecmath/Tuple3f.java +++ b/src/javax/vecmath/Tuple3f.java @@ -405,10 +405,10 @@ public abstract class Tuple3f implements java.io.Serializable, Cloneable { @Override public int hashCode() { long bits = 1L; - bits = 31L * bits + (long)VecMathUtil.floatToIntBits(x); - bits = 31L * bits + (long)VecMathUtil.floatToIntBits(y); - bits = 31L * bits + (long)VecMathUtil.floatToIntBits(z); - return (int) (bits ^ (bits >> 32)); + bits = VecMathUtil.hashFloatBits(bits, x); + bits = VecMathUtil.hashFloatBits(bits, y); + bits = VecMathUtil.hashFloatBits(bits, z); + return VecMathUtil.hashFinish(bits); } diff --git a/src/javax/vecmath/Tuple4d.java b/src/javax/vecmath/Tuple4d.java index f06bf7d..d5269f0 100644 --- a/src/javax/vecmath/Tuple4d.java +++ b/src/javax/vecmath/Tuple4d.java @@ -452,11 +452,11 @@ public abstract class Tuple4d implements java.io.Serializable, Cloneable { @Override public int hashCode() { long bits = 1L; - bits = 31L * bits + VecMathUtil.doubleToLongBits(x); - bits = 31L * bits + VecMathUtil.doubleToLongBits(y); - bits = 31L * bits + VecMathUtil.doubleToLongBits(z); - bits = 31L * bits + VecMathUtil.doubleToLongBits(w); - return (int) (bits ^ (bits >> 32)); + bits = VecMathUtil.hashDoubleBits(bits, x); + bits = VecMathUtil.hashDoubleBits(bits, y); + bits = VecMathUtil.hashDoubleBits(bits, z); + bits = VecMathUtil.hashDoubleBits(bits, w); + return VecMathUtil.hashFinish(bits); } diff --git a/src/javax/vecmath/Tuple4f.java b/src/javax/vecmath/Tuple4f.java index 44cd8e3..ae2205a 100644 --- a/src/javax/vecmath/Tuple4f.java +++ b/src/javax/vecmath/Tuple4f.java @@ -438,11 +438,11 @@ public abstract class Tuple4f implements java.io.Serializable, Cloneable { @Override public int hashCode() { long bits = 1L; - bits = 31L * bits + (long)VecMathUtil.floatToIntBits(x); - bits = 31L * bits + (long)VecMathUtil.floatToIntBits(y); - bits = 31L * bits + (long)VecMathUtil.floatToIntBits(z); - bits = 31L * bits + (long)VecMathUtil.floatToIntBits(w); - return (int) (bits ^ (bits >> 32)); + bits = VecMathUtil.hashFloatBits(bits, x); + bits = VecMathUtil.hashFloatBits(bits, y); + bits = VecMathUtil.hashFloatBits(bits, z); + bits = VecMathUtil.hashFloatBits(bits, w); + return VecMathUtil.hashFinish(bits); } diff --git a/src/javax/vecmath/VecMathUtil.java b/src/javax/vecmath/VecMathUtil.java index 5e1503f..5bc5b53 100644 --- a/src/javax/vecmath/VecMathUtil.java +++ b/src/javax/vecmath/VecMathUtil.java @@ -31,68 +31,38 @@ package javax.vecmath; * objects containing float or double values. This fixes Issue 36. */ class VecMathUtil { - /** - * Returns the representation of the specified floating-point - * value according to the IEEE 754 floating-point "single format" - * bit layout, after first mapping -0.0 to 0.0. This method is - * identical to Float.floatToIntBits(float) except that an integer - * value of 0 is returned for a floating-point value of - * -0.0f. This is done for the purpose of computing a hash code - * that satisfies the contract of hashCode() and equals(). The - * equals() method in each vecmath class does a pair-wise "==" - * test on each floating-point field in the class (e.g., x, y, and - * z for a Tuple3f). Since 0.0f == -0.0f returns true, - * we must also return the same hash code for two objects, one of - * which has a field with a value of -0.0f and the other of which - * has a cooresponding field with a value of 0.0f. - * - * @param f an input floating-point number - * @return the integer bits representing that floating-point - * number, after first mapping -0.0f to 0.0f - */ - static int floatToIntBits(float f) { - // Check for +0 or -0 - if (f == 0.0f) { - return 0; - } - else { - return Float.floatToIntBits(f); - } - } +/** + * Do not construct an instance of this class. + */ +private VecMathUtil() {} - /** - * Returns the representation of the specified floating-point - * value according to the IEEE 754 floating-point "double format" - * bit layout, after first mapping -0.0 to 0.0. This method is - * identical to Double.doubleToLongBits(double) except that an - * integer value of 0L is returned for a floating-point value of - * -0.0. This is done for the purpose of computing a hash code - * that satisfies the contract of hashCode() and equals(). The - * equals() method in each vecmath class does a pair-wise "==" - * test on each floating-point field in the class (e.g., x, y, and - * z for a Tuple3d). Since 0.0 == -0.0 returns true, we - * must also return the same hash code for two objects, one of - * which has a field with a value of -0.0 and the other of which - * has a cooresponding field with a value of 0.0. - * - * @param d an input double precision floating-point number - * @return the integer bits representing that floating-point - * number, after first mapping -0.0f to 0.0f - */ - static long doubleToLongBits(double d) { - // Check for +0 or -0 - if (d == 0.0) { - return 0L; + static final long hashLongBits(long hash, long l) { + hash *= 31L; + return hash + l; } - else { - return Double.doubleToLongBits(d); + + static final long hashFloatBits(long hash, float f) { + hash *= 31L; + // Treat 0.0d and -0.0d the same (all zero bits) + if (f == 0.0f) + return hash; + + return hash + Float.floatToIntBits(f); } - } + static final long hashDoubleBits(long hash, double d) { + hash *= 31L; + // Treat 0.0d and -0.0d the same (all zero bits) + if (d == 0.0d) + return hash; + + return hash + Double.doubleToLongBits(d); + } - /** - * Do not construct an instance of this class. - */ - private VecMathUtil() { - } + /** + * Return an integer hash from a long by mixing it with itself. + */ + static final int hashFinish(long hash) { + return (int)(hash ^ (hash >> 32)); + } } -- cgit v1.2.3