pub struct LockMap<K, V> { /* private fields */ }Expand description
A thread-safe hashmap that supports locking entries at the key level.
LockMap provides a concurrent hashmap with fine-grained per-key locking.
Each key can be independently locked, so operations on different keys can
proceed in parallel. The map is internally sharded to reduce contention on
the map structure itself.
§Storage Design
The key and its pre-computed hash are stored together in the internal entry state, so each operation hashes the key only once. The full hash is also reused for shard selection and table probing.
§Examples
use lockmap::LockMap;
let map = LockMap::<String, u32>::new();
// Basic operations
map.insert("key1".to_string(), 42);
assert_eq!(map.get("key1"), Some(42));
// Entry API for exclusive access
{
let mut entry = map.entry("key2".to_string());
entry.insert(123);
}
// Remove a value
assert_eq!(map.remove("key1"), Some(42));
assert_eq!(map.get("key1"), None);Implementations§
Source§impl<K: Eq + Hash, V> LockMap<K, V>
impl<K: Eq + Hash, V> LockMap<K, V>
Sourcepub fn with_capacity(capacity: usize) -> Self
pub fn with_capacity(capacity: usize) -> Self
Creates a new LockMap with the specified initial capacity.
Sourcepub fn with_capacity_and_shard_amount(
capacity: usize,
shard_amount: usize,
) -> Self
pub fn with_capacity_and_shard_amount( capacity: usize, shard_amount: usize, ) -> Self
Creates a new LockMap with the specified initial capacity and number of shards.
Sourcepub fn entry(&self, key: K) -> Entry<'_, K, V>
pub fn entry(&self, key: K) -> Entry<'_, K, V>
Gets exclusive access to an entry in the map.
The returned Entry provides exclusive access to the key and its
associated value until it is dropped.
Locking behaviour: Deadlock if called when holding the same entry.
§Examples
let map = LockMap::<String, u32>::new();
{
let mut entry = map.entry("key".to_string());
entry.insert(42);
}Sourcepub fn entry_by_ref<Q>(&self, key: &Q) -> Entry<'_, K, V>
pub fn entry_by_ref<Q>(&self, key: &Q) -> Entry<'_, K, V>
Gets exclusive access to an entry by reference.
Locking behaviour: Deadlock if called when holding the same entry.
§Examples
let map = LockMap::<String, u32>::new();
{
let mut entry = map.entry_by_ref("key");
entry.insert(42);
}Sourcepub fn get<Q>(&self, key: &Q) -> Option<V>
pub fn get<Q>(&self, key: &Q) -> Option<V>
Gets the value associated with the given key.
If other threads are currently accessing the key, this will wait until exclusive access is available before returning.
§Performance Note
When no other thread holds an entry for this key, the clone() operation
is performed while holding the shard lock. If V::clone() is expensive,
consider using entry() or entry_by_ref() combined with Entry::get()
to avoid blocking other keys in the same shard.
Locking behaviour: Deadlock if called when holding the same entry.
§Examples
use lockmap::LockMap;
let map = LockMap::<String, u32>::new();
map.insert("key".to_string(), 42);
assert_eq!(map.get("key"), Some(42));
assert_eq!(map.get("missing"), None);Sourcepub fn insert(&self, key: K, value: V) -> Option<V>
pub fn insert(&self, key: K, value: V) -> Option<V>
Sets a value in the map, returning the previous value if any.
Locking behaviour: Deadlock if called when holding the same entry.
§Examples
use lockmap::LockMap;
let map = LockMap::<String, u32>::new();
assert_eq!(map.insert("key".to_string(), 42), None);
assert_eq!(map.insert("key".to_string(), 123), Some(42));Sourcepub fn insert_by_ref<Q>(&self, key: &Q, value: V) -> Option<V>
pub fn insert_by_ref<Q>(&self, key: &Q, value: V) -> Option<V>
Sets a value in the map by reference key.
Locking behaviour: Deadlock if called when holding the same entry.
§Examples
use lockmap::LockMap;
let map = LockMap::<String, u32>::new();
map.insert_by_ref("key", 42);
assert_eq!(map.get("key"), Some(42));Sourcepub fn contains_key<Q>(&self, key: &Q) -> bool
pub fn contains_key<Q>(&self, key: &Q) -> bool
Checks if the map contains a key.
Locking behaviour: Deadlock if called when holding the same entry.
§Examples
use lockmap::LockMap;
let map = LockMap::new();
map.insert("key", 42);
assert!(map.contains_key("key"));
assert!(!map.contains_key("non_existent_key"));Sourcepub fn remove<Q>(&self, key: &Q) -> Option<V>
pub fn remove<Q>(&self, key: &Q) -> Option<V>
Removes a key from the map.
Locking behaviour: Deadlock if called when holding the same entry.
§Examples
use lockmap::LockMap;
let map = LockMap::<String, u32>::new();
map.insert("key".to_string(), 42);
assert_eq!(map.remove("key"), Some(42));
assert_eq!(map.get("key"), None);Sourcepub fn batch_lock<'a, M>(&'a self, keys: BTreeSet<K>) -> M
pub fn batch_lock<'a, M>(&'a self, keys: BTreeSet<K>) -> M
Acquires exclusive locks for a batch of keys in a deadlock-safe manner.
Takes a BTreeSet of keys, ensuring they are processed and locked
in a consistent, sorted order across all threads.
§Examples
use lockmap::LockMap;
use std::collections::BTreeSet;
let map = LockMap::<u32, u32>::new();
map.insert(1, 100);
map.insert(2, 200);
map.insert(3, 300);
let mut keys = BTreeSet::new();
keys.insert(3);
keys.insert(1);
keys.insert(2);
let mut locked_entries = map.batch_lock::<std::collections::HashMap<_, _>>(keys);
locked_entries.get_mut(&1).and_then(|entry| entry.insert(101));
locked_entries.get_mut(&2).and_then(|entry| entry.insert(201));
locked_entries.get_mut(&3).and_then(|entry| entry.insert(301));
drop(locked_entries);
assert_eq!(map.get(&1), Some(101));
assert_eq!(map.get(&2), Some(201));
assert_eq!(map.get(&3), Some(301));