DashMap

repository·master·Indexed 26 days ago

https://github.com/xacrimon/dashmap

A high-performance concurrent associative array (hashmap) for Rust, designed as a direct replacement for `RwLock<HashMap<K, V>>`. It provides a simple API for shared-state concurrency where methods take `&self` instead of `&mut self`, allowing the map to be shared across threads via `Arc`. Features include a comprehensive Entry API, non-blocking lookups via `try_get`, and optional support for serde, rayon, and the arbitrary crate. Minimum Supported Rust Version (MSRV) is 1.70.

Tokens
5.5K
Snippets
9
Records
44
Agent score
87%

What's inside dashmap

  1. Overview of DashMap

    master

    DashMap is a high-performance concurrent associative array (hashmap) implementation for Rust. It is designed to be a direct, easy-to-use replacement for RwLock<HashMap<K, V>>.

    Key characteristics:

    • Concurrency Model: Unlike std::collections::HashMap, DashMap methods take &self instead of &mut self. This allows you to wrap a DashMap in an Arc<T> and share it across multiple threads while still performing mutations.
    • API Design: The API is modeled to be similar to std::collections::HashMap with minor adjustments to accommodate concurrency.
    • MSRV: The Minimum Supported Rust Version is 1.70. Note that DashMap typically stays at least one year behind the current stable Rust release.
  2. Configure DashMap Cargo features

    master

    You can enable additional functionality in dashmap by toggling the following Cargo features in your Cargo.toml:

    • serde: Enables serde support for serialization and deserialization.
    • raw-api: Enables the unstable raw-shard API.
    • rayon: Enables rayon support for parallel processing.
    • inline-more: Enables the inline-more feature from the hashbrown crate (may result in larger binaries due to excessive inlining).
    • arbitrary: Enables support for the arbitrary crate.
  3. Initialize a DashMap

    master

    DashMap is a concurrent associative array that provides an API similar to std::collections::HashMap. It is designed to be a direct replacement for RwLock<HashMap<K, V>>, allowing you to share it across threads using Arc<DashMap<K, V>> because most methods take &self instead of &mut self.

    Common initialization methods include:

    • new(): Creates a new map with capacity 0.
    • with_capacity(capacity): Creates a new map with a specified starting capacity.
    • with_shard_amount(shard_amount): Creates a new map with a specified shard amount. The shard_amount must be greater than 0 and a power of two; otherwise, it will panic.
    • with_hasher(hasher): Creates a new map with a provided hasher.
    • with_capacity_and_hasher(capacity, hasher): Creates a new map with a specified capacity and hasher.
    • with_capacity_and_shard_amount(capacity, shard_amount): Creates a new map with a specified capacity and shard amount (shard amount must be a power of two).
    • with_hasher_and_shard_amount(hasher, shard_amount): Creates a new map with a specified hasher and shard amount.
  4. Handle non-blocking read results with TryResult

    master

    When performing non-blocking reads from a DashMap, the operation returns a TryResult<R> enum. This type indicates whether the value was found, if the shard was unavailable due to a lock, or if the value was simply absent.

    Variants

    • Present(R): The value was found and the shard lock was successfully obtained.
    • Absent: The shard was not locked, but the value was not present in the map.
    • Locked: The shard was currently locked by another thread, preventing the read.

    Helper Methods

    • is_present(&self) -> bool: Returns true if the result is Present.
    • is_absent(&self) -> bool: Returns true if the result is Absent.
    • is_locked(&self) -> bool: Returns true if the result is Locked.
    • try_unwrap(self) -> Option<R>: Returns Some(R) if the result is Present, otherwise returns None. This is the recommended way to safely access the value.
    • unwrap(self) -> R: Returns the value if Present. Panics if the result is Locked or Absent.
  5. Insert and Remove elements from DashSet

    master

    Use the following methods to manage elements in a DashSet:

    • insert(key): Inserts a key into the set. Returns true if the key was not already present.
    • remove(key): Removes an entry from the set. Returns Option<K> containing the key if it existed.
    • remove_if(key, f): Removes an entry if the key exists and the provided predicate function f returns true. Returns Option<K>.
    • clear(): Removes all keys from the set.
    use dashmap::DashSet;
    
    let mut soccer_team = DashSet::new();
    soccer_team.insert("Jack");
    
    // Remove by key
    assert_eq!(soccer_team.remove("Jack").unwrap(), "Jack");
    
    // Conditional removal
    soccer_team.insert("Sam");
    soccer_team.remove_if("Sam", |player| player.starts_with("Ja"));
  6. Serialize and Deserialize DashMap with Serde

    master

    The DashMap type implements serde::Serialize and serde::Deserialize. This allows you to convert a DashMap to and from supported formats like JSON, Bincode, or YAML.

    When deserializing, DashMap is reconstructed using its default hasher. When serializing, it is treated as a standard map structure.

  7. Insert and retrieve values in DashMap

    master

    Use .insert(key, value) to add entries to the map. To retrieve a value, use .get(key), which returns a reference to the value. For mutable access, use .get_mut(key). Note that these methods will lock the shard containing the key.

    dm.insert(0, 0);
    assert_eq!(dm.get(&0).unwrap().value(), &0);
  8. Manage DashMap capacity and contents

    master

    Use these methods to manage the overall state of the map:

    • len(): Returns the total number of key-value pairs.
    • is_empty(): Returns true if the map contains no elements.
    • clear(): Removes all key-value pairs.
    • capacity(): Returns the total number of key-value pairs the map can store without reallocating.
    • shrink_to_fit(): Removes excess capacity to reduce memory usage.
    • retain(f): Keeps only the elements that satisfy the predicate f.
  9. Use `EntryRef` to manipulate map entries with borrowed keys

    master

    EntryRef allows you to access and modify an entry in a DashMap using a borrowed key (Q), which can avoid unnecessary cloning of the key type (K). It can be either Occupied or Vacant.

    Common Operations

    • and_modify(f): If the entry is occupied, applies the function f to the mutable value.
    • key(): Returns a reference to the key used to find the entry.
    • into_key(): Consumes the entry and returns the owned key K.
    • or_default(): Returns a mutable reference to the value. If the entry was vacant, it inserts the default value first.
    • or_insert(value): Returns a mutable reference to the value. If the entry was vacant, it inserts the provided value first.
    • or_insert_with(f): Returns a mutable reference to the value. If the entry was vacant, it inserts the result of the function f first.
    • or_try_insert_with(f): Returns Result<RefMut, E>. If the entry was vacant, it attempts to insert the result of f.
    • insert(value): Sets the value of the entry and returns a RefMut to the new value.
    • insert_entry(value): Sets the value and returns an OccupiedEntryRef. Use this if you need to continue working with the entry without re-cloning the key.
  10. Access and modify values in DashMap

    master

    DashMap provides several ways to access and modify values:

    • get(key): Returns an immutable reference (Ref) to the value.
    • get_mut(key): Returns a mutable reference (RefMut) to the value.
    • try_get(key): Returns a TryResult<Ref>. If the shard is currently locked, it returns TryResult::Locked instead of blocking.
    • try_get_mut(key): Returns a TryResult<RefMut>. If the shard is currently locked, it returns TryResult::Locked instead of blocking.
    • alter(key, f): Modifies a specific value in place using the function f.
    • alter_all(f): Modifies every value in the map using the function f.
    • view(key, f): Performs a scoped operation on a value using function f and returns the result of f.

    Warning: These methods may deadlock if called while holding a reference into the map.