Skip to content

Commit bd6e906

Browse files
andrewhrstuarthalloway
authored andcommitted
CLJ-1766: Serializing+deserializing lists breaks their hash
Lists declare their `hash` and `hasheq` fields as transients, which are deserialized with default value `0`, breaking the expectation of non-computed values. Transients are meant to be non-serialized by default, so changing `0` to be non-computed on this case is not only more natural but also fixes the serialization roundtrip. Signed-off-by: Stuart Halloway <stu@cognitect.com>
1 parent 1d5237f commit bd6e906

File tree

2 files changed

+7
-5
lines changed

2 files changed

+7
-5
lines changed

src/jvm/clojure/lang/ASeq.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@
1414
import java.util.*;
1515

1616
public abstract class ASeq extends Obj implements ISeq, Sequential, List, Serializable, IHashEq {
17-
transient int _hash = -1;
18-
transient int _hasheq = -1;
17+
transient int _hash;
18+
transient int _hasheq;
1919

2020
public String toString(){
2121
return RT.printString(this);
@@ -62,7 +62,7 @@ public boolean equals(Object obj){
6262
}
6363

6464
public int hashCode(){
65-
if(_hash == -1)
65+
if(_hash == 0)
6666
{
6767
int hash = 1;
6868
for(ISeq s = seq(); s != null; s = s.next())
@@ -75,7 +75,7 @@ public int hashCode(){
7575
}
7676

7777
public int hasheq(){
78-
if(_hasheq == -1)
78+
if(_hasheq == 0)
7979
{
8080
// int hash = 1;
8181
// for(ISeq s = seq(); s != null; s = s.next())

test/clojure/test_clojure/serialization.clj

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,9 @@
4343
rt-seq (-> v seq serialize deserialize)]
4444
(and (= v rt)
4545
(= (seq v) (seq rt))
46-
(= (seq v) rt-seq))))
46+
(= (seq v) rt-seq)
47+
(= (hash v) (hash rt))
48+
(= (.hashCode v) (.hashCode rt)))))
4749

4850
(deftest sequable-serialization
4951
(are [val] (roundtrip val)

0 commit comments

Comments
 (0)