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
use std::sync::Arc;
use std::io::{Result, Error, ErrorKind};
use std::marker::PhantomData;
use parking_lot::RwLock;
use hash::{Hash32, HasherFactory};
use backend::Backend;
use content::{Content, Source, Sink};
use lazy::Lazy;
pub struct Store<T> {
backend: Arc<RwLock<Box<Backend>>>,
hasher: HasherFactory,
_p: PhantomData<T>,
}
impl<T> Store<T> where T: Content {
pub fn new(
backend: Box<Backend>,
hasher: HasherFactory,
) -> Self {
Store {
backend: Arc::new(RwLock::new(backend)),
hasher: hasher,
_p: PhantomData,
}
}
pub fn lazy<U: Content>(&self, inner: U) -> Lazy<U> {
Lazy::new(
inner,
self.hasher.clone(),
self.backend.clone(),
)
}
pub fn put(&mut self, t: &T) -> Result<Hash32> {
self.backend.write().store(
&|write, backend| {
t.to_content(&mut Sink::new(write, backend))
},
&self.hasher
)
}
pub fn get(&mut self, hash: &Hash32) -> Result<T> {
let msg = "Request closure not called";
let res = RwLock::new(Err(Error::new(ErrorKind::Other, msg)));
try!(self.backend.read().request(hash, &|read| {
let mut source = Source::new(
read,
&self.hasher,
&self.backend
);
*res.write() = T::from_content(&mut source);
Ok(())
}));
res.into_inner()
}
}
#[cfg(test)]
mod tests {
use test_common;
#[test]
fn put_u8() {
let mut store = test_common::store::<u8>();
let hash = store.put(&42).unwrap();
let hash2 = store.put(&43).unwrap();
assert_eq!(store.get(&hash).unwrap(), 42);
assert_eq!(store.get(&hash2).unwrap(), 43);
}
}