pub struct WASM_INSTANCES { /* private fields */ }Methods from Deref<Target = Cache<String, Arc<WorkerPool>>>§
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::Cache;
let 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'));
// 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()); // -> 3Sourcepub 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.
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 entry(&self, key: K) -> OwnedKeyEntrySelector<'_, K, V, S>
pub fn entry(&self, key: K) -> OwnedKeyEntrySelector<'_, K, V, S>
Takes a key K and returns an OwnedKeyEntrySelector that can be used to
select or insert an entry.
§Example
use moka::sync::Cache;
let cache: Cache<String, u32> = Cache::new(100);
let key = "key1".to_string();
let entry = cache.entry(key.clone()).or_insert(3);
assert!(entry.is_fresh());
assert_eq!(entry.key(), &key);
assert_eq!(entry.into_value(), 3);
let entry = cache.entry(key).or_insert(6);
// Not fresh because the value was already in the cache.
assert!(!entry.is_fresh());
assert_eq!(entry.into_value(), 3);Sourcepub fn entry_by_ref<'a, Q>(
&'a self,
key: &'a Q,
) -> RefKeyEntrySelector<'a, K, Q, V, S>
pub fn entry_by_ref<'a, Q>( &'a self, key: &'a Q, ) -> RefKeyEntrySelector<'a, K, Q, V, S>
Takes a reference &Q of a key and returns an RefKeyEntrySelector that
can be used to select or insert an entry.
§Example
use moka::sync::Cache;
let cache: Cache<String, u32> = Cache::new(100);
let key = "key1".to_string();
let entry = cache.entry_by_ref(&key).or_insert(3);
assert!(entry.is_fresh());
assert_eq!(entry.key(), &key);
assert_eq!(entry.into_value(), 3);
let entry = cache.entry_by_ref(&key).or_insert(6);
// Not fresh because the value was already in the cache.
assert!(!entry.is_fresh());
assert_eq!(entry.into_value(), 3);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.
The following code snippet demonstrates this behavior:
use moka::sync::Cache;
use std::{sync::Arc, thread};
const TEN_MIB: usize = 10 * 1024 * 1024; // 10MiB
let cache = Cache::new(100);
// Spawn four threads.
let threads: Vec<_> = (0..4_u8)
.map(|task_id| {
let my_cache = cache.clone();
thread::spawn(move || {
println!("Thread {} started.", task_id);
// Try to insert and get the value for key1. Although all four
// threads will call `get_with` at the same time, the `init` closure
// must be evaluated only once.
let value = my_cache.get_with("key1", || {
println!("Thread {} inserting a value.", task_id);
Arc::new(vec![0u8; TEN_MIB])
});
// Ensure the value exists now.
assert_eq!(value.len(), TEN_MIB);
assert!(my_cache.get(&"key1").is_some());
println!("Thread {} got the value. (len: {})", task_id, value.len());
})
})
.collect();
// Wait all threads to complete.
threads
.into_iter()
.for_each(|t| t.join().expect("Thread failed"));Result
- The
initclosure was called exactly once by thread 1. - Other threads were blocked until thread 1 inserted the value.
Thread 1 started.
Thread 0 started.
Thread 3 started.
Thread 2 started.
Thread 1 inserting a value.
Thread 2 got the value. (len: 10485760)
Thread 1 got the value. (len: 10485760)
Thread 0 got the value. (len: 10485760)
Thread 3 got the value. (len: 10485760)§Panics
This method panics when the init closure has panicked. When it happens,
only the caller whose init closure panicked will get the panic (e.g. only
thread 1 in the above sample). If there are other calls in progress (e.g.
thread 0, 2 and 3 above), this method will restart and resolve one of the
remaining init closure.
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
👎Deprecated since 0.10.0: Replaced with entry().or_insert_with_if()
pub fn get_with_if( &self, key: K, init: impl FnOnce() -> V, replace_if: impl FnMut(&V) -> bool, ) -> V
entry().or_insert_with_if()Deprecated, replaced with
entry()::or_insert_with_if()
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.
The following code snippet demonstrates this behavior:
use moka::sync::Cache;
use std::{path::Path, thread};
/// This function tries to get the file size in bytes.
fn get_file_size(thread_id: u8, path: impl AsRef<Path>) -> Option<u64> {
println!("get_file_size() called by thread {}.", thread_id);
std::fs::metadata(path).ok().map(|m| m.len())
}
let cache = Cache::new(100);
// Spawn four threads.
let threads: Vec<_> = (0..4_u8)
.map(|thread_id| {
let my_cache = cache.clone();
thread::spawn(move || {
println!("Thread {} started.", thread_id);
// Try to insert and get the value for key1. Although all four
// threads will call `optionally_get_with` at the same time,
// get_file_size() must be called only once.
let value = my_cache.optionally_get_with(
"key1",
|| get_file_size(thread_id, "./Cargo.toml"),
);
// Ensure the value exists now.
assert!(value.is_some());
assert!(my_cache.get(&"key1").is_some());
println!(
"Thread {} got the value. (len: {})",
thread_id,
value.unwrap()
);
})
})
.collect();
// Wait all threads to complete.
threads
.into_iter()
.for_each(|t| t.join().expect("Thread failed"));Result
get_file_size()was called exactly once by thread 0.- Other threads were blocked until thread 0 inserted the value.
Thread 0 started.
Thread 1 started.
Thread 2 started.
get_file_size() called by thread 0.
Thread 3 started.
Thread 2 got the value. (len: 1466)
Thread 0 got the value. (len: 1466)
Thread 1 got the value. (len: 1466)
Thread 3 got the value. (len: 1466)§Panics
This method panics when the init closure has panicked. When it happens,
only the caller whose init closure panicked will get the panic (e.g. only
thread 1 in the above sample). If there are other calls in progress (e.g.
thread 0, 2 and 3 above), this method will restart and resolve one of the
remaining init closure.
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.
The following code snippet demonstrates this behavior:
use moka::sync::Cache;
use std::{path::Path, thread};
/// This function tries to get the file size in bytes.
fn get_file_size(thread_id: u8, path: impl AsRef<Path>) -> Result<u64, std::io::Error> {
println!("get_file_size() called by thread {}.", thread_id);
Ok(std::fs::metadata(path)?.len())
}
let cache = Cache::new(100);
// Spawn four threads.
let threads: Vec<_> = (0..4_u8)
.map(|thread_id| {
let my_cache = cache.clone();
thread::spawn(move || {
println!("Thread {} started.", thread_id);
// Try to insert and get the value for key1. Although all four
// threads will call `try_get_with` at the same time,
// get_file_size() must be called only once.
let value = my_cache.try_get_with(
"key1",
|| get_file_size(thread_id, "./Cargo.toml"),
);
// Ensure the value exists now.
assert!(value.is_ok());
assert!(my_cache.get(&"key1").is_some());
println!(
"Thread {} got the value. (len: {})",
thread_id,
value.unwrap()
);
})
})
.collect();
// Wait all threads to complete.
threads
.into_iter()
.for_each(|t| t.join().expect("Thread failed"));Result
get_file_size()was called exactly once by thread 1.- Other threads were blocked until thread 1 inserted the value.
Thread 1 started.
Thread 2 started.
get_file_size() called by thread 1.
Thread 3 started.
Thread 0 started.
Thread 2 got the value. (len: 1466)
Thread 0 got the value. (len: 1466)
Thread 1 got the value. (len: 1466)
Thread 3 got the value. (len: 1466)§Panics
This method panics when the init closure has panicked. When it happens,
only the caller whose init closure panicked will get the panic (e.g. only
thread 1 in the above sample). If there are other calls in progress (e.g.
thread 0, 2 and 3 above), this method will restart and resolve one of the
remaining init closure.
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.
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.
Sourcepub fn remove<Q>(&self, key: &Q) -> Option<V>
pub fn remove<Q>(&self, key: &Q) -> Option<V>
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.
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<String, PredicateError>
pub fn invalidate_entries_if<F>( &self, predicate: F, ) -> Result<String, 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::Cache;
let cache = Cache::new(100);
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());Trait Implementations§
Source§impl Deref for WASM_INSTANCES
impl Deref for WASM_INSTANCES
impl LazyStatic for WASM_INSTANCES
Auto Trait Implementations§
impl Freeze for WASM_INSTANCES
impl RefUnwindSafe for WASM_INSTANCES
impl Send for WASM_INSTANCES
impl Sync for WASM_INSTANCES
impl Unpin for WASM_INSTANCES
impl UnwindSafe for WASM_INSTANCES
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> GetSetFdFlags for T
impl<T> GetSetFdFlags for T
Source§fn get_fd_flags(&self) -> Result<FdFlags, Error>where
T: AsFilelike,
fn get_fd_flags(&self) -> Result<FdFlags, Error>where
T: AsFilelike,
self file descriptor.Source§fn new_set_fd_flags(&self, fd_flags: FdFlags) -> Result<SetFdFlags<T>, Error>where
T: AsFilelike,
fn new_set_fd_flags(&self, fd_flags: FdFlags) -> Result<SetFdFlags<T>, Error>where
T: AsFilelike,
Source§fn set_fd_flags(&mut self, set_fd_flags: SetFdFlags<T>) -> Result<(), Error>where
T: AsFilelike,
fn set_fd_flags(&mut self, set_fd_flags: SetFdFlags<T>) -> Result<(), Error>where
T: AsFilelike,
self file descriptor. Read moreSource§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more