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