Build Status Latest Version docs.rs License License codecov unsafe forbidden

lockable

The lockable library offers thread-safe HashMap (see LockableHashMap), LruCache (see LockableLruCache) and LockPool (see LockPool) types. In all of these dat atypes, individual keys can be locked/unlocked, even if there is no entry for this key in the map or cache.

This can be very useful for synchronizing access to an underlying key-value store or for building cache data structures on top of such a key-value store.

LRU cache example

This example builds a simple LRU cache and locks some entries. ```rust use lockable::{AsyncLimit, LockableLruCache};

let lockable_cache = LockableLruCache::::new();

// Insert an entry lockablecache.asynclock(4, AsyncLimit::no_limit()) .await? .insert(String::from("Value"));

// Hold a lock on a different entry let guard = lockablecache.asynclock(5, AsyncLimit::no_limit()) .await?;

// This next line would wait until the lock gets released, // which in this case would cause a deadlock because we're // on the same thread // let guard2 = lockablecache.asynclock(5, AsyncLimit::no_limit()) // .await?;

// After dropping the corresponding guard, we can lock it again std::mem::drop(guard); let guard2 = lockablecache.asynclock(5, AsyncLimit::no_limit()) .await?; ```

Lockpool example

This example builds a simple lock pool using the LockPool data structure. A lock pool is a pool of keyable locks. This can be used if you don't need a cache but just some way to synchronize access to an underlying resource. ```rust use lockable::LockPool;

let lockpool = LockPool::new(); let guard1 = lockpool.asynclock(4).await; let guard2 = lockpool.asynclock(5).await;

// This next line would wait until the lock gets released, // which in this case would cause a deadlock because we're // on the same thread. // let guard3 = lockpool.async_lock(4).await;

// After dropping the corresponding guard, we can lock it again std::mem::drop(guard1); let guard3 = lockpool.async_lock(4).await; ```

HashMap example

If you need a lockable key-value store but don't need the LRU ordering, you can use LockableHashMap. ```rust use lockable::{AsyncLimit, LockableHashMap};

let lockable_map = LockableHashMap::::new();

// Insert an entry lockablemap.asynclock(4, AsyncLimit::no_limit()) .await? .insert(String::from("Value"));

// Hold a lock on a different entry let guard = lockablemap.asynclock(5, AsyncLimit::no_limit()) .await?;

// This next line would wait until the lock gets released, // which in this case would cause a deadlock because we're // on the same thread // let guard2 = lockablemap.asynclock(5, AsyncLimit::no_limit()) // .await?;

// After dropping the corresponding guard, we can lock it again std::mem::drop(guard); let guard2 = lockablemap.asynclock(5, AsyncLimit::no_limit()) .await?; ```

Crate Features

License: MIT OR Apache-2.0