Skip to main content

LRUCache

Struct LRUCache 

Source
pub struct LRUCache<V, ID: Hash, const USER_CAPACITY: usize = 2> {
    pub users: FxHashMap<ID, SmallVec<[u64; 2]>>,
    /* private fields */
}
Expand description

Reuse costly results across users, such as text measurements shared by several labels. Each user keeps its last USER_CAPACITY results. Saved results leave when no user needs them.

Fields§

§users: FxHashMap<ID, SmallVec<[u64; 2]>>

Tracks which saved results each user still needs.

Implementations§

Source§

impl<V, ID: Hash + Eq, const USER_CAPACITY: usize> LRUCache<V, ID, USER_CAPACITY>

Source

pub fn utilize<H: Hash>(&mut self, id: ID, hash_value: &H) -> Option<Rc<V>>

Reuses a saved result for this user and makes room by letting go of their oldest results. If it returns None, create the result and save it with insert.

Examples found in repository?
examples/caches.rs (line 22)
8fn main() {
9    let mut fifo = FifoCache::new(2);
10    for key in 0..2 {
11        fifo.insert(key, format!("Value {key}"));
12    }
13    fifo.insert(2, "Newest value".to_owned());
14    assert!(fifo.get(&0).is_none());
15    assert_eq!(fifo.len(), 2);
16    fifo.set_capacity(1);
17    assert_eq!(fifo.get(&1), None);
18    assert_eq!(fifo.len(), 1);
19
20    let mut shared = LRUCache::<String, u64>::default();
21    let first = shared
22        .utilize(1, &"greeting")
23        .unwrap_or_else(|| shared.insert(1, &"greeting", "Hello".to_owned()));
24    let second = shared
25        .utilize(2, &"greeting")
26        .unwrap_or_else(|| shared.insert(2, &"greeting", "Hello".to_owned()));
27    assert!(Rc::ptr_eq(&first, &second));
28
29    shared.remove(&1);
30    assert_eq!(shared.len(), 1);
31    shared.remove(&2);
32    assert!(shared.is_empty());
33    assert_eq!(first.as_str(), "Hello");
34}
Source

pub fn insert<H: Hash>(&mut self, id: ID, hash_value: &H, value: V) -> Rc<V>

Saves a newly created result for this user so others can reuse it without repeating the work. Call utilize first to check for a saved result and make room for this one.

Examples found in repository?
examples/caches.rs (line 23)
8fn main() {
9    let mut fifo = FifoCache::new(2);
10    for key in 0..2 {
11        fifo.insert(key, format!("Value {key}"));
12    }
13    fifo.insert(2, "Newest value".to_owned());
14    assert!(fifo.get(&0).is_none());
15    assert_eq!(fifo.len(), 2);
16    fifo.set_capacity(1);
17    assert_eq!(fifo.get(&1), None);
18    assert_eq!(fifo.len(), 1);
19
20    let mut shared = LRUCache::<String, u64>::default();
21    let first = shared
22        .utilize(1, &"greeting")
23        .unwrap_or_else(|| shared.insert(1, &"greeting", "Hello".to_owned()));
24    let second = shared
25        .utilize(2, &"greeting")
26        .unwrap_or_else(|| shared.insert(2, &"greeting", "Hello".to_owned()));
27    assert!(Rc::ptr_eq(&first, &second));
28
29    shared.remove(&1);
30    assert_eq!(shared.len(), 1);
31    shared.remove(&2);
32    assert!(shared.is_empty());
33    assert_eq!(first.as_str(), "Hello");
34}
Source

pub fn len(&self) -> usize

Counts saved results, counting a result shared by several users only once.

Examples found in repository?
examples/caches.rs (line 30)
8fn main() {
9    let mut fifo = FifoCache::new(2);
10    for key in 0..2 {
11        fifo.insert(key, format!("Value {key}"));
12    }
13    fifo.insert(2, "Newest value".to_owned());
14    assert!(fifo.get(&0).is_none());
15    assert_eq!(fifo.len(), 2);
16    fifo.set_capacity(1);
17    assert_eq!(fifo.get(&1), None);
18    assert_eq!(fifo.len(), 1);
19
20    let mut shared = LRUCache::<String, u64>::default();
21    let first = shared
22        .utilize(1, &"greeting")
23        .unwrap_or_else(|| shared.insert(1, &"greeting", "Hello".to_owned()));
24    let second = shared
25        .utilize(2, &"greeting")
26        .unwrap_or_else(|| shared.insert(2, &"greeting", "Hello".to_owned()));
27    assert!(Rc::ptr_eq(&first, &second));
28
29    shared.remove(&1);
30    assert_eq!(shared.len(), 1);
31    shared.remove(&2);
32    assert!(shared.is_empty());
33    assert_eq!(first.as_str(), "Hello");
34}
Source

