-
-
Notifications
You must be signed in to change notification settings - Fork 574
/
Copy pathcache.rs
51 lines (48 loc) · 1.37 KB
/
cache.rs
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
use parking_lot::RawRwLock;
use std::any::Any;
use std::borrow::Borrow;
use std::cell::RefCell;
use std::collections::hash_map::DefaultHasher;
use std::collections::HashMap;
use std::hash::{Hash, Hasher};
use std::iter::{self, Sum};
use std::marker::PhantomData;
use storage_map::{StorageMap, StorageMapGuard};
/// Caches the output of a given Node and acts as a proxy
/// Automatically resets if it receives different input
pub struct SmartCacheNode<'n, 'c, NODE: Node + 'c> {
node: &'n NODE,
map: StorageMap<RawRwLock, HashMap<u64, CacheNode<'n, 'c, NODE>>>,
}
impl<'n: 'c, 'c, NODE: Node + 'c> Node for SmartCacheNode<'n, 'c, NODE>
where
for<'a> NODE::Input<'a>: Hash,
{
type Input<'a>
= NODE::Input<'a>
where
Self: 'a,
'c: 'a;
type Output<'a>
= StorageMapGuard<'a, RawRwLock, CacheNode<'n, 'c, NODE>>
where
Self: 'a,
'c: 'a;
fn eval<'a, I: Borrow<Self::Input<'a>>>(&'a self, input: I) -> Self::Output<'a> {
let mut hasher = DefaultHasher::new();
input.borrow().hash(&mut hasher);
let hash = hasher.finish();
self.map.get_or_create_with(&hash, || {
trace!("Creating new cache node");
CacheNode::new(self.node)
})
}
}
impl<'n, 'c, NODE: Node> SmartCacheNode<'n, 'c, NODE> {
pub fn clear(&'n mut self) {
self.map = StorageMap::default();
}
pub fn new(node: &'n NODE) -> SmartCacheNode<'n, 'c, NODE> {
SmartCacheNode { node, map: StorageMap::default() }
}
}