Struct lru::LruCache

source ·
pub struct LruCache<K, V, S = DefaultHasher> { /* private fields */ }
Expand description

An LRU Cache

Implementations§

source§

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

source

pub fn new(cap: NonZeroUsize) -> LruCache<K, V>

Creates a new LRU Cache that holds at most cap items.

§Example
use lru::LruCache;
use std::num::NonZeroUsize;
let mut cache: LruCache<isize, &str> = LruCache::new(NonZeroUsize::new(10).unwrap());
source

pub fn unbounded() -> LruCache<K, V>

Creates a new LRU Cache that never automatically evicts items.

§Example
use lru::LruCache;
use std::num::NonZeroUsize;
let mut cache: LruCache<isize, &str> = LruCache::unbounded();
source§

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

source

pub fn with_hasher(cap: NonZeroUsize, hash_builder: S) -> LruCache<K, V, S>

Creates a new LRU Cache that holds at most cap items and uses the provided hash builder to hash keys.

§Example
use lru::{LruCache, DefaultHasher};
use std::num::NonZeroUsize;

let s = DefaultHasher::default();
let mut cache: LruCache<isize, &str> = LruCache::with_hasher(NonZeroUsize::new(10).unwrap(), s);
source

pub fn unbounded_with_hasher(hash_builder: S) -> LruCache<K, V, S>

Creates a new LRU Cache that never automatically evicts items and uses the provided hash builder to hash keys.

§Example
use lru::{LruCache, DefaultHasher};

let s = DefaultHasher::default();
let mut cache: LruCache<isize, &str> = LruCache::unbounded_with_hasher(s);
source

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

Puts a key-value pair into cache. If the key already exists in the cache, then it updates the key’s value and returns the old value. Otherwise, None is returned.

§Example
use lru::LruCache;
use std::num::NonZeroUsize;
let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());

assert_eq!(None, cache.put(1, "a"));
assert_eq!(None, cache.put(2, "b"));
assert_eq!(Some("b"), cache.put(2, "beta"));

assert_eq!(cache.get(&1), Some(&"a"));
assert_eq!(cache.get(&2), Some(&"beta"));
source

pub fn push(&mut self, k: K, v: V) -> Option<(K, V)>

Pushes a key-value pair into the cache. If an entry with key k already exists in the cache or another cache entry is removed (due to the lru’s capacity), then it returns the old entry’s key-value pair. Otherwise, returns None.

§Example
use lru::LruCache;
use std::num::NonZeroUsize;
let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());

assert_eq!(None, cache.push(1, "a"));
assert_eq!(None, cache.push(2, "b"));

// This push call returns (2, "b") because that was previously 2's entry in the cache.
assert_eq!(Some((2, "b")), cache.push(2, "beta"));

// This push call returns (1, "a") because the cache is at capacity and 1's entry was the lru entry.
assert_eq!(Some((1, "a")), cache.push(3, "alpha"));

assert_eq!(cache.get(&1), None);
assert_eq!(cache.get(&2), Some(&"beta"));
assert_eq!(cache.get(&3), Some(&"alpha"));
source

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

Returns a reference to the value of the key in the cache or None if it is not present in the cache. Moves the key to the head of the LRU list if it exists.

§Example
use lru::LruCache;
use std::num::NonZeroUsize;
let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());

cache.put(1, "a");
cache.put(2, "b");
cache.put(2, "c");
cache.put(3, "d");

assert_eq!(cache.get(&1), None);
assert_eq!(cache.get(&2), Some(&"c"));
assert_eq!(cache.get(&3), Some(&"d"));
source

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

Returns a mutable reference to the value of the key in the cache or None if it is not present in the cache. Moves the key to the head of the LRU list if it exists.

§Example
use lru::LruCache;
use std::num::NonZeroUsize;
let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());

cache.put("apple", 8);
cache.put("banana", 4);
cache.put("banana", 6);
cache.put("pear", 2);

assert_eq!(cache.get_mut(&"apple"), None);
assert_eq!(cache.get_mut(&"banana"), Some(&mut 6));
assert_eq!(cache.get_mut(&"pear"), Some(&mut 2));
source

pub fn get_key_value<'a, Q>(&'a mut self, k: &Q) -> Option<(&'a K, &'a V)>
where K: Borrow<Q>, Q: Hash + Eq + ?Sized,

Returns a key-value references pair of the key in the cache or None if it is not present in the cache. Moves the key to the head of the LRU list if it exists.

§Example
use lru::LruCache;
use std::num::NonZeroUsize;
let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());

cache.put(String::from("1"), "a");
cache.put(String::from("2"), "b");
cache.put(String::from("2"), "c");
cache.put(String::from("3"), "d");

