diff options
author | Dominik Gruntz <dominik.gruntz@fhnw.ch> | 2012-05-09 15:01:25 +0200 |
---|---|---|
committer | Dominik Gruntz <dominik.gruntz@fhnw.ch> | 2012-05-09 15:01:25 +0200 |
commit | b5919100e785df58bde35bb24abe9d60b4da08a2 (patch) | |
tree | bfc40fc70e04624bf65d60a540b628cc934bba07 /src/library | |
parent | 58bb2d1bd2000ac3aa2c64b6c5dc56c91e911860 (diff) | |
download | scala-b5919100e785df58bde35bb24abe9d60b4da08a2.tar.gz scala-b5919100e785df58bde35bb24abe9d60b4da08a2.tar.bz2 scala-b5919100e785df58bde35bb24abe9d60b4da08a2.zip |
removes redundant hash implementation from BoxesRunTime.java
Diffstat (limited to 'src/library')
-rw-r--r-- | src/library/scala/runtime/BoxesRunTime.java | 61 | ||||
-rw-r--r-- | src/library/scala/runtime/ScalaRunTime.scala | 30 |
2 files changed, 28 insertions, 63 deletions
diff --git a/src/library/scala/runtime/BoxesRunTime.java b/src/library/scala/runtime/BoxesRunTime.java index 258a176671..0df196b2a6 100644 --- a/src/library/scala/runtime/BoxesRunTime.java +++ b/src/library/scala/runtime/BoxesRunTime.java @@ -203,67 +203,6 @@ public final class BoxesRunTime } } - /** Hashcode algorithm is driven by the requirements imposed - * by primitive equality semantics, namely that equal objects - * have equal hashCodes. The first priority are the integral/char - * types, which already have the same hashCodes for the same - * values except for Long. So Long's hashCode is altered to - * conform to Int's for all values in Int's range. - * - * Float is problematic because it's far too small to hold - * all the Ints, so for instance Int.MaxValue.toFloat claims - * to be == to each of the largest 64 Ints. There is no way - * to preserve equals/hashCode alignment without compromising - * the hashCode distribution, so Floats are only guaranteed - * to have the same hashCode for whole Floats in the range - * Short.MinValue to Short.MaxValue (2^16 total.) - * - * Double has its hashCode altered to match the entire Int range, - * but is not guaranteed beyond that. (But could/should it be? - * The hashCode is only 32 bits so this is a more tractable - * issue than Float's, but it might be better simply to exclude it.) - * - * Note: BigInt and BigDecimal, being arbitrary precision, could - * be made consistent with all other types for the Int range, but - * as yet have not. - * - * Note: Among primitives, Float.NaN != Float.NaN, but the boxed - * verisons are equal. This still needs reconciliation. - */ - public static int hashFromLong(java.lang.Long n) { - int iv = n.intValue(); - if (iv == n.longValue()) return iv; - else return n.hashCode(); - } - public static int hashFromDouble(java.lang.Double n) { - int iv = n.intValue(); - double dv = n.doubleValue(); - if (iv == dv) return iv; - - long lv = n.longValue(); - if (lv == dv) return java.lang.Long.valueOf(lv).hashCode(); - else return n.hashCode(); - } - public static int hashFromFloat(java.lang.Float n) { - int iv = n.intValue(); - float fv = n.floatValue(); - if (iv == fv) return iv; - - long lv = n.longValue(); - if (lv == fv) return java.lang.Long.valueOf(lv).hashCode(); - else return n.hashCode(); - } - public static int hashFromNumber(java.lang.Number n) { - if (n instanceof java.lang.Long) return hashFromLong((java.lang.Long)n); - else if (n instanceof java.lang.Double) return hashFromDouble((java.lang.Double)n); - else if (n instanceof java.lang.Float) return hashFromFloat((java.lang.Float)n); - else return n.hashCode(); - } - public static int hashFromObject(Object a) { - if (a instanceof Number) return hashFromNumber((Number)a); - else return a.hashCode(); - } - private static int unboxCharOrInt(Object arg1, int code) { if (code == CHAR) return ((java.lang.Character) arg1).charValue(); diff --git a/src/library/scala/runtime/ScalaRunTime.scala b/src/library/scala/runtime/ScalaRunTime.scala index a04fd23710..b3d99aa8d8 100644 --- a/src/library/scala/runtime/ScalaRunTime.scala +++ b/src/library/scala/runtime/ScalaRunTime.scala @@ -233,12 +233,39 @@ object ScalaRunTime { // // Note that these are the implementations called by ##, so they // must not call ## themselves. + // + // Hashcode algorithm is driven by the requirements imposed + // by primitive equality semantics, namely that equal objects + // have equal hashCodes. The first priority are the integral/char + // types, which already have the same hashCodes for the same + // values except for Long. So Long's hashCode is altered to + // conform to Int's for all values in Int's range. + // + // Float is problematic because it's far too small to hold + // all the Ints, so for instance Int.MaxValue.toFloat claims + // to be == to each of the largest 64 Ints. There is no way + // to preserve equals/hashCode alignment without compromising + // the hashCode distribution, so Floats are only guaranteed + // to have the same hashCode for whole Floats in the range + // Short.MinValue to Short.MaxValue (2^16 total.) + // + // Double has its hashCode altered to match the entire Int range, + // but is not guaranteed beyond that. (But could/should it be? + // The hashCode is only 32 bits so this is a more tractable + // issue than Float's, but it might be better simply to exclude it.) + // + // Note: BigInt and BigDecimal, being arbitrary precision, could + // be made consistent with all other types for the Int range, but + // as yet have not. + // + // Note: Among primitives, Float.NaN != Float.NaN, but the boxed + // verisons are equal. This still needs reconciliation. @inline def hash(x: Any): Int = x match { case null => 0 + case x: Long => hash(x) case x: Double => hash(x) case x: Float => hash(x) - case x: java.lang.Number => hash(x) case _ => x.hashCode } @@ -266,7 +293,6 @@ object ScalaRunTime { val high = (lv >>> 32).toInt low ^ (high + lowSign) } - @inline def hash(x: Number): Int = runtime.BoxesRunTime.hashFromNumber(x) // The remaining overloads are here for completeness, but the compiler // inlines these definitions directly so they're not generally used. |