pub struct HashMapData<V: HashMapValueElem> {
pub keys: *mut TypedArray<*const StringObj>,
pub values: *mut TypedArray<V>,
pub index: HashMap<u64, Vec<u32>>,
}Expand description
HashMap storage — keys buffer (string-typed v2-raw *mut TypedArray<*const StringObj>)
- per-V monomorphized values buffer (
*mut TypedArray<V>) + eager bucket-index for O(1) lookup.
Wave 2 Round 3b C2-joint ckpt-1 (2026-05-14): the parametric
HashMapValueBuf enum has been REPLACED with a generic type parameter V
constrained by HashMapValueElem. Per audit §C.4 option (a.2):
per-V monomorphization at compile time via the HashMapKindedRef carrier
(defined below). No runtime kind discriminator field on this struct (the
variant tag lives on HashMapKindedRef at the carrier layer).
The values buffer is a raw *mut TypedArray<V> — the v2-raw heap shape
(HeapHeader-at-offset-0 produced via TypedArray::<V>::new). Drop runs
V::release_typed_array(self.values) via the HashMapValueElem trait —
per-V monomorphized at compile time. The keys buffer is a *mut TypedArray<*const StringObj> — v2-raw shape using the HeapElement
dispatch on StringObj.
Per-V monomorphizations supported at landing (mirror of §A migration):
i64, f64, u8 (Bool), *const StringObj, *const DecimalObj,
TypedObjectPtr, TraitObjectPtr. DateTime / Timespan / Duration /
Instant / Char are dead per §C.5 (Char retained as POD-scalar arm only
for the dead-but-derived defensive path; no live root producer).
Eager bucket-only at first landing (preserved from Stage C): index
is built at construction and maintained incrementally on insert / remove.
The shape_id hidden-class fast-path that the pre-bulldozer architecture
used for ≤64-string-keyed-maps remains deferred to a separate
optimization workstream.
Forbidden under Q25.B SUPERSEDED:
Arc<TypedBuffer<V>>field shape (the value-buffer carrier is*mut TypedArray<V>per audit §C.4).- HashMap-wide runtime kind discriminator on this struct (per-V
monomorphization at compile time via the carrier; no inline tag
byte on
HashMapData<V>itself). - Re-introducing
HashMapValueBufarms under any rename.
Fields§
§keys: *mut TypedArray<*const StringObj>Insertion-ordered keys — v2-raw *mut TypedArray<*const StringObj>.
Owned by this struct (one strong-count share on the keys array’s
HeapHeader at offset 0). Drop calls <*const StringObj as HashMapValueElem>::release_typed_array to retire the share.
values: *mut TypedArray<V>Insertion-ordered values — v2-raw *mut TypedArray<V>. Owned by
this struct. Drop calls V::release_typed_array(self.values).
index: HashMap<u64, Vec<u32>>Eager bucket-index: hash → list of indices into keys / values
arrays. Enables O(1) lookup at the user-facing map.get(key) path.
Hash is computed via FNV-1a over the key string bytes.
Implementations§
Source§impl<V: HashMapValueElem> HashMapData<V>
impl<V: HashMapValueElem> HashMapData<V>
Sourcepub fn new() -> Self
pub fn new() -> Self
Build an empty HashMapData with no entries.
Allocates two v2-raw TypedArray storages (keys + values) at
capacity 0. The struct owns one strong-count share on each.
Sourcepub unsafe fn from_pairs(
keys: *mut TypedArray<*const StringObj>,
values: *mut TypedArray<V>,
) -> Self
pub unsafe fn from_pairs( keys: *mut TypedArray<*const StringObj>, values: *mut TypedArray<V>, ) -> Self
Build from parallel buffers — caller transfers one strong-count share
on each TypedArray to this struct. Computes the bucket index eagerly
from the keys buffer.
§Safety
keys must point to a live TypedArray<*const StringObj> and
values to a live TypedArray<V>, both with at least one
strong-count share owned by the caller (transferred to this struct).
keys.len must equal values.len.
Sourcepub unsafe fn value_at_raw(&self, i: usize) -> Vwhere
V: Copy,
pub unsafe fn value_at_raw(&self, i: usize) -> Vwhere
V: Copy,
Read the value at index i. Returns a copy of the V element
(POD scalars copy bytes; *const StringObj / *const DecimalObj /
TypedObjectPtr / TraitObjectPtr copy the pointer bits — caller
must NOT treat the returned value as carrying refcount ownership
unless the caller explicitly bumps the v2-raw refcount).
For owned-share semantics use value_at_owned (ckpt-2 / ckpt-3
territory; not in scope for ckpt-1 foundation).
§Safety
i must be less than self.len().
Sourcepub fn get_index(&self, key: &str) -> Option<usize>
pub fn get_index(&self, key: &str) -> Option<usize>
Look up a value by string key. Returns Some(i) (the index into the
values buffer) if the key is present, else None. The returned
index can be used with value_at_raw / Arc::make_mut-based
mutation paths (ckpt-3 territory).
O(1) via the bucket index plus a short bucket scan for collision disambiguation.
Sourcepub fn contains_key(&self, key: &str) -> bool
pub fn contains_key(&self, key: &str) -> bool
Whether the map contains the given key.
Sourcepub unsafe fn insert(&mut self, key: &str, value: V) -> bool
pub unsafe fn insert(&mut self, key: &str, value: V) -> bool
Insert a key/value pair, transferring one share on value to the
map. If the key was already present, the old value’s share is
retired (via V::release_typed_array-style single-element drop)
and the slot is overwritten with value. Returns true on
new-key insert, false on overwrite.
The key is allocated as a new StringObj (one fresh
v2_retain=1 share owned by the map).
§Safety
value must be a valid owned V — for HeapElement / ptr-newtype V
types, the caller must transfer ownership of one refcount share
to this method. POD V types (i64/f64/u8/char) trivially
own themselves.
Sourcepub unsafe fn remove(&mut self, key: &str) -> Option<V>
pub unsafe fn remove(&mut self, key: &str) -> Option<V>
Remove the entry under key. Returns the removed value (transferring
one share to the caller) if present, else None.
The bucket index is updated to reflect the buffer’s post-removal
indices: every entry after the removed slot shifts down by one
position (mirror of HashSetData::remove).
Look up a value by key. Returns a share-cloned copy of the stored
value (the caller takes one fresh share — for POD V trivial copy;
for HeapElement / ptr-newtype V the v2_retain happens via
HashMapValueElem::share_clone).
Returns None if the key is absent.
Trait Implementations§
Source§impl<V: HashMapValueElem> Clone for HashMapData<V>
Clone-on-write impl for HashMapData<V> (Wave 2 Round 3b C2-joint
ckpt-3, 2026-05-14). Allocates fresh keys + values buffers and
share-clones each element per the per-V HashMapValueElem::share_clone
dispatcher (and v2_retain on each key via the *const StringObj impl).
The fresh HashMapData<V> owns one refcount share on each per-element
allocation; the source’s shares are untouched.
impl<V: HashMapValueElem> Clone for HashMapData<V>
Clone-on-write impl for HashMapData<V> (Wave 2 Round 3b C2-joint
ckpt-3, 2026-05-14). Allocates fresh keys + values buffers and
share-clones each element per the per-V HashMapValueElem::share_clone
dispatcher (and v2_retain on each key via the *const StringObj impl).
The fresh HashMapData<V> owns one refcount share on each per-element
allocation; the source’s shares are untouched.
This impl is required for Arc::make_mut(&mut Arc<HashMapData<V>>) to
work at the consumer side (clone-on-write at the dispatch shell). Per
ADR-006 §2.7.24 Q25.B SUPERSEDED + audit §C.4 option (a.2).