Struct LockFreeMap

Source
pub struct LockFreeMap<K, V, H = RandomState> { /* private fields */ }
Expand description

A lock-free map. Implemented using multi-level hash-tables (in a tree fashion) with ordered buckets.

§Design

In order to implement this map, we shall fix a constant named BITS, which should be smaller than the number of bits in the hash (and not 0). We chose 8 for it. Now, we define a table structure: an array of nodes with length 1 << BITS (256 in this case).

For inserting, we take the first BITS bits of the hash. Now, we verify the node. If it is empty, insert a new bucket with our entry (a leaf of the tree), and assign our hash to the bucket. If there is a branch (i.e. a sub-table), we shift the hash BITS bits to the left, but we also keep the original hash for consultation. Then we try again in the sub-table. If there is another leaf, and if the hash of the leaf’s bucket is equal to ours, we insert our entry into the bucket. If the hashes are not equal, we create a sub-table, insert the old leaf into the new sub-table, and insert our pair after.

Entries in a bucket are a single linked list ordered by key. The ordering of the list is because of possible race conditions if e.g. new nodes were always inserted at end. And if a bucket is detected to be empty, the table will be requested to delete the bucket.

For searching, in a similar way, the hash is shifted and sub-tables are entered until either a node is empty or a leaf is found. If the hash of the leaf’s bucket is equal to our hash, we search for the entry into the bucket. Because the bucket is ordered, we may know the entry is not present with ease.

Because of limitation of sharing in concurrent contexts, we do return plain references to the entries, neither allow the user to move out removed values, as they must be deinitialized correctly. Instead, we return guarded references to the entries and wrappers over removed entries.

Implementations§

Source§

impl<K, V> Map<K, V>

Source

pub fn new() -> Map<K, V>

Creates a new Map with the default hasher builder.

Source

pub fn with_incin(incin: SharedIncin<K, V>) -> Map<K, V>

Creates the Map using the given shared incinerator.

Source§

impl<K, V, H> Map<K, V, H>

Source

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

Creates an iterator over guarded references to the key-value entries.

Source

pub fn iter_mut(&mut self) -> IterMut<'_, K, V>

Creates an iterator over the key-value entries, with a mutable reference to the value.

Source

pub fn optimize_space(&mut self)

Tries to optimize space by removing unnecessary tables without removing any entry. This method might also clear delayed resource destruction. This method cannot be performed in a shared context.

Source

pub fn clear(&mut self)

Removes all entries. This method might also clear delayed resource destruction. This method cannot be performed in a shared context.

Source§

impl<K, V, H> Map<K, V, H>
where H: BuildHasher,

Source

pub fn with_hasher(builder: H) -> Map<K, V, H>

Creates the Map using the given hasher builder.

Source

pub fn with_hasher_and_incin( builder: H, incin: SharedIncin<K, V>, ) -> Map<K, V, H>

Creates the Map using the given hasher builder and shared incinerator.

Source

pub fn incin(&self) -> SharedIncin<K, V>

The shared incinerator used by this Map.

Source

pub fn hasher(&self) -> &H

The hasher buider used by this Map.

Source

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

Searches for the entry identified by the given key. The returned value is a guarded reference. Guarded to ensure no thread deallocates the allocation for the entry while it is being used. The method accepts a type resulted from borrowing the stored key. This method will only work correctly if Hash and Ord are implemented in the same way for the borrowed type and the stored type. If the entry was not found, None is returned.

Source

pub fn insert(&self, key: K, val: V) -> Option<Removed<K, V>>
where K: Hash + Ord,

Inserts unconditionally the given key and value. If there was a previously stored value, it is returned.

Source

pub fn insert_with<F>( &self, key: K, interactive: F, ) -> Insertion<K, V, (K, Option<V>)>
where K: Hash + Ord, F: FnMut(&K, Option<&mut V>, Option<&(K, V)>) -> Preview<V>,

Inserts interactively the given key. A closure is passed to generate the value part of the entry and validate it with the found value. Even though the closure may have already accepted some condition, it might get recalled many times due to concurrent modifications of the Map.

The first argument passed to the closure is the key passed in first place. The second argument is an optional mutable reference to a previously generated value. Obviously, if no value was ever generated, it is None. The third argument is a reference to the found stored entry. Obviously, if no stored entry was found, it is None. The return value of the closure is a specification of “what to do with the insertion now”.

Source

pub fn reinsert(&self, removed: Removed<K, V>) -> Insertion<K, V, Removed<K, V>>
where K: Hash + Ord,

Reinserts a previously removed entry. The entry must have been either:

  1. Removed from any Map using the same SharedIncin as this Map. 2. Removed from an already dead Map with dead SharedIncin. 3. Removed from a Map whose SharedIncin has no sensitive reads active.

If the removed entry does not fit any category, the insertion will fail. Otherwise, insertion cannot fail.

Source

pub fn reinsert_with<F>( &self, removed: Removed<K, V>, interactive: F, ) -> Insertion<K, V, Removed<K, V>>
where K: Hash + Ord, F: FnMut(&(K, V), Option<&(K, V)>) -> bool,

Reinserts interactively a previously removed entry. A closure will be passed to validate if the conditions are correct for the reinsertion. The first argument passed to the closure is a reference to the removed entry, the second argument is a reference to the stored found entry. Obviously, if no stored entry was found, the argument is None. The returned value is a boolean indicating if the reinsertion should go on. Even though the closure may have already accepted some condition, it might get recalled many times due to concurrent modifications of the Map.