pub fn is_empty(&self) -> bool

Examples found in repository?
examples/caches.rs (line 32)
8fn main() {
9    let mut fifo = FifoCache::new(2);
10    for key in 0..2 {
11        fifo.insert(key, format!("Value {key}"));
12    }
13    fifo.insert(2, "Newest value".to_owned());
14    assert!(fifo.get(&0).is_none());
15    assert_eq!(fifo.len(), 2);
16    fifo.set_capacity(1);
17    assert_eq!(fifo.get(&1), None);
18    assert_eq!(fifo.len(), 1);
19
20    let mut shared = LRUCache::<String, u64>::default();
21    let first = shared
22        .utilize(1, &"greeting")
23        .unwrap_or_else(|| shared.insert(1, &"greeting", "Hello".to_owned()));
24    let second = shared
25        .utilize(2, &"greeting")
26        .unwrap_or_else(|| shared.insert(2, &"greeting", "Hello".to_owned()));
27    assert!(Rc::ptr_eq(&first, &second));
28
29    shared.remove(&1);
30    assert_eq!(shared.len(), 1);
31    shared.remove(&2);
32    assert!(shared.is_empty());
33    assert_eq!(first.as_str(), "Hello");
34}
Source

pub fn users_len(&self) -> usize

Counts users being tracked, including those with no saved results yet.

Source

pub fn remove(&mut self, id: &ID)

Stops keeping results for a user that has gone away, such as a label removed from the screen. Results still needed by other users stay saved, and copies already handed out remain usable.

Examples found in repository?
examples/caches.rs (line 29)
8fn main() {
9    let mut fifo = FifoCache::new(2);
10    for key in 0..2 {
11        fifo.insert(key, format!("Value {key}"));
12    }
13    fifo.insert(2, "Newest value".to_owned());
14    assert!(fifo.get(&0).is_none());
15    assert_eq!(fifo.len(), 2);
16    fifo.set_capacity(1);
17    assert_eq!(fifo.get(&1), None);
18    assert_eq!(fifo.len(), 1);
19
20    let mut shared = LRUCache::<String, u64>::default();
21    let first = shared
22        .utilize(1, &"greeting")
23        .unwrap_or_else(|| shared.insert(1, &"greeting", "Hello".to_owned()));
24    let second = shared
25        .utilize(2, &"greeting")
26        .unwrap_or_else(|| shared.insert(2, &"greeting", "Hello".to_owned()));
27    assert!(Rc::ptr_eq(&first, &second));
28
29    shared.remove(&1);
30    assert_eq!(shared.len(), 1);
31    shared.remove(&2);
32    assert!(shared.is_empty());
33    assert_eq!(first.as_str(), "Hello");
34}
Source

pub fn reset(&mut self)

Clears saved results and user tracking.

Trait Implementations§

Source§

impl<V, ID: Hash, const USER_CAPACITY: usize> Debug for LRUCache<V, ID, USER_CAPACITY>

Source§

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

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

impl<V, ID: Hash, const USER_CAPACITY: usize> Default for LRUCache<V, ID, USER_CAPACITY>

Source§

fn default() -> Self

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

Auto Trait Implementations§

§

impl<V, ID, const USER_CAPACITY: usize = 2> !Send for LRUCache<V, ID, USER_CAPACITY>

§

impl<V, ID, const USER_CAPACITY: usize = 2> !Sync for LRUCache<V, ID, USER_CAPACITY>

§

impl<V, ID, const USER_CAPACITY: usize> Forget for LRUCache<V, ID, USER_CAPACITY>

§

impl<V, ID, const USER_CAPACITY: usize> Freeze for LRUCache<V, ID, USER_CAPACITY>

§

impl<V, ID, const USER_CAPACITY: usize> RefUnwindSafe for LRUCache<V, ID, USER_CAPACITY>

§

impl<V, ID, const USER_CAPACITY: usize> Unpin for LRUCache<V, ID, USER_CAPACITY>

§

impl<V, ID, const USER_CAPACITY: usize> UnsafeUnpin for LRUCache<V, ID, USER_CAPACITY>

§

impl<V, ID, const USER_CAPACITY: usize> UnwindSafe for LRUCache<V, ID, USER_CAPACITY>

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 = !

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

fn try_from(value: U) -> Result<T, !>

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.