global: snapshot

This commit is contained in:
nym21
2026-03-07 11:42:11 +01:00
parent 5a73f1a88e
commit bf07570848
31 changed files with 1151 additions and 1009 deletions
@@ -3,9 +3,11 @@ mod cumulative;
mod cumulative_sum;
mod distribution;
mod full;
mod rolling_average;
pub use aggregated::*;
pub use cumulative::*;
pub use cumulative_sum::*;
pub use distribution::*;
pub use full::*;
pub use rolling_average::*;
@@ -0,0 +1,78 @@
//! ComputedFromHeight with rolling average (no distribution stats).
//!
//! Stored height data + 4-window rolling averages (24h, 1w, 1m, 1y).
//! Use instead of ComputedFromHeightDistribution when only the average
//! is analytically useful (e.g., block interval, activity counts).
use brk_error::Result;
use brk_traversable::Traversable;
use brk_types::{Height, Version};
use schemars::JsonSchema;
use vecdb::{Database, EagerVec, Exit, ImportableVec, PcoVec, Rw, StorageMode};
use crate::indexes;
use crate::internal::{NumericValue, RollingWindows, WindowStarts};
#[derive(Traversable)]
pub struct ComputedFromHeightRollingAverage<T, M: StorageMode = Rw>
where
T: NumericValue + JsonSchema,
{
pub height: M::Stored<EagerVec<PcoVec<Height, T>>>,
#[traversable(flatten)]
pub average: RollingWindows<T, M>,
}
impl<T> ComputedFromHeightRollingAverage<T>
where
T: NumericValue + JsonSchema,
{
pub(crate) fn forced_import(
db: &Database,
name: &str,
version: Version,
indexes: &indexes::Vecs,
) -> Result<Self> {
let height: EagerVec<PcoVec<Height, T>> = EagerVec::forced_import(db, name, version)?;
let average =
RollingWindows::forced_import(db, &format!("{name}_average"), version, indexes)?;
Ok(Self { height, average })
}
/// Compute height data via closure, then rolling averages.
pub(crate) fn compute(
&mut self,
max_from: Height,
windows: &WindowStarts<'_>,
exit: &Exit,
compute_height: impl FnOnce(&mut EagerVec<PcoVec<Height, T>>) -> Result<()>,
) -> Result<()>
where
T: Default,
f64: From<T>,
{
compute_height(&mut self.height)?;
self.compute_rest(max_from, windows, exit)
}
/// Compute rolling averages from already-populated height data.
pub(crate) fn compute_rest(
&mut self,
max_from: Height,
windows: &WindowStarts<'_>,
exit: &Exit,
) -> Result<()>
where
T: Default,
f64: From<T>,
{
for (w, starts) in self.average.0.as_mut_array().into_iter().zip(windows.as_array()) {
w.height
.compute_rolling_average(max_from, *starts, &self.height, exit)?;
}
Ok(())
}
}
@@ -1,5 +1,7 @@
mod base;
mod distribution;
mod rolling_average;
pub use base::*;
pub use distribution::*;
pub use rolling_average::*;
@@ -0,0 +1,69 @@
use brk_error::Result;
use brk_traversable::Traversable;
use brk_types::{Height, StoredF32, Version};
use vecdb::{Database, EagerVec, Exit, PcoVec, ReadableCloneableVec, Rw, StorageMode};
use crate::{
indexes,
internal::{BpsType, WindowStarts},
};
use crate::internal::{ComputedFromHeightRollingAverage, LazyFromHeight};
/// Like PercentFromHeight but with rolling average stats on the bps data.
#[derive(Traversable)]
pub struct PercentFromHeightRollingAverage<B: BpsType, M: StorageMode = Rw> {
pub bps: ComputedFromHeightRollingAverage<B, M>,
pub ratio: LazyFromHeight<StoredF32, B>,
pub percent: LazyFromHeight<StoredF32, B>,
}
impl<B: BpsType> PercentFromHeightRollingAverage<B> {
pub(crate) fn forced_import(
db: &Database,
name: &str,
version: Version,
indexes: &indexes::Vecs,
) -> Result<Self> {
let bps = ComputedFromHeightRollingAverage::forced_import(
db,
&format!("{name}_bps"),
version,
indexes,
)?;
let ratio = LazyFromHeight::from_height_source::<B::ToRatio>(
&format!("{name}_ratio"),
version,
bps.height.read_only_boxed_clone(),
indexes,
);
let percent = LazyFromHeight::from_height_source::<B::ToPercent>(
name,
version,
bps.height.read_only_boxed_clone(),
indexes,
);
Ok(Self {
bps,
ratio,
percent,
})
}
pub(crate) fn compute(
&mut self,
max_from: Height,
windows: &WindowStarts<'_>,
exit: &Exit,
compute_height: impl FnOnce(&mut EagerVec<PcoVec<Height, B>>) -> Result<()>,
) -> Result<()>
where
B: Default,
f64: From<B>,
{
self.bps.compute(max_from, windows, exit, compute_height)
}
}
@@ -1,7 +1,7 @@
use brk_error::Result;
use brk_traversable::Traversable;
use brk_types::{Cents, Height, Sats, Version};
use vecdb::{Database, Exit, Rw, StorageMode};
use vecdb::{Database, EagerVec, Exit, PcoVec, Rw, StorageMode};
use crate::{
indexes,
@@ -32,6 +32,17 @@ impl ValueFromHeightCumulative {
})
}
pub(crate) fn compute_with(
&mut self,
max_from: Height,
prices: &prices::Vecs,
exit: &Exit,
compute_sats: impl FnOnce(&mut EagerVec<PcoVec<Height, Sats>>) -> Result<()>,
) -> Result<()> {
compute_sats(&mut self.base.sats.height)?;
self.compute(prices, max_from, exit)
}
pub(crate) fn compute(
&mut self,
prices: &prices::Vecs,
@@ -23,7 +23,7 @@ pub use derived::{
RatioCents64, TimesSqrt,
};
pub use ratio::{
NegRatioDollarsBps32, RatioCentsBp32, RatioCentsSignedCentsBps32,
RatioCentsBp32, RatioCentsSignedCentsBps32,
RatioCentsSignedDollarsBps32, RatioDiffCentsBps32, RatioDiffDollarsBps32, RatioDiffF32Bps32,
RatioDollarsBp16, RatioDollarsBp32, RatioDollarsBps32, RatioSatsBp16, RatioU32Bp16,
RatioU64Bp16,
@@ -84,20 +84,6 @@ impl BinaryTransform<Dollars, Dollars, BasisPointsSigned32> for RatioDollarsBps3
}
}
pub struct NegRatioDollarsBps32;
impl BinaryTransform<Dollars, Dollars, BasisPointsSigned32> for NegRatioDollarsBps32 {
#[inline(always)]
fn apply(numerator: Dollars, denominator: Dollars) -> BasisPointsSigned32 {
let ratio = *(numerator / denominator);
if ratio.is_finite() {
BasisPointsSigned32::from(-ratio)
} else {
BasisPointsSigned32::ZERO
}
}
}
pub struct RatioCentsSignedCentsBps32;
impl BinaryTransform<CentsSigned, Cents, BasisPointsSigned32> for RatioCentsSignedCentsBps32 {