Skip to main content

LruLockMap

Struct LruLockMap 

Source
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 LruEntry guard (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>

Source

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.

Source

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).

Source

pub fn len(&self) -> usize

Returns the total number of entries across all shards.

Source

pub fn is_empty(&self) -> bool

Returns true if the cache contains no entries.

Source

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);
Source

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);
Source

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);
}
Source

pub fn entry_by_ref<Q>(&self, key: &Q) -> LruEntry<'_, K, V>
where K: Borrow<Q> + for<'c> From<&'c Q>, Q: Eq + Hash + ?Sized,

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);
}
Source

pub fn get<Q>(&self, key: &Q) -> Option<V>
where K: Borrow<Q>, V: Clone, Q: Eq + Hash + ?Sized,

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);
Source

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));
Source

pub fn insert_by_ref<Q>(&self, key: &Q, value: V) -> Option<V>
where K: Borrow<Q> + for<'c> From<&'c Q>, Q: Eq + Hash + ?Sized,

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));
Source

pub fn contains_key<Q>(&self, key: &Q) -> bool
where K: Borrow<Q>, Q: Eq + Hash + ?Sized,

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"));
Source

pub fn remove<Q>(&self, key: &Q) -> Option<V>
where K: Borrow<Q>, Q: Eq + Hash + ?Sized,

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);

Trait Implementations§

Source§

impl<K, V> Debug for LruLockMap<K, V>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<K: Eq + Hash, V> Default for LruLockMap<K, V>

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

§

impl<K, V> Freeze for LruLockMap<K, V>

§

impl<K, V> RefUnwindSafe for LruLockMap<K, V>

§

impl<K, V> Send for LruLockMap<K, V>
where K: Send, V: Send,

§

impl<K, V> Sync for LruLockMap<K, V>
where K: Send, V: Send,

§

impl<K, V> Unpin for LruLockMap<K, V>

§

impl<K, V> UnsafeUnpin for LruLockMap<K, V>

§

impl<K, V> UnwindSafe for LruLockMap<K, V>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.