This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2023-03-08
Channels
- # announcements (6)
- # atom-editor (1)
- # babashka (21)
- # beginners (70)
- # clerk (4)
- # clj-kondo (71)
- # clj-yaml (1)
- # clojure (54)
- # clojure-art (1)
- # clojure-denmark (1)
- # clojure-dev (1)
- # clojure-doc (1)
- # clojure-europe (31)
- # clojure-nl (1)
- # clojure-norway (41)
- # clojure-uk (15)
- # clojurescript (36)
- # conjure (1)
- # cursive (2)
- # datomic (14)
- # duct (10)
- # emacs (12)
- # etaoin (176)
- # gratitude (25)
- # hyperfiddle (17)
- # jobs (1)
- # juxt (5)
- # london-clojurians (1)
- # malli (3)
- # nbb (21)
- # off-topic (29)
- # reitit (12)
- # releases (2)
- # remote-jobs (7)
- # shadow-cljs (9)
- # testing (9)
I'm off reading code again. Apologies in advance.
Looking at PersistentHashMap
.
There are two little static helper methods createNode
. They are almost identical. Both called from BitmapIndexedNode
during an assoc
operation, one for the transient case, one for the non-transient case. The non-transient one reads:
private static INode createNode(int shift, Object key1, Object val1, int key2hash, Object key2, Object val2) {
int key1hash = hash(key1);
if(key1hash == key2hash)
return new HashCollisionNode(null, key1hash, 2, new Object[] {key1, val1, key2, val2});
Box addedLeaf = new Box(null);
AtomicReference<Thread> edit = new AtomicReference<Thread>();
return BitmapIndexedNode.EMPTY
.assoc(edit, shift, key1hash, key1, val1, addedLeaf)
.assoc(edit, shift, key2hash, key2, val2, addedLeaf);
}
Why are we creating an edit
value here and using the transient version of assoc
?
For the transient version:
private static INode createNode(AtomicReference<Thread> edit, int shift, Object key1, Object val1, int key2hash, Object key2, Object val2) {
int key1hash = hash(key1);
if(key1hash == key2hash)
return new HashCollisionNode(null, key1hash, 2, new Object[] {key1, val1, key2, val2});
Box addedLeaf = new Box(null);
return BitmapIndexedNode.EMPTY
.assoc(edit, shift, key1hash, key1, val1, addedLeaf)
.assoc(edit, shift, key2hash, key2, val2, addedLeaf);
}
For the BitmapIndexedNode
case it is okay to start with a BitmapIndexedNode.Empty
, having a null
edit field, because the first assoc
will call ensureEditable
and get us all fixed up.
My question is: Why is the HashCollisionNode
created with a null
edit field? If it gets touched again during this transient transaction, it will be copied needlessly, yes?
Even if I'm correct, I realize the impact is trivial and not worth consideration; I just don't like not understanding.
,