From 7870b26e7bff3feba08a7af76c3c870c6b2e9fc5 Mon Sep 17 00:00:00 2001 From: Kang Xiao Date: Tue, 8 Jan 2013 00:04:22 +0800 Subject: [PATCH 1/3] use java.util.Arrays.deepHashCode() instead of List.hashCode() for tuple hash code --- src/clj/backtype/storm/tuple.clj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/clj/backtype/storm/tuple.clj b/src/clj/backtype/storm/tuple.clj index 66a0de6aa7..2c41a434b0 100644 --- a/src/clj/backtype/storm/tuple.clj +++ b/src/clj/backtype/storm/tuple.clj @@ -5,4 +5,4 @@ (bootstrap) (defn list-hash-code [^List alist] - (.hashCode alist)) + (java.util.Arrays/deepHashCode (.toArray alist))) From b846ea13b75e1ac0ee2aa9289b5c6d88b9a55b3a Mon Sep 17 00:00:00 2001 From: Kang Xiao Date: Thu, 14 Nov 2013 17:20:45 +0800 Subject: [PATCH 2/3] implement deep-hash-code in clojure --- storm-core/src/clj/backtype/storm/tuple.clj | 30 ++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/storm-core/src/clj/backtype/storm/tuple.clj b/storm-core/src/clj/backtype/storm/tuple.clj index 2c41a434b0..4bcd6e1819 100644 --- a/storm-core/src/clj/backtype/storm/tuple.clj +++ b/storm-core/src/clj/backtype/storm/tuple.clj @@ -4,5 +4,33 @@ (bootstrap) +(def ARRAY-TYPES-MAP + { + (type (to-array [])) nil + (type (byte-array 0)) nil + (type (char-array 0)) nil + (type (short-array 0)) nil + (type (int-array 0)) nil + (type (long-array 0)) nil + (type (float-array 0)) nil + (type (double-array 0)) nil + (type (boolean-array 0)) nil + }) + +(defn deep-hash-code [alist] + "deep hash code based on array/list content. + it's the same as java.util.Arrays.deepHashCode(), + but without convert a list to array to avoid copy." + (reduce + #(.intValue (+ (.intValue (* 31 %1)) (hash-code %2))) + 1 alist)) + +(defn hash-code [obj] + (let [t (type obj)] + (if (contains? ARRAY-TYPES-MAP t) + (deep-hash-code obj) + (.hashCode obj)))) + (defn list-hash-code [^List alist] - (java.util.Arrays/deepHashCode (.toArray alist))) + (deep-hash-code alist)) + From 92e30befcd9be3abe28716b473df222e07f95841 Mon Sep 17 00:00:00 2001 From: Kang Xiao Date: Sat, 16 Nov 2013 18:56:53 +0800 Subject: [PATCH 3/3] fix according to review comments --- storm-core/src/clj/backtype/storm/tuple.clj | 32 ++++++++++++--------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/storm-core/src/clj/backtype/storm/tuple.clj b/storm-core/src/clj/backtype/storm/tuple.clj index 4bcd6e1819..7437c954a2 100644 --- a/storm-core/src/clj/backtype/storm/tuple.clj +++ b/storm-core/src/clj/backtype/storm/tuple.clj @@ -4,30 +4,34 @@ (bootstrap) -(def ARRAY-TYPES-MAP - { - (type (to-array [])) nil - (type (byte-array 0)) nil - (type (char-array 0)) nil - (type (short-array 0)) nil - (type (int-array 0)) nil - (type (long-array 0)) nil - (type (float-array 0)) nil - (type (double-array 0)) nil - (type (boolean-array 0)) nil +(def ARRAY-TYPES + #{ + (type (to-array [])) + (type (byte-array 0)) + (type (char-array 0)) + (type (short-array 0)) + (type (int-array 0)) + (type (long-array 0)) + (type (float-array 0)) + (type (double-array 0)) + (type (boolean-array 0)) }) +(declare hash-code) + (defn deep-hash-code [alist] "deep hash code based on array/list content. it's the same as java.util.Arrays.deepHashCode(), - but without convert a list to array to avoid copy." + but without convert a list to array to avoid copy. + + use unchecked-* to make sure use int instead of long." (reduce - #(.intValue (+ (.intValue (* 31 %1)) (hash-code %2))) + #(unchecked-add-int (unchecked-multiply-int 31 %1) (hash-code %2)) 1 alist)) (defn hash-code [obj] (let [t (type obj)] - (if (contains? ARRAY-TYPES-MAP t) + (if (contains? ARRAY-TYPES t) (deep-hash-code obj) (.hashCode obj))))