Skip to content

Commit 2995007

Browse files
committed
Added IHash support for PersistentVector and associated node types
1 parent 12483c6 commit 2995007

File tree

2 files changed

+42
-36
lines changed

2 files changed

+42
-36
lines changed

src/cljc/cljc/core.cljc

Lines changed: 38 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -994,14 +994,16 @@ reduces them without incurring seq initialization"
994994
(bit-shift-right seed 2))))
995995

996996
(defn- hash-coll [coll]
997-
(reduce #(hash-combine %1 (-hash %2)) (-hash (first coll)) (next coll)))
997+
(reduce #(hash-combine %1 (hash %2)) (hash (first coll)) (next coll)))
998+
999+
(declare key val)
9981000

9991001
(defn- hash-imap [m]
10001002
;; a la clojure.lang.APersistentMap
10011003
(loop [h 0 s (seq m)]
10021004
(if s
10031005
(let [e (first s)]
1004-
(recur (mod (+ h (bit-xor (-hash (-key e)) (-hash (-val e))))
1006+
(recur (mod (+ h (bit-xor (hash (key e)) (hash (val e))))
10051007
4503599627370496)
10061008
(next s)))
10071009
h)))
@@ -1344,9 +1346,9 @@ reduces them without incurring seq initialization"
13441346
tv-push-tail editable-array-for TransientVector tv-editable-root
13451347
tv-editable-tail)
13461348

1347-
(deftype PersistentVector [meta cnt shift root tail]
1349+
(deftype PersistentVector [meta cnt shift root tail ^:mutable __hash]
13481350
IWithMeta
1349-
(-with-meta [coll meta] (PersistentVector. meta cnt shift root tail))
1351+
(-with-meta [coll meta] (PersistentVector. meta cnt shift root tail __hash))
13501352

13511353
IMeta
13521354
(-meta [coll] meta)
@@ -1361,7 +1363,7 @@ reduces them without incurring seq initialization"
13611363
new-tail (make-array (inc tail-len))]
13621364
(array-copy tail new-tail)
13631365
(aset new-tail tail-len o)
1364-
(PersistentVector. meta (inc cnt) shift root new-tail))
1366+
(PersistentVector. meta (inc cnt) shift root new-tail nil))
13651367
(let [root-overflow? (> (bit-shift-right-zero-fill cnt 5) (bit-shift-left 1 shift))
13661368
new-shift (if root-overflow? (+ shift 5) shift)
13671369
new-root (if root-overflow?
@@ -1372,7 +1374,7 @@ reduces them without incurring seq initialization"
13721374
(push-tail coll shift root (VectorNode. nil tail)))
13731375
new-tail (make-array 1)]
13741376
(aset new-tail 0 o)
1375-
(PersistentVector. meta (inc cnt) new-shift new-root new-tail))))
1377+
(PersistentVector. meta (inc cnt) new-shift new-root new-tail nil))))
13761378

13771379
IIndexed
13781380
(-nth [coll n]
@@ -1397,14 +1399,14 @@ reduces them without incurring seq initialization"
13971399
(< 1 (- cnt (tail-off coll))) (let [new-tail-len (dec (alength tail))
13981400
new-tail (make-array new-tail-len)]
13991401
(PersistentVector. meta (dec cnt) shift root
1400-
(array-copy tail new-tail new-tail-len)))
1402+
(array-copy tail new-tail new-tail-len) nil))
14011403
true (let [new-tail (array-for coll (- cnt 2))
14021404
nr (pop-tail coll shift root)
14031405
new-root (if (nil? nr) cljc.core.PersistentVector/EMPTY_NODE nr)
14041406
cnt-1 (dec cnt)]
14051407
(if (and (< 5 shift) (nil? (pv-aget new-root 1)))
1406-
(PersistentVector. meta cnt-1 (- shift 5) (pv-aget new-root 0) new-tail)
1407-
(PersistentVector. meta cnt-1 shift new-root new-tail)))))
1408+
(PersistentVector. meta cnt-1 (- shift 5) (pv-aget new-root 0) new-tail nil)
1409+
(PersistentVector. meta cnt-1 shift new-root new-tail nil)))))
14081410

14091411
IEmptyableCollection
14101412
(-empty [coll] (-with-meta cljc.core.PersistentVector/EMPTY meta))
@@ -1416,8 +1418,8 @@ reduces them without incurring seq initialization"
14161418
(if (<= (tail-off coll) k)
14171419
(let [new-tail (aclone tail)]
14181420
(aset new-tail (bit-and k 0x01f) v)
1419-
(PersistentVector. meta cnt shift root new-tail))
1420-
(PersistentVector. meta cnt shift (do-assoc coll shift root k v) tail))
1421+
(PersistentVector. meta cnt shift root new-tail nil))
1422+
(PersistentVector. meta cnt shift (do-assoc coll shift root k v) tail nil))
14211423
(== k cnt) (-conj coll v)
14221424
true (error (str "Index " k " out of bounds [0," cnt "]"))))
14231425

@@ -1450,19 +1452,19 @@ reduces them without incurring seq initialization"
14501452
(-as-transient [coll]
14511453
(TransientVector cnt shift (tv-editable-root root) (tv-editable-tail tail)))
14521454

