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