assert_eq!(cache.get_key_value("1"), None);
assert_eq!(cache.get_key_value("2"), Some((&String::from("2"), &"c")));
assert_eq!(cache.get_key_value("3"), Some((&String::from("3"), &"d")));
source

pub fn get_or_insert<'a, F>(&'a mut self, k: K, f: F) -> &'a V
where F: FnOnce() -> V,

Returns a reference to the value of the key in the cache if it is present in the cache and moves the key to the head of the LRU list. If the key does not exist the provided FnOnce is used to populate the list and a reference is returned.

§Example
use lru::LruCache;
use std::num::NonZeroUsize;
let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());

cache.put(1, "a");
cache.put(2, "b");
cache.put(2, "c");
cache.put(3, "d");

assert_eq!(cache.get_or_insert(2, ||"a"), &"c");
assert_eq!(cache.get_or_insert(3, ||"a"), &"d");
assert_eq!(cache.get_or_insert(1, ||"a"), &"a");
assert_eq!(cache.get_or_insert(1, ||"b"), &"a");
source

pub fn try_get_or_insert<F, E>(&mut self, k: K, f: F) -> Result<&V, E>
where F: FnOnce() -> Result<V, E>,

Returns a reference to the value of the key in the cache if it is present in the cache and moves the key to the head of the LRU list. If the key does not exist the provided FnOnce is used to populate the list and a reference is returned. If FnOnce returns Err, returns the Err.

§Example
use lru::LruCache;
use std::num::NonZeroUsize;
let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());

cache.put(1, "a");
cache.put(2, "b");
cache.put(2, "c");
cache.put(3, "d");

let f = ||->Result<&str, String> {Err("failed".to_owned())};
let a = ||->Result<&str, String> {Ok("a")};
let b = ||->Result<&str, String> {Ok("b")};
assert_eq!(cache.try_get_or_insert(2, a), Ok(&"c"));
assert_eq!(cache.try_get_or_insert(3, a), Ok(&"d"));
assert_eq!(cache.try_get_or_insert(4, f), Err("failed".to_owned()));
assert_eq!(cache.try_get_or_insert(5, b), Ok(&"b"));
assert_eq!(cache.try_get_or_insert(5, a), Ok(&"b"));
source

pub fn get_or_insert_mut<'a, F>(&'a mut self, k: K, f: F) -> &'a mut V
where F: FnOnce() -> V,

Returns a mutable reference to the value of the key in the cache if it is present in the cache and moves the key to the head of the LRU list. If the key does not exist the provided FnOnce is used to populate the list and a mutable reference is returned.

§Example
use lru::LruCache;
use std::num::NonZeroUsize;
let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());

cache.put(1, "a");
cache.put(2, "b");

let v = cache.get_or_insert_mut(2, ||"c");
assert_eq!(v, &"b");
*v = "d";
assert_eq!(cache.get_or_insert_mut(2, ||"e"), &mut "d");
assert_eq!(cache.get_or_insert_mut(3, ||"f"), &mut "f");
assert_eq!(cache.get_or_insert_mut(3, ||"e"), &mut "f");
source

pub fn try_get_or_insert_mut<'a, F, E>( &'a mut self, k: K, f: F ) -> Result<&'a mut V, E>
where F: FnOnce() -> Result<V, E>,

Returns a mutable reference to the value of the key in the cache if it is present in the cache and moves the key to the head of the LRU list. If the key does not exist the provided FnOnce is used to populate the list and a mutable reference is returned. If FnOnce returns Err, returns the Err.

§Example
use lru::LruCache;
use std::num::NonZeroUsize;
let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());

cache.put(1, "a");
cache.put(2, "b");
cache.put(2, "c");

let f = ||->Result<&str, String> {Err("failed".to_owned())};
let a = ||->Result<&str, String> {Ok("a")};
let b = ||->Result<&str, String> {Ok("b")};
if let Ok(v) = cache.try_get_or_insert_mut(2, a) {
    *v = "d";
}
assert_eq!(cache.try_get_or_insert_mut(2, a), Ok(&mut "d"));
assert_eq!(cache.try_get_or_insert_mut(3, f), Err("failed".to_owned()));
assert_eq!(cache.try_get_or_insert_mut(4, b), Ok(&mut "b"));
assert_eq!(cache.try_get_or_insert_mut(4, a), Ok(&mut "b"));
source

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

Returns a reference to the value corresponding to the key in the cache or None if it is not present in the cache. Unlike get, peek does not update the LRU list so the key’s position will be unchanged.

§Example
use lru::LruCache;
use std::num::NonZeroUsize;
let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());

cache.put(1, "a");
cache.put(2, "b");

assert_eq!(cache.peek(&1), Some(&"a"));
assert_eq!(cache.peek(&2), Some(&"b"));
source

