pub struct Cache<K, V, S = RandomState> { /* private fields */ }Expand description
An in-memory cache that is not thread-safe.
Cache utilizes a hash table std::collections::HashMap from the
standard library for the central key-value storage. Cache performs a
best-effort bounding of the map using an entry replacement algorithm to determine
which entries to evict when the capacity is exceeded.
§Characteristic difference between unsync and sync/future caches
If you use a cache from a single thread application, unsync::Cache may
outperform other caches for updates and retrievals because other caches have some
overhead on syncing internal data structures between threads.
§Examples
Cache entries are manually added using the insert method, and are stored in the cache until either evicted or manually invalidated.
Here’s an example of reading and updating a cache by using the main thread:
use micro_moka::unsync::Cache;
const NUM_KEYS: usize = 64;
fn value(n: usize) -> String {
format!("value {}", n)
}
// Create a cache that can store up to 10,000 entries.
let mut cache = Cache::new(10_000);
// Insert 64 entries.
for key in 0..NUM_KEYS {
cache.insert(key, value(key));
}
// Invalidate every 4 element of the inserted entries.
for key in (0..NUM_KEYS).step_by(4) {
cache.invalidate(&key);
}
// Verify the result.
for key in 0..NUM_KEYS {
if key % 4 == 0 {
assert_eq!(cache.get(&key), None);
} else {
assert_eq!(cache.get(&key), Some(&value(key)));
}
}§Hashing Algorithm
By default, Cache uses a hashing algorithm selected to provide resistance
against HashDoS attacks. It will the same one used by
std::collections::HashMap, which is currently SipHash 1-3.
While SipHash’s performance is very competitive for medium sized keys, other hashing algorithms will outperform it for small keys such as integers as well as large keys such as long strings. However those algorithms will typically not protect against attacks such as HashDoS.
The hashing algorithm can be replaced on a per-Cache basis using the
build_with_hasher method of the
CacheBuilder. Many alternative algorithms are available on crates.io, such
as the aHash crate.
Implementations§
Source§impl<K, V> Cache<K, V, RandomState>
impl<K, V> Cache<K, V, RandomState>
Sourcepub fn new(max_capacity: u64) -> Self
pub fn new(max_capacity: u64) -> Self
Constructs a new Cache<K, V> that will store up to the max_capacity entries.
To adjust various configuration knobs such as initial_capacity, use the
CacheBuilder.
Sourcepub fn builder() -> CacheBuilder<K, V, Cache<K, V, RandomState>>
pub fn builder() -> CacheBuilder<K, V, Cache<K, V, RandomState>>
Returns a CacheBuilder, which can builds a Cache with
various configuration knobs.
Source§impl<K, V, S> Cache<K, V, S>
impl<K, V, S> Cache<K, V, S>
Sourcepub fn policy(&self) -> Policy
pub fn policy(&self) -> Policy
Returns a read-only cache policy of this cache.
At this time, cache policy cannot be modified after cache creation. A future version may support to modify it.
Sourcepub fn entry_count(&self) -> u64
pub fn entry_count(&self) -> u64
Returns the number of entries in this cache.
§Example
use micro_moka::unsync::Cache;
let mut cache = Cache::new(10);
cache.insert('n', "Netherland Dwarf");
cache.insert('l', "Lop Eared");
cache.insert('d', "Dutch");
// Ensure an entry exists.
assert!(cache.contains_key(&'n'));
// Followings will print the actual numbers.
println!("{}", cache.entry_count()); // -> 3Sourcepub fn weighted_size(&self) -> u64
pub fn weighted_size(&self) -> u64
Returns the total weighted size of entries in this cache.
This is equivalent to entry_count as weight support has been removed.
Source§impl<K, V, S> Cache<K, V, S>
impl<K, V, S> Cache<K, V, S>
Sourcepub fn contains_key<Q>(&mut self, key: &Q) -> bool
pub fn contains_key<Q>(&mut self, key: &Q) -> bool
Returns true if the cache contains a value for the key.
Unlike the get method, this method is not considered a cache read operation,
so it does not update the historic popularity estimator.
The key may be any borrowed form of the cache’s key type, but Hash and Eq
on the borrowed form must match those for the key type.
Sourcepub fn get<Q>(&mut self, key: &Q) -> Option<&V>
pub fn get<Q>(&mut self, key: &Q) -> Option<&V>
Returns an immutable reference of the value corresponding to the key.
The key may be any borrowed form of the cache’s key type, but Hash and Eq
on the borrowed form must match those for the key type.
Sourcepub fn insert(&mut self, key: K, value: V)
pub fn insert(&mut self, key: K, value: V)
Inserts a key-value pair into the cache.
If the cache has this key present, the value is updated.
Sourcepub fn invalidate<Q>(&mut self, key: &Q)
pub fn invalidate<Q>(&mut self, key: &Q)
Discards any cached value for the key.
The key may be any borrowed form of the cache’s key type, but Hash and Eq
on the borrowed form must match those for the key type.
Sourcepub fn remove<Q>(&mut self, key: &Q) -> Option<V>
pub fn remove<Q>(&mut self, key: &Q) -> Option<V>
Discards any cached value for the key, returning the cached value.
The key may be any borrowed form of the cache’s key type, but Hash and Eq
on the borrowed form must match those for the key type.
Sourcepub fn invalidate_all(&mut self)
pub fn invalidate_all(&mut self)
Discards all cached values.
Like the invalidate method, this method does not clear the historic
popularity estimator of keys so that it retains the client activities of
trying to retrieve an item.
Sourcepub fn invalidate_entries_if(&mut self, predicate: impl FnMut(&K, &V) -> bool)
pub fn invalidate_entries_if(&mut self, predicate: impl FnMut(&K, &V) -> bool)
Discards cached values that satisfy a predicate.
invalidate_entries_if takes a closure that returns true or false.
invalidate_entries_if will apply the closure to each cached value,
and if the closure returns true, the value will be invalidated.
Like the invalidate method, this method does not clear the historic
popularity estimator of keys so that it retains the client activities of
trying to retrieve an item.
Sourcepub fn iter(&self) -> Iter<'_, K, V> ⓘ
pub fn iter(&self) -> Iter<'_, K, V> ⓘ
Creates an iterator visiting all key-value pairs in arbitrary order. The
iterator element type is (&K, &V).
Unlike the get method, visiting entries via an iterator do not update the
historic popularity estimator or reset idle timers for keys.
§Examples
use micro_moka::unsync::Cache;
let mut cache = Cache::new(100);
cache.insert("Julia", 14);
let mut iter = cache.iter();
let (k, v) = iter.next().unwrap(); // (&K, &V)
assert_eq!(k, &"Julia");
assert_eq!(v, &14);
assert!(iter.next().is_none());