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
use once_cell::sync::OnceCell;
use recur_fn::RecurFn;
use std::collections::HashMap;
use std::hash::Hash;
use std::sync::{Arc, RwLock};
impl<Arg, Output> super::Cache for RwLock<HashMap<Arg, Arc<OnceCell<Output>>>>
where
Arg: Eq + Hash,
{
type Arg = Arg;
type Output = Output;
fn new() -> Self {
RwLock::new(HashMap::new())
}
fn get(&self, arg: &Self::Arg) -> Option<Arc<OnceCell<Self::Output>>> {
self.read().unwrap().get(arg).map(|arc| Arc::clone(arc))
}
fn get_or_new(&self, arg: Self::Arg) -> Arc<OnceCell<Self::Output>> {
Arc::clone(
self.write()
.unwrap()
.entry(arg)
.or_insert_with(|| Arc::new(OnceCell::new())),
)
}
fn clear(&self) {
self.write().unwrap().clear()
}
}
pub fn memoize<Arg, Output, F>(f: F) -> impl crate::FnMemo<Arg, Output>
where
Arg: Clone + Eq + Hash,
Output: Clone,
F: RecurFn<Arg, Output>,
{
super::Memo::<RwLock<HashMap<_, _>>, _>::new(f)
}
impl<Output> super::Cache for RwLock<Vec<Arc<OnceCell<Output>>>> {
type Arg = usize;
type Output = Output;
fn new() -> Self {
RwLock::new(Vec::new())
}
fn get(&self, arg: &Self::Arg) -> Option<Arc<OnceCell<Self::Output>>> {
self.read().unwrap().get(*arg).map(|arc| Arc::clone(arc))
}
fn get_or_new(&self, arg: Self::Arg) -> Arc<OnceCell<Self::Output>> {
let mut write = self.write().unwrap();
if arg >= write.len() {
let delta: usize = arg + 1 - write.len();
write.reserve(delta);
while write.len() <= arg {
write.push(Arc::new(OnceCell::new()));
}
}
Arc::clone(&write[arg])
}
fn clear(&self) {
self.write().unwrap().clear()
}
}
pub fn memoize_seq<Output, F>(f: F) -> impl crate::FnMemo<usize, Output>
where
Output: Clone,
F: RecurFn<usize, Output>,
{
super::Memo::<RwLock<Vec<_>>, _>::new(f)
}