aesahaettr
aesahaettr copied to clipboard
Maps in sets produce an exception when trying to hash due to sorting of the set
Since maps don't implement Comparable the sorting of the set during the hashing process fails. I was expecting aesahaettr to handle any composition of plain clojure data. Is it fair to call this a bug? I can take a look and try to provide a PR if so.
To reproduce:
(æsahættr/hash-object (æsahættr/md5) {:bogos #{{:test "this"} {:test "that"}}})
The stacktrace:
#error{:cause "clojure.lang.PersistentArrayMap cannot be cast to java.lang.Comparable",
:via [{:type java.lang.ClassCastException,
:message "clojure.lang.PersistentArrayMap cannot be cast to java.lang.Comparable",
:at [clojure.lang.Util compare "Util.java" 153]}],
:trace [[clojure.lang.Util compare "Util.java" 153]
[clojure.core$compare invokeStatic "core.clj" 832]
[clojure.core$compare invoke "core.clj" 823]
[clojure.lang.AFunction compare "AFunction.java" 47]
[java.util.TimSort countRunAndMakeAscending "TimSort.java" 355]
[java.util.TimSort sort "TimSort.java" 220]
[java.util.Arrays sort "Arrays.java" 1438]
[clojure.core$sort invokeStatic "core.clj" 3107]
[clojure.core$sort invokeStatic "core.clj" 3094]
[clojure.core$sort invoke "core.clj" 3094]
[æsahættr$eval10961$fn__10962 invoke "æsahættr.clj" 207]
[æsahættr$eval10936$fn__10937$G__10927__10944 invoke "æsahættr.clj" 167]
[æsahættr$eval10991$fn__10992 invoke "æsahættr.clj" 193]
[æsahættr$eval10936$fn__10937$G__10927__10944 invoke "æsahættr.clj" 167]
[æsahættr$eval10981$fn__10982 invoke "æsahættr.clj" 211]
[æsahættr$eval10936$fn__10937$G__10927__10944 invoke "æsahættr.clj" 167]
[æsahættr$eval10977$fn__10978 invoke "æsahættr.clj" 202]
[æsahættr$eval10936$fn__10937$G__10927__10944 invoke "æsahættr.clj" 167]
[æsahættr$reify__10955 funnel "æsahættr.clj" 177]
[com.google.common.hash.AbstractByteHasher putObject "AbstractByteHasher.java" 119]
[com.google.common.hash.AbstractStreamingHashFunction hashObject "AbstractStreamingHashFunction.java" 37]
[æsahættr$hash_object invokeStatic "æsahættr.clj" 156]
[æsahættr$hash_object invoke "æsahættr.clj" 150]
[app.util_test$eval52789 invokeStatic "form-init3332181017406736896.clj" 1]
[app.util_test$eval52789 invoke "form-init3332181017406736896.clj" 1]
[clojure.lang.Compiler eval "Compiler.java" 7062]
[clojure.lang.Compiler eval "Compiler.java" 7025]
[clojure.core$eval invokeStatic "core.clj" 3206]
[clojure.core$eval invoke "core.clj" 3202]
[clojure.main$repl$read_eval_print__8572$fn__8575 invoke "main.clj" 243]
[clojure.main$repl$read_eval_print__8572 invoke "main.clj" 243]
[clojure.main$repl$fn__8581 invoke "main.clj" 261]
[clojure.main$repl invokeStatic "main.clj" 261]
[clojure.main$repl doInvoke "main.clj" 177]
[clojure.lang.RestFn invoke "RestFn.java" 1523]
[clojure.tools.nrepl.middleware.interruptible_eval$evaluate$fn__51535 invoke "interruptible_eval.clj" 87]
[clojure.lang.AFn applyToHelper "AFn.java" 152]
[clojure.lang.AFn applyTo "AFn.java" 144]
[clojure.core$apply invokeStatic "core.clj" 657]
[clojure.core$with_bindings_STAR_ invokeStatic "core.clj" 1965]
[clojure.core$with_bindings_STAR_ doInvoke "core.clj" 1965]
[clojure.lang.RestFn invoke "RestFn.java" 425]
[clojure.tools.nrepl.middleware.interruptible_eval$evaluate invokeStatic "interruptible_eval.clj" 85]
[clojure.tools.nrepl.middleware.interruptible_eval$evaluate invoke "interruptible_eval.clj" 55]
[clojure.tools.nrepl.middleware.interruptible_eval$interruptible_eval$fn__51580$fn__51583
invoke
"interruptible_eval.clj"
222]
[clojure.tools.nrepl.middleware.interruptible_eval$run_next$fn__51575
invoke
"interruptible_eval.clj"
190]
[clojure.lang.AFn run "AFn.java" 22]
[java.util.concurrent.ThreadPoolExecutor runWorker "ThreadPoolExecutor.java" 1149]
[java.util.concurrent.ThreadPoolExecutor$Worker run "ThreadPoolExecutor.java" 624]
[java.lang.Thread run "Thread.java" 748]]}
We sort maps to ensure the results don't depend on the hash function used. A commutative hash function would remove the need for sorting--looks like I considered this when I wrote aesahaettr (https://github.com/aphyr/aesahaettr/blob/master/src/%C3%A6sah%C3%A6ttr.clj#L197-L203) but never figured it out. If you have ideas, go for it!