Skip to main content

LruCache

Struct LruCache 

Source
pub struct LruCache<K, V, S = DefaultHashBuilder> { /* private fields */ }
Expand description

A Least Recently Used (LRU) cache with O(1) operations.

Maintains items in order of access recency. When capacity is reached, the least recently accessed item is evicted to make room for new entries.

§Type Parameters

  • K: Key type. Must implement Hash + Eq. For mutation operations, also needs Clone.
  • V: Value type. Must implement Clone for retrieval operations.
  • S: Hash builder type. Defaults to DefaultHashBuilder.

§Capacity Modes

  • Count-based: LruCache::new(cap) - limits number of entries
  • Size-based: LruCache::init(config, None) with max_size set - limits total content size
  • Dual-limit: LruCache::with_limits(cap, bytes) - limits both

§Example

use cache_rs::LruCache;
use cache_rs::config::LruCacheConfig;
use core::num::NonZeroUsize;

let config = LruCacheConfig {
    capacity: NonZeroUsize::new(2).unwrap(),
    max_size: u64::MAX,
};
let mut cache = LruCache::init(config, None);

cache.put("apple", 1);
cache.put("banana", 2);
assert_eq!(cache.get(&"apple"), Some(&1));

// "banana" is now LRU, so it gets evicted
cache.put("cherry", 3);
assert_eq!(cache.get(&"banana"), None);

Implementations§

Source§

impl<K: Hash + Eq, V: Clone, S: BuildHasher> LruCache<K, V, S>

Source

pub fn cap(&self) -> NonZeroUsize

Returns the maximum number of entries the cache can hold.

Source

pub fn len(&self) -> usize

Returns the current number of entries in the cache.

Source

pub fn is_empty(&self) -> bool

Returns true if the cache contains no entries.

Source

pub fn current_size(&self) -> u64

Returns the current total size of all cached content.

This is the sum of all size values passed to put_with_size(), or estimated sizes for entries added via put().

Source

pub fn max_size(&self) -> u64

Returns the maximum total content size the cache can hold.

Returns u64::MAX if no size limit was configured.

Source

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

Retrieves a reference to the value for the given key.

If the key exists, it is moved to the most-recently-used (MRU) position. Returns None if the key is not present.

§Example
use cache_rs::LruCache;
use cache_rs::config::LruCacheConfig;
use core::num::NonZeroUsize;

let config = LruCacheConfig {
    capacity: NonZeroUsize::new(10).unwrap(),
    max_size: u64::MAX,
};
let mut cache = LruCache::init(config, None);
cache.put("key", 42);

assert_eq!(cache.get(&"key"), Some(&42));
assert_eq!(cache.get(&"missing"), None);
Source

pub fn record_miss(&mut self, object_size: u64)

Records a cache miss for metrics tracking.

Call this when you look up a key, find it missing, and fetch from the underlying data source. This updates the miss counter in metrics.

§Arguments
  • object_size - Size of the object that was fetched (for byte tracking)
Source

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

Retrieves a mutable reference to the value for the given key.

If the key exists, it is moved to the MRU position. Returns None if the key is not present.

§Example
use cache_rs::LruCache;
use cache_rs::config::LruCacheConfig;
use core::num::NonZeroUsize;

let config = LruCacheConfig {
    capacity: NonZeroUsize::new(10).unwrap(),
    max_size: u64::MAX,
};
let mut cache = LruCache::init(config, None);
cache.put("counter", 0);

if let Some(val) = cache.get_mut(&"counter") {
    *val += 1;
}
assert_eq!(cache.get(&"counter"), Some(&1));
Source§

impl<K: Hash + Eq + Clone, V: Clone, S: BuildHasher> LruCache<K, V, S>

Source

pub fn put(&mut self, key: K, value: V) -> Option<(K, V)>

Inserts a key-value pair into the cache.

If the key already exists, the value is updated and the entry moves to the MRU position. The old key-value pair is returned.

If the cache is at capacity, the least recently used entry is evicted and returned.

§Returns
  • Some((old_key, old_value)) if the key existed or an entry was evicted
  • None if this was a new insertion with available capacity
§Example
use cache_rs::LruCache;
use cache_rs::config::LruCacheConfig;
use core::num::NonZeroUsize;

let config = LruCacheConfig {
    capacity: NonZeroUsize::new(2).unwrap(),
    max_size: u64::MAX,
};
let mut cache = LruCache::init(config, None);

