SHashMap

Struct SHashMap 

Source
pub struct SHashMap<K: StableType + AsFixedSizeBytes + Hash + Eq, V: StableType + AsFixedSizeBytes> { /* private fields */ }
Expand description

Reallocating, open addressing, linear probing, eager removes hash map

Conceptually the same thing as std::collections::HashMap, but with a couple of twists:

  1. zwohash is used, instead of SipHash, to make hashes faster and deterministic between canister upgrades.
  2. eager removes (no tombstones) are performed in order to prevent performance degradation.

This is a “finite” data structure - it can only handle up to u32::MAX / (1 + K::SIZE + V::SIZE) elements total. Putting more elements inside will panic.

Both K and V have to implement StableType and AsFixedSizeBytes traits. SHashMap also implements these traits itself, so you can nest it inside other stable structures.

Implementations§

Source§

impl<K: StableType + AsFixedSizeBytes + Hash + Eq, V: StableType + AsFixedSizeBytes> SHashMap<K, V>

Source

pub fn new() -> Self

Creates a new SHashMap of default capacity

Does not allocate any heap or stable memory.

§Example
// won't allocate until you insert something in it
let mut number_pairs = SHashMap::<u64, u64>::new();
Source

pub fn new_with_capacity(capacity: usize) -> Result<Self, OutOfMemory>

Creates a SHashMap of requested capacity.

Does allocate stable memory, returning OutOfMemory if there is not enough of it. If this function returns Ok, you are guaranteed to have enough stable memory to store at least capacity entries in it.

§Example
let mut at_least_10_number_pairs = SHashMap::<u64, u64>::new_with_capacity(10)
    .expect("Out of memory");
Source

pub fn insert(&mut self, key: K, value: V) -> Result<Option<V>, (K, V)>

Inserts a key-value pair in this SHashMap

Will try to reallocate, if length == capacity * 3/4 and there is no key-value pair stored by the same key. If the canister is out of stable memory, will return Err with the key-value pair that was about to get inserted.

If the insertion was successful, returns Option with a previous value stored by this key, if there was one.

Reallocation triggers a process of complete rehashing of keys.

§Example
let mut map = SHashMap::new();

match map.insert(1, 10) {
    Ok(prev) => println!("Success! Previous value == {prev:?}"),
    Err((k, v)) => println!("Out of memory. Unable to insert: {k}, {v}"),
};
Source

pub fn remove<Q>(&mut self, key: &Q) -> Option<V>
where K: Borrow<Q>, Q: Hash + Eq + ?Sized,

Removes a key-value pair by the provided key

Returns None if no pair was found by this key

§Examples
let mut map = SHashMap::new();

map.insert(1, 10).expect("Out of memory");

assert_eq!(map.remove(&1).unwrap(), 10);

Borrowed type is also accepted. If your key type is, for example, [SBox] of String, then you can remove the pair by String.

let mut map = SHashMap::new();
let str_key = String::from("The key");
let key = SBox::new(str_key.clone()).expect("Out of memory");

map.insert(key, 10).expect("Out of memory");

assert_eq!(map.remove(&str_key).unwrap(), 10);
Source

pub fn get<Q>(&self, key: &Q) -> Option<SRef<'_, V>>
where K: Borrow<Q>, Q: Hash + Eq + ?Sized,

Returns an immutable reference SRef to a value stored by the key

See also SHashMap::get_mut.

If no such key-value pair is found, returns None

Borrowed type is also accepted. If your key type is, for example, [SBox] of String, then you can get the value by String.

§Example
let mut map = SHashMap::new();   

let str_key = String::from("The key");
let key = SBox::new(str_key.clone()).expect("Out of memory");

map.insert(key, 10).expect("Out of memory");

assert_eq!(*map.get(&str_key).unwrap(), 10);
Source

pub fn get_mut<Q>(&mut self, key: &Q) -> Option<SRefMut<'_, V>>
where K: Borrow<Q>, Q: Hash + Eq + ?Sized,

Returns a mutable reference SRefMut to a value stored by the key

See also SHashMap::get.

If no such key-value pair is found, returns None

Borrowed type is also accepted. If your key type is, for example, [SBox] of String, then you can get the value by String.

Source

pub fn contains_key<Q>(&self, key: &Q) -> bool
where K: Borrow<Q>, Q: Hash + Eq + ?Sized,

