global: snapshot

This commit is contained in:
nym21
2026-02-28 23:14:06 +01:00
parent 1750c06369
commit a6664bbb93
64 changed files with 57 additions and 80 deletions

View File

@@ -0,0 +1,120 @@
use brk_error::Result;
use schemars::JsonSchema;
use vecdb::{
Database, Exit, ReadableVec, Ro, Rw, VecIndex, VecValue, Version,
};
use crate::internal::{
AverageVec, ComputedVecValue, DistributionStats, MaxVec, MedianVec, MinVec, Pct10Vec,
Pct25Vec, Pct75Vec, Pct90Vec,
};
/// Distribution stats (average + min + max + percentiles) — concrete vec type alias.
pub type Distribution<I, T, M = Rw> = DistributionStats<
AverageVec<I, T, M>,
MinVec<I, T, M>,
MaxVec<I, T, M>,
Pct10Vec<I, T, M>,
Pct25Vec<I, T, M>,
MedianVec<I, T, M>,
Pct75Vec<I, T, M>,
Pct90Vec<I, T, M>,
>;
impl<I: VecIndex, T: ComputedVecValue + JsonSchema> Distribution<I, T> {
pub(crate) fn forced_import(db: &Database, name: &str, version: Version) -> Result<Self> {
Ok(Self {
average: AverageVec::forced_import(db, name, version)?,
min: MinVec::forced_import(db, name, version)?,
max: MaxVec::forced_import(db, name, version)?,
pct10: Pct10Vec::forced_import(db, name, version)?,
pct25: Pct25Vec::forced_import(db, name, version)?,
median: MedianVec::forced_import(db, name, version)?,
pct75: Pct75Vec::forced_import(db, name, version)?,
pct90: Pct90Vec::forced_import(db, name, version)?,
})
}
/// Compute distribution stats, skipping first N items from all calculations.
///
/// Use `skip_count: 1` to exclude coinbase transactions from fee/feerate stats.
pub(crate) fn compute_with_skip<A>(
&mut self,
max_from: I,
source: &impl ReadableVec<A, T>,
first_indexes: &impl ReadableVec<I, A>,
count_indexes: &impl ReadableVec<I, brk_types::StoredU64>,
exit: &Exit,
skip_count: usize,
) -> Result<()>
where
A: VecIndex + VecValue + brk_types::CheckedSub<A>,
{
crate::internal::compute_aggregations(
max_from,
source,
first_indexes,
count_indexes,
exit,
skip_count,
None, // first
None, // last
Some(&mut self.min.0),
Some(&mut self.max.0),
Some(&mut self.average.0),
None, // sum
None, // cumulative
Some(&mut self.median.0),
Some(&mut self.pct10.0),
Some(&mut self.pct25.0),
Some(&mut self.pct75.0),
Some(&mut self.pct90.0),
)
}
/// Compute distribution stats from a fixed n-block rolling window.
///
/// For each index `i`, aggregates all source items from blocks `max(0, i - n_blocks + 1)..=i`.
pub(crate) fn compute_from_nblocks<A>(
&mut self,
max_from: I,
source: &impl ReadableVec<A, T>,
first_indexes: &impl ReadableVec<I, A>,
count_indexes: &impl ReadableVec<I, brk_types::StoredU64>,
n_blocks: usize,
exit: &Exit,
) -> Result<()>
where
A: VecIndex + VecValue + brk_types::CheckedSub<A>,
{
crate::internal::compute_aggregations_nblock_window(
max_from,
source,
first_indexes,
count_indexes,
n_blocks,
exit,
&mut self.min.0,
&mut self.max.0,
&mut self.average.0,
&mut self.median.0,
&mut self.pct10.0,
&mut self.pct25.0,
&mut self.pct75.0,
&mut self.pct90.0,
)
}
pub fn read_only_clone(&self) -> Distribution<I, T, Ro> {
DistributionStats {
average: self.average.read_only_clone(),
min: self.min.read_only_clone(),
max: self.max.read_only_clone(),
pct10: self.pct10.read_only_clone(),
pct25: self.pct25.read_only_clone(),
median: self.median.read_only_clone(),
pct75: self.pct75.read_only_clone(),
pct90: self.pct90.read_only_clone(),
}
}
}

View File

@@ -0,0 +1,71 @@
use brk_error::Result;
use brk_traversable::Traversable;
use schemars::JsonSchema;
use vecdb::{Database, Exit, ReadableVec, Ro, Rw, StorageMode, VecIndex, VecValue, Version};
use crate::internal::ComputedVecValue;
use super::{Distribution, SumCumulative};
/// Full stats aggregate: distribution + sum_cumulative
/// Matches the common full_stats() pattern: average + minmax + percentiles + sum + cumulative
#[derive(Traversable)]
pub struct Full<I: VecIndex, T: ComputedVecValue + JsonSchema, M: StorageMode = Rw> {
#[traversable(flatten)]
pub distribution: Distribution<I, T, M>,
#[traversable(flatten)]
pub sum_cumulative: SumCumulative<I, T, M>,
}
impl<I: VecIndex, T: ComputedVecValue + JsonSchema> Full<I, T> {
pub(crate) fn forced_import(db: &Database, name: &str, version: Version) -> Result<Self> {
Ok(Self {
distribution: Distribution::forced_import(db, name, version)?,
sum_cumulative: SumCumulative::forced_import(db, name, version)?,
})
}
/// Compute all stats, skipping first N items from all calculations.
///
/// Use `skip_count: 1` to exclude coinbase transactions from fee/feerate stats.
pub(crate) fn compute_with_skip<A>(
&mut self,
max_from: I,
source: &impl ReadableVec<A, T>,
first_indexes: &impl ReadableVec<I, A>,
count_indexes: &impl ReadableVec<I, brk_types::StoredU64>,
exit: &Exit,
skip_count: usize,
) -> Result<()>
where
A: VecIndex + VecValue + brk_types::CheckedSub<A>,
{
crate::internal::compute_aggregations(
max_from,
source,
first_indexes,
count_indexes,
exit,
skip_count,
None, // first
None, // last
Some(&mut self.distribution.min.0),
Some(&mut self.distribution.max.0),
Some(&mut self.distribution.average.0),
Some(&mut self.sum_cumulative.sum.0),
Some(&mut self.sum_cumulative.cumulative.0),
Some(&mut self.distribution.median.0),
Some(&mut self.distribution.pct10.0),
Some(&mut self.distribution.pct25.0),
Some(&mut self.distribution.pct75.0),
Some(&mut self.distribution.pct90.0),
)
}
pub fn read_only_clone(&self) -> Full<I, T, Ro> {
Full {
distribution: self.distribution.read_only_clone(),
sum_cumulative: self.sum_cumulative.read_only_clone(),
}
}
}

View File

@@ -0,0 +1,7 @@
mod distribution;
mod full;
mod sum_cumulative;
pub use distribution::*;
pub use full::*;
pub use sum_cumulative::*;

View File

@@ -0,0 +1,31 @@
use brk_error::Result;
use brk_traversable::Traversable;
use schemars::JsonSchema;
use vecdb::{Database, Ro, Rw, StorageMode, VecIndex, Version};
use crate::internal::{ComputedVecValue, CumulativeVec, SumVec};
/// Sum + Cumulative (12% of usage)
#[derive(Traversable)]
pub struct SumCumulative<I: VecIndex, T: ComputedVecValue + JsonSchema, M: StorageMode = Rw> {
#[traversable(flatten)]
pub sum: SumVec<I, T, M>,
#[traversable(flatten)]
pub cumulative: CumulativeVec<I, T, M>,
}
impl<I: VecIndex, T: ComputedVecValue + JsonSchema> SumCumulative<I, T> {
pub(crate) fn forced_import(db: &Database, name: &str, version: Version) -> Result<Self> {
Ok(Self {
sum: SumVec::forced_import(db, name, version)?,
cumulative: CumulativeVec::forced_import(db, name, version)?,
})
}
pub fn read_only_clone(&self) -> SumCumulative<I, T, Ro> {
SumCumulative {
sum: self.sum.read_only_clone(),
cumulative: self.cumulative.read_only_clone(),
}
}
}