pub fn peek_mut<'a, Q>(&'a mut self, k: &Q) -> Option<&'a mut V>
where K: Borrow<Q>, Q: Hash + Eq + ?Sized,

Returns a mutable reference to the value corresponding to the key in the cache or None if it is not present in the cache. Unlike get_mut, peek_mut does not update the LRU list so the key’s position will be unchanged.

§Example
use lru::LruCache;
use std::num::NonZeroUsize;
let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());

cache.put(1, "a");
cache.put(2, "b");

assert_eq!(cache.peek_mut(&1), Some(&mut "a"));
assert_eq!(cache.peek_mut(&2), Some(&mut "b"));
source

pub fn peek_lru<'a>(&'a self) -> Option<(&'a K, &'a V)>

Returns the value corresponding to the least recently used item or None if the cache is empty. Like peek, peek_lru does not update the LRU list so the item’s position will be unchanged.

§Example
use lru::LruCache;
use std::num::NonZeroUsize;
let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());

cache.put(1, "a");
cache.put(2, "b");

assert_eq!(cache.peek_lru(), Some((&1, &"a")));
source

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

Returns a bool indicating whether the given key is in the cache. Does not update the LRU list.

§Example
use lru::LruCache;
use std::num::NonZeroUsize;
let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());

cache.put(1, "a");
cache.put(2, "b");
cache.put(3, "c");

assert!(!cache.contains(&1));
assert!(cache.contains(&2));
assert!(cache.contains(&3));
source

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

Removes and returns the value corresponding to the key from the cache or None if it does not exist.

§Example
use lru::LruCache;
use std::num::NonZeroUsize;
let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());

cache.put(2, "a");

assert_eq!(cache.pop(&1), None);
assert_eq!(cache.pop(&2), Some("a"));
assert_eq!(cache.pop(&2), None);
assert_eq!(cache.len(), 0);
source

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

Removes and returns the key and the value corresponding to the key from the cache or None if it does not exist.

§Example
use lru::LruCache;
use std::num::NonZeroUsize;
let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());

cache.put(1, "a");
cache.put(2, "a");

assert_eq!(cache.pop(&1), Some("a"));
assert_eq!(cache.pop_entry(&2), Some((2, "a")));
assert_eq!(cache.pop(&1), None);
assert_eq!(cache.pop_entry(&2), None);
assert_eq!(cache.len(), 0);
source

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

Removes and returns the key and value corresponding to the least recently used item or None if the cache is empty.

§Example
use lru::LruCache;
use std::num::NonZeroUsize;
let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());

cache.put(2, "a");
cache.put(3, "b");
cache.put(4, "c");
cache.get(&3);

assert_eq!(cache.pop_lru(), Some((4, "c")));
assert_eq!(cache.pop_lru(), Some((3, "b")));
assert_eq!(cache.pop_lru(), None);
assert_eq!(cache.len(), 0);
source

pub fn promote<'a, Q>(&'a mut self, k: &Q)
where K: Borrow<Q>, Q: Hash + Eq + ?Sized,

Marks the key as the most recently used one.

§Example
use lru::LruCache;
use std::num::NonZeroUsize;
let mut cache = LruCache::new(NonZeroUsize::new(3).unwrap());

cache.put(1, "a");
cache.put(2, "b");
cache.put(3, "c");
cache.get(&1);
cache.get(&2);

// If we do `pop_lru` now, we would pop 3.
// assert_eq!(cache.pop_lru(), Some((3, "c")));

// By promoting 3, we make sure it isn't popped.
cache.promote(&3);
assert_eq!(cache.pop_lru(), Some((1, "a")));
source

pub fn demote<'a, Q>(&'a mut self, k: &Q)
where K: Borrow<Q>, Q: Hash + Eq + ?Sized,

Marks the key as the least recently used one.

§Example
use lru::LruCache;
use std::num::NonZeroUsize;
let mut cache = LruCache::new(NonZeroUsize::new(3).unwrap());

cache.put(1, "a");
cache.put(2, "b");
cache.put(3, "c");
cache.get(&1);
cache.get(&2);

// If we do `pop_lru` now, we would pop 3.
// assert_eq!(cache.pop_lru(), Some((3, "c")));

// By demoting 1 and 2, we make sure those are popped first.
cache.demote(&2);
cache.demote(&1);
assert_eq!(cache.pop_lru(), Some((1, "a")));
assert_eq!(cache.pop_lru(), Some((2, "b")));
source

pub fn len(&self) -> usize

Returns the number of key-value pairs that are currently in the the cache.

§Example
use lru::LruCache;
use std::num::NonZeroUsize;
let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
assert_eq!(cache.len(), 0);

cache.put(1, "a");
assert_eq!(cache.len(), 1);

cache.put(2, "b");
assert_eq!(cache.len(), 2);

cache.put(3, "c");
assert_eq!(cache.len(), 2);
source