assert_eq!(cache.put("a", 1), None);           // New entry
assert_eq!(cache.put("b", 2), None);           // New entry
assert_eq!(cache.put("a", 10), Some(("a", 1))); // Update existing
assert_eq!(cache.put("c", 3), Some(("b", 2))); // Evicts "b"
Source

pub fn put_with_size(&mut self, key: K, value: V, size: u64) -> Option<(K, V)>

Inserts a key-value pair with an explicit size.

Use this for size-aware caching where you want to track the actual memory or storage footprint of cached items.

§Arguments
  • key - The key to insert
  • value - The value to cache
  • size - The size this entry consumes (in your chosen unit, e.g., bytes)
§Returns

Same as put() - returns evicted or replaced entry if any.

§Example
use cache_rs::LruCache;
use cache_rs::config::LruCacheConfig;
use core::num::NonZeroUsize;

let config = LruCacheConfig {
    capacity: NonZeroUsize::new(100).unwrap(),
    max_size: 1024 * 1024,  // 1MB max
};
let mut cache: LruCache<String, Vec<u8>> = LruCache::init(config, None);

let data = vec![0u8; 1000];
cache.put_with_size("file".to_string(), data, 1000);

assert_eq!(cache.current_size(), 1000);
Source

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

Removes a key from the cache.

Returns the value if the key was present, None otherwise.

§Example
use cache_rs::LruCache;
use cache_rs::config::LruCacheConfig;
use core::num::NonZeroUsize;

let config = LruCacheConfig {
    capacity: NonZeroUsize::new(10).unwrap(),
    max_size: u64::MAX,
};
let mut cache = LruCache::init(config, None);
cache.put("key", 42);

assert_eq!(cache.remove(&"key"), Some(42));
assert_eq!(cache.remove(&"key"), None);  // Already removed
Source

pub fn clear(&mut self)

Removes all entries from the cache.

Resets current_size to 0 and clears all metrics counters.

Source

pub fn iter(&self) -> Iter<'_, K, V>

Returns an iterator over the cache entries.

§Panics

Not yet implemented.

Source

pub fn iter_mut(&mut self) -> IterMut<'_, K, V>

Returns a mutable iterator over the cache entries.

§Panics

Not yet implemented.

Source§

impl<K: Hash + Eq, V> LruCache<K, V>
where V: Clone,

Source

pub fn init( config: LruCacheConfig, hasher: Option<DefaultHashBuilder>, ) -> LruCache<K, V, DefaultHashBuilder>

Creates a new LRU cache from a configuration with an optional hasher.

This is the only way to create an LRU cache.

§Arguments
  • config - Configuration specifying capacity and optional size limit
  • hasher - Optional custom hash builder. If None, uses DefaultHashBuilder
§Example
use cache_rs::LruCache;
use cache_rs::config::LruCacheConfig;
use core::num::NonZeroUsize;

// Simple capacity-only cache
let config = LruCacheConfig {
    capacity: NonZeroUsize::new(100).unwrap(),
    max_size: u64::MAX,
};
let mut cache: LruCache<&str, i32> = LruCache::init(config, None);
cache.put("key", 42);

// Cache with size limit
let config = LruCacheConfig {
    capacity: NonZeroUsize::new(1000).unwrap(),
    max_size: 10 * 1024 * 1024,  // 10MB
};
let cache: LruCache<String, Vec<u8>> = LruCache::init(config, None);

Trait Implementations§

Source§

impl<K: Hash + Eq, V: Clone, S: BuildHasher> CacheMetrics for LruCache<K, V, S>

Source§

fn metrics(&self) -> BTreeMap<String, f64>

Returns all metrics as key-value pairs in deterministic order Read more
Source§

fn algorithm_name(&self) -> &'static str

Algorithm name for identification Read more
Source§

impl<K: Debug, V: Debug, S: Debug> Debug for LruCache<K, V, S>

Source§

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

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<K, V, S> Freeze for LruCache<K, V, S>
where S: Freeze,

§

impl<K, V, S> RefUnwindSafe for LruCache<K, V, S>

§

impl<K, V, S> Send for LruCache<K, V, S>
where K: Send, V: Send, S: Send,

§

impl<K, V, S> Sync for LruCache<K, V, S>
where K: Send, V: Send, S: Sync,

§

impl<K, V, S> Unpin for LruCache<K, V, S>
where S: Unpin, K: Unpin,

§

impl<K, V, S> UnwindSafe for LruCache<K, V, S>

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.