tur/hamt
persistent hash-array-mapped trie (HAMT) map.
Immutable, structurally-sharing key-value map. All update operations return a new root; the old root remains valid (snapshot semantics).
Since: Phase P1
hamt/new
(hamt/new :ptr<void>)
create a new empty persistent HAMT.
Pointer to a freshly allocated, empty HAMT with reference count 1.
(hamt/new) ; => <hamt ptr>
Since: Phase P1
hamt/free
(hamt/free [m :ptr<void>] :void)
decrement the reference count of a HAMT; free if it reaches zero.
| m | HAMT pointer |
(hamt/free my-map)
Since: Phase P1
hamt/retain
(hamt/retain [m :ptr<void>] :ptr<void>)
increment the reference count of a HAMT and return it.
| m | HAMT pointer |
The same HAMT pointer m, with its reference count incremented.
(hamt/retain my-map) ; => my-map
Since: Phase P1
hamt/set
(hamt/set [m :ptr<void> hash :int key :ptr<void> val :ptr<void>])
insert or update a key/value pair; returns a new HAMT.
| m | source HAMT pointer | |
| hash | 64-bit hash of the key (passed as int64_t) | |
| key | key pointer | |
| val | value pointer |
A new HAMT containing the inserted/updated entry. The original is unchanged.
(hamt/set m (hamt/hash-str "k") k v) ; => <new hamt ptr>
Since: Phase P1
hamt/del
(hamt/del [m :ptr<void> hash :int key :ptr<void>])
delete a key from the HAMT; returns a new HAMT.
| m | source HAMT pointer | |
| hash | 64-bit hash of the key | |
| key | key pointer |
A new HAMT with the key removed. The original is unchanged.
(hamt/del m (hamt/hash-str "k") k) ; => <new hamt ptr>
Since: Phase P1
hamt/get
(hamt/get [m :ptr<void> hash :int key :ptr<void>])
look up a key and return its value, or NULL if absent.
| m | HAMT pointer | |
| hash | 64-bit hash of the key | |
| key | key pointer |
The value pointer associated with key, or NULL if not found.
(hamt/get m (hamt/hash-str "k") k) ; => <value ptr or NULL>
Since: Phase P1
hamt/has?
(hamt/has? [m :ptr<void> hash :int key :ptr<void>])
check whether a key exists in the HAMT.
| m | HAMT pointer | |
| hash | 64-bit hash of the key | |
| key | key pointer |
true if the key is present, false otherwise.
(hamt/has? m (hamt/hash-str "k") k) ; => true
Since: Phase P1
hamt/set-cstr
(hamt/set-cstr [m :ptr<void> key :cstr val :ptr<void>])
insert or update a string-keyed entry, compared by content.
The key is hashed by content (xxHash64 of the bytes) and compared by content on hash collision, so equal text at distinct addresses is one key. The map stores the key pointer (no copy); the caller owns its lifetime. Prefer this over hamt/set + hamt/hash-ptr for :cstr keys.
| m | source HAMT pointer | |
| key | NUL-terminated string key | |
| val | value pointer |
A new HAMT containing the inserted/updated entry. The original is unchanged.
(hamt/set-cstr m "name" v) ; => <new hamt ptr>
Since: Phase P3
hamt/del-cstr
(hamt/del-cstr [m :ptr<void> key :cstr])
delete a string key, compared by content; returns a new HAMT.
| m | source HAMT pointer | |
| key | NUL-terminated string key |
A new HAMT with the key removed. The original is unchanged.
(hamt/del-cstr m "name") ; => <new hamt ptr>
Since: Phase P3
hamt/get-cstr
(hamt/get-cstr [m :ptr<void> key :cstr])
look up a string key by content; NULL if absent.
| m | HAMT pointer | |
| key | NUL-terminated string key |
The value pointer associated with key, or NULL if not found.
(hamt/get-cstr m "name") ; => <value ptr or NULL>
Since: Phase P3
hamt/has-cstr?
(hamt/has-cstr? [m :ptr<void> key :cstr])
check whether a string key exists, compared by content.
| m | HAMT pointer | |
| key | NUL-terminated string key |
true if the key is present, false otherwise.
(hamt/has-cstr? m "name") ; => true
Since: Phase P3
hamt/count
(hamt/count [m :ptr<void>] :int)
return the number of key/value pairs in the HAMT.
| m | HAMT pointer |
Integer count of entries stored in the HAMT.
(hamt/count my-map) ; => 3
Since: Phase P1
hamt/merge
(hamt/merge [a :ptr<void> b :ptr<void>])
merge two HAMTs; values from b win on key collision.
| a | first HAMT pointer | |
| b | second HAMT pointer (wins on collision) |
A new HAMT containing all entries from a and b.
(hamt/merge map-a map-b) ; => <merged hamt ptr>
Since: Phase P1
hamt/hash-str
(hamt/hash-str [str :cstr] :int)
compute an xxHash64 of a NUL-terminated C string.
| str | NUL-terminated C string to hash |
64-bit hash value as int64_t.
(hamt/hash-str "hello") ; => <hash int>
Since: Phase P1
hamt/hash-ptr
(hamt/hash-ptr [ptr :ptr<void>] :int)
hash a pointer value directly (identity hash).
| ptr | pointer whose address is used as the hash input |
64-bit hash value derived from the pointer address.
(hamt/hash-ptr my-key) ; => <hash int>
Since: Phase P1
hamt/iter-init
(hamt/iter-init [iter :ptr<void> m :ptr<void>])
initialize a stack-allocated iterator over a HAMT.
| iter | pre-allocated buffer of at least 64 bytes | |
| m | HAMT pointer to iterate over |
(hamt/iter-init iter-buf my-map)
Since: Phase P1
hamt/iter-free
(hamt/iter-free [iter :ptr<void>] :void)
release any resources held by an iterator.
| iter | iterator buffer previously passed to hamt/iter-init |
(hamt/iter-free iter-buf)
Since: Phase P1
hamt/iter-next
(hamt/iter-next [iter :ptr<void> hash-out :ptr<void> key-out :ptr<void> val-out :ptr<void>])
advance an iterator and write the next entry into out-pointers.
| iter | iterator buffer | |
| hash-out | pointer that receives the key hash | |
| key-out | pointer that receives the key pointer | |
| val-out | pointer that receives the value pointer |
true if a pair was written; false when the iteration is exhausted.
(hamt/iter-next iter hash-out key-out val-out) ; => true/false
Since: Phase P1
hamt/iter-alloc
(hamt/iter-alloc [m :ptr<void>] :ptr<void>)
allocate an iterator box for HAMT m.
Returns an opaque handle that owns a HamtIter plus cached current (hash, key, val) slots. Pair with hamt/iter-destroy! when done.
Since: Phase TCO-Eq-MapSet
hamt/iter-destroy!
(hamt/iter-destroy! [box :ptr<void>])
free an iterator box.
hamt/iter-advance!
(hamt/iter-advance! [box :ptr<void>])
step to the next entry; returns false on exhaustion.
The current hash / key / value are exposed via the cur-* accessors.
hamt/iter-cur-hash
(hamt/iter-cur-hash [box :ptr<void>])
current entry's 64-bit hash (only valid after a successful hamt/iter-advance!).
hamt/iter-cur-key
(hamt/iter-cur-key [box :ptr<void>])
current entry's key pointer.
hamt/iter-cur-val
(hamt/iter-cur-val [box :ptr<void>])
current entry's value pointer.
hamt/keyeq
(hamt/keyeq [m :ptr<void>] :ptr<void>)
read the stamped key comparator off a HAMT (NULL = identity).
hamt/get-dynamic
(hamt/get-dynamic [m :ptr<void> hash :int key :ptr<void> keyeq :ptr<void>])
lookup using the supplied key comparator when non-NULL, else identity. Used by the pure-Turmeric Eq[Map] loop so the loop body has no conditional around the per-entry lookup.
hamt/has-dynamic?
(hamt/has-dynamic? [m :ptr<void> hash :int key :ptr<void> keyeq :ptr<void>])
presence check matching hamt/get-dynamic's semantics.
hamt/map
(hamt/map [m :ptr<void> fn :ptr<void> ctx :ptr<void>])
return a new HAMT with each value replaced by fn(val, ctx).
| m | source HAMT pointer | |
| fn | C function pointer (val :ptr, ctx :ptr) -> :ptr | |
| ctx | caller-supplied context passed to fn |
A new HAMT with transformed values.
(hamt/map my-map transform-fn ctx) ; => <new hamt ptr>
Since: Phase P1
hamt/filter
(hamt/filter [m :ptr<void> fn :ptr<void> ctx :ptr<void>])
return a new HAMT keeping only entries where fn(key, val, ctx) is true.
| m | source HAMT pointer | |
| fn | C predicate pointer (key :ptr, val :ptr, ctx :ptr) -> bool | |
| ctx | caller-supplied context passed to fn |
A new HAMT containing only the entries that passed the predicate.
(hamt/filter my-map pred-fn ctx) ; => <filtered hamt ptr>
Since: Phase P1
hamt/reduce
(hamt/reduce [m :ptr<void> fn :ptr<void> init :ptr<void> ctx :ptr<void>])
fold all entries into an accumulator using fn(acc, key, val, ctx).
| m | source HAMT pointer | |
| fn | C function pointer (acc :ptr, key :ptr, val :ptr, ctx :ptr) -> :ptr | |
| init | initial accumulator pointer | |
| ctx | caller-supplied context passed to fn |
Final accumulator pointer after visiting all entries.
(hamt/reduce my-map fold-fn init-acc ctx) ; => <result ptr>
Since: Phase P1
hamt/merge-with
(hamt/merge-with [a :ptr<void> b :ptr<void> fn :ptr<void> ctx :ptr<void>])
merge two HAMTs, resolving key conflicts with fn(val_a, val_b, ctx).
| a | first HAMT pointer | |
| b | second HAMT pointer | |
| fn | C function pointer (val_a :ptr, val_b :ptr, ctx :ptr) -> :ptr | |
| ctx | caller-supplied context passed to fn |
A new HAMT where colliding keys are resolved by fn instead of last-write-wins.
(hamt/merge-with map-a map-b merge-fn ctx) ; => <merged hamt ptr>
Since: Phase P1
hamt/show
(hamt/show [m :ptr<void>] :cstr)
return a debug string "{k->v, ...}" for the HAMT; caller must free.
| m | HAMT pointer |
NUL-terminated C string; the caller is responsible for freeing it.
(hamt/show my-map) ; => "{...}"
Since: Phase P1
hamt/dump
(hamt/dump [m :ptr<void>] :void)
write the HAMT structure in DOT format to stderr for debugging.
| m | HAMT pointer to dump |
(hamt/dump my-map)
Since: Phase P1
hamt/transient
(hamt/transient [m :ptr<void>] :ptr<void>)
fork a mutable transient from an immutable HAMT.
| m | immutable HAMT pointer to fork from |
A transient (mutable) view that shares structure with m.
(hamt/transient my-map) ; => <transient ptr>
Since: Phase P1
hamt/transient-set!
(hamt/transient-set! [t :ptr<void> hash :int key :ptr<void> val :ptr<void>])
mutate a transient by inserting or updating a key in place.
| t | transient HAMT pointer | |
| hash | 64-bit hash of the key | |
| key | key pointer | |
| val | value pointer |
(hamt/transient-set! t (hamt/hash-str "k") k v)
Since: Phase P1
hamt/transient-del!
(hamt/transient-del! [t :ptr<void> hash :int key :ptr<void>])
mutate a transient by deleting a key in place.
| t | transient HAMT pointer | |
| hash | 64-bit hash of the key | |
| key | key pointer |
(hamt/transient-del! t (hamt/hash-str "k") k)
Since: Phase P1
hamt/persistent!
(hamt/persistent! [t :ptr<void>])
seal a transient into an immutable HAMT.
| t | transient HAMT pointer (must not be used after this call) |
A new immutable HAMT containing all mutations applied to the transient.
(hamt/persistent! t) ; => <immutable hamt ptr>
Since: Phase P1
Internal definitions
hamt/autolink-hint-- internal marker that triggers hamt.c compilation in tur build/run.