pub struct LruLockMap<K, V> { /* private fields */ }Expand description
A thread-safe LRU cache that supports locking entries at the key level.
LruLockMap extends the per-key locking design of LockMap
with LRU (Least Recently Used) eviction. The total capacity is divided evenly
among internal shards, and each shard independently evicts its least-recently-used
entries when it exceeds its share of the capacity.
§Eviction Policy
- On every access (get, insert, entry, remove, contains_key), the accessed entry is promoted to the head of its shard’s LRU list.
- After an access that may increase the shard size, entries are evicted from the tail of the LRU list until the shard is within capacity.
- Entries with an active
LruEntryguard (refcnt > 0) are skipped during eviction — traversal continues to the next candidate so that eviction still makes progress even when the tail entry is held.
§Examples
use lockmap::LruLockMap;
let cache = LruLockMap::<String, u32>::new(1024);
cache.insert("a".to_string(), 1);
cache.insert("b".to_string(), 2);
assert_eq!(cache.get("a"), Some(1));
{
let mut entry = cache.entry("c".to_string());
entry.insert(3);
}
assert_eq!(cache.remove("b"), Some(2));Implementations§
Source§impl<K: Eq + Hash, V> LruLockMap<K, V>
impl<K: Eq + Hash, V> LruLockMap<K, V>
Sourcepub fn new(max_size: usize) -> Self
pub fn new(max_size: usize) -> Self
Creates a new LruLockMap with the given total capacity.
The capacity is divided evenly among the default number of shards.
Sourcepub fn with_options(
max_size: usize,
initial_capacity: usize,
shard_amount: usize,
) -> Self
pub fn with_options( max_size: usize, initial_capacity: usize, shard_amount: usize, ) -> Self
Creates a new LruLockMap with the given total capacity and number of shards.
Each shard will have a capacity of max_size / shard_amount (rounded up).
Sourcepub fn max_size(&self) -> usize
pub fn max_size(&self) -> usize
Returns the configured target capacity of the cache, in number of entries.
This is the total logical capacity across all shards, computed from the
per‑shard limits. The per‑shard limit is derived using
max_size.div_ceil(shard_amount), so the effective total capacity may be
rounded up compared to the value originally passed to [with_options].
§Examples
let cache = LruLockMap::<String, u32>::with_options(100, 100, 10);
assert_eq!(cache.max_size(), 100);Sourcepub fn set_max_size(&self, max_size: usize)
pub fn set_max_size(&self, max_size: usize)
Sets the maximum number of entries that can be stored in the cache.
The capacity is divided evenly among all shards. Note that the actual capacity may be slightly larger than requested due to rounding up when dividing by number of shards.
Eviction behavior: This operation does not immediately trigger eviction of excess entries. Eviction will occur lazily on subsequent insertions and other operations that may increase the cache size.
§Examples
let cache = LruLockMap::<u32, u32>::with_options(100, 100, 10);
cache.set_max_size(200);
assert_eq!(cache.max_size(), 200);Sourcepub fn entry(&self, key: K) -> LruEntry<'_, K, V>
pub fn entry(&self, key: K) -> LruEntry<'_, K, V>
Gets exclusive access to an entry in the cache.
The returned LruEntry provides exclusive access to the key and
its associated value until it is dropped. Accessing the entry promotes it
in the LRU list and may trigger eviction of other entries.
Locking behaviour: Deadlock if called when holding the same entry.
§Examples
let cache = LruLockMap::<String, u32>::new(100);
{
let mut entry = cache.entry("key".to_string());
entry.insert(42);
}Sourcepub fn entry_by_ref<Q>(&self, key: &Q) -> LruEntry<'_, K, V>
pub fn entry_by_ref<Q>(&self, key: &Q) -> LruEntry<'_, K, V>
Gets exclusive access to an entry by reference.
Locking behaviour: Deadlock if called when holding the same entry.
§Examples
let cache = LruLockMap::<String, u32>::new(100);
{
let mut entry = cache.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.
Accessing the key promotes it in the LRU list.
Locking behaviour: Deadlock if called when holding the same entry.
§Examples
let cache = LruLockMap::<String, u32>::new(100);
cache.insert("key".to_string(), 42);
assert_eq!(cache.get("key"), Some(42));
assert_eq!(cache.get("missing"), None);Sourcepub fn insert(&self, key: K, value: V) -> Option<V>
pub fn insert(&self, key: K, value: V) -> Option<V>
Inserts a value into the cache, returning the previous value if any.
Locking behaviour: Deadlock if called when holding the same entry.
§Examples
let cache = LruLockMap::<String, u32>::new(100);
assert_eq!(cache.insert("key".to_string(), 42), None);
assert_eq!(cache.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>
Inserts a value by reference key.
Locking behaviour: Deadlock if called when holding the same entry.
§Examples
let cache = LruLockMap::<String, u32>::new(100);
cache.insert_by_ref("key", 42);
assert_eq!(cache.get("key"), Some(42));Sourcepub fn contains_key<Q>(&self, key: &Q) -> bool
pub fn contains_key<Q>(&self, key: &Q) -> bool
Returns true if the cache contains the given key.
Accessing the key promotes it in the LRU list.
Locking behaviour: Deadlock if called when holding the same entry.
§Examples
let cache = LruLockMap::<String, u32>::new(100);
cache.insert("key".to_string(), 42);
assert!(cache.contains_key("key"));
assert!(!cache.contains_key("missing"));Sourcepub fn remove<Q>(&self, key: &Q) -> Option<V>
pub fn remove<Q>(&self, key: &Q) -> Option<V>
Removes a key from the cache, returning the value if it existed.
Locking behaviour: Deadlock if called when holding the same entry.
§Examples
let cache = LruLockMap::<String, u32>::new(100);
cache.insert("key".to_string(), 42);
assert_eq!(cache.remove("key"), Some(42));
assert_eq!(cache.get("key"), None);