computer: indexes + rolling

This commit is contained in:
nym21
2026-02-24 17:07:35 +01:00
parent cefc8cfd42
commit f74115c6e2
160 changed files with 2604 additions and 4739 deletions

View File

@@ -1,163 +0,0 @@
//! TxDerivedFull - aggregates from TxIndex to height Full + lazy time periods + epochs.
use brk_error::Result;
use brk_indexer::Indexer;
use brk_traversable::Traversable;
use brk_types::{
Day1, Day3, DifficultyEpoch, HalvingEpoch, Height, Hour1, Hour12, Hour4, Minute1, Minute10,
Minute30, Minute5, Month1, Month3, Month6, TxIndex, Version, Week1, Year1, Year10,
};
use schemars::JsonSchema;
use vecdb::{Database, Exit, ReadableCloneableVec, ReadableVec, Rw, StorageMode};
use crate::{
indexes, ComputeIndexes,
internal::{ComputedVecValue, Full, LazyFull, NumericValue},
};
/// Aggregates from TxIndex to height/time periods with full stats.
#[derive(Traversable)]
#[traversable(merge)]
pub struct TxDerivedFull<T, M: StorageMode = Rw>
where
T: ComputedVecValue + PartialOrd + JsonSchema,
{
pub height: Full<Height, T, M>,
pub minute1: LazyFull<Minute1, T, Height, Height>,
pub minute5: LazyFull<Minute5, T, Height, Height>,
pub minute10: LazyFull<Minute10, T, Height, Height>,
pub minute30: LazyFull<Minute30, T, Height, Height>,
pub hour1: LazyFull<Hour1, T, Height, Height>,
pub hour4: LazyFull<Hour4, T, Height, Height>,
pub hour12: LazyFull<Hour12, T, Height, Height>,
pub day1: LazyFull<Day1, T, Height, Height>,
pub day3: LazyFull<Day3, T, Height, Height>,
pub week1: LazyFull<Week1, T, Height, Height>,
pub month1: LazyFull<Month1, T, Height, Height>,
pub month3: LazyFull<Month3, T, Height, Height>,
pub month6: LazyFull<Month6, T, Height, Height>,
pub year1: LazyFull<Year1, T, Height, Height>,
pub year10: LazyFull<Year10, T, Height, Height>,
pub halvingepoch: LazyFull<HalvingEpoch, T, Height, HalvingEpoch>,
pub difficultyepoch: LazyFull<DifficultyEpoch, T, Height, DifficultyEpoch>,
}
const VERSION: Version = Version::ONE;
impl<T> TxDerivedFull<T>
where
T: NumericValue + JsonSchema,
{
pub(crate) fn forced_import(
db: &Database,
name: &str,
version: Version,
indexes: &indexes::Vecs,
) -> Result<Self> {
let height = Full::forced_import(db, name, version + VERSION)?;
let v = version + VERSION;
macro_rules! period {
($idx:ident) => {
LazyFull::from_height_source(
name,
v,
height.boxed_sum(),
height.boxed_cumulative(),
indexes.$idx.first_height.read_only_boxed_clone(),
)
};
}
macro_rules! epoch {
($idx:ident) => {
LazyFull::from_stats_aggregate(
name,
v,
height.boxed_average(),
height.boxed_min(),
height.boxed_max(),
height.boxed_sum(),
height.boxed_cumulative(),
height.boxed_average(),
indexes.$idx.identity.read_only_boxed_clone(),
)
};
}
let minute1 = period!(minute1);
let minute5 = period!(minute5);
let minute10 = period!(minute10);
let minute30 = period!(minute30);
let hour1 = period!(hour1);
let hour4 = period!(hour4);
let hour12 = period!(hour12);
let day1 = period!(day1);
let day3 = period!(day3);
let week1 = period!(week1);
let month1 = period!(month1);
let month3 = period!(month3);
let month6 = period!(month6);
let year1 = period!(year1);
let year10 = period!(year10);
let halvingepoch = epoch!(halvingepoch);
let difficultyepoch = epoch!(difficultyepoch);
Ok(Self {
height,
minute1,
minute5,
minute10,
minute30,
hour1,
hour4,
hour12,
day1,
day3,
week1,
month1,
month3,
month6,
year1,
year10,
halvingepoch,
difficultyepoch,
})
}
pub(crate) fn derive_from(
&mut self,
indexer: &Indexer,
indexes: &indexes::Vecs,
starting_indexes: &ComputeIndexes,
txindex_source: &impl ReadableVec<TxIndex, T>,
exit: &Exit,
) -> Result<()> {
self.derive_from_with_skip(indexer, indexes, starting_indexes, txindex_source, exit, 0)
}
/// Derive from source, skipping first N transactions per block from all calculations.
///
/// Use `skip_count: 1` to exclude coinbase transactions from fee/feerate stats.
pub(crate) fn derive_from_with_skip(
&mut self,
indexer: &Indexer,
indexes: &indexes::Vecs,
starting_indexes: &ComputeIndexes,
txindex_source: &impl ReadableVec<TxIndex, T>,
exit: &Exit,
skip_count: usize,
) -> Result<()> {
self.height.compute_with_skip(
starting_indexes.height,
txindex_source,
&indexer.vecs.transactions.first_txindex,
&indexes.height.txindex_count,
exit,
skip_count,
)?;
Ok(())
}
}

