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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
use crate::{
database::Column,
state::in_memory::transaction::MemoryTransactionView,
};
use std::{
fmt::Debug,
marker::PhantomData,
sync::Arc,
};
pub use fuel_core_interfaces::db::Error;
pub type Result<T> = core::result::Result<T, Error>;
pub type DataSource = Arc<dyn TransactableStorage>;
pub type ColumnId = u32;
#[derive(Clone, Debug, Default)]
pub struct MultiKey<K1: AsRef<[u8]>, K2: AsRef<[u8]>> {
_marker_1: PhantomData<K1>,
_marker_2: PhantomData<K2>,
inner: Vec<u8>,
}
impl<K1: AsRef<[u8]>, K2: AsRef<[u8]>> MultiKey<K1, K2> {
pub fn new(key: &(K1, K2)) -> Self {
Self {
_marker_1: Default::default(),
_marker_2: Default::default(),
inner: key
.0
.as_ref()
.iter()
.chain(key.1.as_ref().iter())
.copied()
.collect(),
}
}
}
impl<K1: AsRef<[u8]>, K2: AsRef<[u8]>> AsRef<[u8]> for MultiKey<K1, K2> {
fn as_ref(&self) -> &[u8] {
self.inner.as_slice()
}
}
impl<K1: AsRef<[u8]>, K2: AsRef<[u8]>> From<MultiKey<K1, K2>> for Vec<u8> {
fn from(key: MultiKey<K1, K2>) -> Vec<u8> {
key.inner
}
}
pub type KVItem = Result<(Vec<u8>, Vec<u8>)>;
pub trait KeyValueStore {
fn get(&self, key: &[u8], column: Column) -> Result<Option<Vec<u8>>>;
fn put(&self, key: &[u8], column: Column, value: Vec<u8>) -> Result<Option<Vec<u8>>>;
fn delete(&self, key: &[u8], column: Column) -> Result<Option<Vec<u8>>>;
fn exists(&self, key: &[u8], column: Column) -> Result<bool>;
fn iter_all(
&self,
column: Column,
prefix: Option<Vec<u8>>,
start: Option<Vec<u8>>,
direction: IterDirection,
) -> Box<dyn Iterator<Item = KVItem> + '_>;
}
#[derive(Copy, Clone, Debug, PartialOrd, Eq, PartialEq)]
pub enum IterDirection {
Forward,
Reverse,
}
impl Default for IterDirection {
fn default() -> Self {
Self::Forward
}
}
pub trait BatchOperations: KeyValueStore {
fn batch_write(
&self,
entries: &mut dyn Iterator<Item = WriteOperation>,
) -> Result<()> {
for entry in entries {
match entry {
WriteOperation::Insert(key, column, value) => {
let _ = self.put(&key, column, value);
}
WriteOperation::Remove(key, column) => {
let _ = self.delete(&key, column);
}
}
}
Ok(())
}
}
#[derive(Debug)]
pub enum WriteOperation {
Insert(Vec<u8>, Column, Vec<u8>),
Remove(Vec<u8>, Column),
}
pub trait Transaction {
fn transaction<F, R>(&mut self, f: F) -> TransactionResult<R>
where
F: FnOnce(&mut MemoryTransactionView) -> TransactionResult<R> + Copy;
}
pub type TransactionResult<T> = core::result::Result<T, TransactionError>;
pub trait TransactableStorage:
KeyValueStore + BatchOperations + Debug + Send + Sync
{
}
#[derive(Clone, Debug)]
pub enum TransactionError {
Aborted,
}
pub mod in_memory;
#[cfg(feature = "rocksdb")]
pub mod rocks_db;