Skip to main content

TinyLfuCache

Struct TinyLfuCache 

Source
pub struct TinyLfuCache<K, V> { /* private fields */ }
Available on crate feature std only.
Expand description

A bounded, thread-safe cache with admission control.

TinyLfuCache tracks the access frequency of every key it observes — including keys that aren’t (yet) in the cache — using a fixed-size Count-Min Sketch. On capacity overflow, an incoming key is admitted only if its estimated frequency exceeds the LRU victim’s. One-hit-wonders are rejected at the door instead of evicting hot entries.

This is a deliberate semantic deviation from LruCache / LfuCache / TtlCache: a successful insert call does not guarantee that the value is in the cache. The admission filter may have rejected it. Callers that need strict insertion guarantees should use LruCache or LfuCache instead.

Reference implementation details:

  • depth-4 Count-Min Sketch with u8 saturating counters
  • width = max(MIN_SKETCH_WIDTH, 2 × capacity), rounded to the next power of two
  • periodic frequency decay: every 10 × capacity increments, every counter is right-shifted by 1 (this is the “aging” step from the W-TinyLFU paper, which keeps the sketch responsive to shifting workloads)
  • main cache uses LRU ordering; eviction victim = least-recently-accessed
  • lock-minimized via &self + Mutex<Inner>; a true sharded / lock-free variant lands in a later minor without changing this public surface

§Example

use cache_mod::{Cache, TinyLfuCache};

let cache: TinyLfuCache<&'static str, u32> =
    TinyLfuCache::new(4).expect("capacity > 0");

// Build up the frequency signal for "hot".
for _ in 0..16 {
    let _ = cache.get(&"hot");
    let _ = cache.insert("hot", 1);
}

// A subsequent insert will see "hot" as warm in the sketch.
assert_eq!(cache.get(&"hot"), Some(1));

Implementations§

Source§

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

Source

pub fn new(capacity: usize) -> Result<Self, CacheError>

Creates a cache with the given entry-count capacity.

Returns CacheError::InvalidCapacity if capacity == 0.

§Example
use cache_mod::TinyLfuCache;

let cache: TinyLfuCache<String, u32> =
    TinyLfuCache::new(256).expect("capacity > 0");
Source

pub fn with_capacity(capacity: NonZeroUsize) -> Self

Creates a cache with the given non-zero capacity. Infallible.

§Example
use std::num::NonZeroUsize;
use cache_mod::TinyLfuCache;

let cap = NonZeroUsize::new(256).expect("256 != 0");
let cache: TinyLfuCache<String, u32> = TinyLfuCache::with_capacity(cap);

Trait Implementations§

Source§

impl<K, V> Cache<K, V> for TinyLfuCache<K, V>
where K: Eq + Hash + Clone, V: Clone,

Source§

fn get(&self, key: &K) -> Option<V>

Returns the value associated with key, if any, and counts as an access for the purposes of the eviction policy.
Source§

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

Inserts value under key. Returns the previously-stored value if key was already present. Read more
Source§

fn remove(&self, key: &K) -> Option<V>

Removes the entry for key and returns the value if present.
Source§

fn contains_key(&self, key: &K) -> bool

Returns true if the cache currently holds an entry for key. Read more
Source§

fn len(&self) -> usize

Number of entries currently stored.
Source§

fn clear(&self)

Removes every entry. Capacity is preserved.
Source§

fn capacity(&self) -> usize

Configured capacity bound. Read more
Source§

fn is_empty(&self) -> bool

Returns true when the cache holds no entries.

Auto Trait Implementations§

§

impl<K, V> !Freeze for TinyLfuCache<K, V>

§

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

§

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

§

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

§

impl<K, V> Unpin for TinyLfuCache<K, V>
where K: Unpin, V: Unpin,

§

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

§

impl<K, V> UnwindSafe for TinyLfuCache<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.