global: snapshot

This commit is contained in:
nym21
2026-03-08 01:30:30 +01:00
parent cf6c755e51
commit 6bb5c63db7
23 changed files with 2024 additions and 198 deletions
@@ -25,7 +25,7 @@ use crate::{
/// Pre-collect source data from the earliest needed offset.
/// Returns (source_data, offset) for use in compute_delta_window.
fn collect_source<S: NumericValue>(
pub(super) fn collect_source<S: NumericValue>(
source: &impl ReadableVec<Height, S>,
skip: usize,
earliest_starts: &impl ReadableVec<Height, Height>,
@@ -40,7 +40,7 @@ fn collect_source<S: NumericValue>(
}
/// Shared computation: change = current - ago, rate = change / ago.
fn compute_delta_window<S, C, B>(
pub(super) fn compute_delta_window<S, C, B>(
change_h: &mut EagerVec<PcoVec<Height, C>>,
rate_bps_h: &mut EagerVec<PcoVec<Height, B>>,
max_from: Height,
@@ -0,0 +1,275 @@
//! Fiat delta variants — same as RollingDelta* but change is FiatFromHeight<C>
//! (stored cents + lazy USD) instead of ComputedFromHeight<C> (stored cents only).
use brk_error::Result;
use brk_traversable::Traversable;
use brk_types::{BasisPointsSigned32, Height, Version};
use schemars::JsonSchema;
use vecdb::{AnyVec, Database, Exit, ReadableVec, Rw, StorageMode};
use crate::{
indexes,
internal::{
CentsType, FiatFromHeight, NumericValue, PercentFromHeight, PercentRollingWindows,
WindowStarts,
},
};
use super::delta::{collect_source, compute_delta_window};
/// Fiat 1m-only delta: fiat change (cents + usd) + rate for the 1-month window.
#[derive(Traversable)]
pub struct FiatRollingDelta1m<S, C, M: StorageMode = Rw>
where
S: NumericValue + JsonSchema,
C: CentsType,
{
pub change_1m: FiatFromHeight<C, M>,
pub rate_1m: PercentFromHeight<BasisPointsSigned32, M>,
_phantom: std::marker::PhantomData<S>,
}
impl<S, C> FiatRollingDelta1m<S, C>
where
S: NumericValue + JsonSchema,
C: CentsType,
{
pub(crate) fn forced_import(
db: &Database,
name: &str,
version: Version,
indexes: &indexes::Vecs,
) -> Result<Self> {
Ok(Self {
change_1m: FiatFromHeight::forced_import(
db,
&format!("{name}_change_1m"),
version,
indexes,
)?,
rate_1m: PercentFromHeight::forced_import(
db,
&format!("{name}_rate_1m"),
version,
indexes,
)?,
_phantom: std::marker::PhantomData,
})
}
pub(crate) fn compute(
&mut self,
max_from: Height,
height_1m_ago: &impl ReadableVec<Height, Height>,
source: &impl ReadableVec<Height, S>,
exit: &Exit,
) -> Result<()> {
let skip = self.change_1m.cents.height.len();
let (source_data, offset) = collect_source(source, skip, height_1m_ago);
compute_delta_window(
&mut self.change_1m.cents.height,
&mut self.rate_1m.bps.height,
max_from,
height_1m_ago,
&source_data,
offset,
exit,
)
}
}
/// Fiat extended delta: 24h + 1w + 1y windows, fiat change (cents + usd) + rate.
#[derive(Traversable)]
pub struct FiatRollingDeltaExcept1m<S, C, M: StorageMode = Rw>
where
S: NumericValue + JsonSchema,
C: CentsType,
{
#[traversable(rename = "24h")]
pub change_24h: FiatFromHeight<C, M>,
pub change_1w: FiatFromHeight<C, M>,
pub change_1y: FiatFromHeight<C, M>,
#[traversable(rename = "24h")]
pub rate_24h: PercentFromHeight<BasisPointsSigned32, M>,
pub rate_1w: PercentFromHeight<BasisPointsSigned32, M>,
pub rate_1y: PercentFromHeight<BasisPointsSigned32, M>,
_phantom: std::marker::PhantomData<S>,
}
impl<S, C> FiatRollingDeltaExcept1m<S, C>
where
S: NumericValue + JsonSchema,
C: CentsType,
{
pub(crate) fn forced_import(
db: &Database,
name: &str,
version: Version,
indexes: &indexes::Vecs,
) -> Result<Self> {
Ok(Self {
change_24h: FiatFromHeight::forced_import(
db,
&format!("{name}_change_24h"),
version,
indexes,
)?,
change_1w: FiatFromHeight::forced_import(
db,
&format!("{name}_change_1w"),
version,
indexes,
)?,
change_1y: FiatFromHeight::forced_import(
db,
&format!("{name}_change_1y"),
version,
indexes,
)?,
rate_24h: PercentFromHeight::forced_import(
db,
&format!("{name}_rate_24h"),
version,
indexes,
)?,
rate_1w: PercentFromHeight::forced_import(
db,
&format!("{name}_rate_1w"),
version,
indexes,
)?,
rate_1y: PercentFromHeight::forced_import(
db,
&format!("{name}_rate_1y"),
version,
indexes,
)?,
_phantom: std::marker::PhantomData,
})
}
pub(crate) fn compute(
&mut self,
max_from: Height,
windows: &WindowStarts<'_>,
source: &impl ReadableVec<Height, S>,
exit: &Exit,
) -> Result<()> {
let skip = self.change_24h.cents.height.len();
let (source_data, offset) = collect_source(source, skip, windows._1y);
let changes: [&mut FiatFromHeight<C>; 3] =
[&mut self.change_24h, &mut self.change_1w, &mut self.change_1y];
let rates = [&mut self.rate_24h, &mut self.rate_1w, &mut self.rate_1y];
let starts = [windows._24h, windows._1w, windows._1y];
for ((change_w, rate_w), starts) in changes.into_iter().zip(rates).zip(starts) {
compute_delta_window(
&mut change_w.cents.height,
&mut rate_w.bps.height,
max_from,
starts,
&source_data,
offset,
exit,
)?;
}
Ok(())
}
}
/// Fiat rolling delta: all 4 windows, fiat change (cents + usd) + rate.
#[derive(Traversable)]
pub struct FiatRollingDelta<S, C, M: StorageMode = Rw>
where
S: NumericValue + JsonSchema,
C: CentsType,
{
pub change_24h: FiatFromHeight<C, M>,
pub change_1w: FiatFromHeight<C, M>,
pub change_1m: FiatFromHeight<C, M>,
pub change_1y: FiatFromHeight<C, M>,
pub rate: PercentRollingWindows<BasisPointsSigned32, M>,
_phantom: std::marker::PhantomData<S>,
}
impl<S, C> FiatRollingDelta<S, C>
where
S: NumericValue + JsonSchema,
C: CentsType,
{
pub(crate) fn forced_import(
db: &Database,
name: &str,
version: Version,
indexes: &indexes::Vecs,
) -> Result<Self> {
Ok(Self {
change_24h: FiatFromHeight::forced_import(
db,
&format!("{name}_change_24h"),
version,
indexes,
)?,
change_1w: FiatFromHeight::forced_import(
db,
&format!("{name}_change_1w"),
version,
indexes,
)?,
change_1m: FiatFromHeight::forced_import(
db,
&format!("{name}_change_1m"),
version,
indexes,
)?,
change_1y: FiatFromHeight::forced_import(
db,
&format!("{name}_change_1y"),
version,
indexes,
)?,
rate: PercentRollingWindows::forced_import(
db,
&format!("{name}_rate"),
version,
indexes,
)?,
_phantom: std::marker::PhantomData,
})
}
pub(crate) fn compute(
&mut self,
max_from: Height,
windows: &WindowStarts<'_>,
source: &impl ReadableVec<Height, S>,
exit: &Exit,
) -> Result<()> {
let skip = self.change_24h.cents.height.len();
let (source_data, offset) = collect_source(source, skip, windows._1y);
let changes: [&mut FiatFromHeight<C>; 4] = [
&mut self.change_24h,
&mut self.change_1w,
&mut self.change_1m,
&mut self.change_1y,
];
let rates = self.rate.0.as_mut_array();
let starts = windows.as_array();
for ((change_w, rate_w), starts) in changes.into_iter().zip(rates).zip(starts) {
compute_delta_window(
&mut change_w.cents.height,
&mut rate_w.bps.height,
max_from,
*starts,
&source_data,
offset,
exit,
)?;
}
Ok(())
}
}
@@ -2,6 +2,7 @@ mod aggregated;
mod cumulative;
mod cumulative_sum;
mod delta;
mod fiat_delta;
mod full;
mod rolling_average;
mod sum;
@@ -10,6 +11,7 @@ pub use aggregated::*;
pub use cumulative::*;
pub use cumulative_sum::*;
pub use delta::*;
pub use fiat_delta::*;
pub use full::*;
pub use rolling_average::*;
pub use sum::*;
@@ -0,0 +1,41 @@
use brk_traversable::Traversable;
use brk_types::{Dollars, Version};
use vecdb::ReadableCloneableVec;
use super::{ComputedFromHeight, LazyFromHeight};
use crate::internal::{Identity, NumericValue};
use super::fiat::CentsType;
/// Lazy fiat: both cents and usd are lazy views of a stored source.
/// Zero extra stored vecs.
#[derive(Clone, Traversable)]
pub struct LazyFiatFromHeight<C: CentsType> {
pub cents: LazyFromHeight<C, C>,
pub usd: LazyFromHeight<Dollars, C>,
}
impl<C: CentsType> LazyFiatFromHeight<C> {
pub(crate) fn from_computed(
name: &str,
version: Version,
source: &ComputedFromHeight<C>,
) -> Self
where
C: NumericValue,
{
let cents = LazyFromHeight::from_computed::<Identity<C>>(
&format!("{name}_cents"),
version,
source.height.read_only_boxed_clone(),
source,
);
let usd = LazyFromHeight::from_computed::<C::ToDollars>(
&format!("{name}_usd"),
version,
source.height.read_only_boxed_clone(),
source,
);
Self { cents, usd }
}
}
@@ -4,6 +4,7 @@ mod computed;
mod constant;
mod fiat;
mod lazy;
mod lazy_fiat;
mod percent;
mod percentiles;
mod price;
@@ -17,6 +18,7 @@ pub use computed::*;
pub use constant::*;
pub use fiat::*;
pub use lazy::*;
pub use lazy_fiat::*;
pub use percent::*;
pub use percentiles::*;
pub use price::*;