std/collections/hashmap
std/collections/hashmap — generic HashMap<K, V>, a pure-Axle
open-addressing SwissTable. Resolves by bare name throughuse std::collections::HashMap; (the file it lives in does not
affect the import path).
C class HashMap<K, V>
get(K) : V | null returns null on a miss — null is a distinct
type, so V | null is a sound union over any V (a value-primitiveV carries a present flag alongside the payload, so 0 is never
confused with absence). Reach the value with get(k) ?? fallback or
an if (get(k) != null) guard. remove returns bool (whether a
binding was present) rather than the prior value.K = f64 is unsupported: NaN-keys and float-precision-as-equality
are common footguns. Use i64 or string instead.
Pure-Axle SwissTable. Mirrors abseil flathashmap / hashbrown :
meta : i8[cap + 16] — meta byte per slot + 16-byte trailing
mirror so a wrap-around SIMD load
never reads past the buffer end.
keys : K[cap] — parallel key array
values : V[cap] — parallel value array
Meta encoding (low 7 bits = h2 hash; MSB = "control"):
0x00..0x7F occupied — low 7 bits are h2(key)
0x80 empty
0xFE tombstone (removed; probing must walk over it)
Hashing dispatches statically per K via the hash_key compiler
builtin — i32/i64 and user classes inline a double-keyed SplitMix64;
string routes to a keyed mix (hashStringSeeded). Both pull the
128-bit OS-CSPRNG @axle_hash_seed_lo/_hi key (HashDoS-safe).
Load factor target 7/8 (hashbrown convention) ; the sum of len andtombstones counts toward the trigger so a churning workload
doesn't degrade to O(n) probe chains. Rehash doubles the
capacity and re-inserts every live entry (tombstones are
dropped).
Bit-twiddling on the SIMD match mask goes through cttz_i32
(compiler builtin → @llvm.cttz.i32 → one tzcnt on x86).
Constructors
| Type | Method and description |
|---|---|
| constructor() Build an empty map sized to one 16-slot SIMD group, its meta array (plus 16-byte mirror) splatted to the empty sentinel. |
Method detail
#constructor
Build an empty map sized to one 16-slot SIMD group, its meta
array (plus 16-byte mirror) splatted to the empty sentinel.
Methods
| Type | Method and description |
|---|---|
| size(self) : i32 |
| isEmpty(self) : bool |
| clear(mut self) : void |
| put(mut self, key : K, value : V) : void Insert or overwrite. Grows past the 7/8 load factor first, then SIMD-probes for an existing key (overwrite) or the first hole (insert), reclaiming a tombstone slot when one is chosen. |
| containsKey(self, key : K) : bool |
| get(self, key : K) : V | null |
| getOrDefault(self, key : K, defaultValue : V) : V Single-probe variant of get — returns defaultValue on missinstead of throwing. Matches the getOrDefault shape sohot-path lookup loops can avoid the containsKey + get doubleprobe (the only safe way to use get without catching theexception). Algorithm body is identical to get ; the onlydifference is the miss branch. |
| remove(mut self, key : K) : bool |
Method detail
#size
#isEmpty
#clear
#put
Insert or overwrite. Grows past the 7/8 load factor first, then
SIMD-probes for an existing key (overwrite) or the first hole
(insert), reclaiming a tombstone slot when one is chosen.
key lookup key; == equality decides the target slotvalue value bound to key, overwriting any prior binding#containsKey
#get
#getOrDefault
Single-probe variant of get — returns defaultValue on miss
instead of throwing. Matches the getOrDefault shape so
hot-path lookup loops can avoid the containsKey + get double
probe (the only safe way to use get without catching the
exception). Algorithm body is identical to get ; the only
difference is the miss branch.
key key to look up; matched by ==defaultValue value returned unchanged when key is absent