1#[cfg(feature = "buffered")]
5mod buffered;
6#[cfg(feature = "resolve")]
7pub mod resolve;
8#[cfg(feature = "sled")]
9mod sled;
10#[cfg(feature = "tracking")]
11mod tracking;
12
13#[cfg(feature = "buffered")]
14pub use self::buffered::BufferedBlockStore;
15
16#[cfg(feature = "tracking")]
17pub use self::tracking::{BSStats, TrackingBlockStore};
18
19use cid::{Cid, Code};
20use db::{MemoryDB, Store};
21use encoding::{de::DeserializeOwned, from_slice, ser::Serialize, to_vec};
22use std::error::Error as StdError;
23
24#[cfg(feature = "rocksdb")]
25use db::rocks::{RocksDb, WriteBatch};
26
27pub trait BlockStore: Store {
29 fn get_bytes(&self, cid: &Cid) -> Result<Option<Vec<u8>>, Box<dyn StdError>> {
31 Ok(self.read(cid.to_bytes())?)
32 }
33
34 fn get<T>(&self, cid: &Cid) -> Result<Option<T>, Box<dyn StdError>>
36 where
37 T: DeserializeOwned,
38 {
39 match self.get_bytes(cid)? {
40 Some(bz) => Ok(Some(from_slice(&bz)?)),
41 None => Ok(None),
42 }
43 }
44
45 fn put<S>(&self, obj: &S, code: Code) -> Result<Cid, Box<dyn StdError>>
47 where
48 S: Serialize,
49 {
50 let bytes = to_vec(obj)?;
51 self.put_raw(bytes, code)
52 }
53
54 fn put_raw(&self, bytes: Vec<u8>, code: Code) -> Result<Cid, Box<dyn StdError>> {
56 let cid = cid::new_from_cbor(&bytes, code);
57 self.write(cid.to_bytes(), bytes)?;
58 Ok(cid)
59 }
60
61 fn bulk_put<'a, S, V>(&self, values: V, code: Code) -> Result<Vec<Cid>, Box<dyn StdError>>
63 where
64 S: Serialize + 'a,
65 V: IntoIterator<Item = &'a S>,
66 {
67 values
68 .into_iter()
69 .map(|value| self.put(value, code))
70 .collect()
71 }
72}
73
74impl BlockStore for MemoryDB {}
75
76#[cfg(feature = "rocksdb")]
77impl BlockStore for RocksDb {
78 fn bulk_put<'a, S, V>(&self, values: V, code: Code) -> Result<Vec<Cid>, Box<dyn StdError>>
79 where
80 S: Serialize + 'a,
81 V: IntoIterator<Item = &'a S>,
82 {
83 let mut batch = WriteBatch::default();
84 let cids: Vec<Cid> = values
85 .into_iter()
86 .map(|v| {
87 let bz = to_vec(v)?;
88 let cid = cid::new_from_cbor(&bz, code);
89 batch.put(cid.to_bytes(), bz);
90 Ok(cid)
91 })
92 .collect::<Result<_, Box<dyn StdError>>>()?;
93 self.db.write(batch)?;
94
95 Ok(cids)
96 }
97}