use brk_error::Result;
use brk_traversable::Traversable;
use brk_types::{Bitcoin, Cents, Dollars, Height, Sats, Version};
use vecdb::{
AnyVec, Database, Exit, ReadableCloneableVec, ReadableVec, Rw, StorageMode, VecIndex, VecValue,
};
use crate::{
indexes,
internal::{
CachedPerBlock, CentsUnsignedToDollars, LazyPerBlock, PerBlock, SatsToBitcoin,
ValuePerBlockCumulative,
},
};
#[derive(Traversable)]
pub struct CachedValuePerBlock<M: StorageMode = Rw> {
pub btc: LazyPerBlock<Bitcoin, Sats>,
pub sats: CachedPerBlock<Sats, M>,
pub usd: LazyPerBlock<Dollars, Cents>,
pub cents: PerBlock<Cents, M>,
}
impl CachedValuePerBlock {
pub(crate) fn forced_import(
db: &Database,
name: &str,
version: Version,
indexes: &indexes::Vecs,
) -> Result<Self> {
let sats = CachedPerBlock::forced_import(db, &format!("{name}_sats"), version, indexes)?;
let btc = LazyPerBlock::from_cached_computed::<SatsToBitcoin>(
name,
version,
sats.height.read_only_boxed_clone(),
&sats,
);
let cents = PerBlock::forced_import(db, &format!("{name}_cents"), version, indexes)?;
let usd = LazyPerBlock::from_computed::<CentsUnsignedToDollars>(
&format!("{name}_usd"),
version,
cents.height.read_only_boxed_clone(),
¢s,
);
Ok(Self {
btc,
sats,
usd,
cents,
})
}
#[allow(clippy::too_many_arguments)]
pub(crate) fn compute_sats_from_indexes<A, B>(
&mut self,
max_from: Height,
first_indexes: &impl ReadableVec<Height, A>,
indexes_count: &impl ReadableVec<Height, B>,
source: &impl ReadableVec<A, Sats>,
exit: &Exit,
) -> Result<()>
where
A: VecIndex + VecValue,
B: VecValue,
usize: From<B>,
{
if max_from.to_usize() < self.sats.height.len() {
self.sats.height.clear();
}
ValuePerBlockCumulative::compute_sats_height_from_indexes(
&mut self.sats.height.inner,
max_from,
first_indexes,
indexes_count,
source,
|_| true,
exit,
)
}
}