pub struct SegmentedCache<K, V, S = RandomState> { /* private fields */ }
Expand description
A thread-safe concurrent in-memory cache, with multiple internal segments.
SegmentedCache
has multiple internal Cache
instances for
increased concurrent update performance. However, it has little overheads on
retrievals and updates for managing these segments.
For usage examples, see the document of the Cache
.
Implementations§
Source§impl<K, V> SegmentedCache<K, V, RandomState>
impl<K, V> SegmentedCache<K, V, RandomState>
Sourcepub fn new(max_capacity: u64, num_segments: usize) -> Self
pub fn new(max_capacity: u64, num_segments: usize) -> Self
Constructs a new SegmentedCache<K, V>
that has multiple internal
segments and will store up to the max_capacity
.
To adjust various configuration knobs such as initial_capacity
or
time_to_live
, use the CacheBuilder
.
§Panics
Panics if num_segments
is 0.
Sourcepub fn builder(
num_segments: usize,
) -> CacheBuilder<K, V, SegmentedCache<K, V, RandomState>>
pub fn builder( num_segments: usize, ) -> CacheBuilder<K, V, SegmentedCache<K, V, RandomState>>
Returns a CacheBuilder
, which can builds a
SegmentedCache
with various configuration knobs.
Source§impl<K, V, S> SegmentedCache<K, V, S>
impl<K, V, S> SegmentedCache<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 an approximate number of entries in this cache.
The value returned is an estimate; the actual count may differ if there are
concurrent insertions or removals, or if some entries are pending removal due
to expiration. This inaccuracy can be mitigated by performing a sync()
first.
§Example
use moka::sync::SegmentedCache;
let cache = SegmentedCache::new(10, 4);
cache.insert('n', "Netherland Dwarf");
cache.insert('l', "Lop Eared");
cache.insert('d', "Dutch");
// Ensure an entry exists.
assert!(cache.contains_key(&'n'));
// However, followings may print stale number zeros instead of threes.
println!("{}", cache.entry_count()); // -> 0
println!("{}", cache.weighted_size()); // -> 0
// To mitigate the inaccuracy, bring `ConcurrentCacheExt` trait to
// the scope so we can use `sync` method.
use moka::sync::ConcurrentCacheExt;
// Call `sync` to run pending internal tasks.
cache.sync();
// Followings will print the actual numbers.
println!("{}", cache.entry_count()); // -> 3
println!("{}", cache.weighted_size()); // -> 3
Sourcepub fn weighted_size(&self) -> u64
pub fn weighted_size(&self) -> u64
Returns an approximate total weighted size of entries in this cache.
The value returned is an estimate; the actual size may differ if there are
concurrent insertions or removals, or if some entries are pending removal due
to expiration. This inaccuracy can be mitigated by performing a sync()
first. See entry_count
for a sample code.
Source§impl<K, V, S> SegmentedCache<K, V, S>
impl<K, V, S> SegmentedCache<K, V, S>
Sourcepub fn contains_key<Q>(&self, key: &Q) -> bool
pub fn contains_key<Q>(&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 or reset the idle
timer 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 get<Q>(&self, key: &Q) -> Option<V>
pub fn get<Q>(&self, key: &Q) -> Option<V>
Returns a clone of the value corresponding to the key.
If you want to store values that will be expensive to clone, wrap them by
std::sync::Arc
before storing in a cache. Arc
is a
thread-safe reference-counted pointer and its clone()
method is cheap.
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_or_insert_with(&self, key: K, init: impl FnOnce() -> V) -> V
👎Deprecated since 0.8.0: Replaced with get_with
pub fn get_or_insert_with(&self, key: K, init: impl FnOnce() -> V) -> V
get_with
Deprecated, replaced with get_with
Sourcepub fn get_or_try_insert_with<F, E>(&self, key: K, init: F) -> Result<V, Arc<E>>
👎Deprecated since 0.8.0: Replaced with try_get_with
pub fn get_or_try_insert_with<F, E>(&self, key: K, init: F) -> Result<V, Arc<E>>
try_get_with
Deprecated, replaced with try_get_with
Sourcepub fn get_with(&self, key: K, init: impl FnOnce() -> V) -> V
pub fn get_with(&self, key: K, init: impl FnOnce() -> V) -> V
Returns a clone of the value corresponding to the key. If the value does
not exist, evaluates the init
closure and inserts the output.
§Concurrent calls on the same key
This method guarantees that concurrent calls on the same not-existing key are
coalesced into one evaluation of the init
closure. Only one of the calls
evaluates its closure, and other calls wait for that closure to complete. See
Cache::get_with
for more details.
Sourcepub fn get_with_by_ref<Q>(&self, key: &Q, init: impl FnOnce() -> V) -> V
pub fn get_with_by_ref<Q>(&self, key: &Q, init: impl FnOnce() -> V) -> V
Similar to get_with
, but instead of passing an owned
key, you can pass a reference to the key. If the key does not exist in the
cache, the key will be cloned to create new entry in the cache.
Sourcepub fn get_with_if(
&self,
key: K,
init: impl FnOnce() -> V,
replace_if: impl FnMut(&V) -> bool,
) -> V
pub fn get_with_if( &self, key: K, init: impl FnOnce() -> V, replace_if: impl FnMut(&V) -> bool, ) -> V
Works like get_with
, but takes an additional
replace_if
closure.
This method will evaluate the init
closure and insert the output to the
cache when:
- The key does not exist.
- Or,
replace_if
closure returnstrue
.
Sourcepub fn optionally_get_with<F>(&self, key: K, init: F) -> Option<V>
pub fn optionally_get_with<F>(&self, key: K, init: F) -> Option<V>
Returns a clone of the value corresponding to the key. If the value does
not exist, evaluates the init
closure, and inserts the value if
Some(value)
was returned. If None
was returned from the closure, this
method does not insert a value and returns None
.
§Concurrent calls on the same key
This method guarantees that concurrent calls on the same not-existing key are
coalesced into one evaluation of the init
closure. Only one of the calls
evaluates its closure, and other calls wait for that closure to complete.
See Cache::optionally_get_with
for more details.
Sourcepub fn optionally_get_with_by_ref<F, Q>(&self, key: &Q, init: F) -> Option<V>
pub fn optionally_get_with_by_ref<F, Q>(&self, key: &Q, init: F) -> Option<V>
Similar to optionally_get_with
, but instead
of passing an owned key, you can pass a reference to the key. If the key does
not exist in the cache, the key will be cloned to create new entry in the
cache.
Sourcepub fn try_get_with<F, E>(&self, key: K, init: F) -> Result<V, Arc<E>>
pub fn try_get_with<F, E>(&self, key: K, init: F) -> Result<V, Arc<E>>
Returns a clone of the value corresponding to the key. If the value does
not exist, evaluates the init
closure, and inserts the value if Ok(value)
was returned. If Err(_)
was returned from the closure, this method does not
insert a value and returns the Err
wrapped by std::sync::Arc
.
§Concurrent calls on the same key
This method guarantees that concurrent calls on the same not-existing key are
coalesced into one evaluation of the init
closure (as long as these
closures return the same error type). Only one of the calls evaluates its
closure, and other calls wait for that closure to complete. See
Cache::try_get_with
for more details.
Sourcepub fn try_get_with_by_ref<F, E, Q>(
&self,
key: &Q,
init: F,
) -> Result<V, Arc<E>>
pub fn try_get_with_by_ref<F, E, Q>( &self, key: &Q, init: F, ) -> Result<V, Arc<E>>
Similar to try_get_with
, but instead of passing an
owned key, you can pass a reference to the key. If the key does not exist in
the cache, the key will be cloned to create new entry in the cache.
Sourcepub fn insert(&self, key: K, value: V)
pub fn insert(&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>(&self, key: &Q)
pub fn invalidate<Q>(&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 invalidate_all(&self)
pub fn invalidate_all(&self)
Discards all cached values.
This method returns immediately and a background thread will evict all the
cached values inserted before the time when this method was called. It is
guaranteed that the get
method must not return these invalidated values
even if they have not been evicted.
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<F>(
&self,
predicate: F,
) -> Result<(), PredicateError>
pub fn invalidate_entries_if<F>( &self, predicate: F, ) -> Result<(), PredicateError>
Discards cached values that satisfy a predicate.
invalidate_entries_if
takes a closure that returns true
or false
. This
method returns immediately and a background thread will apply the closure to
each cached value inserted before the time when invalidate_entries_if
was
called. If the closure returns true
on a value, that value will be evicted
from the cache.
Also the get
method will apply the closure to a value to determine if it
should have been invalidated. Therefore, it is guaranteed that the get
method must not return invalidated values.
Note that you must call
CacheBuilder::support_invalidation_closures
at the cache creation time as the cache needs to maintain additional internal
data structures to support this method. Otherwise, calling this method will
fail with a
PredicateError::InvalidationClosuresDisabled
.
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 (Arc<K>, V)
, where V
is a clone of a stored
value.
Iterators do not block concurrent reads and writes on the cache. An entry can be inserted to, invalidated or evicted from a cache while iterators are alive on the same cache.
Unlike the get
method, visiting entries via an iterator do not update the
historic popularity estimator or reset idle timers for keys.
§Guarantees
In order to allow concurrent access to the cache, iterator’s next
method
does not guarantee the following:
- It does not guarantee to return a key-value pair (an entry) if its key has
been inserted to the cache after the iterator was created.
- Such an entry may or may not be returned depending on key’s hash and timing.
and the next
method guarantees the followings:
- It guarantees not to return the same entry more than once.
- It guarantees not to return an entry if it has been removed from the cache
after the iterator was created.
- Note: An entry can be removed by following reasons:
- Manually invalidated.
- Expired (e.g. time-to-live).
- Evicted as the cache capacity exceeded.
- Note: An entry can be removed by following reasons:
§Examples
use moka::sync::SegmentedCache;
let cache = SegmentedCache::new(100, 4);
cache.insert("Julia", 14);
let mut iter = cache.iter();
let (k, v) = iter.next().unwrap(); // (Arc<K>, V)
assert_eq!(*k, "Julia");
assert_eq!(v, 14);
assert!(iter.next().is_none());