intrusive_lru_cache

Struct LRUCache

Source
pub struct LRUCache<K, V> { /* private fields */ }
Expand description

LRU Cache implementation using intrusive collections.

This cache uses an intrusive_collections::LinkedList to maintain the LRU order, and an intrusive_collections::RBTree to allow for efficient lookups by key, while maintaining only one allocation per key-value pair. Unfortunately, this is a linked structure, so cache locality is likely poor, but memory usage and flexibility are improved.

The cache is unbounded by default, but can be limited to a maximum capacity.

§Example

use intrusive_lru_cache::LRUCache;

let mut lru: LRUCache<&'static str, &'static str> = LRUCache::default();

lru.insert("a", "1");
lru.insert("b", "2");
lru.insert("c", "3");

let _ = lru.get("b"); // updates LRU order

assert_eq!(lru.pop(), Some(("a", "1")));
assert_eq!(lru.pop(), Some(("c", "3")));
assert_eq!(lru.pop(), Some(("b", "2")));
assert_eq!(lru.pop(), None);

§Notes

  • The cache is not thread-safe, and requires external synchronization.
  • Cloning the cache will preserve the LRU order.

Implementations§

Source§

impl<K, V> LRUCache<K, V>

Source

pub fn new() -> Self

Creates a new unbounded LRU cache.

This cache has no limit on the number of entries it can hold, so entries must be manually removed via pop, or you can use set_max_capacity to set a limit.

Source

pub fn new_with_max_capacity(max_capacity: usize) -> Self

Creates a new LRU cache with a maximum capacity, after which old entries will be evicted to make room for new ones.

This does not preallocate any memory, only sets an upper limit.

Source§

impl<K, V> LRUCache<K, V>
where K: Ord + 'static,

Source

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

Returns a reference to the value corresponding to the key, and bumps the key to the front of the LRU list.

This returns a mutable reference to the value because we already have a mutable reference to the cache.

Source

pub fn peek<'a, Q>(&'a self, key: &Q) -> Option<&'a V>
where K: Borrow<Q>, Q: Ord + ?Sized,

Returns a reference to the value corresponding to the key, without updating the LRU list.

Source

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

Inserts a key-value pair into the cache, returning the old value if the key was already present.

Source

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

Removes the value corresponding to the key from the cache, and returning it if it was present.

Source

pub fn insert_or_get(&mut self, key: K, value: V) -> InsertOrGetResult<'_, K, V>

Inserts a key-value pair into the cache only if it wasn’t already present, otherwise update the LRU order for this element and return a reference to the value.

The returned value contains a mutable reference to the value, and if the key already existed, it also contains the key and value that were passed in.

Source§

impl<K, V> LRUCache<K, V>

Source

pub fn set_max_capacity(&mut self, max_capacity: usize)

Sets the maximum capacity of the cache.

This does not remove any entries, but will cause the cache to evict entries when inserting new ones if the length exceeds the new capacity.

Use shrink to manually trigger removal of entries to meet the new capacity.

Source

pub fn clear(&mut self)

Clears the cache, removing all key-value pairs.

Source

pub fn shrink(&mut self)

Removes the oldest entries from the cache until the length is less than or equal to the maximum capacity.

Source

pub fn shrink_with<F>(&mut self, cb: F)
where F: FnMut(K, V),

Removes the oldest entries from the cache until the length is less than or equal to the maximum capacity, and calls the provided closure with the removed key-value pairs.

§Example
let mut lru: LRUCache<&'static str, &'static str> = LRUCache::default();

lru.insert("a", "1");
lru.insert("b", "2");
lru.insert("c", "3");

lru.set_max_capacity(1);

let mut removed = Vec::new();

lru.shrink_with(|key, value| {
   removed.push((key, value));
});

assert_eq!(removed, vec![("a", "1"), ("b", "2")]);
Source

pub const fn len(&self) -> usize

Returns the number of key-value pairs in the cache.

Source

pub fn is_empty(&self) -> bool

Returns true if the cache is empty.

Source

pub fn pop(&mut self) -> Option<(K, V)>

Removes and returns the least recently used key-value pair.

This is an O(1) operation.

Source

pub fn iter_lru(&self) -> impl DoubleEndedIterator<Item = (&K, &V)>

Returns an iterator over the key-value pairs in the cache, in order of most recently used to least recently used.

Source

pub fn iter_ord(&self) -> impl DoubleEndedIterator<Item = (&K, &V)>

Returns an iterator over the key-value pairs in the cache, in order of key Ord order.

Trait Implementations§

Source§

impl<K, V> Clone for LRUCache<K, V>
where K: Clone + Ord + 'static, V: Clone,

Source§

fn clone(&self) -> Self

Returns a copy of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<K, V> Default for LRUCache<K, V>

Source§

fn default() -> Self

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

impl<K, V> Drop for LRUCache<K, V>

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

impl<K, V> Extend<(K, V)> for LRUCache<K, V>
where K: Ord + 'static,

Source§

fn extend<T>(&mut self, iter: T)
where T: IntoIterator<Item = (K, V)>,

Extends a collection with the contents of an iterator. Read more
Source§

fn extend_one(&mut self, item: A)

🔬This is a nightly-only experimental API. (extend_one)
Extends a collection with exactly one element.
Source§

fn extend_reserve(&mut self, additional: usize)

🔬This is a nightly-only experimental API. (extend_one)
Reserves capacity in a collection for the given number of additional elements. Read more
Source§

impl<K, V> FromIterator<(K, V)> for LRUCache<K, V>
where K: Ord + 'static,

Source§

fn from_iter<T>(iter: T) -> Self
where T: IntoIterator<Item = (K, V)>,

Creates a value from an iterator. Read more
Source§

impl<K, V> IntoIterator for LRUCache<K, V>
where K: Ord + 'static,

Source§

type Item = (K, V)

The type of the elements being iterated over.
Source§

type IntoIter = IntoIter<K, V>

Which kind of iterator are we turning this into?
Source§

fn into_iter(self) -> Self::IntoIter

Creates an iterator from a value. Read more

Auto Trait Implementations§

§

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

§

impl<K, V> !RefUnwindSafe for LRUCache<K, V>

§

impl<K, V> Send for LRUCache<K, V>
where K: Send + Sync, V: Send + Sync,

§

impl<K, V> Sync for LRUCache<K, V>
where K: Sync, V: Sync,

§

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

§

impl<K, V> !UnwindSafe for LRUCache<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> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dst: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dst. 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> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
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.