Skip to main content

Table

Struct Table 

Source
pub struct Table<H> { /* private fields */ }
Expand description

An open-addressing multimap from 64-bit hashes to caller-owned handles.

See the module documentation for the lookup contract.

§Example

use commonware_utils::handles::Table;

// FNV-1a stands in for a keyed hasher.
fn hash(key: &str) -> u64 {
    key.bytes().fold(0xcbf2_9ce4_8422_2325, |h, b| {
        (h ^ u64::from(b)).wrapping_mul(0x0100_0000_01b3)
    })
}

let keys = ["apple", "banana", "cherry"];
let mut table = Table::new();
for (handle, key) in keys.iter().enumerate() {
    table.insert(hash(key), handle, |handle| hash(keys[handle]));
}

// Confirm each candidate against the key it resolves to.
let find = |table: &Table<usize>, key| table.get(hash(key)).find(|&handle| keys[handle] == key);
assert_eq!(find(&table, "banana"), Some(1));
assert!(table.remove(hash("banana"), 1));
assert_eq!(find(&table, "banana"), None);

Implementations§

Source§

impl<H: Copy + Eq + Default> Table<H>

Source

pub const fn new() -> Self

Creates an empty table without allocating.

Source

pub fn with_capacity(entries: usize) -> Self

Creates an empty table that fits entries entries without growing.

§Panics

Panics if the required slot count overflows usize.

Source

pub const fn len(&self) -> usize

Returns the number of entries.

Source

pub const fn is_empty(&self) -> bool

Returns whether the table has no entries.

Source

pub const fn capacity(&self) -> usize

Returns the number of entries that fit before the next growth.

Source

pub fn reserve(&mut self, additional: usize, rehash: impl FnMut(H) -> u64)

Grows the table, if needed, so that inserting additional more entries never grows it. rehash is as for Table::insert.

§Panics

Panics if the required entry or slot count overflows usize, or if the slots need more than isize::MAX bytes.

Source

pub fn get(&self, hash: u64) -> impl Iterator<Item = H> + '_

Returns the handles whose home slot and fingerprint match hash, in probe order.

Every handle inserted under hash is yielded. Callers confirm each candidate against the key it resolves to, since entries with a different hash that shares the home slot and fingerprint are yielded too.

Source

pub fn prefetch(&self, hash: u64)

Hints the CPU to load the home slot of hash, so that a following lookup, insertion, or removal under hash waits less on memory.

Source

pub fn insert(&mut self, hash: u64, handle: H, rehash: impl FnMut(H) -> u64)

Inserts handle under hash.

Duplicate hashes and duplicate handles are allowed. rehash must map every handle already in the table to the hash it was inserted under, and it is called only when the table grows.

§Panics

Panics if an entry would end up more than 2^24 - 2 slots from its home, which takes a run of 2^24 occupied slots (for example, 2^24 entries with identical hashes).

Source

pub fn find_or_insert( &mut self, hash: u64, matches: impl FnMut(H) -> bool, handle: H, rehash: impl FnMut(H) -> u64, ) -> (H, bool)

Returns the first handle among the candidates for hash that matches accepts, or inserts handle under hash and returns it, in one walk of the run. The second value reports whether handle was inserted.

A full table grows first, even if a candidate is then accepted, so the candidates are those Table::get yields after any growth, in the same order. rehash is as for Table::insert.

§Panics

Panics if an entry would end up more than 2^24 - 2 slots from its home, or if growing the table would need more than isize::MAX bytes of slots.

Source

pub fn remove(&mut self, hash: u64, handle: H) -> bool

Removes one entry holding handle whose home slot and fingerprint match hash, returning whether one existed.

hash must be the hash the entry was inserted under. Like Table::get, matching is by home slot and fingerprint, so a different hash sharing both would remove the entry too.

Trait Implementations§

Source§

impl<H> Debug for Table<H>

Source§

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

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

impl<H: Copy + Eq + Default> Default for Table<H>

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

§

impl<H> Freeze for Table<H>
where Vec<Slot<H>>: Freeze,

§

impl<H> RefUnwindSafe for Table<H>
where Vec<Slot<H>>: RefUnwindSafe,

§

impl<H> Send for Table<H>
where Vec<Slot<H>>: Send,

§

impl<H> Sync for Table<H>
where Vec<Slot<H>>: Sync,

§

impl<H> Unpin for Table<H>
where Vec<Slot<H>>: Unpin,

§

impl<H> UnsafeUnpin for Table<H>
where Vec<Slot<H>>: UnsafeUnpin,

§

impl<H> UnwindSafe for Table<H>
where Vec<Slot<H>>: 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> 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> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

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> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Threaded<T> for T

Source§

type Rest = ()

The outputs beyond the threaded value.
Source§

fn split(self) -> (T, ())

Splits into the threaded value and the extra outputs.
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<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