Transient hashmaps mishandle hash collisions


  • Type: Defect Defect
  • Status: Closed Closed
  • Priority: Major Major
  • Resolution: Completed
  • Affects Version/s: Release 1.3
  • Fix Version/s: Release 1.4
  • Component/s: None
  • Labels:
  • Patch:
    Code and Test
  • Approval:


Clojure 1.2.1 and 1.3.0-beta1 both exhibit the following behavior:

user> (let [m (into {} (for [x (range 100000)] [(rand) (rand)]))]
(println (count (distinct (map hash (keys m)))))
((juxt count identity) (persistent!
(reduce dissoc! (transient m) (keys m)))))
[2 {0.42548900739367024 0.8725039567983159}]

We create a large transient map with random keys and values, and check to see how many unique hashcodes we get. Then, we iterate over all the keys, dissoc'ing each out of the transient map. The resulting map has one element in it (wrong - it should be empty, since we dissoc'ed all the keys), and reports its count as being two (wrong - not sure whether it should be zero or one given the other breakage). As far as I can tell, each duplicated hash value is represented once in the output map, and the map's count is the number of keys that hashed to something duplicated.

The problem seems to be restricted to transients, as if we remove the transient/persistent! pair and use dissoc instead of dissoc!, the map is always empty.

Inspired by discussion at

  1. clj-829.diff
    08/Sep/11 1:15 PM
    2 kB
    Christophe Grand
  2. clj-829-2.diff
    10/Sep/11 3:48 AM
    2 kB
    Christophe Grand


Aaron Bedra made changes -
Field Original Value New Value
Fix Version/s Release.Next [ 10038 ]
Affects Version/s Release.Next [ 10038 ]
Christophe Grand made changes -
Assignee Christophe Grand [ cgrand ]
Attachment clj-829.diff [ 10333 ]
Patch Code and Test
Christophe Grand made changes -
Approval Test
Christophe Grand made changes -
Attachment clj-829-2.diff [ 10340 ]
Stuart Halloway made changes -
Fix Version/s Release 1.4 [ 10040 ]
Fix Version/s Release 1.3 [ 10038 ]
Approval Test Screened
Rich Hickey made changes -
Approval Screened Ok
Stuart Halloway made changes -
Status Open [ 1 ] Resolved [ 5 ]
Resolution Completed [ 1 ]
Stuart Halloway made changes -
Status Resolved [ 5 ] Closed [ 6 ]


Vote (0)
Watch (3)


  • Created: