mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-04-24 06:39:58 -07:00
global: snapshot
This commit is contained in:
@@ -1085,40 +1085,6 @@ pub struct CapGrossInvestorLossMvrvNetPeakPriceProfitSellSoprPattern {
|
||||
pub sopr: AdjustedRatioValuePattern,
|
||||
}
|
||||
|
||||
/// Pattern struct for repeated tree structure.
|
||||
pub struct AverageCumulativeMaxMedianMinPct10Pct25Pct75Pct90RollingSumPattern {
|
||||
pub average: SeriesPattern1<StoredU64>,
|
||||
pub cumulative: SeriesPattern1<StoredU64>,
|
||||
pub max: SeriesPattern1<StoredU64>,
|
||||
pub median: SeriesPattern1<StoredU64>,
|
||||
pub min: SeriesPattern1<StoredU64>,
|
||||
pub pct10: SeriesPattern1<StoredU64>,
|
||||
pub pct25: SeriesPattern1<StoredU64>,
|
||||
pub pct75: SeriesPattern1<StoredU64>,
|
||||
pub pct90: SeriesPattern1<StoredU64>,
|
||||
pub rolling: AverageMaxMedianMinPct10Pct25Pct75Pct90SumPattern,
|
||||
pub sum: SeriesPattern1<StoredU64>,
|
||||
}
|
||||
|
||||
impl AverageCumulativeMaxMedianMinPct10Pct25Pct75Pct90RollingSumPattern {
|
||||
/// Create a new pattern node with accumulated series name.
|
||||
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
|
||||
Self {
|
||||
average: SeriesPattern1::new(client.clone(), _m(&acc, "average")),
|
||||
cumulative: SeriesPattern1::new(client.clone(), _m(&acc, "cumulative")),
|
||||
max: SeriesPattern1::new(client.clone(), _m(&acc, "max")),
|
||||
median: SeriesPattern1::new(client.clone(), _m(&acc, "median")),
|
||||
min: SeriesPattern1::new(client.clone(), _m(&acc, "min")),
|
||||
pct10: SeriesPattern1::new(client.clone(), _m(&acc, "pct10")),
|
||||
pct25: SeriesPattern1::new(client.clone(), _m(&acc, "pct25")),
|
||||
pct75: SeriesPattern1::new(client.clone(), _m(&acc, "pct75")),
|
||||
pct90: SeriesPattern1::new(client.clone(), _m(&acc, "pct90")),
|
||||
rolling: AverageMaxMedianMinPct10Pct25Pct75Pct90SumPattern::new(client.clone(), acc.clone()),
|
||||
sum: SeriesPattern1::new(client.clone(), _m(&acc, "sum")),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Pattern struct for repeated tree structure.
|
||||
pub struct AverageBaseCumulativeMaxMedianMinPct10Pct25Pct75Pct90SumPattern2 {
|
||||
pub average: _1m1w1y24hPattern<StoredU64>,
|
||||
@@ -2498,6 +2464,24 @@ impl CentsSatsUsdPattern {
|
||||
}
|
||||
}
|
||||
|
||||
/// Pattern struct for repeated tree structure.
|
||||
pub struct CumulativeRollingSumPattern {
|
||||
pub cumulative: SeriesPattern1<StoredU64>,
|
||||
pub rolling: AverageMaxMedianMinPct10Pct25Pct75Pct90SumPattern,
|
||||
pub sum: SeriesPattern1<StoredU64>,
|
||||
}
|
||||
|
||||
impl CumulativeRollingSumPattern {
|
||||
/// Create a new pattern node with accumulated series name.
|
||||
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
|
||||
Self {
|
||||
cumulative: SeriesPattern1::new(client.clone(), _m(&acc, "cumulative")),
|
||||
rolling: AverageMaxMedianMinPct10Pct25Pct75Pct90SumPattern::new(client.clone(), acc.clone()),
|
||||
sum: SeriesPattern1::new(client.clone(), _m(&acc, "sum")),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Pattern struct for repeated tree structure.
|
||||
pub struct DeltaHalfTotalPattern {
|
||||
pub delta: AbsoluteRatePattern,
|
||||
@@ -3418,7 +3402,7 @@ impl SeriesTree_Transactions_Volume {
|
||||
pub struct SeriesTree_Inputs {
|
||||
pub raw: SeriesTree_Inputs_Raw,
|
||||
pub spent: SeriesTree_Inputs_Spent,
|
||||
pub count: AverageCumulativeMaxMedianMinPct10Pct25Pct75Pct90RollingSumPattern,
|
||||
pub count: CumulativeRollingSumPattern,
|
||||
}
|
||||
|
||||
impl SeriesTree_Inputs {
|
||||
@@ -3426,7 +3410,7 @@ impl SeriesTree_Inputs {
|
||||
Self {
|
||||
raw: SeriesTree_Inputs_Raw::new(client.clone(), format!("{base_path}_raw")),
|
||||
spent: SeriesTree_Inputs_Spent::new(client.clone(), format!("{base_path}_spent")),
|
||||
count: AverageCumulativeMaxMedianMinPct10Pct25Pct75Pct90RollingSumPattern::new(client.clone(), "input_count".to_string()),
|
||||
count: CumulativeRollingSumPattern::new(client.clone(), "input_count".to_string()),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3520,14 +3504,14 @@ impl SeriesTree_Outputs_Spent {
|
||||
|
||||
/// Series tree node.
|
||||
pub struct SeriesTree_Outputs_Count {
|
||||
pub total: AverageCumulativeMaxMedianMinPct10Pct25Pct75Pct90RollingSumPattern,
|
||||
pub total: CumulativeRollingSumPattern,
|
||||
pub unspent: SeriesPattern1<StoredU64>,
|
||||
}
|
||||
|
||||
impl SeriesTree_Outputs_Count {
|
||||
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
|
||||
Self {
|
||||
total: AverageCumulativeMaxMedianMinPct10Pct25Pct75Pct90RollingSumPattern::new(client.clone(), "output_count".to_string()),
|
||||
total: CumulativeRollingSumPattern::new(client.clone(), "output_count".to_string()),
|
||||
unspent: SeriesPattern1::new(client.clone(), "utxo_count_bis".to_string()),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,8 +67,8 @@ pub(crate) fn process_blocks(
|
||||
let height_to_first_txout_index = &indexer.vecs.outputs.first_txout_index;
|
||||
let height_to_first_txin_index = &indexer.vecs.inputs.first_txin_index;
|
||||
let height_to_tx_count = &transactions.count.total.base.height;
|
||||
let height_to_output_count = &outputs.count.total.full.sum.height;
|
||||
let height_to_input_count = &inputs.count.full.sum.height;
|
||||
let height_to_output_count = &outputs.count.total.sum.height;
|
||||
let height_to_input_count = &inputs.count.sum.height;
|
||||
let tx_index_to_output_count = &indexes.tx_index.output_count;
|
||||
let tx_index_to_input_count = &indexes.tx_index.input_count;
|
||||
|
||||
|
||||
@@ -16,17 +16,15 @@ impl Vecs {
|
||||
exit: &Exit,
|
||||
) -> Result<()> {
|
||||
let window_starts = blocks.lookback.window_starts();
|
||||
self.0
|
||||
.compute(starting_indexes.height, &window_starts, exit, |full| {
|
||||
full.compute_with_skip(
|
||||
starting_indexes.height,
|
||||
&indexes.tx_index.input_count,
|
||||
&indexer.vecs.transactions.first_tx_index,
|
||||
&indexes.height.tx_index_count,
|
||||
exit,
|
||||
0,
|
||||
)
|
||||
})?;
|
||||
self.0.compute(
|
||||
starting_indexes.height,
|
||||
&indexes.tx_index.input_count,
|
||||
&indexer.vecs.transactions.first_tx_index,
|
||||
&indexes.height.tx_index_count,
|
||||
&window_starts,
|
||||
exit,
|
||||
0,
|
||||
)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -1,17 +1,15 @@
|
||||
//! PerBlockAggregated - PerBlockDistributionFull (distribution + sum + cumulative) + RollingComplete.
|
||||
//!
|
||||
//! For metrics aggregated per-block from finer-grained sources (e.g., per-tx data),
|
||||
//! where we want full per-block stats plus rolling window stats.
|
||||
|
||||
use brk_error::Result;
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::{Height, Version};
|
||||
use brk_types::Height;
|
||||
use schemars::JsonSchema;
|
||||
use vecdb::{Database, Exit, Rw, StorageMode};
|
||||
use vecdb::{Database, Exit, ReadableVec, Rw, StorageMode, VecIndex, VecValue, Version};
|
||||
|
||||
use crate::{
|
||||
indexes,
|
||||
internal::{CachedWindowStarts, PerBlockDistributionFull, NumericValue, RollingComplete, WindowStarts},
|
||||
internal::{
|
||||
CachedWindowStarts, NumericValue, PerBlock, RollingComplete, WindowStarts,
|
||||
algo::compute_aggregations,
|
||||
},
|
||||
};
|
||||
|
||||
#[derive(Traversable)]
|
||||
@@ -19,8 +17,8 @@ pub struct PerBlockAggregated<T, M: StorageMode = Rw>
|
||||
where
|
||||
T: NumericValue + JsonSchema,
|
||||
{
|
||||
#[traversable(flatten)]
|
||||
pub full: PerBlockDistributionFull<T, M>,
|
||||
pub sum: PerBlock<T, M>,
|
||||
pub cumulative: PerBlock<T, M>,
|
||||
pub rolling: RollingComplete<T, M>,
|
||||
}
|
||||
|
||||
@@ -35,34 +33,63 @@ where
|
||||
indexes: &indexes::Vecs,
|
||||
cached_starts: &CachedWindowStarts,
|
||||
) -> Result<Self> {
|
||||
let full = PerBlockDistributionFull::forced_import(db, name, version, indexes)?;
|
||||
let sum = PerBlock::forced_import(db, &format!("{name}_sum"), version, indexes)?;
|
||||
let cumulative =
|
||||
PerBlock::forced_import(db, &format!("{name}_cumulative"), version, indexes)?;
|
||||
let rolling = RollingComplete::forced_import(
|
||||
db,
|
||||
name,
|
||||
version,
|
||||
indexes,
|
||||
&full.cumulative.height,
|
||||
&cumulative.height,
|
||||
cached_starts,
|
||||
)?;
|
||||
|
||||
Ok(Self { full, rolling })
|
||||
Ok(Self {
|
||||
sum,
|
||||
cumulative,
|
||||
rolling,
|
||||
})
|
||||
}
|
||||
|
||||
/// Compute PerBlockDistributionFull stats via closure, then rolling distribution from the per-block sum.
|
||||
pub(crate) fn compute(
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub(crate) fn compute<A>(
|
||||
&mut self,
|
||||
max_from: Height,
|
||||
source: &impl ReadableVec<A, T>,
|
||||
first_indexes: &impl ReadableVec<Height, A>,
|
||||
count_indexes: &impl ReadableVec<Height, brk_types::StoredU64>,
|
||||
windows: &WindowStarts<'_>,
|
||||
exit: &Exit,
|
||||
compute_full: impl FnOnce(&mut PerBlockDistributionFull<T>) -> Result<()>,
|
||||
skip_count: usize,
|
||||
) -> Result<()>
|
||||
where
|
||||
T: From<f64> + Default + Copy + Ord,
|
||||
f64: From<T>,
|
||||
A: VecIndex + VecValue + brk_types::CheckedSub<A>,
|
||||
{
|
||||
compute_full(&mut self.full)?;
|
||||
compute_aggregations(
|
||||
max_from,
|
||||
source,
|
||||
first_indexes,
|
||||
count_indexes,
|
||||
exit,
|
||||
skip_count,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
Some(&mut self.sum.height),
|
||||
Some(&mut self.cumulative.height),
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
)?;
|
||||
self.rolling
|
||||
.compute(max_from, windows, &self.full.sum.height, exit)?;
|
||||
.compute(max_from, windows, &self.sum.height, exit)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,73 +0,0 @@
|
||||
use brk_error::Result;
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::Height;
|
||||
use schemars::JsonSchema;
|
||||
use vecdb::{
|
||||
Database, Exit, ReadableVec, Rw, StorageMode,
|
||||
VecIndex, VecValue, Version,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
indexes,
|
||||
internal::{ComputedVecValue, NumericValue, PerBlock, algo::compute_aggregations},
|
||||
};
|
||||
|
||||
use super::PerBlockDistribution;
|
||||
|
||||
#[derive(Traversable)]
|
||||
pub struct PerBlockDistributionFull<T: ComputedVecValue + PartialOrd + JsonSchema, M: StorageMode = Rw> {
|
||||
pub sum: PerBlock<T, M>,
|
||||
pub cumulative: PerBlock<T, M>,
|
||||
#[traversable(flatten)]
|
||||
pub distribution: PerBlockDistribution<T, M>,
|
||||
}
|
||||
|
||||
impl<T: NumericValue + JsonSchema> PerBlockDistributionFull<T> {
|
||||
pub(crate) fn forced_import(
|
||||
db: &Database,
|
||||
name: &str,
|
||||
version: Version,
|
||||
indexes: &indexes::Vecs,
|
||||
) -> Result<Self> {
|
||||
Ok(Self {
|
||||
distribution: PerBlockDistribution::forced_import(db, name, version, indexes)?,
|
||||
sum: PerBlock::forced_import(db, &format!("{name}_sum"), version, indexes)?,
|
||||
cumulative: PerBlock::forced_import(db, &format!("{name}_cumulative"), version, indexes)?,
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn compute_with_skip<A>(
|
||||
&mut self,
|
||||
max_from: Height,
|
||||
source: &impl ReadableVec<A, T>,
|
||||
first_indexes: &impl ReadableVec<Height, A>,
|
||||
count_indexes: &impl ReadableVec<Height, brk_types::StoredU64>,
|
||||
exit: &Exit,
|
||||
skip_count: usize,
|
||||
) -> Result<()>
|
||||
where
|
||||
A: VecIndex + VecValue + brk_types::CheckedSub<A>,
|
||||
{
|
||||
let d = &mut self.distribution.0;
|
||||
compute_aggregations(
|
||||
max_from,
|
||||
source,
|
||||
first_indexes,
|
||||
count_indexes,
|
||||
exit,
|
||||
skip_count,
|
||||
None,
|
||||
None,
|
||||
Some(&mut d.min.height),
|
||||
Some(&mut d.max.height),
|
||||
Some(&mut d.average.height),
|
||||
Some(&mut self.sum.height),
|
||||
Some(&mut self.cumulative.height),
|
||||
Some(&mut d.median.height),
|
||||
Some(&mut d.pct10.height),
|
||||
Some(&mut d.pct25.height),
|
||||
Some(&mut d.pct75.height),
|
||||
Some(&mut d.pct90.height),
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,6 @@ mod base;
|
||||
mod cumulative;
|
||||
mod cumulative_sum;
|
||||
mod distribution;
|
||||
mod distribution_full;
|
||||
mod full;
|
||||
mod lazy_distribution;
|
||||
mod lazy_rolling;
|
||||
@@ -17,7 +16,6 @@ pub use base::*;
|
||||
pub use cumulative::*;
|
||||
pub use cumulative_sum::*;
|
||||
pub use distribution::*;
|
||||
pub use distribution_full::*;
|
||||
pub use full::*;
|
||||
pub use lazy_distribution::*;
|
||||
pub use lazy_rolling::*;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::{Dollars, Height, StoredF32, Version};
|
||||
use derive_more::{Deref, DerefMut};
|
||||
use schemars::JsonSchema;
|
||||
use vecdb::{DeltaChange, DeltaRate, LazyDeltaVec, LazyVecFrom1, ReadableCloneableVec, VecValue};
|
||||
|
||||
@@ -7,7 +8,7 @@ use crate::{
|
||||
indexes,
|
||||
internal::{
|
||||
BpsType, CachedWindowStarts, CentsType, DerivedResolutions, LazyPerBlock, NumericValue,
|
||||
Resolutions, Windows,
|
||||
Percent, Resolutions, Windows,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -31,16 +32,14 @@ where
|
||||
/// Single-slot lazy delta percent: BPS delta + lazy ratio + lazy percent views.
|
||||
///
|
||||
/// Mirrors `PercentPerBlock<B>` but with lazy delta for the BPS source.
|
||||
#[derive(Clone, Traversable)]
|
||||
pub struct LazyDeltaPercentFromHeight<S, B>
|
||||
#[derive(Clone, Deref, DerefMut, Traversable)]
|
||||
#[traversable(transparent)]
|
||||
pub struct LazyDeltaPercentFromHeight<S, B>(
|
||||
pub Percent<LazyDeltaFromHeight<S, B, DeltaRate>, LazyPerBlock<StoredF32, B>>,
|
||||
)
|
||||
where
|
||||
S: VecValue,
|
||||
B: BpsType,
|
||||
{
|
||||
pub bps: LazyDeltaFromHeight<S, B, DeltaRate>,
|
||||
pub ratio: LazyPerBlock<StoredF32, B>,
|
||||
pub percent: LazyPerBlock<StoredF32, B>,
|
||||
}
|
||||
B: BpsType;
|
||||
|
||||
/// Lazy rolling deltas for all 4 window durations (24h, 1w, 1m, 1y).
|
||||
///
|
||||
@@ -151,11 +150,11 @@ where
|
||||
)),
|
||||
};
|
||||
|
||||
let rate = LazyDeltaPercentFromHeight {
|
||||
let rate = LazyDeltaPercentFromHeight(Percent {
|
||||
bps,
|
||||
ratio,
|
||||
percent,
|
||||
};
|
||||
});
|
||||
|
||||
(absolute, rate)
|
||||
};
|
||||
@@ -304,11 +303,11 @@ where
|
||||
)),
|
||||
};
|
||||
|
||||
let rate = LazyDeltaPercentFromHeight {
|
||||
let rate = LazyDeltaPercentFromHeight(Percent {
|
||||
bps,
|
||||
ratio,
|
||||
percent,
|
||||
};
|
||||
});
|
||||
|
||||
(absolute, rate)
|
||||
};
|
||||
|
||||
@@ -19,22 +19,20 @@ impl Vecs {
|
||||
exit: &Exit,
|
||||
) -> Result<()> {
|
||||
let window_starts = blocks.lookback.window_starts();
|
||||
self.total
|
||||
.compute(starting_indexes.height, &window_starts, exit, |full| {
|
||||
full.compute_with_skip(
|
||||
starting_indexes.height,
|
||||
&indexes.tx_index.output_count,
|
||||
&indexer.vecs.transactions.first_tx_index,
|
||||
&indexes.height.tx_index_count,
|
||||
exit,
|
||||
0,
|
||||
)
|
||||
})?;
|
||||
self.total.compute(
|
||||
starting_indexes.height,
|
||||
&indexes.tx_index.output_count,
|
||||
&indexer.vecs.transactions.first_tx_index,
|
||||
&indexes.height.tx_index_count,
|
||||
&window_starts,
|
||||
exit,
|
||||
0,
|
||||
)?;
|
||||
|
||||
self.unspent.height.compute_transform3(
|
||||
starting_indexes.height,
|
||||
&self.total.full.cumulative.height,
|
||||
&inputs_count.full.cumulative.height,
|
||||
&self.total.cumulative.height,
|
||||
&inputs_count.cumulative.height,
|
||||
&scripts_count.op_return.cumulative.height,
|
||||
|(h, output_count, input_count, op_return_count, ..)| {
|
||||
let block_count = u64::from(h + 1_usize);
|
||||
|
||||
@@ -39,14 +39,14 @@ impl Vecs {
|
||||
self.taproot.compute_binary::<_, _, RatioU64Bp16>(
|
||||
starting_indexes.height,
|
||||
&count.p2tr.base.height,
|
||||
&outputs_count.total.full.sum.height,
|
||||
&outputs_count.total.sum.height,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.segwit.compute_binary::<_, _, RatioU64Bp16>(
|
||||
starting_indexes.height,
|
||||
&count.segwit.base.height,
|
||||
&outputs_count.total.full.sum.height,
|
||||
&outputs_count.total.sum.height,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ impl Vecs {
|
||||
.height
|
||||
.compute_binary::<_, Timestamp, PerSec>(
|
||||
starting_indexes.height,
|
||||
&inputs_count.full.sum.height,
|
||||
&inputs_count.sum.height,
|
||||
&blocks.interval.base,
|
||||
exit,
|
||||
)?;
|
||||
@@ -58,7 +58,7 @@ impl Vecs {
|
||||
.height
|
||||
.compute_binary::<_, Timestamp, PerSec>(
|
||||
starting_indexes.height,
|
||||
&outputs_count.total.full.sum.height,
|
||||
&outputs_count.total.sum.height,
|
||||
&blocks.interval.base,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
Reference in New Issue
Block a user