4 releases
0.1.3 | Apr 6, 2024 |
---|---|
0.1.2 | Mar 18, 2024 |
0.1.1 | Mar 18, 2024 |
0.1.0 | Mar 18, 2024 |
#980 in Concurrency
16KB
402 lines
KeyMutex
What is KeyMutex?
KeyMutex<K, V>
is basically a lock-free HashMap<K, Mutex<V>>
(or RwLock
) with a few extra features.
Why do I need it?
Imagine you have a bunch of users identified by their IDs, and you want to have a lock for each user. That's when a KeyMutex<K, ()>
comes in handy. The difference from DashMap<K, Mutex<()>>
is that KeyMutex
will automatically release the entry when the last mutex guard is dropped.
Things might get trickier when you want to, say, maintain a user's active sessions. You need to have a KeyMutex<K, Vec<Session>>
, and you certainly don't want the entry be dropped unless the sessions are empty. Don't worry, KeyMutex
handles this for you. The entry will be dropped only when Empty::is_empty
returns true
, which is implemented for all collections in the standard library and also, of course, for KeyMutex
.
lib.rs
:
A concurrent, lock-free version of HashMap<K, Mutex<V>>
and HashMap<K, RwLock<V>>
.
It automatically allocates mutexes and rwlocks for you, and it automatically deallocates
them when they are no longer in use. The "no longer in use" condition is when the last
guard is dropped AND Empty::is_empty
returns true
.
It's a bit like Web Locks API
when V
is ()
.
Tokio version is available behind tokio
feature.
Example
use std::sync::Arc;
use key_mutex::KeyMutex;
fn main() {
let locks = KeyMutex::<u32, BTreeSet<String>>::new();
let mut lock = locks.lock(1).unwrap();
lock.insert("Hello".to_owned());
lock.insert("World".to_owned());
drop(lock);
// Value is not empty and thus is not dropped
assert_eq!(locks.len(), 1);
let mut lock = locks.lock(1).unwrap();
assert_eq!(lock.len(), 2);
lock.clear();
drop(lock);
// Should be dropped now
assert_eq!(locks.len(), 0);
}
Dependencies
~1–6.5MB
~41K SLoC