1455+
IHash
1456+
(-hash [coll] (caching-hash coll hash-coll __hash))
1457+
1458+
IMapEntry
1459+
(-key [coll]
1460+
(-nth coll 0))
1461+
(-val [coll]
1462+
(-nth coll 1))
1463+
14531464
IPrintable
14541465
(-pr-seq [coll opts] (pr-sequential pr-seq "[" " " "]" opts coll))
14551466
;; Not yet ported from ClojureScript
14561467

1457-
;; IHash
1458-
;; (-hash [coll] (caching-hash coll hash-coll __hash))
1459-
1460-
;; IMapEntry
1461-
;; (-key [coll]
1462-
;; (-nth coll 0))
1463-
;; (-val [coll]
1464-
;; (-nth coll 1))
1465-
14661468
;; IKVReduce
14671469
;; (-kv-reduce [v f init]
14681470
;; (let [step-init (array 0 init)] ; [step 0 init init]
@@ -1573,7 +1575,7 @@ reduces them without incurring seq initialization"
15731575

15741576
(set! cljc.core.PersistentVector/EMPTY_NODE (pv-fresh-node nil))
15751577
(set! cljc.core.PersistentVector/EMPTY
1576-
(PersistentVector. nil 0 5 cljc.core.PersistentVector/EMPTY_NODE (make-array 0)))
1578+
(PersistentVector. nil 0 5 cljc.core.PersistentVector/EMPTY_NODE (make-array 0) 0))
15771579

15781580
(deftype ChunkedSeq [vec node i off meta]
15791581
IWithMeta
@@ -1646,9 +1648,9 @@ reduces them without incurring seq initialization"
16461648
([vec node i off meta]
16471649
(ChunkedSeq. vec node i off meta)))
16481650

1649-
(deftype Subvec [meta v start end]
1651+
(deftype Subvec [meta v start end ^:mutable __hash]
16501652
IWithMeta
1651-
(-with-meta [coll meta] (Subvec. meta v start end))
1653+
(-with-meta [coll meta] (Subvec. meta v start end __hash))
16521654

16531655
IMeta
16541656
(-meta [coll] meta)
@@ -1659,11 +1661,11 @@ reduces them without incurring seq initialization"
16591661
(-pop [coll]
16601662
(if (== start end)
16611663
(error "Can't pop empty vector")
1662-
(Subvec. meta v start (dec end))))
1664+
(Subvec. meta v start (dec end) nil)))
16631665

16641666
ICollection
16651667
(-conj [coll o]
1666-
(Subvec. meta (-assoc-n v end o) start (inc end)))
1668+
(Subvec. meta (-assoc-n v end o) start (inc end) nil))
16671669

16681670
IEmptyableCollection
16691671
(-empty [coll] (-with-meta cljc.core.PersistentVector/EMPTY meta))
@@ -1689,7 +1691,8 @@ reduces them without incurring seq initialization"
16891691
(-assoc [coll key val]
16901692
(let [v-pos (+ start key)]
16911693
(Subvec. meta (assoc v v-pos val)
1692-
start (max end (inc v-pos)))))
1694+
start (max end (inc v-pos))
1695+
nil)))
16931696

16941697
IVector
16951698
(-assoc-n [coll n val] (-assoc coll n val))
@@ -1706,15 +1709,16 @@ reduces them without incurring seq initialization"
17061709
(-invoke [coll k not-found]
17071710
(-lookup coll k not-found))
17081711

1712+
IHash
1713+
(-hash [coll] (caching-hash coll hash-coll __hash))
1714+
1715+
ISequential
1716+
IEquiv
1717+
(-equiv [coll other] (equiv-sequential coll other))
1718+
17091719
IPrintable
17101720
(-pr-seq [coll opts] (pr-sequential pr-seq "[" " " "]" opts coll))
17111721

1712-
;; IHash
1713-
;; (-hash [coll] (caching-hash coll hash-coll __hash))
1714-
1715-
;; ISequential
1716-
;; IEquiv
1717-
;; (-equiv [coll other] (equiv-sequential coll other))
17181722

17191723
;; ISeqable
17201724
;; (-seq [coll]
@@ -1736,7 +1740,7 @@ reduces them without incurring seq initialization"
17361740
(subvec v start (count v)))
17371741
([v start end]
17381742
(if (<= start end)
1739-
(Subvec. nil v start end)
1743+
(Subvec. nil v start end nil)
17401744
(error "Invalid subvec range"))))
17411745

17421746
(deftype TransientVector [^:mutable cnt
@@ -1777,7 +1781,7 @@ reduces them without incurring seq initialization"
17771781
trimmed-tail (make-array len)]
17781782
(set! root persistent-root)
17791783
(array-copy tail trimmed-tail len)
1780-
(PersistentVector. nil cnt shift root trimmed-tail))
1784+
(PersistentVector. nil cnt shift root trimmed-tail nil))
17811785
(error "persistent! called twice")))
17821786

17831787
ITransientAssociative

test/clojurec/core_test.clj

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -539,8 +539,10 @@
539539
(hash 0)
540540
(hash "")
541541
(hash :a)
542-
(hash 'a))
543-
[97 2354 0 0 0 1 0 0 4093931314 4093931313]))))
542+
(hash 'a)
543+
(hash [1 2 3])
544+
(hash {:a 1 :b 2 :c 3}))
545+
[97 2354 0 0 0 1 0 0 4093931314 4093931313 175247765312 10960786183]))))
544546

545547
(deftest sets
546548
(testing "sets"

0 commit comments

Comments
 (0)