The entry must have been either:

  1. Removed from any Map using the same SharedIncin as this Map. 2. Removed from an already dead Map with dead SharedIncin. 3. Removed from a Map whose SharedIncin has no sensitive reads active.

If the removed entry does not fit any category, the insertion will fail. Otherwise, insertion cannot fail.

Source

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

Removes unconditionally the entry identified by the given key. If no entry was found, None is returned. This method will only work correctly if Hash and Ord are implemented in the same way for the borrowed type and the stored type. If the entry was not found, None is returned.

Source

pub fn remove_with<Q, F>( &self, key: &Q, interactive: F, ) -> Option<Removed<K, V>>
where Q: Hash + Ord + ?Sized, K: Borrow<Q>, F: FnMut(&(K, V)) -> bool,

Removes interactively the entry identified by the given key. A closure is passed to validate the removal. The only argument passed to the closure is a reference to the found entry. The closure returns if the removal should go on. If no entry was found, None is returned. This method will only work correctly if Hash and Ord are implemented in the same way for the borrowed type and the stored type. If the entry was not found, None is returned.

Source

pub fn extend<I>(&self, iterable: I)
where I: IntoIterator<Item = (K, V)>, K: Hash + Ord,

Acts just like Extend::extend but does not require mutability.

Trait Implementations§

Source§

impl<K, V, H> Debug for Map<K, V, H>
where H: Debug,

Source§

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

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

impl<K, V, H> Default for Map<K, V, H>
where H: BuildHasher + Default,

Source§

fn default() -> Map<K, V, H>

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

impl<K, V, H> Drop for Map<K, V, H>

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

impl<K, V, H> Extend<(K, V)> for Map<K, V, H>
where H: BuildHasher, K: Hash + Ord,

Source§

fn extend<I>(&mut self, iterable: I)
where I: IntoIterator<Item = (K, V)>,

Extends a collection with the contents of an iterator. Read more
Source§

fn extend_one(&mut self, item: A)

🔬This is a nightly-only experimental API. (extend_one)
Extends a collection with exactly one element.
Source§

fn extend_reserve(&mut self, additional: usize)

🔬This is a nightly-only experimental API. (extend_one)
Reserves capacity in a collection for the given number of additional elements. Read more
Source§

impl<K, V, H> FromIterator<(K, V)> for Map<K, V, H>
where H: BuildHasher + Default, K: Hash + Ord,

Source§

fn from_iter<I>(iterable: I) -> Map<K, V, H>
where I: IntoIterator<Item = (K, V)>,

Creates a value from an iterator. Read more
Source§

impl<'map, K, V, H> IntoIterator for &'map Map<K, V, H>

Source§

type Item = ReadGuard<'map, K, V>

The type of the elements being iterated over.
Source§

type IntoIter = Iter<'map, K, V>

Which kind of iterator are we turning this into?
Source§

fn into_iter(self) -> <&'map Map<K, V, H> as IntoIterator>::IntoIter

Creates an iterator from a value. Read more
Source§

impl<'map, K, V, H> IntoIterator for &'map mut Map<K, V, H>

Source§

type Item = (&'map K, &'map mut V)

The type of the elements being iterated over.
Source§

type IntoIter = IterMut<'map, K, V>

Which kind of iterator are we turning this into?
Source§

fn into_iter(self) -> <&'map mut Map<K, V, H> as IntoIterator>::IntoIter

Creates an iterator from a value. Read more
Source§

impl<K, V, H> IntoIterator for Map<K, V, H>

Source§

type Item = (K, V)

The type of the elements being iterated over.
Source§

type IntoIter = IntoIter<K, V>

Which kind of iterator are we turning this into?
Source§

fn into_iter(self) -> <Map<K, V, H> as IntoIterator>::IntoIter

Creates an iterator from a value. Read more
Source§

impl<K, V> TableIndex<K, V> for Map<K, V>
where K: Hash + Clone + Ord + Send + Sync + 'static, V: Clone + Send + Sync + 'static,

Source§

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

Source§

fn peek(&self, key: &K) -> Option<V>

Source§

fn remove(&self, key: &K) -> bool

Source§

fn iter<'a>(&'a self) -> impl Iterator<Item = (&'a K, &'a V)>
where K: 'a, V: 'a,

Source§

fn range<'a, R: RangeBounds<K>>( &'a self, _: R, ) -> impl Iterator<Item = (&'a K, &'a V)>
where K: 'a, V: 'a,

Source§

impl<K, V, H> Send for Map<K, V, H>
where K: Send, V: Send, H: Send,

Source§

impl<K, V, H> Sync for Map<K, V, H>
where K: Sync, V: Sync, H: Sync,

Auto Trait Implementations§

§

impl<K, V, H> Freeze for Map<K, V, H>
where H: Freeze,

§

impl<K, V, H = RandomState> !RefUnwindSafe for Map<K, V, H>

§

impl<K, V, H> Unpin for Map<K, V, H>
where H: Unpin, K: Unpin, V: Unpin,

§

impl<K, V, H = RandomState> !UnwindSafe for Map<K, V, H>

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

Source§

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

Returns the layout of the type.
Source§

impl<T, N1, N2> Niching<NichedOption<T, N1>> for N2
where T: SharedNiching<N1, N2>, N1: Niching<T>, N2: Niching<T>,

Source§

unsafe fn is_niched(niched: *const NichedOption<T, N1>) -> bool

Returns whether the given value has been niched. Read more
Source§

fn resolve_niched(out: Place<NichedOption<T, N1>>)

Writes data to out indicating that a T is niched.
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 metadata type for pointers and references to this type.
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.