1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
use crate::{FnCache, FnCacheMany};
use std::sync::Arc;
/// A cache for a function which uses a [`Vec`].
///
/// This cache is optimized for functions which must
/// be calculated in order, so that there can be no
/// gaps in the cache, and use `usize` as an argument.
///
/// If the function does not start at zero, or require
/// every previous value to be calculated for the next
/// one, consider using a [`HashCache`](crate::HashCache)
/// instead.
pub struct VecCache<'f, O> {
pub(crate) cache: Vec<O>,
f: Arc<dyn Fn(&mut Self, &usize) -> O + 'f + Send + Sync>,
}
impl<'f, O> FnCache<usize, O> for VecCache<'f, O> {
fn get(&mut self, input: usize) -> &O {
let len = self.cache.len();
if len <= input {
self.cache.reserve(input - len + 1);
}
while self.cache.len() <= input {
let next = self.cache.len();
let next_val = self.compute(next);
self.cache.push(next_val);
}
self.cache.get(input).unwrap()
}
}
impl<'f, O> FnCacheMany<usize, O> for VecCache<'f, O> {
fn get_many<const N: usize>(&mut self, inputs: [usize; N]) -> [&O; N] {
let len = self.cache.len();
let max = inputs.iter().max().copied().unwrap_or(0);
if len <= max {
self.cache.reserve(max - len + 1);
}
for i in inputs {
self.get(i);
}
inputs.map(|i| self.cache.get(i).unwrap())
}
}
impl<'f, O> VecCache<'f, O> {
/// Create a cache for the provided function. If the
/// function stores references, the cache can only
/// live as long as those references.
pub fn new<F>(f: F) -> Self
where
F: Fn(&usize) -> O + 'f + Send + Sync,
{
Self::recursive(move |_, x| f(x))
}
/// Create a cache for the provided recursive function.
/// If the function stores references, the cache can
/// only live as long as those references.
pub fn recursive<F>(f: F) -> Self
where
F: Fn(&mut Self, &usize) -> O + 'f + Send + Sync,
{
VecCache {
cache: Vec::default(),
f: Arc::new(f),
}
}
fn compute(&mut self, input: usize) -> O {
(self.f.clone())(self, &input)
}
/// Clears the cache. removing all values.
/// Keeps the allocated memory for reuse.
pub fn clear(&mut self) {
self.cache.clear();
}
/// Returns the number of elements in the cache.
pub fn len(&self) -> usize {
self.cache.len()
}
/// Reserves capacity for at least `additional` more elements
/// to be inserted in the cache. The collection may
/// reserve more space to avoid frequent reallocations.
pub fn reserve(&mut self, additional: usize) {
self.cache.reserve(additional)
}
}