Skip to content

Commit 6ed5857

Browse files
committed
align string, keyword & symbol hashing with Clojure 1.6.0. fix reduce-kv
test which had assumptions about kv order
1 parent 6a19be8 commit 6ed5857

File tree

3 files changed

+39
-44
lines changed

3 files changed

+39
-44
lines changed

src/clj/cljs/compiler.clj

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -195,14 +195,6 @@
195195
(let [[_ flags pattern] (re-find #"^(?:\(\?([idmsux]*)\))?(.*)" (str x))]
196196
(emits \/ (.replaceAll (re-matcher #"/" pattern) "\\\\/") \/ flags))))
197197

198-
(def ^:const goog-hash-max 0x100000000)
199-
200-
(defn goog-string-hash [s]
201-
(reduce
202-
(fn [r c]
203-
(mod (+ (* 31 r) (int c)) goog-hash-max))
204-
0 s))
205-
206198
(defmethod emit-constant clojure.lang.Keyword [x]
207199
(if (-> @env/*compiler* :opts :emit-constants)
208200
(let [value (-> @env/*compiler* ::ana/constant-table x)]
@@ -218,10 +210,7 @@
218210
(str ns "/" name)
219211
name))
220212
(emits ",")
221-
(emit-constant (+ (clojure.lang.Util/hashCombine
222-
(unchecked-int (goog-string-hash ns))
223-
(unchecked-int (goog-string-hash name)))
224-
0x9e3779b9))
213+
(emit-constant (hash x))
225214
(emits ")"))))
226215

227216
(defmethod emit-constant clojure.lang.Symbol [x]
@@ -237,9 +226,7 @@
237226
(emits ",")
238227
(emit-constant symstr)
239228
(emits ",")
240-
(emit-constant (clojure.lang.Util/hashCombine
241-
(unchecked-int (goog-string-hash ns))
242-
(unchecked-int (goog-string-hash name))))
229+
(emit-constant (hash x))
243230
(emits ",")
244231
(emit-constant nil)
245232
(emits ")")))

src/cljs/cljs/core.cljs

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -470,22 +470,24 @@
470470
(def string-hash-cache-count 0)
471471

472472
;;http://hg.openjdk.java.net/jdk7u/jdk7u6/jdk/file/8c2c5d63a17e/src/share/classes/java/lang/String.java
473-
(defn hash-string [s]
474-
(let [len (alength s)]
475-
(if (pos? len)
476-
(loop [i 0 hash 0]
477-
(if (< i len)
478-
(recur (inc i) (+ (imul 31 hash) (.charCodeAt s i)))
479-
hash))
480-
0)))
473+
(defn hash-string* [s]
474+
(if-not (nil? s)
475+
(let [len (alength s)]
476+
(if (pos? len)
477+
(loop [i 0 hash 0]
478+
(if (< i len)
479+
(recur (inc i) (+ (imul 31 hash) (.charCodeAt s i)))
480+
hash))
481+
0))
482+
0))
481483

482484
(defn add-to-string-hash-cache [k]
483-
(let [h (goog.string/hashCode k)]
485+
(let [h (hash-string* k)]
484486
(aset string-hash-cache k h)
485487
(set! string-hash-cache-count (inc string-hash-cache-count))
486488
h))
487489

488-
(defn check-string-hash-cache [k]
490+
(defn hash-string [k]
489491
(when (> string-hash-cache-count 255)
490492
(set! string-hash-cache (js-obj))
491493
(set! string-hash-cache-count 0))
@@ -507,7 +509,7 @@
507509
(false? o) 0
508510

509511
(string? o)
510-
(check-string-hash-cache o)
512+
(m3-hash-int (hash-string o))
511513

512514
(nil? o) 0
513515

@@ -528,7 +530,9 @@
528530
(instance? Symbol x))
529531

530532
(defn- hash-symbol [sym]
531-
(hash-combine (hash (.-ns sym)) (hash (.-name sym))))
533+
(hash-combine
534+
(m3-hash-unencoded-chars (.-name sym))
535+
(hash-string (.-ns sym))))
532536

533537
(defn- compare-symbols [a b]
534538
(cond
@@ -2243,6 +2247,9 @@ reduces them without incurring seq initialization"
22432247
(defn ^boolean list? [x]
22442248
(satisfies? IList x))
22452249

2250+
(defn hash-keyword [k]
2251+
(+ (hash-symbol k) 0x9e3779b9))
2252+
22462253
(deftype Keyword [ns name fqn ^:mutable _hash]
22472254
Object
22482255
(toString [_] (str ":" fqn))
@@ -2259,14 +2266,8 @@ reduces them without incurring seq initialization"
22592266
(get coll kw not-found))
22602267

22612268
IHash
2262-
(-hash [_]
2263-
; This was checking if _hash == -1, should it stay that way?
2264-
(if (nil? _hash)
2265-
(do
2266-
(set! _hash (+ (hash-combine (hash ns) (hash name))
2267-
0x9e3779b9))
2268-
_hash)
2269-
_hash))
2269+
(-hash [this]
2270+
(caching-hash this hash-keyword _hash))
22702271

22712272
INamed
22722273
(-name [_] name)

test/cljs/cljs/core_test.cljs

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1835,16 +1835,23 @@
18351835

18361836
;; Test builtin implementations of IKVReduce
18371837
(letfn [(kvr-test [data expect]
1838-
(assert (= :reduced (reduce-kv (fn [_ _ _] (reduced :reduced))
1839-
[] data)))
1840-
(assert (= expect (reduce-kv (fn [r k v] (-> r (conj k) (conj v)))
1841-
[] data))))]
1842-
(kvr-test (obj-map :k0 :v0 :k1 :v1) [:k0 :v0 :k1 :v1])
1843-
(kvr-test (hash-map :k0 :v0 :k1 :v1) [:k0 :v0 :k1 :v1])
1844-
(kvr-test (array-map :k0 :v0 :k1 :v1) [:k0 :v0 :k1 :v1])
1845-
(kvr-test [:v0 :v1] [0 :v0 1 :v1]))
1838+
(assert
1839+
(= :reduced
1840+
(reduce-kv
1841+
(fn [_ _ _] (reduced :reduced))
1842+
[] data)))
1843+
(assert
1844+
(= (sort expect)
1845+
(sort
1846+
(reduce-kv
1847+
(fn [r k v] (-> r (conj [k v])))
1848+
[] data)))))]
1849+
(kvr-test (obj-map :k0 :v0 :k1 :v1) [[:k0 :v0] [:k1 :v1]])
1850+
(kvr-test (hash-map :k0 :v0 :k1 :v1) [[:k0 :v0] [:k1 :v1]])
1851+
(kvr-test (array-map :k0 :v0 :k1 :v1) [[:k0 :v0] [:k1 :v1]])
1852+
(kvr-test [:v0 :v1] [[0 :v0] [1 :v1]]))
18461853
(assert (= {:init :val} (reduce-kv assoc {:init :val} nil)))
1847-
1854+
18481855
;; data conveying exception
18491856
(assert (= {:foo 1}
18501857
(try (throw (ex-info "asdf" {:foo 1}))

0 commit comments

Comments
 (0)