Struct cache::mem::TypeCache

source ·
pub struct TypeCache { /* private fields */ }
Expand description

An in-memory cache based on hashable types.

Implementations§

source§

impl TypeCache

source

pub fn new() -> Self

Creates a new cache.

source

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.

source

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.

source

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);
source

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.

source

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)]);
source

pub fn get_blocking<K: Cacheable>( &mut self, key: K ) -> &Result<K::Output, K::Error>

The blocking equivalent of TypeCache::get.

source

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));
source

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.

source

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§

source§

impl Debug for TypeCache

source§

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

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

impl Default for TypeCache

source§

fn default() -> TypeCache

Returns the “default value” for a type. Read more

Auto Trait Implementations§

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.

§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
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> IntoRequest<T> for T

source§

fn into_request(self) -> Request<T>

Wrap the input message T in a tonic::Request
source§

impl<T> Same for T

§

type Output = T

Should always be Self
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.
§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more