Skip to main content

hashtable_nodes

Struct hashtable_nodes 

Source
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 * 2 the table quadruples and every node is re-added in old-traversal order (c:183/219 → expandhashtable c:458-482);
  • an unsorted scan walks bucket 0..hsize-1, each chain head→tail (scanmatchtable c: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>

Source

pub fn newhashtable(size: usize) -> Self

Port of newhashtable(int size, …) from Src/hashtable.c:100 — zshcalloc(size * sizeof(HashNode)) + hsize = size + ct = 0.

Source

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.

Source

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.

Source

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.

Source

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.

Source

pub fn emptyhashtable(&mut self)

Port of emptyhashtable(HashTable ht) from Src/hashtable.c:517 (resizehashtable(ht, ht->hsize)) — frees every node, keeps hsize.

Source

pub fn len(&self) -> usize

C’s ht->ct (Src/zsh.h:1181).

Source

pub fn is_empty(&self) -> bool

ht->ct == 0.

Source

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.

Source

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.

Source

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.

Source

pub fn values(&self) -> impl Iterator<Item = &T>

The nodes in scanmatchtable order (Src/hashtable.c:420-434).

Source

pub fn values_mut(&mut self) -> impl Iterator<Item = &mut T>

Mutable companion of hashtable_nodes::values (Src/hashtable.c:420-434).

Source

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.

Source

pub fn contains_key(&self, nam: &str) -> bool

ht->getnode2(ht, nam) != NULL (Src/hashtable.c:255).

Source

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.

Source

pub fn remove(&mut self, nam: &str) -> Option<T>

ht->removenode(ht, nam) (Src/hashtable.c:275 removehashnode).

Source

pub fn clear(&mut self)

ht->emptytable(ht) (Src/hashtable.c:517 emptyhashtable).

Source

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>

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<T: Debug> Debug for hashtable_nodes<T>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<T> Default for hashtable_nodes<T>

Source§

fn default() -> Self

newparamtable/newmoduletable fall back to size = 17 when handed 0 (Src/params.c:541-542, and Src/module.c:1602 creates 17-bucket sub-tables); use that as the neutral default for #[derive(Default)] containers.

Source§

impl<T, Q: ?Sized + Borrow<str>> Index<&Q> for hashtable_nodes<T>

Source§

fn index(&self, nam: &Q) -> &T

ht->getnode2(ht, nam) with C’s “caller already checked” contract (Src/hashtable.c:255) — panics on a missing name, like the HashMap indexing it replaces.

Source§

type Output = T

The returned type after indexing.
Source§

impl<'a, T> IntoIterator for &'a hashtable_nodes<T>

Source§

fn into_iter(self) -> Self::IntoIter

for (k, v) in &table — the scanmatchtable walk (Src/hashtable.c:420-434).

Source§

type Item = (&'a String, &'a T)

The type of the elements being iterated over.
Source§

type IntoIter = Map<Flatten<Iter<'a, Vec<(String, T)>>>, fn(&'a (String, T)) -> (&'a String, &'a T)>

Which kind of iterator are we turning this into?

Auto Trait Implementations§

§

impl<T> Freeze for hashtable_nodes<T>
where Vec<Vec<(String, T)>>: Freeze,

§

impl<T> RefUnwindSafe for hashtable_nodes<T>
where Vec<Vec<(String, T)>>: RefUnwindSafe,

§

impl<T> Send for hashtable_nodes<T>
where Vec<Vec<(String, T)>>: Send,

§

impl<T> Sync for hashtable_nodes<T>
where Vec<Vec<(String, T)>>: Sync,

§

impl<T> Unpin for hashtable_nodes<T>
where Vec<Vec<(String, T)>>: Unpin,

§

impl<T> UnsafeUnpin for hashtable_nodes<T>
where Vec<Vec<(String, T)>>: UnsafeUnpin,

§

impl<T> UnwindSafe for hashtable_nodes<T>
where Vec<Vec<(String, T)>>: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> ArchivePointee for T

Source§

type ArchivedMetadata = ()

The archived version of the pointer metadata for this type.
Source§

fn pointer_metadata( _: &<T as ArchivePointee>::ArchivedMetadata, ) -> <T as Pointee>::Metadata

Converts some archived metadata to the pointer metadata for itself.
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<F, W, T, D> Deserialize<With<T, W>, D> for F
where W: DeserializeWith<F, T, D>, D: Fallible + ?Sized, F: ?Sized,

Source§

fn deserialize( &self, deserializer: &mut D, ) -> Result<With<T, W>, <D as Fallible>::Error>

Deserializes using the given deserializer
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> FromRef<T> for T
where T: Clone,

Source§

fn from_ref(input: &T) -> T

Converts to this type from a reference to the input type.
Source§

impl<A, B, T> HttpServerConnExec<A, B> for T
where B: Body,

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
where F: FnOnce(&Self) -> bool,

Converts 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
Source§

impl<T> LayoutRaw for T

Source§

fn layout_raw(_: <T as Pointee>::Metadata) -> Result<Layout, LayoutError>

Gets the layout of the type.
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> Pointee for T

Source§

type Metadata = ()

The type for metadata in pointers and references to Self.
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more