1use smallvec::SmallVec;
12use std::io;
13
14mod io_stats;
15
16pub const PREFIX_LEN: usize = 12;
18
19pub type DBValue = Vec<u8>;
21pub type DBKey = SmallVec<[u8; 32]>;
23pub type DBKeyValue = (DBKey, DBValue);
25
26pub use io_stats::{IoStats, Kind as IoStatsKind};
27
28#[derive(Default, Clone, PartialEq)]
30pub struct DBTransaction {
31 pub ops: Vec<DBOp>,
33}
34
35#[derive(Clone, PartialEq)]
37pub enum DBOp {
38 Insert { col: u32, key: DBKey, value: DBValue },
39 Delete { col: u32, key: DBKey },
40 DeletePrefix { col: u32, prefix: DBKey },
41}
42
43impl DBOp {
44 pub fn key(&self) -> &[u8] {
46 match *self {
47 DBOp::Insert { ref key, .. } => key,
48 DBOp::Delete { ref key, .. } => key,
49 DBOp::DeletePrefix { ref prefix, .. } => prefix,
50 }
51 }
52
53 pub fn col(&self) -> u32 {
55 match *self {
56 DBOp::Insert { col, .. } => col,
57 DBOp::Delete { col, .. } => col,
58 DBOp::DeletePrefix { col, .. } => col,
59 }
60 }
61}
62
63impl DBTransaction {
64 pub fn new() -> DBTransaction {
66 DBTransaction::with_capacity(256)
67 }
68
69 pub fn with_capacity(cap: usize) -> DBTransaction {
71 DBTransaction { ops: Vec::with_capacity(cap) }
72 }
73
74 pub fn put(&mut self, col: u32, key: &[u8], value: &[u8]) {
76 self.ops
77 .push(DBOp::Insert { col, key: DBKey::from_slice(key), value: value.to_vec() })
78 }
79
80 pub fn put_vec(&mut self, col: u32, key: &[u8], value: Vec<u8>) {
82 self.ops.push(DBOp::Insert { col, key: DBKey::from_slice(key), value });
83 }
84
85 pub fn delete(&mut self, col: u32, key: &[u8]) {
87 self.ops.push(DBOp::Delete { col, key: DBKey::from_slice(key) });
88 }
89
90 pub fn delete_prefix(&mut self, col: u32, prefix: &[u8]) {
94 self.ops.push(DBOp::DeletePrefix { col, prefix: DBKey::from_slice(prefix) });
95 }
96}
97
98pub trait KeyValueDB: Sync + Send {
108 fn transaction(&self) -> DBTransaction {
110 DBTransaction::new()
111 }
112
113 fn get(&self, col: u32, key: &[u8]) -> io::Result<Option<DBValue>>;
115
116 fn get_by_prefix(&self, col: u32, prefix: &[u8]) -> io::Result<Option<DBValue>>;
118
119 fn write(&self, transaction: DBTransaction) -> io::Result<()>;
121
122 fn iter<'a>(&'a self, col: u32) -> Box<dyn Iterator<Item = io::Result<DBKeyValue>> + 'a>;
124
125 fn iter_with_prefix<'a>(
128 &'a self,
129 col: u32,
130 prefix: &'a [u8],
131 ) -> Box<dyn Iterator<Item = io::Result<DBKeyValue>> + 'a>;
132
133 fn io_stats(&self, _kind: IoStatsKind) -> IoStats {
140 IoStats::empty()
141 }
142
143 fn has_key(&self, col: u32, key: &[u8]) -> io::Result<bool> {
145 self.get(col, key).map(|opt| opt.is_some())
146 }
147
148 fn has_prefix(&self, col: u32, prefix: &[u8]) -> io::Result<bool> {
150 self.get_by_prefix(col, prefix).map(|opt| opt.is_some())
151 }
152}
153
154pub fn end_prefix(prefix: &[u8]) -> Option<Vec<u8>> {
159 let mut end_range = prefix.to_vec();
160 while let Some(0xff) = end_range.last() {
161 end_range.pop();
162 }
163 if let Some(byte) = end_range.last_mut() {
164 *byte += 1;
165 Some(end_range)
166 } else {
167 None
168 }
169}
170
171#[cfg(test)]
172mod test {
173 use super::end_prefix;
174
175 #[test]
176 fn end_prefix_test() {
177 assert_eq!(end_prefix(&[5, 6, 7]), Some(vec![5, 6, 8]));
178 assert_eq!(end_prefix(&[5, 6, 255]), Some(vec![5, 7]));
179 assert_ne!(end_prefix(&[5, 255, 255]), Some(vec![5, 255]));
181 assert_eq!(end_prefix(&[5, 255, 255]), Some(vec![6]));
184 assert_eq!(end_prefix(&[255, 255, 255]), None);
185
186 assert_eq!(end_prefix(&[0x00, 0xff]), Some(vec![0x01]));
187 assert_eq!(end_prefix(&[0xff]), None);
188 assert_eq!(end_prefix(&[]), None);
189 assert_eq!(end_prefix(b"0"), Some(b"1".to_vec()));
190 }
191}