View File

@@ -1,94 +0,0 @@
//! Lazy transform of TxDerivedFull.
use brk_traversable::Traversable;
use brk_types::{
Day1, Day3, DifficultyEpoch, HalvingEpoch, Height, Hour1, Hour12, Hour4, Minute1, Minute10,
Minute30, Minute5, Month1, Month3, Month6, Version, Week1, Year1, Year10,
};
use schemars::JsonSchema;
use vecdb::{ReadableCloneableVec, UnaryTransform};
use crate::internal::{ComputedVecValue, TxDerivedFull, LazyTransformFull};
#[derive(Clone, Traversable)]
#[traversable(merge)]
pub struct LazyTxDerivedFull<T, S1T = T>
where
T: ComputedVecValue + PartialOrd + JsonSchema,
S1T: ComputedVecValue,
{
pub height: LazyTransformFull<Height, T, S1T>,
pub minute1: LazyTransformFull<Minute1, T, S1T>,
pub minute5: LazyTransformFull<Minute5, T, S1T>,
pub minute10: LazyTransformFull<Minute10, T, S1T>,
pub minute30: LazyTransformFull<Minute30, T, S1T>,
pub hour1: LazyTransformFull<Hour1, T, S1T>,
pub hour4: LazyTransformFull<Hour4, T, S1T>,
pub hour12: LazyTransformFull<Hour12, T, S1T>,
pub day1: LazyTransformFull<Day1, T, S1T>,
pub day3: LazyTransformFull<Day3, T, S1T>,
pub week1: LazyTransformFull<Week1, T, S1T>,
pub month1: LazyTransformFull<Month1, T, S1T>,
pub month3: LazyTransformFull<Month3, T, S1T>,
pub month6: LazyTransformFull<Month6, T, S1T>,
pub year1: LazyTransformFull<Year1, T, S1T>,
pub year10: LazyTransformFull<Year10, T, S1T>,
pub halvingepoch: LazyTransformFull<HalvingEpoch, T, S1T>,
pub difficultyepoch: LazyTransformFull<DifficultyEpoch, T, S1T>,
}
const VERSION: Version = Version::ZERO;
impl<T, S1T> LazyTxDerivedFull<T, S1T>
where
T: ComputedVecValue + JsonSchema + 'static,
S1T: ComputedVecValue + JsonSchema,
{
pub(crate) fn from_computed<F: UnaryTransform<S1T, T>>(
name: &str,
version: Version,
source: &TxDerivedFull<S1T>,
) -> Self {
let v = version + VERSION;
macro_rules! period {
($p:ident) => {
LazyTransformFull::from_boxed::<F>(
name,
v,
source.$p.average.read_only_boxed_clone(),
source.$p.min.read_only_boxed_clone(),
source.$p.max.read_only_boxed_clone(),
source.$p.percentiles.pct10.read_only_boxed_clone(),
source.$p.percentiles.pct25.read_only_boxed_clone(),
source.$p.percentiles.median.read_only_boxed_clone(),
source.$p.percentiles.pct75.read_only_boxed_clone(),
source.$p.percentiles.pct90.read_only_boxed_clone(),
source.$p.sum.read_only_boxed_clone(),
source.$p.cumulative.read_only_boxed_clone(),
)
};
}
Self {
height: LazyTransformFull::from_stats_aggregate::<F>(name, v, &source.height),
minute1: period!(minute1),
minute5: period!(minute5),
minute10: period!(minute10),
minute30: period!(minute30),
hour1: period!(hour1),
hour4: period!(hour4),
hour12: period!(hour12),
day1: period!(day1),
day3: period!(day3),
week1: period!(week1),
month1: period!(month1),
month3: period!(month3),
month6: period!(month6),
year1: period!(year1),
year10: period!(year10),
halvingepoch: period!(halvingepoch),
difficultyepoch: period!(difficultyepoch),
}
}
}

