pub struct hashtable_nodes<T> { /* private fields */ }Expand description
Port of the node-storage half of struct hashtable
(Src/zsh.h:1175-1235: HashNode *nodes; int hsize; int ct;) as
Src/hashtable.c actually drives it — an OPEN-HASHED BUCKET ARRAY:
- bucket index is
ht->hash(nam) % ht->hsize(c:176/236/260/280); - a new key goes to the FRONT of its chain (c:194-196 for an empty bucket, c:214-215 otherwise);
- replacing an existing key keeps that key’s POSITION in the chain
(c:187-203
replacing:—hn->next = hp->next); - once
ct >= hsize * 2the table quadruples and every node is re-added in old-traversal order (c:183/219 →expandhashtablec:458-482); - an unsorted scan walks bucket 0..hsize-1, each chain head→tail
(
scanmatchtablec:420-434).
That walk order is OBSERVABLE: ${(k)functions} /
${(k)commands} / compadd -k <assoc> all emit it verbatim
(Src/Modules/parameter.c:480-481 loops shfunctab->nodes[i]
directly), and join_clines is a non-commutative fold, so the
order matches are added in decides the common prefix compadd -k
produces.
The port previously stood a std::collections::HashMap in for the
bucket array. That is not merely a different order — RandomState
re-seeds per process, so print -rl -- ${(k)functions} returned a
DIFFERENT order on every run of the same binary against the same
46761-function table, and any completion enumerating the table was
nondeterministic.
!!! WARNING: RUST-ONLY HELPER !!!
C reaches these fields through one polymorphic struct hashtable
with hash/cmpnodes/addnode/getnode function pointers. Rust
has no equivalent of the HashNode-as-first-member downcast, so the
storage is a generic struct and the typed wrappers below embed it.
Every method is named for the Src/hashtable.c function it ports.
Implementations§
Source§impl<T> hashtable_nodes<T>
impl<T> hashtable_nodes<T>
Sourcepub fn newhashtable(size: usize) -> Self
pub fn newhashtable(size: usize) -> Self
Port of newhashtable(int size, …) from Src/hashtable.c:100 —
zshcalloc(size * sizeof(HashNode)) + hsize = size + ct = 0.
Sourcepub fn addhashnode2(&mut self, nam: &str, nodeptr: T) -> Option<T>
pub fn addhashnode2(&mut self, nam: &str, nodeptr: T) -> Option<T>
Port of addhashnode2(HashTable ht, char *nam, void *nodeptr) from
Src/hashtable.c:168 — inserts, returning the displaced node.
Sourcepub fn gethashnode2(&self, nam: &str) -> Option<&T>
pub fn gethashnode2(&self, nam: &str) -> Option<&T>
Port of gethashnode2(HashTable ht, const char *nam) from
Src/hashtable.c:255 — lookup WITHOUT the DISABLED filter.
Sourcepub fn get_mut(&mut self, nam: &str) -> Option<&mut T>
pub fn get_mut(&mut self, nam: &str) -> Option<&mut T>
Mutable companion of hashtable_nodes::gethashnode2. C mutates
straight through the returned HashNode pointer; Rust needs the
separate borrow.
Sourcepub fn removehashnode(&mut self, nam: &str) -> Option<T>
pub fn removehashnode(&mut self, nam: &str) -> Option<T>
Port of removehashnode(HashTable ht, const char *nam) from
Src/hashtable.c:275 — unlinks the node from its chain and
decrements ct.
Sourcepub fn emptyhashtable(&mut self)
pub fn emptyhashtable(&mut self)
Port of emptyhashtable(HashTable ht) from Src/hashtable.c:517
(resizehashtable(ht, ht->hsize)) — frees every node, keeps hsize.
Sourcepub fn iter(&self) -> impl Iterator<Item = (&String, &T)>
pub fn iter(&self) -> impl Iterator<Item = (&String, &T)>
The unsorted scan order of scanmatchtable (Src/hashtable.c:420-434):
bucket 0..hsize-1, each chain head→tail. This IS the order zsh’s
${(k)assoc} / compadd -k emit.
Sourcepub fn iter_mut(&mut self) -> impl Iterator<Item = (&String, &mut T)>
pub fn iter_mut(&mut self) -> impl Iterator<Item = (&String, &mut T)>
Mutable companion of hashtable_nodes::iter — same
scanmatchtable walk (Src/hashtable.c:420-434); C hands the
scan function a writable HashNode, Rust needs the separate
borrow.
Sourcepub fn keys(&self) -> impl Iterator<Item = &String>
pub fn keys(&self) -> impl Iterator<Item = &String>
The names in scanmatchtable order (Src/hashtable.c:420-434) —
C’s scan reads hn->nam off each node in the same walk.
Sourcepub fn values(&self) -> impl Iterator<Item = &T>
pub fn values(&self) -> impl Iterator<Item = &T>
The nodes in scanmatchtable order (Src/hashtable.c:420-434).
Sourcepub fn values_mut(&mut self) -> impl Iterator<Item = &mut T>
pub fn values_mut(&mut self) -> impl Iterator<Item = &mut T>
Mutable companion of hashtable_nodes::values
(Src/hashtable.c:420-434).
Sourcepub fn get(&self, nam: &str) -> Option<&T>
pub fn get(&self, nam: &str) -> Option<&T>
ht->getnode2(ht, nam) (Src/hashtable.c:255 gethashnode2) —
map-shaped alias so tables converted from a HashMap keep their
call sites. Same O(1) bucket hash + short-chain walk as C.
Sourcepub fn contains_key(&self, nam: &str) -> bool
pub fn contains_key(&self, nam: &str) -> bool
ht->getnode2(ht, nam) != NULL (Src/hashtable.c:255).
Sourcepub fn insert(&mut self, nam: String, nodeptr: T) -> Option<T>
pub fn insert(&mut self, nam: String, nodeptr: T) -> Option<T>
ht->addnode(ht, ztrdup(nam), node) (Src/hashtable.c:157
addhashnode → addhashnode2 at c:168) — returns the
displaced node instead of running freenode.
Sourcepub fn remove(&mut self, nam: &str) -> Option<T>
pub fn remove(&mut self, nam: &str) -> Option<T>
ht->removenode(ht, nam) (Src/hashtable.c:275
removehashnode).
Sourcepub fn retain<F: FnMut(&String, &mut T) -> bool>(&mut self, f: F)
pub fn retain<F: FnMut(&String, &mut T) -> bool>(&mut self, f: F)
The scanmatchtable walk (Src/hashtable.c:420-434) with the
C freenode arm taken for every node the predicate rejects.
Chain order of the survivors is preserved exactly, which is what
makes this different from rebuilding the table.
Trait Implementations§
Source§impl<T: Clone> Clone for hashtable_nodes<T>
impl<T: Clone> Clone for hashtable_nodes<T>
Source§impl<T: Debug> Debug for hashtable_nodes<T>
impl<T: Debug> Debug for hashtable_nodes<T>
Source§impl<T> Default for hashtable_nodes<T>
impl<T> Default for hashtable_nodes<T>
Source§impl<'a, T> IntoIterator for &'a hashtable_nodes<T>
impl<'a, T> IntoIterator for &'a hashtable_nodes<T>
Auto Trait Implementations§
impl<T> Freeze for hashtable_nodes<T>
impl<T> RefUnwindSafe for hashtable_nodes<T>
impl<T> Send for hashtable_nodes<T>
impl<T> Sync for hashtable_nodes<T>
impl<T> Unpin for hashtable_nodes<T>
impl<T> UnsafeUnpin for hashtable_nodes<T>
impl<T> UnwindSafe for hashtable_nodes<T>
Blanket Implementations§
Source§impl<T> ArchivePointee for T
impl<T> ArchivePointee for T
Source§type ArchivedMetadata = ()
type ArchivedMetadata = ()
Source§fn pointer_metadata(
_: &<T as ArchivePointee>::ArchivedMetadata,
) -> <T as Pointee>::Metadata
fn pointer_metadata( _: &<T as ArchivePointee>::ArchivedMetadata, ) -> <T as Pointee>::Metadata
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<F, W, T, D> Deserialize<With<T, W>, D> for F
impl<F, W, T, D> Deserialize<With<T, W>, D> for F
impl<A, B, T> HttpServerConnExec<A, B> for Twhere
B: Body,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more