//! Value type with height-level data only (no period-derived views). //! //! Stores sats and cents per index, plus lazy btc and usd transforms. //! Use when period views are unnecessary (e.g., rolling windows provide windowed data). use brk_error::Result; use brk_traversable::Traversable; use brk_types::{Bitcoin, Cents, Dollars, Height, Sats, Version}; use vecdb::{ Database, EagerVec, Exit, ImportableVec, LazyVecFrom1, PcoVec, ReadableCloneableVec, Rw, StorageMode, VecIndex, }; use crate::{internal::{CentsUnsignedToDollars, SatsToBitcoin, SatsToCents}, prices}; const VERSION: Version = Version::TWO; // Match ValueFromHeight versioning #[derive(Traversable)] pub struct Value { pub sats: M::Stored>>, pub btc: LazyVecFrom1, pub cents: M::Stored>>, pub usd: LazyVecFrom1, } impl Value { pub(crate) fn forced_import( db: &Database, name: &str, version: Version, ) -> Result { let v = version + VERSION; let sats: EagerVec> = EagerVec::forced_import(db, name, v)?; let btc = LazyVecFrom1::transformed::( &format!("{name}_btc"), v, sats.read_only_boxed_clone(), ); let cents: EagerVec> = EagerVec::forced_import(db, &format!("{name}_cents"), v)?; let usd = LazyVecFrom1::transformed::( &format!("{name}_usd"), v, cents.read_only_boxed_clone(), ); Ok(Self { sats, btc, cents, usd }) } /// Eagerly compute cents height values: sats[h] * price_cents[h] / 1e8. pub(crate) fn compute_cents( &mut self, prices: &prices::Vecs, max_from: Height, exit: &Exit, ) -> Result<()> { self.cents.compute_binary::( max_from, &self.sats, &prices.price.cents.height, exit, )?; Ok(()) } }