1use super::{
5 car::ManyCar,
6 parity_db::{GarbageCollectableDb, GarbageCollectableParityDb, ParityDb},
7 *,
8};
9use crate::{
10 db::car::ReloadableManyCar, libp2p_bitswap::*, prelude::*,
11 tool::subcommands::api_cmd::generate_test_snapshot::ReadOpsTrackingStore,
12};
13use ambassador::Delegate;
14use spire_enum::prelude::delegated_enum;
15use std::path::PathBuf;
16
17#[derive(Delegate)]
18#[delegate(SettingsStore)]
19#[delegate(EthMappingsStore)]
20#[delegate(EthBlockBloomStore)]
21#[delegate(HeaviestTipsetKeyProvider)]
22#[delegate(BitswapStoreRead)]
23#[delegate(BitswapStoreReadWrite)]
24#[delegated_enum(impl_conversions)]
25pub enum DbImpl {
26 ManyCarWithGarbageCollectableParityDb(Arc<ManyCar<Arc<GarbageCollectableParityDb>>>),
27 ManyCarWithMemoryDB(Arc<ManyCar<MemoryDB>>),
28 ManyCarParityDb(Arc<ManyCar<ParityDb>>),
29 Memory(Arc<MemoryDB>),
30 ReadOpsTrackingManyCarParityDb(Arc<ReadOpsTrackingStore<ManyCar<ParityDb>>>),
31}
32
33impl ShallowClone for DbImpl {
34 fn shallow_clone(&self) -> Self {
35 delegate_db_impl!(self.shallow_clone().into())
36 }
37}
38
39impl Blockstore for DbImpl {
40 fn get(&self, k: &Cid) -> anyhow::Result<Option<Vec<u8>>> {
41 delegate_db_impl!(self => |i| Blockstore::get(i, k))
42 }
43
44 fn put_keyed(&self, k: &Cid, block: &[u8]) -> anyhow::Result<()> {
45 delegate_db_impl!(self => |i| Blockstore::put_keyed(i, k, block))
46 }
47
48 fn has(&self, k: &Cid) -> anyhow::Result<bool> {
49 delegate_db_impl!(self => |i| Blockstore::has(i, k))
50 }
51
52 #[allow(clippy::disallowed_types)]
53 fn put<D>(
54 &self,
55 mh_code: multihash_codetable::Code,
56 block: &fvm_ipld_blockstore::Block<D>,
57 ) -> anyhow::Result<Cid>
58 where
59 Self: Sized,
60 D: AsRef<[u8]>,
61 {
62 delegate_db_impl!(self => |i| Blockstore::put(i, mh_code, block))
63 }
64
65 #[allow(clippy::disallowed_types)]
66 fn put_many<D, I>(&self, blocks: I) -> anyhow::Result<()>
67 where
68 Self: Sized,
69 D: AsRef<[u8]>,
70 I: IntoIterator<Item = (multihash_codetable::Code, fvm_ipld_blockstore::Block<D>)>,
71 {
72 delegate_db_impl!(self => |i| Blockstore::put_many(i, blocks))
73 }
74
75 fn put_many_keyed<D, I>(&self, blocks: I) -> anyhow::Result<()>
76 where
77 Self: Sized,
78 D: AsRef<[u8]>,
79 I: IntoIterator<Item = (Cid, D)>,
80 {
81 delegate_db_impl!(self => |i| Blockstore::put_many_keyed(i, blocks))
82 }
83}
84
85impl GarbageCollectableDb for DbImpl {
86 fn reset_gc_columns(&self) -> anyhow::Result<()> {
87 match self {
88 Self::ManyCarWithGarbageCollectableParityDb(db) => db.reset_gc_columns(),
89 _ => anyhow::bail!("db is not garbage collectable"),
90 }
91 }
92}
93
94impl BlockstoreWriteOpsSubscribable for DbImpl {
95 fn subscribe_write_ops(
96 &self,
97 ) -> anyhow::Result<tokio::sync::broadcast::Receiver<Vec<(Cid, bytes::Bytes)>>> {
98 if let Self::ManyCarWithGarbageCollectableParityDb(db) = self {
99 db.subscribe_write_ops()
100 } else {
101 anyhow::bail!("not supported")
102 }
103 }
104
105 fn unsubscribe_write_ops(&self) {
106 if let Self::ManyCarWithGarbageCollectableParityDb(db) = self {
107 db.unsubscribe_write_ops();
108 }
109 }
110}
111
112impl ReloadableManyCar for DbImpl {
113 fn clear_and_reload_cars(&self, files: impl Iterator<Item = PathBuf>) -> anyhow::Result<()> {
114 match self {
115 Self::ManyCarWithGarbageCollectableParityDb(db) => db.clear_and_reload_cars(files),
116 Self::ManyCarWithMemoryDB(db) => db.clear_and_reload_cars(files),
117 Self::ManyCarParityDb(db) => db.clear_and_reload_cars(files),
118 _ => anyhow::bail!("not supported"),
119 }
120 }
121
122 fn heaviest_car_tipset(&self) -> anyhow::Result<Tipset> {
123 match self {
124 Self::ManyCarWithGarbageCollectableParityDb(db) => db.heaviest_car_tipset(),
125 Self::ManyCarWithMemoryDB(db) => db.heaviest_car_tipset(),
126 Self::ManyCarParityDb(db) => db.heaviest_car_tipset(),
127 _ => anyhow::bail!("not supported"),
128 }
129 }
130}