use brk_traversable::Traversable;
use brk_types::{Bitcoin, Cents, Dollars, Height, Sats, Version};
use derive_more::{Deref, DerefMut};
use vecdb::{DeltaSub, LazyDeltaVec, LazyVecFrom1, ReadableCloneableVec};
use crate::{
indexes,
internal::{
CachedWindowStarts, CentsUnsignedToDollars, DerivedResolutions, LazyPerBlock,
LazyRollingSumFromHeight, Resolutions, SatsToBitcoin, Windows,
},
};
#[derive(Clone, Traversable)]
pub struct LazyRollingSumAmountFromHeight {
pub btc: LazyPerBlock<Bitcoin, Sats>,
pub sats: LazyRollingSumFromHeight<Sats>,
pub usd: LazyPerBlock<Dollars, Cents>,
pub cents: LazyRollingSumFromHeight<Cents>,
}
#[derive(Clone, Deref, DerefMut, Traversable)]
#[traversable(transparent)]
pub struct LazyRollingSumsAmountFromHeight(pub Windows<LazyRollingSumAmountFromHeight>);
impl LazyRollingSumsAmountFromHeight {
pub fn new(
name: &str,
version: Version,
cumulative_sats: &(impl ReadableCloneableVec<Height, Sats> + 'static),
cumulative_cents: &(impl ReadableCloneableVec<Height, Cents> + 'static),
cached_starts: &CachedWindowStarts,
indexes: &indexes::Vecs,
) -> Self {
let cum_sats = cumulative_sats.read_only_boxed_clone();
let cum_cents = cumulative_cents.read_only_boxed_clone();
let make_slot = |suffix: &str, cached_start: &vecdb::CachedVec<Height, Height>| {
let full_name = format!("{name}_{suffix}");
let cached = cached_start.clone();
let starts_version = cached.version();
let sats_sum = LazyDeltaVec::<Height, Sats, Sats, DeltaSub>::new(
&format!("{full_name}_sats"),
version,
cum_sats.clone(),
starts_version,
{
let cached = cached.clone();
move || cached.get()
},
);
let sats_resolutions = Resolutions::forced_import(
&format!("{full_name}_sats"),
sats_sum.read_only_boxed_clone(),
version,
indexes,
);
let sats = LazyRollingSumFromHeight {
height: sats_sum,
resolutions: Box::new(sats_resolutions),
};
let btc = LazyPerBlock {
height: LazyVecFrom1::transformed::<SatsToBitcoin>(
&full_name,
version,
sats.height.read_only_boxed_clone(),
),
resolutions: Box::new(DerivedResolutions::from_derived_computed::<SatsToBitcoin>(
&full_name,
version,
&sats.resolutions,
)),
};
let cents_sum = LazyDeltaVec::<Height, Cents, Cents, DeltaSub>::new(
&format!("{full_name}_cents"),
version,
cum_cents.clone(),
starts_version,
move || cached.get(),
);
let cents_resolutions = Resolutions::forced_import(
&format!("{full_name}_cents"),
cents_sum.read_only_boxed_clone(),
version,
indexes,
);
let cents = LazyRollingSumFromHeight {
height: cents_sum,
resolutions: Box::new(cents_resolutions),
};
let usd = LazyPerBlock {
height: LazyVecFrom1::transformed::<CentsUnsignedToDollars>(
&format!("{full_name}_usd"),
version,
cents.height.read_only_boxed_clone(),
),
resolutions: Box::new(DerivedResolutions::from_derived_computed::<
CentsUnsignedToDollars,
>(
&format!("{full_name}_usd"), version, ¢s.resolutions
)),
};
LazyRollingSumAmountFromHeight {
btc,
sats,
usd,
cents,
}
};
Self(cached_starts.0.map_with_suffix(make_slot))
}
}