pub struct TypeCache { /* private fields */ }
Expand description
An in-memory cache based on hashable types.
Implementations§
source§impl TypeCache
impl TypeCache
sourcepub fn generate_blocking<K: Hash + Eq + Any + Send + Sync, V: Send + Sync + Any>(
&mut self,
key: K,
generate_fn: impl GenerateFn<K, V>
) -> &V
pub fn generate_blocking<K: Hash + Eq + Any + Send + Sync, V: Send + Sync + Any>( &mut self, key: K, generate_fn: impl GenerateFn<K, V> ) -> &V
The blocking equivalent of TypeCache::generate
.
sourcepub fn generate_partial_blocking<K: Hash + Eq + Any + Send + Sync, V1: Send + Sync + Any, V2: Send + Sync + Any, S: Send + Sync + Any>(
&mut self,
key: K,
blocking_generate_fn: impl FnOnce(&K) -> (V1, S),
generate_fn: impl GenerateWithStateFn<K, S, V2>
) -> (&V1, CacheHandle<V2>)
pub fn generate_partial_blocking<K: Hash + Eq + Any + Send + Sync, V1: Send + Sync + Any, V2: Send + Sync + Any, S: Send + Sync + Any>( &mut self, key: K, blocking_generate_fn: impl FnOnce(&K) -> (V1, S), generate_fn: impl GenerateWithStateFn<K, S, V2> ) -> (&V1, CacheHandle<V2>)
Blocks on generating a portion V1
of the cached value as in TypeCache::generate_blocking
,
then generates the remainder V2
in the background as in TypeCache::generate
.
Accesses a separate cache from TypeCache::generate_blocking
and TypeCache::generate
.
That is, a key being accessed with this method will not affect the set of available
key-value pairs for the other two methods.
sourcepub fn generate<K: Hash + Eq + Any + Send + Sync, V: Send + Sync + Any>(
&mut self,
key: K,
generate_fn: impl GenerateFn<K, V>
) -> CacheHandle<V>
pub fn generate<K: Hash + Eq + Any + Send + Sync, V: Send + Sync + Any>( &mut self, key: K, generate_fn: impl GenerateFn<K, V> ) -> CacheHandle<V>
Ensures that a value corresponding to key
is generated, using generate_fn
to generate it if it has not already been generated.
A more general counterpart to TypeCache::get
.
Returns a handle to the value. If the value is not yet generated, it is generated in the background.
§Panics
Panics if a different type V
or E
is already associated with type K
.
§Examples
use std::sync::{Arc, Mutex};
use cache::{mem::TypeCache, error::Error, CacheableWithState};
let mut cache = TypeCache::new();
fn generate_fn(tuple: &(u64, u64)) -> u64 {
tuple.0 + tuple.1
}
let handle = cache.generate((5, 6), generate_fn);
assert_eq!(*handle.get(), 11);
// Does not call `generate_fn` again as the result has been cached.
let handle = cache.generate((5, 6), generate_fn);
assert_eq!(*handle.get(), 11);
sourcepub fn generate_with_state_blocking<K: Hash + Eq + Any + Send + Sync, V: Send + Sync + Any, S: Send + Sync + Any>(
&mut self,
key: K,
state: S,
generate_fn: impl GenerateWithStateFn<K, S, V>
) -> &V
pub fn generate_with_state_blocking<K: Hash + Eq + Any + Send + Sync, V: Send + Sync + Any, S: Send + Sync + Any>( &mut self, key: K, state: S, generate_fn: impl GenerateWithStateFn<K, S, V> ) -> &V
The blocking equivalent of TypeCache::generate_with_state
.
sourcepub fn generate_with_state<K: Hash + Eq + Any + Send + Sync, V: Send + Sync + Any, S: Send + Sync + Any>(
&mut self,
key: K,
state: S,
generate_fn: impl GenerateWithStateFn<K, S, V>
) -> CacheHandle<V>
pub fn generate_with_state<K: Hash + Eq + Any + Send + Sync, V: Send + Sync + Any, S: Send + Sync + Any>( &mut self, key: K, state: S, generate_fn: impl GenerateWithStateFn<K, S, V> ) -> CacheHandle<V>
Ensures that a value corresponding to key
is generated, using generate_fn
to generate it if it has not already been generated.
A more general counterpart to TypeCache::get_with_state
.
Returns a handle to the value. If the value is not yet generated, it is generated in the background.
§Panics
Panics if a different type V
or E
is already associated with type K
.
§Examples
use std::sync::{Arc, Mutex};
use cache::{mem::TypeCache, error::Error, CacheableWithState};
#[derive(Clone)]
pub struct Log(Arc<Mutex<Vec<(u64, u64)>>>);
let mut cache = TypeCache::new();
let log = Log(Arc::new(Mutex::new(Vec::new())));
fn generate_fn(tuple: &(u64, u64), state: Log) -> u64 {
println!("Logging parameters...");
state.0.lock().unwrap().push(*tuple);
tuple.0 + tuple.1
}
let handle = cache.generate_with_state((5, 6), log.clone(), generate_fn);
assert_eq!(*handle.get(), 11);
// Does not call `generate_fn` again as the result has been cached.
let handle = cache.generate_with_state((5, 6), log.clone(), generate_fn);
assert_eq!(*handle.get(), 11);
assert_eq!(log.0.lock().unwrap().clone(), vec![(5, 6)]);
sourcepub fn get_blocking<K: Cacheable>(
&mut self,
key: K
) -> &Result<K::Output, K::Error>
pub fn get_blocking<K: Cacheable>( &mut self, key: K ) -> &Result<K::Output, K::Error>
The blocking equivalent of TypeCache::get
.
sourcepub fn get<K: Cacheable>(
&mut self,
key: K
) -> CacheHandle<Result<K::Output, K::Error>>
pub fn get<K: Cacheable>( &mut self, key: K ) -> CacheHandle<Result<K::Output, K::Error>>
Gets a handle to a cacheable object from the cache, generating the object in the background if needed.
§Examples
use cache::{mem::TypeCache, error::Error, Cacheable};
use serde::{Deserialize, Serialize};
#[derive(Deserialize, Serialize, Hash, Eq, PartialEq)]
pub struct Params {
param1: u64,
param2: String,
};
impl Cacheable for Params {
type Output = u64;
type Error = anyhow::Error;
fn generate(&self) -> anyhow::Result<u64> {
if self.param1 == 5 {
anyhow::bail!("invalid param");
} else if &self.param2 == "panic" {
panic!("unrecoverable param");
}
Ok(2 * self.param1)
}
}
let mut cache = TypeCache::new();
let handle = cache.get(Params { param1: 50, param2: "cache".to_string() });
assert_eq!(*handle.unwrap_inner(), 100);
let handle = cache.get(Params { param1: 5, param2: "cache".to_string() });
assert_eq!(format!("{}", handle.unwrap_err_inner().root_cause()), "invalid param");
let handle = cache.get(Params { param1: 50, param2: "panic".to_string() });
assert!(matches!(handle.get_err().as_ref(), Error::Panic));
sourcepub fn get_with_state_blocking<S: Send + Sync + Any, K: CacheableWithState<S>>(
&mut self,
key: K,
state: S
) -> &Result<K::Output, K::Error>
pub fn get_with_state_blocking<S: Send + Sync + Any, K: CacheableWithState<S>>( &mut self, key: K, state: S ) -> &Result<K::Output, K::Error>
The blocking equivalent of TypeCache::get_with_state
.
sourcepub fn get_with_state<S: Send + Sync + Any, K: CacheableWithState<S>>(
&mut self,
key: K,
state: S
) -> CacheHandle<Result<K::Output, K::Error>>
pub fn get_with_state<S: Send + Sync + Any, K: CacheableWithState<S>>( &mut self, key: K, state: S ) -> CacheHandle<Result<K::Output, K::Error>>
Gets a handle to a cacheable object from the cache, generating the object in the background if needed.
Note: The state is not used to determine whether the object should be regenerated. As such, it should not impact the output of this function but rather should only be used to store collateral or reuse computation from other function calls.
However, the entries generated with different state types are not interchangeable. That is,
getting the same key with different states will regenerate the key several times, once for
each state type S
.
§Examples
use std::sync::{Arc, Mutex};
use cache::{mem::TypeCache, error::Error, CacheableWithState};
use serde::{Deserialize, Serialize};
#[derive(Debug, Deserialize, Serialize, Clone, Hash, Eq, PartialEq)]
pub struct Params(u64);
#[derive(Clone)]
pub struct Log(Arc<Mutex<Vec<Params>>>);
impl CacheableWithState<Log> for Params {
type Output = u64;
type Error = anyhow::Error;
fn generate_with_state(&self, state: Log) -> anyhow::Result<u64> {
println!("Logging parameters...");
state.0.lock().unwrap().push(self.clone());
if self.0 == 5 {
anyhow::bail!("invalid param");
} else if self.0 == 8 {
panic!("unrecoverable param");
}
Ok(2 * self.0)
}
}
let mut cache = TypeCache::new();
let log = Log(Arc::new(Mutex::new(Vec::new())));
let handle = cache.get_with_state(Params(0), log.clone());
assert_eq!(*handle.unwrap_inner(), 0);
let handle = cache.get_with_state(Params(5), log.clone());
assert_eq!(format!("{}", handle.unwrap_err_inner().root_cause()), "invalid param");
let handle = cache.get_with_state(Params(8), log.clone());
assert!(matches!(handle.get_err().as_ref(), Error::Panic));
assert_eq!(log.0.lock().unwrap().clone(), vec![Params(0), Params(5), Params(8)]);
Trait Implementations§
Auto Trait Implementations§
impl !RefUnwindSafe for TypeCache
impl Send for TypeCache
impl Sync for TypeCache
impl Unpin for TypeCache
impl !UnwindSafe for TypeCache
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
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
source§impl<T> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
source§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
T
in a tonic::Request