View File

@@ -1,9 +1,3 @@
mod distribution;
mod full;
mod lazy_full;
mod value_full;
pub use distribution::*;
pub use full::*;
pub use lazy_full::*;
pub use value_full::*;

View File

@@ -1,84 +0,0 @@
//! Value type for Full pattern from TxIndex.
use brk_error::Result;
use brk_indexer::Indexer;
use brk_traversable::Traversable;
use brk_types::{Bitcoin, Sats, TxIndex, Version};
use vecdb::{Database, Exit, ReadableCloneableVec, ReadableVec, Rw, StorageMode};
use crate::{
ComputeIndexes, indexes,
internal::{LazyTxDerivedFull, SatsToBitcoin, TxDerivedFull, ValueDollarsFromTxFull},
prices,
};
#[derive(Traversable)]
pub struct ValueTxDerivedFull<M: StorageMode = Rw> {
pub sats: TxDerivedFull<Sats, M>,
pub btc: LazyTxDerivedFull<Bitcoin, Sats>,
pub usd: ValueDollarsFromTxFull<M>,
}
const VERSION: Version = Version::ZERO;
impl ValueTxDerivedFull {
pub(crate) fn forced_import(
db: &Database,
name: &str,
version: Version,
indexes: &indexes::Vecs,
indexer: &Indexer,
prices: &prices::Vecs,
sats_txindex: &impl ReadableCloneableVec<TxIndex, Sats>,
) -> Result<Self> {
let v = version + VERSION;
let sats = TxDerivedFull::forced_import(db, name, v, indexes)?;
let btc =
LazyTxDerivedFull::from_computed::<SatsToBitcoin>(&format!("{name}_btc"), v, &sats);
let usd = ValueDollarsFromTxFull::forced_import(
db,
&format!("{name}_usd"),
v,
indexes,
&sats.height,
prices.usd.price.read_only_boxed_clone(),
sats_txindex.read_only_boxed_clone(),
indexer.vecs.transactions.height.read_only_boxed_clone(),
)?;
Ok(Self {
sats,
btc,
usd,
})
}
/// Derive from source, skipping first N transactions per block from all calculations.
///
/// Use `skip_count: 1` to exclude coinbase transactions from fee/feerate stats.
pub(crate) fn derive_from_with_skip(
&mut self,
indexer: &Indexer,
indexes: &indexes::Vecs,
starting_indexes: &ComputeIndexes,
txindex_source: &impl ReadableVec<TxIndex, Sats>,
exit: &Exit,
skip_count: usize,
) -> Result<()> {
self.sats.derive_from_with_skip(
indexer,
indexes,
starting_indexes,
txindex_source,
exit,
skip_count,
)?;
self.usd.derive_from(indexes, starting_indexes, exit)?;
Ok(())
}
}