diff --git a/crates/brk_computer/src/stores.rs b/crates/brk_computer/src/stores.rs index f23a08120..f507b1b1a 100644 --- a/crates/brk_computer/src/stores.rs +++ b/crates/brk_computer/src/stores.rs @@ -1,19 +1,23 @@ use std::{path::Path, thread}; use brk_core::{ - AddressData, EmptyAddressData, P2AAddressIndex, P2AAddressIndexOutputindex, P2PK33AddressIndex, - P2PK33AddressIndexOutputindex, P2PK65AddressIndex, P2PK65AddressIndexOutputindex, - P2PKHAddressIndex, P2PKHAddressIndexOutputindex, P2SHAddressIndex, P2SHAddressIndexOutputindex, - P2TRAddressIndex, P2TRAddressIndexOutputindex, P2WPKHAddressIndex, - P2WPKHAddressIndexOutputindex, P2WSHAddressIndex, P2WSHAddressIndexOutputindex, Unit, Version, + AddressData, EmptyAddressData, Height, P2AAddressIndex, P2AAddressIndexOutputindex, + P2PK33AddressIndex, P2PK33AddressIndexOutputindex, P2PK65AddressIndex, + P2PK65AddressIndexOutputindex, P2PKHAddressIndex, P2PKHAddressIndexOutputindex, + P2SHAddressIndex, P2SHAddressIndexOutputindex, P2TRAddressIndex, P2TRAddressIndexOutputindex, + P2WPKHAddressIndex, P2WPKHAddressIndexOutputindex, P2WSHAddressIndex, + P2WSHAddressIndexOutputindex, Result, Unit, Version, }; -use brk_store::Store; -use fjall::TransactionalKeyspace; +use brk_store::{AnyStore, Store}; +use fjall::{PersistMode, TransactionalKeyspace}; +use rayon::prelude::*; const VERSION: Version = Version::ZERO; #[derive(Clone)] pub struct Stores { + keyspace: TransactionalKeyspace, + pub p2aaddressindex_to_addressdata: Store, pub p2aaddressindex_to_emptyaddressdata: Store, pub p2aaddressindex_to_utxos_received: Store, @@ -420,6 +424,8 @@ impl Stores { }); Ok(Self { + keyspace: keyspace.clone(), + p2aaddressindex_to_addressdata, p2aaddressindex_to_emptyaddressdata, p2aaddressindex_to_utxos_received, @@ -461,4 +467,102 @@ impl Stores { p2wshaddressindex_to_utxos_sent, }) } + + pub fn starting_height(&self) -> Height { + self.as_slice() + .into_iter() + .map(|store| store.height().map(Height::incremented).unwrap_or_default()) + .min() + .unwrap() + } + + pub fn commit(&mut self, height: Height) -> Result<()> { + self.as_mut_slice() + .into_par_iter() + .try_for_each(|store| store.commit(height))?; + + self.keyspace + .persist(PersistMode::SyncAll) + .map_err(|e| e.into()) + } + + pub fn rotate_memtables(&self) { + self.as_slice() + .into_iter() + .for_each(|store| store.rotate_memtable()); + } + + fn as_slice(&self) -> [&(dyn AnyStore + Send + Sync); 32] { + [ + &self.p2aaddressindex_to_addressdata, + &self.p2aaddressindex_to_emptyaddressdata, + &self.p2aaddressindex_to_utxos_received, + &self.p2aaddressindex_to_utxos_sent, + &self.p2pk33addressindex_to_addressdata, + &self.p2pk33addressindex_to_emptyaddressdata, + &self.p2pk33addressindex_to_utxos_received, + &self.p2pk33addressindex_to_utxos_sent, + &self.p2pk65addressindex_to_addressdata, + &self.p2pk65addressindex_to_emptyaddressdata, + &self.p2pk65addressindex_to_utxos_received, + &self.p2pk65addressindex_to_utxos_sent, + &self.p2pkhaddressindex_to_addressdata, + &self.p2pkhaddressindex_to_emptyaddressdata, + &self.p2pkhaddressindex_to_utxos_received, + &self.p2pkhaddressindex_to_utxos_sent, + &self.p2shaddressindex_to_addressdata, + &self.p2shaddressindex_to_emptyaddressdata, + &self.p2shaddressindex_to_utxos_received, + &self.p2shaddressindex_to_utxos_sent, + &self.p2traddressindex_to_addressdata, + &self.p2traddressindex_to_emptyaddressdata, + &self.p2traddressindex_to_utxos_received, + &self.p2traddressindex_to_utxos_sent, + &self.p2wpkhaddressindex_to_addressdata, + &self.p2wpkhaddressindex_to_emptyaddressdata, + &self.p2wpkhaddressindex_to_utxos_received, + &self.p2wpkhaddressindex_to_utxos_sent, + &self.p2wshaddressindex_to_addressdata, + &self.p2wshaddressindex_to_emptyaddressdata, + &self.p2wshaddressindex_to_utxos_received, + &self.p2wshaddressindex_to_utxos_sent, + ] + } + + fn as_mut_slice(&mut self) -> [&mut (dyn AnyStore + Send + Sync); 32] { + [ + &mut self.p2aaddressindex_to_addressdata, + &mut self.p2aaddressindex_to_emptyaddressdata, + &mut self.p2aaddressindex_to_utxos_received, + &mut self.p2aaddressindex_to_utxos_sent, + &mut self.p2pk33addressindex_to_addressdata, + &mut self.p2pk33addressindex_to_emptyaddressdata, + &mut self.p2pk33addressindex_to_utxos_received, + &mut self.p2pk33addressindex_to_utxos_sent, + &mut self.p2pk65addressindex_to_addressdata, + &mut self.p2pk65addressindex_to_emptyaddressdata, + &mut self.p2pk65addressindex_to_utxos_received, + &mut self.p2pk65addressindex_to_utxos_sent, + &mut self.p2pkhaddressindex_to_addressdata, + &mut self.p2pkhaddressindex_to_emptyaddressdata, + &mut self.p2pkhaddressindex_to_utxos_received, + &mut self.p2pkhaddressindex_to_utxos_sent, + &mut self.p2shaddressindex_to_addressdata, + &mut self.p2shaddressindex_to_emptyaddressdata, + &mut self.p2shaddressindex_to_utxos_received, + &mut self.p2shaddressindex_to_utxos_sent, + &mut self.p2traddressindex_to_addressdata, + &mut self.p2traddressindex_to_emptyaddressdata, + &mut self.p2traddressindex_to_utxos_received, + &mut self.p2traddressindex_to_utxos_sent, + &mut self.p2wpkhaddressindex_to_addressdata, + &mut self.p2wpkhaddressindex_to_emptyaddressdata, + &mut self.p2wpkhaddressindex_to_utxos_received, + &mut self.p2wpkhaddressindex_to_utxos_sent, + &mut self.p2wshaddressindex_to_addressdata, + &mut self.p2wshaddressindex_to_emptyaddressdata, + &mut self.p2wshaddressindex_to_utxos_received, + &mut self.p2wshaddressindex_to_utxos_sent, + ] + } } diff --git a/crates/brk_core/src/structs/addressdata.rs b/crates/brk_core/src/structs/addressdata.rs index 936660c20..03a3260b1 100644 --- a/crates/brk_core/src/structs/addressdata.rs +++ b/crates/brk_core/src/structs/addressdata.rs @@ -1,11 +1,11 @@ use byteview::ByteView; use zerocopy::{FromBytes, IntoBytes}; -use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout}; +use zerocopy_derive::{FromBytes, Immutable, KnownLayout}; -use crate::{Dollars, Sats}; +use crate::{CheckedSub, Dollars, EmptyAddressData, Error, Result, Sats}; -#[derive(Debug, Default, Clone, FromBytes, Immutable, IntoBytes, KnownLayout)] -#[repr(C, packed)] +#[derive(Debug, Default, Clone, FromBytes, Immutable, KnownLayout)] +#[repr(C)] pub struct AddressData { pub sent: Sats, pub received: Sats, @@ -17,6 +17,54 @@ impl AddressData { pub fn amount(&self) -> Sats { (u64::from(self.received) - u64::from(self.sent)).into() } + + #[inline(always)] + pub fn is_empty(&self) -> bool { + if self.amount() == Sats::ZERO { + if self.outputs_len != 0 { + unreachable!(); + } + + true + } else { + false + } + } + + pub fn receive(&mut self, amount: Sats, price: Dollars) { + self.received += amount; + self.outputs_len += 1; + self.realized_cap += price * amount; + } + + pub fn send(&mut self, amount: Sats, previous_price: Dollars) -> Result<()> { + if self.amount() < amount { + return Err(Error::String("Previous_amount smaller than sent amount")); + } + self.sent += amount; + self.outputs_len -= 1; + self.realized_cap = self + .realized_cap + .checked_sub(previous_price * amount) + .unwrap(); + Ok(()) + } +} + +impl From for AddressData { + fn from(value: EmptyAddressData) -> Self { + Self::from(&value) + } +} +impl From<&EmptyAddressData> for AddressData { + fn from(value: &EmptyAddressData) -> Self { + Self { + sent: value.transfered, + received: value.transfered, + realized_cap: Dollars::ZERO, + outputs_len: 0, + } + } } impl From for AddressData { @@ -31,6 +79,14 @@ impl From for ByteView { } impl From<&AddressData> for ByteView { fn from(value: &AddressData) -> Self { - Self::new(value.as_bytes()) + Self::new( + &[ + value.sent.as_bytes(), + value.received.as_bytes(), + value.realized_cap.as_bytes(), + value.outputs_len.as_bytes(), + ] + .concat(), + ) } } diff --git a/crates/brk_core/src/structs/emptyaddressdata.rs b/crates/brk_core/src/structs/emptyaddressdata.rs index 34c9e0ce3..d081ed0e8 100644 --- a/crates/brk_core/src/structs/emptyaddressdata.rs +++ b/crates/brk_core/src/structs/emptyaddressdata.rs @@ -2,14 +2,30 @@ use byteview::ByteView; use zerocopy::{FromBytes, IntoBytes}; use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout}; -use crate::Sats; +use crate::{AddressData, Sats}; #[derive(Debug, Default, Clone, FromBytes, Immutable, IntoBytes, KnownLayout)] pub struct EmptyAddressData { pub transfered: Sats, } -impl EmptyAddressData {} +impl From for EmptyAddressData { + fn from(value: AddressData) -> Self { + Self::from(&value) + } +} + +impl From<&AddressData> for EmptyAddressData { + fn from(value: &AddressData) -> Self { + if value.sent != value.received { + dbg!(&value); + panic!("Trying to convert not empty wallet to empty !"); + } + Self { + transfered: value.sent, + } + } +} impl From for EmptyAddressData { fn from(value: ByteView) -> Self { diff --git a/crates/brk_core/src/structs/p2aaddressindex_outputindex.rs b/crates/brk_core/src/structs/p2aaddressindex_outputindex.rs index f5e182bbc..50c442dd5 100644 --- a/crates/brk_core/src/structs/p2aaddressindex_outputindex.rs +++ b/crates/brk_core/src/structs/p2aaddressindex_outputindex.rs @@ -11,6 +11,15 @@ pub struct P2AAddressIndexOutputindex { outputindex: OutputIndex, } +impl From<(P2AAddressIndex, OutputIndex)> for P2AAddressIndexOutputindex { + fn from(value: (P2AAddressIndex, OutputIndex)) -> Self { + Self { + addressindex: value.0, + outputindex: value.1, + } + } +} + impl From for P2AAddressIndexOutputindex { fn from(value: ByteView) -> Self { let addressindex = diff --git a/crates/brk_core/src/structs/p2pk33addressindex_outputindex.rs b/crates/brk_core/src/structs/p2pk33addressindex_outputindex.rs index f96989599..b921c5c8b 100644 --- a/crates/brk_core/src/structs/p2pk33addressindex_outputindex.rs +++ b/crates/brk_core/src/structs/p2pk33addressindex_outputindex.rs @@ -11,6 +11,15 @@ pub struct P2PK33AddressIndexOutputindex { outputindex: OutputIndex, } +impl From<(P2PK33AddressIndex, OutputIndex)> for P2PK33AddressIndexOutputindex { + fn from(value: (P2PK33AddressIndex, OutputIndex)) -> Self { + Self { + addressindex: value.0, + outputindex: value.1, + } + } +} + impl From for P2PK33AddressIndexOutputindex { fn from(value: ByteView) -> Self { let addressindex = diff --git a/crates/brk_core/src/structs/p2pk65addressindex_outputindex.rs b/crates/brk_core/src/structs/p2pk65addressindex_outputindex.rs index 6e17d6bdc..a19b4d2fc 100644 --- a/crates/brk_core/src/structs/p2pk65addressindex_outputindex.rs +++ b/crates/brk_core/src/structs/p2pk65addressindex_outputindex.rs @@ -11,6 +11,15 @@ pub struct P2PK65AddressIndexOutputindex { outputindex: OutputIndex, } +impl From<(P2PK65AddressIndex, OutputIndex)> for P2PK65AddressIndexOutputindex { + fn from(value: (P2PK65AddressIndex, OutputIndex)) -> Self { + Self { + addressindex: value.0, + outputindex: value.1, + } + } +} + impl From for P2PK65AddressIndexOutputindex { fn from(value: ByteView) -> Self { let addressindex = diff --git a/crates/brk_core/src/structs/p2pkhaddressindex_outputindex.rs b/crates/brk_core/src/structs/p2pkhaddressindex_outputindex.rs index d2a23313f..d7e6df5db 100644 --- a/crates/brk_core/src/structs/p2pkhaddressindex_outputindex.rs +++ b/crates/brk_core/src/structs/p2pkhaddressindex_outputindex.rs @@ -11,6 +11,15 @@ pub struct P2PKHAddressIndexOutputindex { outputindex: OutputIndex, } +impl From<(P2PKHAddressIndex, OutputIndex)> for P2PKHAddressIndexOutputindex { + fn from(value: (P2PKHAddressIndex, OutputIndex)) -> Self { + Self { + addressindex: value.0, + outputindex: value.1, + } + } +} + impl From for P2PKHAddressIndexOutputindex { fn from(value: ByteView) -> Self { let addressindex = diff --git a/crates/brk_core/src/structs/p2shaddressindex_outputindex.rs b/crates/brk_core/src/structs/p2shaddressindex_outputindex.rs index 5a0898729..2b3650db4 100644 --- a/crates/brk_core/src/structs/p2shaddressindex_outputindex.rs +++ b/crates/brk_core/src/structs/p2shaddressindex_outputindex.rs @@ -11,6 +11,15 @@ pub struct P2SHAddressIndexOutputindex { outputindex: OutputIndex, } +impl From<(P2SHAddressIndex, OutputIndex)> for P2SHAddressIndexOutputindex { + fn from(value: (P2SHAddressIndex, OutputIndex)) -> Self { + Self { + addressindex: value.0, + outputindex: value.1, + } + } +} + impl From for P2SHAddressIndexOutputindex { fn from(value: ByteView) -> Self { let addressindex = diff --git a/crates/brk_core/src/structs/p2traddressindex_outputindex.rs b/crates/brk_core/src/structs/p2traddressindex_outputindex.rs index ae9d4cfd8..1cc9647ff 100644 --- a/crates/brk_core/src/structs/p2traddressindex_outputindex.rs +++ b/crates/brk_core/src/structs/p2traddressindex_outputindex.rs @@ -11,6 +11,15 @@ pub struct P2TRAddressIndexOutputindex { outputindex: OutputIndex, } +impl From<(P2TRAddressIndex, OutputIndex)> for P2TRAddressIndexOutputindex { + fn from(value: (P2TRAddressIndex, OutputIndex)) -> Self { + Self { + addressindex: value.0, + outputindex: value.1, + } + } +} + impl From for P2TRAddressIndexOutputindex { fn from(value: ByteView) -> Self { let addressindex = diff --git a/crates/brk_core/src/structs/p2wpkhaddressindex_outputindex.rs b/crates/brk_core/src/structs/p2wpkhaddressindex_outputindex.rs index abd91bc35..c16d91d74 100644 --- a/crates/brk_core/src/structs/p2wpkhaddressindex_outputindex.rs +++ b/crates/brk_core/src/structs/p2wpkhaddressindex_outputindex.rs @@ -11,6 +11,15 @@ pub struct P2WPKHAddressIndexOutputindex { outputindex: OutputIndex, } +impl From<(P2WPKHAddressIndex, OutputIndex)> for P2WPKHAddressIndexOutputindex { + fn from(value: (P2WPKHAddressIndex, OutputIndex)) -> Self { + Self { + addressindex: value.0, + outputindex: value.1, + } + } +} + impl From for P2WPKHAddressIndexOutputindex { fn from(value: ByteView) -> Self { let addressindex = diff --git a/crates/brk_core/src/structs/p2wshaddressindex_outputindex.rs b/crates/brk_core/src/structs/p2wshaddressindex_outputindex.rs index 2ef4742f3..d3fb72571 100644 --- a/crates/brk_core/src/structs/p2wshaddressindex_outputindex.rs +++ b/crates/brk_core/src/structs/p2wshaddressindex_outputindex.rs @@ -11,6 +11,15 @@ pub struct P2WSHAddressIndexOutputindex { outputindex: OutputIndex, } +impl From<(P2WSHAddressIndex, OutputIndex)> for P2WSHAddressIndexOutputindex { + fn from(value: (P2WSHAddressIndex, OutputIndex)) -> Self { + Self { + addressindex: value.0, + outputindex: value.1, + } + } +} + impl From for P2WSHAddressIndexOutputindex { fn from(value: ByteView) -> Self { let addressindex = diff --git a/crates/brk_indexer/src/lib.rs b/crates/brk_indexer/src/lib.rs index 876e445db..1189c2110 100644 --- a/crates/brk_indexer/src/lib.rs +++ b/crates/brk_indexer/src/lib.rs @@ -14,6 +14,7 @@ use brk_core::{ use bitcoin::{Transaction, TxIn, TxOut}; use brk_exit::Exit; use brk_parser::Parser; +use brk_store::AnyStore; use brk_vec::{AnyVec, VecIterator}; use color_eyre::eyre::{ContextCompat, eyre}; use log::{error, info}; diff --git a/crates/brk_indexer/src/stores.rs b/crates/brk_indexer/src/stores.rs index 9ea1ef32c..1f1835da5 100644 --- a/crates/brk_indexer/src/stores.rs +++ b/crates/brk_indexer/src/stores.rs @@ -4,9 +4,10 @@ use brk_core::{ AddressBytes, AddressBytesHash, BlockHashPrefix, Height, OutputType, Result, TxIndex, TxidPrefix, TypeIndex, Value, Version, }; -use brk_store::Store; +use brk_store::{AnyStore, Store}; use brk_vec::AnyIterableVec; use fjall::{PersistMode, TransactionalKeyspace}; +use rayon::prelude::*; use crate::Indexes; @@ -283,34 +284,17 @@ impl Stores { } pub fn starting_height(&self) -> Height { - [ - self.addressbyteshash_to_typeindex.height(), - self.blockhashprefix_to_height.height(), - self.txidprefix_to_txindex.height(), - ] - .into_iter() - .map(|height| height.map(Height::incremented).unwrap_or_default()) - .min() - .unwrap() + self.as_slice() + .into_iter() + .map(|store| store.height().map(Height::incremented).unwrap_or_default()) + .min() + .unwrap() } pub fn commit(&mut self, height: Height) -> Result<()> { - thread::scope(|scope| -> Result<()> { - let addressbyteshash_to_typeindex_commit_handle = - scope.spawn(|| self.addressbyteshash_to_typeindex.commit(height)); - let blockhashprefix_to_height_commit_handle = - scope.spawn(|| self.blockhashprefix_to_height.commit(height)); - let txidprefix_to_txindex_commit_handle = - scope.spawn(|| self.txidprefix_to_txindex.commit(height)); - - addressbyteshash_to_typeindex_commit_handle - .join() - .unwrap()?; - blockhashprefix_to_height_commit_handle.join().unwrap()?; - txidprefix_to_txindex_commit_handle.join().unwrap()?; - - Ok(()) - })?; + self.as_mut_slice() + .into_par_iter() + .try_for_each(|store| store.commit(height))?; self.keyspace .persist(PersistMode::SyncAll) @@ -318,8 +302,24 @@ impl Stores { } pub fn rotate_memtables(&self) { - self.addressbyteshash_to_typeindex.rotate_memtable(); - self.blockhashprefix_to_height.rotate_memtable(); - self.txidprefix_to_txindex.rotate_memtable(); + self.as_slice() + .into_iter() + .for_each(|store| store.rotate_memtable()); + } + + fn as_slice(&self) -> [&(dyn AnyStore + Send + Sync); 3] { + [ + &self.addressbyteshash_to_typeindex, + &self.blockhashprefix_to_height, + &self.txidprefix_to_txindex, + ] + } + + fn as_mut_slice(&mut self) -> [&mut (dyn AnyStore + Send + Sync); 3] { + [ + &mut self.addressbyteshash_to_typeindex, + &mut self.blockhashprefix_to_height, + &mut self.txidprefix_to_txindex, + ] } } diff --git a/crates/brk_store/examples/main.rs b/crates/brk_store/examples/main.rs index d7f80d31d..6c9f0f202 100644 --- a/crates/brk_store/examples/main.rs +++ b/crates/brk_store/examples/main.rs @@ -1,7 +1,7 @@ use std::path::Path; use brk_core::{Dollars, Height, Result, Sats, Version}; -use brk_store::Store; +use brk_store::{AnyStore, Store}; fn main() -> Result<()> { let p = Path::new("./examples/_fjall"); diff --git a/crates/brk_store/src/lib.rs b/crates/brk_store/src/lib.rs index 7b99eace6..9a4d75ab6 100644 --- a/crates/brk_store/src/lib.rs +++ b/crates/brk_store/src/lib.rs @@ -18,7 +18,10 @@ use fjall::{ }; mod meta; +mod r#trait; + use meta::*; +pub use r#trait::*; pub struct Store { meta: StoreMeta, @@ -33,7 +36,7 @@ pub struct Store { /// Use default if will read const DEFAULT_BLOOM_FILTER_BITS: Option = Some(5); -// const CHECK_COLLISISONS: bool = true; +// const CHECK_COLLISIONS: bool = true; const MAJOR_FJALL_VERSION: Version = Version::TWO; pub fn open_keyspace(path: &Path) -> fjall::Result { @@ -161,79 +164,6 @@ where // }); // } - pub fn commit(&mut self, height: Height) -> Result<()> { - if self.has(height) && self.puts.is_empty() && self.dels.is_empty() { - return Ok(()); - } - - self.meta.export(self.len(), height)?; - - let mut wtx = self.keyspace.write_tx(); - - let partition = self.partition.as_ref().unwrap(); - - mem::take(&mut self.dels) - .into_iter() - .for_each(|key| wtx.remove(partition, ByteView::from(key))); - - mem::take(&mut self.puts) - .into_iter() - .for_each(|(key, value)| { - // if CHECK_COLLISISONS { - // #[allow(unused_must_use)] - // if let Ok(Some(value)) = wtx.get(&self.partition, key.as_bytes()) { - // dbg!( - // &key, - // V::try_from(value.as_bytes().into()).unwrap(), - // &self.meta, - // self.rtx.get(&self.partition, key.as_bytes()) - // ); - // unreachable!(); - // } - // } - wtx.insert(partition, ByteView::from(key), ByteView::from(value)) - }); - - wtx.commit()?; - - self.rtx = self.keyspace.read_tx(); - - Ok(()) - } - - pub fn rotate_memtable(&self) { - let _ = self.partition.as_ref().unwrap().inner().rotate_memtable(); - } - - pub fn height(&self) -> Option { - self.meta.height() - } - - pub fn len(&self) -> usize { - let len = self.meta.len() + self.puts.len() - self.dels.len(); - if len > 18440000000000000000 { - dbg!(( - len, - self.meta.path(), - self.meta.len(), - self.puts.len(), - &self.dels, - )); - unreachable!() - } - len - } - pub fn is_empty(&self) -> bool { - self.len() == 0 - } - - pub fn has(&self, height: Height) -> bool { - self.meta.has(height) - } - pub fn needs(&self, height: Height) -> bool { - self.meta.needs(height) - } - fn open_partition_handle( keyspace: &TransactionalKeyspace, name: &str, @@ -268,6 +198,83 @@ where } } +impl<'a, K, V> AnyStore for Store +where + K: Debug + Clone + From + Ord + 'a, + V: Debug + Clone + From, + ByteView: From + From<&'a K> + From, +{ + fn commit(&mut self, height: Height) -> Result<()> { + if self.has(height) && self.puts.is_empty() && self.dels.is_empty() { + return Ok(()); + } + + self.meta.export(self.len(), height)?; + + let mut wtx = self.keyspace.write_tx(); + + let partition = self.partition.as_ref().unwrap(); + + mem::take(&mut self.dels) + .into_iter() + .for_each(|key| wtx.remove(partition, ByteView::from(key))); + + mem::take(&mut self.puts) + .into_iter() + .for_each(|(key, value)| { + // if CHECK_COLLISIONS { + // #[allow(unused_must_use)] + // if let Ok(Some(value)) = wtx.get(&self.partition, key.as_bytes()) { + // dbg!( + // &key, + // V::try_from(value.as_bytes().into()).unwrap(), + // &self.meta, + // self.rtx.get(&self.partition, key.as_bytes()) + // ); + // unreachable!(); + // } + // } + wtx.insert(partition, ByteView::from(key), ByteView::from(value)) + }); + + wtx.commit()?; + + self.rtx = self.keyspace.read_tx(); + + Ok(()) + } + + fn rotate_memtable(&self) { + let _ = self.partition.as_ref().unwrap().inner().rotate_memtable(); + } + + fn height(&self) -> Option { + self.meta.height() + } + + fn len(&self) -> usize { + let len = self.meta.len() + self.puts.len() - self.dels.len(); + if len > 18440000000000000000 { + dbg!(( + len, + self.meta.path(), + self.meta.len(), + self.puts.len(), + &self.dels, + )); + unreachable!() + } + len + } + + fn has(&self, height: Height) -> bool { + self.meta.has(height) + } + fn needs(&self, height: Height) -> bool { + self.meta.needs(height) + } +} + impl Clone for Store where Key: Clone, diff --git a/crates/brk_store/src/trait.rs b/crates/brk_store/src/trait.rs new file mode 100644 index 000000000..2bd0b1268 --- /dev/null +++ b/crates/brk_store/src/trait.rs @@ -0,0 +1,19 @@ +use brk_core::{Height, Result}; + +pub trait AnyStore { + fn commit(&mut self, height: Height) -> Result<()>; + + fn rotate_memtable(&self); + + fn height(&self) -> Option; + + fn len(&self) -> usize; + + fn is_empty(&self) -> bool { + self.len() == 0 + } + + fn has(&self, height: Height) -> bool; + + fn needs(&self, height: Height) -> bool; +}