Skip to content
Browse files

clojure.lang.APersistentMap-like hashing for maps

Introduces a new function -- cljs.core/hash-imap -- which calculates a
hash for an IMap using the algorithm from c.l.APM, which is
independent of the ordering on map entries.

This is necessary so that the various map types hash to the same value
when equal, independent of insertion ordering and the like and without
sorting of keys.
  • Loading branch information...
1 parent 0b7d04b commit 6fd16df50bca7a6118693712e6918c70a64de255 @michalmarczyk michalmarczyk committed with David Nolen
Showing with 13 additions and 3 deletions.
  1. +13 −3 src/cljs/cljs/core.cljs
View
16 src/cljs/cljs/core.cljs
@@ -1177,6 +1177,16 @@ reduces them without incurring seq initialization"
(defn- hash-coll [coll]
(reduce #(hash-combine %1 (hash %2)) (hash (first coll)) (next coll)))
+(defn- hash-imap [m]
+ ;; a la clojure.lang.APersistentMap
+ (loop [h 0 s (seq m)]
+ (if s
+ (let [e (first s)]
+ (recur (mod (+ h (bit-xor (hash (key e)) (hash (val e))))
+ 4503599627370496)
+ (next s)))
+ h)))
+
(declare name)
(defn- extend-object!
@@ -2588,7 +2598,7 @@ reduces them without incurring seq initialization"
(-equiv [coll other] (equiv-map coll other))
IHash
- (-hash [coll] (hash-coll coll))
+ (-hash [coll] (hash-imap coll))
ISeqable
(-seq [coll]
@@ -2675,7 +2685,7 @@ reduces them without incurring seq initialization"
(-equiv [coll other] (equiv-map coll other))
IHash
- (-hash [coll] (hash-coll coll))
+ (-hash [coll] (hash-imap coll))
ISeqable
(-seq [coll]
@@ -3105,7 +3115,7 @@ reduces them without incurring seq initialization"
(-equiv [coll other] (equiv-map coll other))
IHash
- (-hash [coll] (hash-coll coll))
+ (-hash [coll] (hash-imap coll))
ISeqable
(-seq [coll]

0 comments on commit 6fd16df

Please sign in to comment.
Something went wrong with that request. Please try again.