pub struct GenericCache<'f, C: SparseContainer> { /* private fields */ }Expand description
A generic cache for a function backed by anything that implements the SparseContainer
trait.
Not all containers may support the precise access pattern, such as [VecCache] which
implements FnCache directly, but most uses can simply implement SparseContainer for
their container and immediately have everything working with GenericCache.
The cache takes ownership of all inputs, but only passes a reference to the function, allowing
it to store the input in the cache without any copies or clones. Additionally, the function is
shared using by using a RefCache when actually calling the function, preventing any
reference counting or clones of the closure.
Implementations§
Source§impl<'f, C: SparseContainer> GenericCache<'f, C>
impl<'f, C: SparseContainer> GenericCache<'f, C>
Sourcepub fn with_cache(
cache: C,
f: impl Fn(&C::Input) -> C::Output + Send + 'f,
) -> Self
pub fn with_cache( cache: C, f: impl Fn(&C::Input) -> C::Output + Send + 'f, ) -> Self
Create a GenericCache out of a cache and a function.
Using this function you can pre-initialize some values into the cache if desired, change
settings using specific constructors on the cache type, or any variation. If a default
version of the cache is sufficient for your needs, Self::new may be less verbose.
let cache = GenericCache::with_cache(HashMap::<usize, usize>::new(), |x: &usize| *x);Sourcepub fn recursive_with_cache(
cache: C,
f: impl Fn(&mut RefCache<'_, C>, &C::Input) -> C::Output + Send + 'f,
) -> Self
pub fn recursive_with_cache( cache: C, f: impl Fn(&mut RefCache<'_, C>, &C::Input) -> C::Output + Send + 'f, ) -> Self
Create a GenericCache out of a cache and a recursive function.
Using this function you can pre-initialize some values into the cache if desired, change
settings using specific constructors on the cache type, or any variation. If a default
version of the cache is sufficient for your needs, Self::recursive may be less verbose.
let cache = GenericCache::recursive_with_cache(HashMap::<usize, usize>::new(), |cache, x| match x {
0 => 1,
1 => 1,
_ => cache.get_many([x - 1, x - 2]).into_iter().sum()
});Source§impl<'f, C> GenericCache<'f, C>where
C: SparseContainer + Default,
impl<'f, C> GenericCache<'f, C>where
C: SparseContainer + Default,
Sourcepub fn new(f: impl Fn(&C::Input) -> C::Output + Send + 'f) -> Self
pub fn new(f: impl Fn(&C::Input) -> C::Output + Send + 'f) -> Self
Create a GenericCache using the Default implementation of the [Cache] type.
If a specific instance of a cache is required, see Self::with_cache.
let cache: GenericCache<HashMap<_,_>> = GenericCache::new(|x: &usize| *x);Sourcepub fn recursive(
f: impl Fn(&mut RefCache<'_, C>, &C::Input) -> C::Output + Send + 'f,
) -> Self
pub fn recursive( f: impl Fn(&mut RefCache<'_, C>, &C::Input) -> C::Output + Send + 'f, ) -> Self
Create a GenericCache using the Default implementation of the [Cache] type, using a
recursive function.
If a specific instance of a cache is required, see Self::recursive_with_cache.
let cache: GenericCache<HashMap<usize, u64>> = GenericCache::recursive(|cache, x| match x {
0 => 1,
1 => 1,
_ => cache.get_many([x - 1, x - 2]).into_iter().sum()
});§Issues
Currently it does not work if you pass in a recursive function generic over FnCache via
a function pointer. Wrap the pointer in a closure.
fn increment(cache: &mut impl FnCache<usize, usize>, x: &usize) -> usize {
match x {
0 => 0,
_ => cache.get(x - 1) + 1,
}
}
// no good
//let cache: GenericCache<HashMap<_, _>> = GenericCache::recursive(increment);
//okay
let cache: GenericCache<HashMap<_, _>> = GenericCache::recursive(|c, i| increment(c, i));