pub fn is_empty(&self) -> bool

Returns a bool indicating whether the cache is empty or not.

§Example
use lru::LruCache;
use std::num::NonZeroUsize;
let mut cache = LruCache::new(NonZeroUsize::new(2).unwrap());
assert!(cache.is_empty());

cache.put(1, "a");
assert!(!cache.is_empty());
source

pub fn cap(&self) -> NonZeroUsize

Returns the maximum number of key-value pairs the cache can hold.

§Example
use lru::LruCache;
use std::num::NonZeroUsize;
let mut cache: LruCache<isize, &str> = LruCache::new(NonZeroUsize::new(2).unwrap());
assert_eq!(cache.cap().get(), 2);
source

pub fn resize(&mut self, cap: NonZeroUsize)

Resizes the cache. If the new capacity is smaller than the size of the current cache any entries past the new capacity are discarded.

§Example
use lru::LruCache;
use std::num::NonZeroUsize;
let mut cache: LruCache<isize, &str> = LruCache::new(NonZeroUsize::new(2).unwrap());

cache.put(1, "a");
cache.put(2, "b");
cache.resize(NonZeroUsize::new(4).unwrap());
cache.put(3, "c");
cache.put(4, "d");

assert_eq!(cache.len(), 4);
assert_eq!(cache.get(&1), Some(&"a"));
assert_eq!(cache.get(&2), Some(&"b"));
assert_eq!(cache.get(&3), Some(&"c"));
assert_eq!(cache.get(&4), Some(&"d"));
source

pub fn clear(&mut self)

Clears the contents of the cache.

§Example
use lru::LruCache;
use std::num::NonZeroUsize;
let mut cache: LruCache<isize, &str> = LruCache::new(NonZeroUsize::new(2).unwrap());
assert_eq!(cache.len(), 0);

cache.put(1, "a");
assert_eq!(cache.len(), 1);

cache.put(2, "b");
assert_eq!(cache.len(), 2);

cache.clear();
assert_eq!(cache.len(), 0);
source

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

An iterator visiting all entries in most-recently used order. The iterator element type is (&K, &V).

§Examples
use lru::LruCache;
use std::num::NonZeroUsize;

let mut cache = LruCache::new(NonZeroUsize::new(3).unwrap());
cache.put("a", 1);
cache.put("b", 2);
cache.put("c", 3);

for (key, val) in cache.iter() {
    println!("key: {} val: {}", key, val);
}
source

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

An iterator visiting all entries in most-recently-used order, giving a mutable reference on V. The iterator element type is (&K, &mut V).

§Examples
use lru::LruCache;
use std::num::NonZeroUsize;

struct HddBlock {
    dirty: bool,
    data: [u8; 512]
}

let mut cache = LruCache::new(NonZeroUsize::new(3).unwrap());
cache.put(0, HddBlock { dirty: false, data: [0x00; 512]});
cache.put(1, HddBlock { dirty: true,  data: [0x55; 512]});
cache.put(2, HddBlock { dirty: true,  data: [0x77; 512]});

// write dirty blocks to disk.
for (block_id, block) in cache.iter_mut() {
    if block.dirty {
        // write block to disk
        block.dirty = false
    }
}

Trait Implementations§

source§

impl<K, V> Clone for LruCache<K, V>
where K: Hash + PartialEq + Eq + Clone, 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: Hash + Eq, V, S: BuildHasher> Debug for LruCache<K, V, S>

source§

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

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

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

source§

fn drop(&mut self)

Executes the destructor for this type. Read more
source§

impl<'a, K: Hash + Eq, V, S: BuildHasher> IntoIterator for &'a LruCache<K, V, S>

§

type Item = (&'a K, &'a V)

The type of the elements being iterated over.
§

type IntoIter = Iter<'a, K, V>

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

fn into_iter(self) -> Iter<'a, K, V>

Creates an iterator from a value. Read more
source§

impl<'a, K: Hash + Eq, V, S: BuildHasher> IntoIterator for &'a mut LruCache<K, V, S>

§

type Item = (&'a K, &'a mut V)

The type of the elements being iterated over.
§

type IntoIter = IterMut<'a, K, V>

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

fn into_iter(self) -> IterMut<'a, K, V>

Creates an iterator from a value. Read more
source§

impl<K: Hash + Eq, V> IntoIterator for LruCache<K, V>

§

type Item = (K, V)

The type of the elements being iterated over.
§

type IntoIter = IntoIter<K, V>

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

fn into_iter(self) -> IntoIter<K, V>

Creates an iterator from a value. Read more
source§

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

source§

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

Auto Trait Implementations§

§

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

§

impl<K, V, S> Unpin for LruCache<K, V, S>
where S: 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> ToOwned for T
where T: Clone,

§

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>,

§

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>,

§

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.