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
#[cfg(feature = "buffered")]
mod buffered;
#[cfg(feature = "resolve")]
pub mod resolve;
#[cfg(feature = "sled")]
mod sled;
#[cfg(feature = "tracking")]
mod tracking;
#[cfg(feature = "buffered")]
pub use self::buffered::BufferedBlockStore;
#[cfg(feature = "tracking")]
pub use self::tracking::{BSStats, TrackingBlockStore};
use cid::{Cid, Code};
use db::{MemoryDB, Store};
use encoding::{de::DeserializeOwned, from_slice, ser::Serialize, to_vec};
use std::error::Error as StdError;
#[cfg(feature = "rocksdb")]
use db::rocks::{RocksDb, WriteBatch};
pub trait BlockStore: Store {
fn get_bytes(&self, cid: &Cid) -> Result<Option<Vec<u8>>, Box<dyn StdError>> {
Ok(self.read(cid.to_bytes())?)
}
fn get<T>(&self, cid: &Cid) -> Result<Option<T>, Box<dyn StdError>>
where
T: DeserializeOwned,
{
match self.get_bytes(cid)? {
Some(bz) => Ok(Some(from_slice(&bz)?)),
None => Ok(None),
}
}
fn put<S>(&self, obj: &S, code: Code) -> Result<Cid, Box<dyn StdError>>
where
S: Serialize,
{
let bytes = to_vec(obj)?;
self.put_raw(bytes, code)
}
fn put_raw(&self, bytes: Vec<u8>, code: Code) -> Result<Cid, Box<dyn StdError>> {
let cid = cid::new_from_cbor(&bytes, code);
self.write(cid.to_bytes(), bytes)?;
Ok(cid)
}
fn bulk_put<'a, S, V>(&self, values: V, code: Code) -> Result<Vec<Cid>, Box<dyn StdError>>
where
S: Serialize + 'a,
V: IntoIterator<Item = &'a S>,
{
values
.into_iter()
.map(|value| self.put(value, code))
.collect()
}
}
impl BlockStore for MemoryDB {}
#[cfg(feature = "rocksdb")]
impl BlockStore for RocksDb {
fn bulk_put<'a, S, V>(&self, values: V, code: Code) -> Result<Vec<Cid>, Box<dyn StdError>>
where
S: Serialize + 'a,
V: IntoIterator<Item = &'a S>,
{
let mut batch = WriteBatch::default();
let cids: Vec<Cid> = values
.into_iter()
.map(|v| {
let bz = to_vec(v)?;
let cid = cid::new_from_cbor(&bz, code);
batch.put(cid.to_bytes(), bz);
Ok(cid)
})
.collect::<Result<_, Box<dyn StdError>>>()?;
self.db.write(batch)?;
Ok(cids)
}
}