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
101
102
103
104
use crate::{
error::StoreError,
read_transform,
readwrite::{
Readable,
Writer,
},
value::Value,
};
use lmdb::{
Cursor,
Database,
Iter as LmdbIter,
RoCursor,
WriteFlags,
};
#[derive(Copy, Clone)]
pub struct SingleStore {
db: Database,
}
pub struct Iter<'env> {
iter: LmdbIter<'env>,
cursor: RoCursor<'env>,
}
impl SingleStore {
pub(crate) fn new(db: Database) -> SingleStore {
SingleStore {
db,
}
}
pub fn get<T: Readable, K: AsRef<[u8]>>(self, reader: &T, k: K) -> Result<Option<Value>, StoreError> {
reader.get(self.db, &k)
}
pub fn put<K: AsRef<[u8]>>(self, writer: &mut Writer, k: K, v: &Value) -> Result<(), StoreError> {
writer.put(self.db, &k, v, WriteFlags::empty())
}
pub fn delete<K: AsRef<[u8]>>(self, writer: &mut Writer, k: K) -> Result<(), StoreError> {
writer.delete(self.db, &k, None)
}
pub fn iter_start<T: Readable>(self, reader: &T) -> Result<Iter, StoreError> {
let mut cursor = reader.open_ro_cursor(self.db)?;
let iter = cursor.iter();
Ok(Iter {
iter,
cursor,
})
}
pub fn iter_from<T: Readable, K: AsRef<[u8]>>(self, reader: &T, k: K) -> Result<Iter, StoreError> {
let mut cursor = reader.open_ro_cursor(self.db)?;
let iter = cursor.iter_from(k);
Ok(Iter {
iter,
cursor,
})
}
pub fn clear(self, writer: &mut Writer) -> Result<(), StoreError> {
writer.clear(self.db)
}
}
impl<'env> Iterator for Iter<'env> {
type Item = Result<(&'env [u8], Option<Value<'env>>), StoreError>;
fn next(&mut self) -> Option<Self::Item> {
match self.iter.next() {
None => None,
Some(Ok((key, bytes))) => match read_transform(Ok(bytes)) {
Ok(val) => Some(Ok((key, val))),
Err(err) => Some(Err(err)),
},
Some(Err(err)) => Some(Err(StoreError::LmdbError(err))),
}
}
}