Struct moka::sync::SegmentedCache

source ·
pub struct SegmentedCache<K, V, S = RandomState> { /* private fields */ }
Available on crate feature sync only.
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>
where K: Hash + Eq + Send + Sync + 'static, V: Clone + Send + Sync + 'static,

source

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.

source

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>

source

pub fn name(&self) -> Option<&str>

Returns cache’s name.

source

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.

source

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, call `run_pending_tasks` method to run
// pending internal tasks.
cache.run_pending_tasks();

// Followings will print the actual numbers.
println!("{}", cache.entry_count());   // -> 3
println!("{}", cache.weighted_size()); // -> 3
source

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>
where K: Hash + Eq + Send + Sync + 'static, V: Clone + Send + Sync + 'static, S: BuildHasher + Clone + Send + Sync + 'static,

source

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

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.

source

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

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.

source

pub fn entry(&self, key: K) -> OwnedKeyEntrySelector<'_, K, V, S>
where K: Hash + Eq,

source

pub fn entry_by_ref<'a, Q>( &'a self, key: &'a Q ) -> RefKeyEntrySelector<'a, K, Q, V, S>
where K: Borrow<Q>, Q: ToOwned<Owned = K> + Hash + Eq + ?Sized,

source

pub fn get_or_insert_with(&self, key: K, init: impl FnOnce() -> V) -> V

👎Deprecated since 0.8.0: Replaced with get_with

TODO: Remove this in v0.13.0. Deprecated, replaced with get_with

source

pub fn get_or_try_insert_with<F, E>(&self, key: K, init: F) -> Result<V, Arc<E>>
where F: FnOnce() -> Result<V, E>, E: Send + Sync + 'static,

👎Deprecated since 0.8.0: Replaced with try_get_with

TODO: Remove this in v0.13.0. Deprecated, replaced with try_get_with

source

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.

source

pub fn get_with_by_ref<Q>(&self, key: &Q, init: impl FnOnce() -> V) -> V
where K: Borrow<Q>, Q: ToOwned<Owned = K> + Hash + Eq + ?Sized,

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.

source

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 returns true.
source

pub fn optionally_get_with<F>(&self, key: K, init: F) -> Option<V>
where F: FnOnce() -> 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.

source

pub fn optionally_get_with_by_ref<F, Q>(&self, key: &Q, init: F) -> Option<V>
where F: FnOnce() -> Option<V>, K: Borrow<Q>, Q: ToOwned<Owned = K> + Hash + Eq + ?Sized,

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.

source

pub fn try_get_with<F, E>(&self, key: K, init: F) -> Result<V, Arc<E>>
where F: FnOnce() -> Result<V, E>, E: Send + Sync + 'static,

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.

source

pub fn try_get_with_by_ref<F, E, Q>( &self, key: &Q, init: F ) -> Result<V, Arc<E>>
where F: FnOnce() -> Result<V, E>, E: Send + Sync + 'static, K: Borrow<Q>, Q: ToOwned<Owned = K> + Hash + Eq + ?Sized,

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.

source

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.

source

pub fn invalidate<Q>(&self, key: &Q)
where K: Borrow<Q>, Q: Hash + Eq + ?Sized,

Discards any cached value for the key.

If you need to get a the value that has been discarded, use the remove method instead.

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.

source

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

Discards any cached value for the key and returns a clone of the value.

If you do not need to get the value that has been discarded, use the invalidate method instead.

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.

source

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.

source

pub fn invalidate_entries_if<F>( &self, predicate: F ) -> Result<(), PredicateError>
where F: Fn(&K, &V) -> bool + Send + Sync + 'static,

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.

source

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.
§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());
source

pub fn run_pending_tasks(&self)

Performs any pending maintenance operations needed by the cache.

Trait Implementations§

source§

impl<K, V, S> Clone for SegmentedCache<K, V, S>

source§

fn clone(&self) -> Self

Makes a clone of this shared cache.

This operation is cheap as it only creates thread-safe reference counted pointers to the shared internal data structures.

1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<K, V, S> Debug for SegmentedCache<K, V, S>
where K: Debug + Eq + Hash + Send + Sync + 'static, V: Debug + Clone + Send + Sync + 'static, S: BuildHasher + Clone + Send + Sync + 'static,

source§

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

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

impl<'a, K, V, S> IntoIterator for &'a SegmentedCache<K, V, S>
where K: Hash + Eq + Send + Sync + 'static, V: Clone + Send + Sync + 'static, S: BuildHasher + Clone + Send + Sync + 'static,

§

type Item = (Arc<K>, 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) -> Self::IntoIter

Creates an iterator from a value. Read more
source§

impl<K, V, S> Send for SegmentedCache<K, V, S>
where K: Send + Sync, V: Send + Sync, S: Send,

source§

impl<K, V, S> Sync for SegmentedCache<K, V, S>
where K: Send + Sync, V: Send + Sync, S: Sync,

Auto Trait Implementations§

§

impl<K, V, S> Freeze for SegmentedCache<K, V, S>

§

impl<K, V, S = RandomState> !RefUnwindSafe for SegmentedCache<K, V, S>

§

impl<K, V, S> Unpin for SegmentedCache<K, V, S>

§

impl<K, V, S = RandomState> !UnwindSafe for SegmentedCache<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> Pointable for T

source§

const ALIGN: usize = _

The alignment of pointer.
§

type Init = T

The type for initializers.
source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
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.