[][src]Struct dyn_cache::sync::SharedSendCache

pub struct SharedSendCache { /* fields omitted */ }

Provides shared, synchronized access to a SendCache and a function-memoization API in SharedSendCache::cache_with.

For convenience wrappers around SharedSendCache::cache_with see SharedSendCache::cache for returned types that implement Clone and SharedSendCache::hold for values that just need to be stored without returning a reference.

Example

let storage = dyn_cache::sync::SharedSendCache::default();
let call_count = std::cell::Cell::new(0);
let increment_count = |&to_add: &i32| {
    let new_count = call_count.get() + to_add;
    call_count.set(new_count);
    new_count
};

assert_eq!(call_count.get(), 0, "not called yet");

let with_one = storage.cache_with(&'a', &1, &increment_count, Clone::clone);
assert_eq!(call_count.get(), 1, "called only once");
assert_eq!(call_count.get(), with_one);

let with_one_again = storage.cache_with(&'a', &1, &increment_count, Clone::clone);
assert_eq!(call_count.get(), 1, "still called only once, previous value cached");
assert_eq!(call_count.get(), with_one_again);

let with_two = storage.cache_with(&'a', &2, &increment_count, Clone::clone);
assert_eq!(call_count.get(), 3, "called again with a new, larger increment");
assert_eq!(call_count.get(), with_two);

let with_other_query = storage.cache_with(&'b', &1, &increment_count, Clone::clone);
assert_eq!(call_count.get(), 4, "called again with the same increment, different scope");
assert_eq!(call_count.get(), with_other_query);

let with_two_again = storage.cache_with(&'a', &2, &increment_count, Clone::clone);
assert_eq!(call_count.get(), 4, "cell still has last mutation's value");
assert_eq!(with_two_again, with_two, "cache should still have previous value");

storage.gc(); // won't drop any values, but sets all of the cached values to be dropped
call_count.set(0);

// re-run 'b', marking it live
let reran_other_query = storage.cache_with(&'b', &1, &increment_count, Clone::clone);
assert_eq!(reran_other_query , 4, "returns the cached value");
assert_eq!(call_count.get(), 0, "without running increment_count");

storage.gc(); // query 'a' will be dropped

// re-run 'b', observing cached value
let reran_other_query = storage.cache_with(&'b', &1, &increment_count, Clone::clone);
assert_eq!(reran_other_query , 4, "still returns the cached value");
assert_eq!(call_count.get(), 0, "still without running increment_count");

// run 'a' again, observe no cached value
let with_one_again = storage.cache_with(&'a', &1, &increment_count, Clone::clone);
assert_eq!(call_count.get(), 1, "called without caching");
assert_eq!(call_count.get(), with_one_again);

Implementations

impl SharedSendCache[src]

pub fn cache_with<Key: ?Sized, Scope, Arg: ?Sized, Input, Output, Ret>(
    &self,
    key: &Key,
    arg: &Arg,
    init: impl FnOnce(&Input) -> Output,
    with: impl FnOnce(&Output) -> Ret
) -> Ret where
    Key: Eq + Hash + ToOwned<Owned = Scope>,
    Scope: 'static + Borrow<Key> + Eq + Hash + Send,
    Arg: PartialEq<Input> + ToOwned<Owned = Input>,
    Input: 'static + Borrow<Arg> + Send,
    Output: 'static + Send,
    Ret: 'static + Send
[src]

Caches the result of init(arg) once per key, re-running it when arg changes. Always runs with on the stored Output before returning the result.

See SharedSendCache::cache for an ergonomic wrapper that requires Output: Clone.

pub fn cache<Key: ?Sized, Scope, Arg: ?Sized, Input, Output>(
    &self,
    key: &Key,
    arg: &Arg,
    init: impl FnOnce(&Input) -> Output
) -> Output where
    Key: Eq + Hash + ToOwned<Owned = Scope>,
    Scope: 'static + Borrow<Key> + Eq + Hash + Send,
    Arg: PartialEq<Input> + ToOwned<Owned = Input>,
    Input: 'static + Borrow<Arg> + Send,
    Output: 'static + Clone + Send
[src]

Caches the result of init(arg) once per key, re-running it when arg changes. Clones the cached output before returning the result.

See SharedSendCache::cache_with for a lower-level version which does not require Output: Clone.

pub fn hold<Key: ?Sized, Scope, Arg: ?Sized, Input, Output>(
    &self,
    key: &Key,
    arg: &Arg,
    init: impl FnOnce(&Input) -> Output
) where
    Key: Eq + Hash + ToOwned<Owned = Scope>,
    Scope: 'static + Borrow<Key> + Eq + Hash + Send,
    Arg: PartialEq<Input> + ToOwned<Owned = Input>,
    Input: 'static + Borrow<Arg> + Send,
    Output: 'static + Send
[src]

Caches the result of init(arg) once per key, re-running it when arg changes.

Does not return any reference to the cached value. See SharedSendCache::cache for similar functionality that returns a copy of Output or SharedSendCache::cache_with which allows specifying other pre-return functions.

pub fn gc(&self)[src]

Forwards to SendCache::gc.

Trait Implementations

impl Clone for SharedSendCache[src]

impl Debug for SharedSendCache[src]

impl Default for SharedSendCache[src]

impl Eq for SharedSendCache[src]

impl From<SendCache> for SharedSendCache[src]

impl Hash for SharedSendCache[src]

impl Ord for SharedSendCache[src]

impl PartialEq<SharedSendCache> for SharedSendCache[src]

impl PartialOrd<SharedSendCache> for SharedSendCache[src]

impl RefUnwindSafe for SharedSendCache[src]

impl UnwindSafe for SharedSendCache[src]

Auto Trait Implementations

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> AsContext for T where
    T: Debug + 'static, 
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Downcast for T where
    T: Any
[src]

impl<T> DowncastSync for T where
    T: Send + Sync + Any
[src]

impl<T> Erased for T

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.