Returns true if there exists a key-value pair stored by the provided key

Borrowed type is also accepted. If your key type is, for example, [SBox] of String, then you can get the value by String.

Source

pub const fn len(&self) -> usize

Returns the length of this SHashMap

Source

pub const fn capacity(&self) -> usize

Returns the capacity of this SHashMap

Source

pub const fn max_capacity() -> usize

Returns the maximum possible capacity of this SHashMap

Source

pub fn is_empty(&self) -> bool

Returns true if the length of this SHashMap is 0

Source

pub const fn is_full(&self) -> bool

Returns true if the next unique key insert will trigger the reallocation and rehashing

Source

pub fn iter(&self) -> SHashMapIter<'_, K, V>

Returns an iterator over entries of this SHashMap

Elements of this iterator are presented in unpredictable and non-deterministic order.

§Example
let mut map = SHashMap::new();

for i in 0..100 {
    map.insert(i, i).expect("Out of memory");
}

for (k, v) in map.iter() {
    println!("{}, {}", *k, *v);
}
Source

pub fn clear(&mut self)

Removes all elements from this SHashMap

Source

pub fn retain<F>(&mut self, f: F)
where F: FnMut(&K, &V) -> bool,

Filters this SHashMap, so only entries for which the provided lambda returns true are left

Source

pub fn debug_print(&self)

Prints byte representation of this SHashMap

Useful for tests

Trait Implementations§

Source§

impl<K: StableType + AsFixedSizeBytes + Hash + Eq, V: StableType + AsFixedSizeBytes> AsFixedSizeBytes for SHashMap<K, V>

Source§

const SIZE: usize = 24usize

Size of self when encoded
Source§

type Buf = [u8; 24]

Buffer that is used to encode this value into
Source§

fn as_fixed_size_bytes(&self, buf: &mut [u8])

Encodes itself into a slice of bytes. Read more
Source§

fn from_fixed_size_bytes(buf: &[u8]) -> Self

Decodes itself from a slice of bytes. Read more
Source§

fn as_new_fixed_size_bytes(&self) -> Self::Buf

Encodes itself into a new Self::Buf of size == Self::SIZE
Source§

impl<K: StableType + AsFixedSizeBytes + Hash + Eq + Debug, V: StableType + AsFixedSizeBytes + Debug> Debug for SHashMap<K, V>

Source§

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

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

impl<K: StableType + AsFixedSizeBytes + Hash + Eq, V: StableType + AsFixedSizeBytes> Default for SHashMap<K, V>

Source§

fn default() -> Self

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

impl<K: StableType + AsFixedSizeBytes + Hash + Eq, V: StableType + AsFixedSizeBytes> Drop for SHashMap<K, V>

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

impl<K: StableType + AsFixedSizeBytes + Hash + Eq, V: StableType + AsFixedSizeBytes> StableType for SHashMap<K, V>

Source§

unsafe fn stable_drop_flag_off(&mut self)

Sets stable drop flag to off position, if it is applicable Read more
Source§

unsafe fn stable_drop_flag_on(&mut self)

Should set stable drop flag to on position, if it is applicable Read more
Source§

fn should_stable_drop(&self) -> bool

Should return the value of the stable drop flag
Source§

unsafe fn stable_drop(&mut self)

Performs stable drop, releasing all underlying stable memory of this data structure Read more

Auto Trait Implementations§

§

impl<K, V> Freeze for SHashMap<K, V>

§

impl<K, V> RefUnwindSafe for SHashMap<K, V>

§

impl<K, V> Send for SHashMap<K, V>
where K: Send, V: Send,

§

impl<K, V> Sync for SHashMap<K, V>
where K: Sync, V: Sync,

§

impl<K, V> Unpin for SHashMap<K, V>
where K: Unpin, V: Unpin,

§

impl<K, V> UnwindSafe for SHashMap<K, V>
where K: UnwindSafe, V: 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> AsDynSizeBytes for T

Source§

fn as_dyn_size_bytes(&self) -> Vec<u8>

Encodes self into vector of bytes Read more
Source§

fn from_dyn_size_bytes(buf: &[u8]) -> T

Decodes self from a slice of bytes. 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<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

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> Same for T

Source§

type Output = T

Should always be Self
Source§

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

Source§

type Error = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

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.