Skip to content

Commit 833c924

Browse files
puredangerstuarthalloway
authored andcommitted
CLJ-1364 Add hash and equality methods for primitive vec seqs
Signed-off-by: Stuart Halloway <stu@cognitect.com>
1 parent 05c193c commit 833c924

File tree

3 files changed

+65
-5
lines changed

3 files changed

+65
-5
lines changed

src/clj/clojure/gvec.clj

+33-2
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@
1010

1111
(in-ns 'clojure.core)
1212

13-
(import '(clojure.lang Murmur3))
13+
(import '(clojure.lang Murmur3 IHashEq Sequential Util SeqIterator)
14+
'(java.util List))
1415

1516
(set! *warn-on-reflection* true)
1617

@@ -131,7 +132,37 @@
131132

132133
clojure.lang.IObj
133134
(withMeta [_ m]
134-
(new VecSeq am vec anode i offset m)))
135+
(new VecSeq am vec anode i offset m))
136+
137+
Object
138+
(hashCode [this]
139+
(loop [hash 1
140+
s (seq this)]
141+
(if s
142+
(let [v (first s)]
143+
(if (nil? v)
144+
(recur (unchecked-multiply-int 31 hash) (next s))
145+
(recur (unchecked-add-int (unchecked-multiply-int 31 hash) (.hashCode v)) (next s))))
146+
hash)))
147+
(equals [this other]
148+
(cond (identical? this other) true
149+
(or (instance? Sequential other) (instance? List other))
150+
(loop [s this
151+
os (seq other)]
152+
(if (nil? s)
153+
(nil? os)
154+
(if (Util/equals (first s) (first os))
155+
(recur (next s) (next os))
156+
false)))
157+
:else false))
158+
159+
IHashEq
160+
(hasheq [this]
161+
(Murmur3/hashOrdered this))
162+
163+
Iterable
164+
(iterator [this]
165+
(SeqIterator. this)))
135166

136167
(defmethod print-method ::VecSeq [v w]
137168
((get (methods print-method) clojure.lang.ISeq) v w))

src/jvm/clojure/lang/MySeq.java

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package clojure.lang;
2+
3+
public class MySeq extends ASeq {
4+
@Override
5+
public Object first() {
6+
return null;
7+
}
8+
9+
@Override
10+
public ISeq next() {
11+
return null;
12+
}
13+
14+
@Override
15+
public Obj withMeta(IPersistentMap meta) {
16+
return null;
17+
}
18+
}

test/clojure/test_clojure/data_structures.clj

+14-3
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@
1414
[clojure.test.generative :exclude (is)])
1515
(:require [clojure.test-clojure.generators :as cgen]
1616
[clojure.data.generators :as gen]
17-
[clojure.string :as string]))
17+
[clojure.string :as string])
18+
(:import [java.util Collection]))
1819

1920

2021
;; *** Helper functions ***
@@ -1107,7 +1108,11 @@
11071108
(defn is-same-collection [a b]
11081109
(let [msg (format "(class a)=%s (class b)=%s a=%s b=%s"
11091110
(.getName (class a)) (.getName (class b)) a b)]
1110-
(is (= (count a) (count b) (.size a) (.size b)) msg)
1111+
(is (= (count a) (count b)) msg)
1112+
(when (instance? Collection a)
1113+
(is (= (count a) (.size a)) msg))
1114+
(when (instance? Collection b)
1115+
(is (= (count b) (.size b)) msg))
11111116
(is (= a b) msg)
11121117
(is (= b a) msg)
11131118
(is (.equals ^Object a b) msg)
@@ -1133,7 +1138,13 @@
11331138
(sequence (map identity) [-3 :a "7th"]) ]]
11341139
(doseq [c1 colls1, c2 colls1]
11351140
(is-same-collection c1 c2)))
1136-
(is-same-collection [-3 1 7] (vector-of :long -3 1 7)))
1141+
(let [long-colls [ [2 3 4]
1142+
'(2 3 4)
1143+
(vector-of :long 2 3 4)
1144+
(seq (vector-of :long 2 3 4))
1145+
(range 2 5)]]
1146+
(doseq [c1 long-colls, c2 long-colls]
1147+
(is-same-collection c1 c2))))
11371148

11381149
(defn case-indendent-string-cmp [s1 s2]
11391150
(compare (string/lower-case s1) (string/lower-case s2)))

0 commit comments

Comments
 (0)