global: snapshot

This commit is contained in:
nym21
2026-03-04 13:19:49 +01:00
parent 91b7f86225
commit 730e8bb4d4
33 changed files with 166 additions and 310 deletions

View File

@@ -13,7 +13,7 @@ use vecdb::{
use brk_types::get_percentile;
use super::ComputedVecValue;
use crate::internal::ComputedVecValue;
/// Helper to validate and get starting index for a single vec
fn validate_and_start<I: VecIndex, T: ComputedVecValue + JsonSchema>(

View File

@@ -0,0 +1,6 @@
mod aggregation;
pub(crate) mod sliding_window;
mod tdigest;
pub(crate) use aggregation::*;
pub(crate) use tdigest::*;

View File

@@ -1,9 +1,9 @@
mod full;
mod last;
mod lazy_last;
mod lazy_value_last;
mod lazy_value;
pub use full::*;
pub use last::*;
pub use lazy_last::*;
pub use lazy_value_last::*;
pub use lazy_value::*;

View File

@@ -1,4 +1,4 @@
//! Generic 2-slot container for 1w + 1m EMA pairs.
//! Generic EMA window containers.
use brk_traversable::Traversable;
@@ -30,3 +30,29 @@ impl<A> Emas1w1m<A> {
[&mut self._1w, &mut self._1m]
}
}
#[derive(Clone, Traversable)]
pub struct Emas2w<A> {
#[traversable(rename = "2w")]
pub _2w: A,
}
impl<A> Emas2w<A> {
pub const SUFFIXES: [&'static str; 1] = ["ema_2w"];
pub fn try_from_fn<E>(
mut f: impl FnMut(&str) -> std::result::Result<A, E>,
) -> std::result::Result<Self, E> {
Ok(Self {
_2w: f(Self::SUFFIXES[0])?,
})
}
pub fn as_array(&self) -> [&A; 1] {
[&self._2w]
}
pub fn as_mut_array(&mut self) -> [&mut A; 1] {
[&mut self._2w]
}
}

View File

@@ -1,29 +0,0 @@
//! Generic 1-slot container for 2w EMA.
use brk_traversable::Traversable;
#[derive(Clone, Traversable)]
pub struct Emas2w<A> {
#[traversable(rename = "2w")]
pub _2w: A,
}
impl<A> Emas2w<A> {
pub const SUFFIXES: [&'static str; 1] = ["ema_2w"];
pub fn try_from_fn<E>(
mut f: impl FnMut(&str) -> std::result::Result<A, E>,
) -> std::result::Result<Self, E> {
Ok(Self {
_2w: f(Self::SUFFIXES[0])?,
})
}
pub fn as_array(&self) -> [&A; 1] {
[&self._2w]
}
pub fn as_mut_array(&mut self) -> [&mut A; 1] {
[&mut self._2w]
}
}

View File

@@ -1,5 +0,0 @@
mod emas_1w_1m;
mod emas_2w;
pub use emas_1w_1m::*;
pub use emas_2w::*;

View File

@@ -1,6 +1,5 @@
mod rolling_full;
mod rolling_sum;
mod windows;
use brk_error::Result;
use brk_traversable::Traversable;
@@ -10,7 +9,7 @@ use vecdb::{Database, ReadableCloneableVec, Rw, StorageMode};
use crate::{
indexes,
internal::{
CentsUnsignedToDollars, ComputedFromHeight, LazyFromHeight, SatsToBitcoin,
CentsUnsignedToDollars, ComputedFromHeight, LazyFromHeight, SatsToBitcoin, Windows,
},
};
@@ -63,3 +62,16 @@ impl ByUnit {
})
}
}
impl Windows<ByUnit> {
pub(crate) fn forced_import(
db: &Database,
name: &str,
version: Version,
indexes: &indexes::Vecs,
) -> Result<Self> {
Windows::try_from_fn(|suffix| {
ByUnit::forced_import(db, &format!("{name}_{suffix}"), version, indexes)
})
}
}

View File

@@ -1,21 +0,0 @@
use brk_error::Result;
use brk_types::Version;
use vecdb::Database;
use crate::{
indexes,
internal::{ByUnit, Windows},
};
impl Windows<ByUnit> {
pub(crate) fn forced_import(
db: &Database,
name: &str,
version: Version,
indexes: &indexes::Vecs,
) -> Result<Self> {
Windows::try_from_fn(|suffix| {
ByUnit::forced_import(db, &format!("{name}_{suffix}"), version, indexes)
})
}
}

View File

@@ -7,7 +7,7 @@ mod cumulative_sum;
mod distribution;
mod fiat;
mod full;
mod lazy_base;
mod lazy;
mod percent;
mod percent_distribution;
mod percentiles;
@@ -25,7 +25,7 @@ pub use cumulative_sum::*;
pub use distribution::*;
pub use fiat::*;
pub use full::*;
pub use lazy_base::*;
pub use lazy::*;
pub use percent::*;
pub use percent_distribution::*;
pub use percentiles::*;

View File

@@ -1,5 +1,7 @@
mod derived;
mod distribution;
mod lazy_distribution;
pub use derived::*;
pub use distribution::*;
pub use lazy_distribution::*;

View File

@@ -1,40 +1,35 @@
mod compute;
pub(crate) mod algo;
mod aggregate;
mod derived;
mod distribution_stats;
mod eager_indexes;
mod emas;
mod from_height;
mod from_tx;
mod group;
mod height_derived;
mod indexes;
mod lazy_eager_indexes;
mod lazy_value;
mod rolling;
pub(crate) mod sliding_window;
mod tdigest;
mod stat_vec;
mod traits;
mod transform;
mod tx_derived;
mod value;
mod vec;
mod windows;
pub(crate) use compute::*;
pub(crate) use algo::*;
pub(crate) use aggregate::*;
pub(crate) use derived::*;
pub(crate) use distribution_stats::*;
pub(crate) use eager_indexes::*;
pub(crate) use emas::*;
pub(crate) use from_height::*;
pub(crate) use from_tx::*;
pub(crate) use group::*;
pub(crate) use height_derived::*;
pub(crate) use indexes::*;
pub(crate) use lazy_eager_indexes::*;
pub(crate) use lazy_value::*;
pub(crate) use rolling::*;
pub(crate) use tdigest::*;
pub(crate) use stat_vec::*;
pub(crate) use traits::*;
pub use transform::*;
pub(crate) use tx_derived::*;
pub(crate) use value::*;
pub(crate) use vec::*;
pub(crate) use windows::*;

View File

@@ -0,0 +1,103 @@
use brk_error::Result;
use brk_traversable::Traversable;
use derive_more::{Deref, DerefMut};
use schemars::JsonSchema;
use vecdb::{
Database, EagerVec, ImportableVec, PcoVec, Ro, Rw, StorageMode, StoredVec, VecIndex, Version,
};
use crate::internal::ComputedVecValue;
macro_rules! define_stat_vec {
($name:ident, $suffix:literal, $doc:literal) => {
#[doc = $doc]
#[derive(Deref, DerefMut, Traversable)]
pub struct $name<I: VecIndex, T: ComputedVecValue + JsonSchema, M: StorageMode = Rw>(
pub M::Stored<EagerVec<PcoVec<I, T>>>,
);
impl<I: VecIndex, T: ComputedVecValue + JsonSchema> $name<I, T> {
pub(crate) fn forced_import(
db: &Database,
name: &str,
version: Version,
) -> Result<Self> {
Ok(Self(EagerVec::forced_import(
db,
&format!("{name}_{}", $suffix),
version,
)?))
}
pub fn read_only_clone(&self) -> $name<I, T, Ro> {
$name(StoredVec::read_only_clone(&self.0))
}
}
};
}
macro_rules! define_stat_vec_transparent {
($name:ident, $suffix:literal, $doc:literal) => {
#[doc = $doc]
#[derive(Deref, DerefMut, Traversable)]
#[traversable(transparent)]
pub struct $name<I: VecIndex, T: ComputedVecValue + JsonSchema, M: StorageMode = Rw>(
pub M::Stored<EagerVec<PcoVec<I, T>>>,
);
impl<I: VecIndex, T: ComputedVecValue + JsonSchema> $name<I, T> {
pub(crate) fn forced_import(
db: &Database,
name: &str,
version: Version,
) -> Result<Self> {
Ok(Self(EagerVec::forced_import(
db,
&format!("{name}_{}", $suffix),
version,
)?))
}
pub fn read_only_clone(&self) -> $name<I, T, Ro> {
$name(StoredVec::read_only_clone(&self.0))
}
}
};
}
define_stat_vec!(AverageVec, "average", "Average value in an aggregation period");
define_stat_vec!(MinVec, "min", "Minimum value in an aggregation period");
define_stat_vec!(MaxVec, "max", "Maximum value in an aggregation period");
define_stat_vec!(Pct10Vec, "pct10", "10th percentile in an aggregation period");
define_stat_vec!(Pct25Vec, "pct25", "25th percentile in an aggregation period");
define_stat_vec!(MedianVec, "median", "Median (50th percentile) in an aggregation period");
define_stat_vec!(Pct75Vec, "pct75", "75th percentile in an aggregation period");
define_stat_vec!(Pct90Vec, "pct90", "90th percentile in an aggregation period");
define_stat_vec_transparent!(CumulativeVec, "cumulative", "Cumulative sum across aggregation periods");
/// Sum of values in an aggregation period
#[derive(Deref, DerefMut, Traversable)]
#[traversable(transparent)]
pub struct SumVec<I: VecIndex, T: ComputedVecValue + JsonSchema, M: StorageMode = Rw>(
pub M::Stored<EagerVec<PcoVec<I, T>>>,
);
impl<I: VecIndex, T: ComputedVecValue + JsonSchema> SumVec<I, T> {
pub(crate) fn forced_import(db: &Database, name: &str, version: Version) -> Result<Self> {
Ok(Self(EagerVec::forced_import(
db,
&format!("{name}_sum"),
version,
)?))
}
#[inline]
pub(crate) fn inner(&self) -> &EagerVec<PcoVec<I, T>> {
&self.0
}
pub fn read_only_clone(&self) -> SumVec<I, T, Ro> {
SumVec(StoredVec::read_only_clone(&self.0))
}
}

View File

@@ -1,3 +0,0 @@
mod distribution;
pub use distribution::*;

View File

@@ -1,29 +0,0 @@
use brk_error::Result;
use brk_traversable::Traversable;
use derive_more::{Deref, DerefMut};
use schemars::JsonSchema;
use vecdb::{
Database, EagerVec, ImportableVec, PcoVec, Ro, Rw, StorageMode, StoredVec, VecIndex, Version,
};
use crate::internal::ComputedVecValue;
/// Average value in an aggregation period
#[derive(Deref, DerefMut, Traversable)]
pub struct AverageVec<I: VecIndex, T: ComputedVecValue + JsonSchema, M: StorageMode = Rw>(
pub M::Stored<EagerVec<PcoVec<I, T>>>,
);
impl<I: VecIndex, T: ComputedVecValue + JsonSchema> AverageVec<I, T> {
pub(crate) fn forced_import(db: &Database, name: &str, version: Version) -> Result<Self> {
Ok(Self(EagerVec::forced_import(
db,
&format!("{name}_average"),
version,
)?))
}
pub fn read_only_clone(&self) -> AverageVec<I, T, Ro> {
AverageVec(StoredVec::read_only_clone(&self.0))
}
}

View File

@@ -1,30 +0,0 @@
use brk_error::Result;
use brk_traversable::Traversable;
use derive_more::{Deref, DerefMut};
use schemars::JsonSchema;
use vecdb::{
Database, EagerVec, ImportableVec, PcoVec, Ro, Rw, StorageMode, StoredVec, VecIndex, Version,
};
use crate::internal::ComputedVecValue;
/// Cumulative sum across aggregation periods
#[derive(Deref, DerefMut, Traversable)]
#[traversable(transparent)]
pub struct CumulativeVec<I: VecIndex, T: ComputedVecValue + JsonSchema, M: StorageMode = Rw>(
pub M::Stored<EagerVec<PcoVec<I, T>>>,
);
impl<I: VecIndex, T: ComputedVecValue + JsonSchema> CumulativeVec<I, T> {
pub(crate) fn forced_import(db: &Database, name: &str, version: Version) -> Result<Self> {
Ok(Self(EagerVec::forced_import(
db,
&format!("{name}_cumulative"),
version,
)?))
}
pub fn read_only_clone(&self) -> CumulativeVec<I, T, Ro> {
CumulativeVec(StoredVec::read_only_clone(&self.0))
}
}

View File

@@ -1,29 +0,0 @@
use brk_error::Result;
use brk_traversable::Traversable;
use derive_more::{Deref, DerefMut};
use schemars::JsonSchema;
use vecdb::{
Database, EagerVec, ImportableVec, PcoVec, Ro, Rw, StorageMode, StoredVec, VecIndex, Version,
};
use crate::internal::ComputedVecValue;
/// Maximum value in an aggregation period
#[derive(Deref, DerefMut, Traversable)]
pub struct MaxVec<I: VecIndex, T: ComputedVecValue + JsonSchema, M: StorageMode = Rw>(
pub M::Stored<EagerVec<PcoVec<I, T>>>,
);
impl<I: VecIndex, T: ComputedVecValue + JsonSchema> MaxVec<I, T> {
pub(crate) fn forced_import(db: &Database, name: &str, version: Version) -> Result<Self> {
Ok(Self(EagerVec::forced_import(
db,
&format!("{name}_max"),
version,
)?))
}
pub fn read_only_clone(&self) -> MaxVec<I, T, Ro> {
MaxVec(StoredVec::read_only_clone(&self.0))
}
}

View File

@@ -1,29 +0,0 @@
use brk_error::Result;
use brk_traversable::Traversable;
use derive_more::{Deref, DerefMut};
use schemars::JsonSchema;
use vecdb::{
Database, EagerVec, ImportableVec, PcoVec, Ro, Rw, StorageMode, StoredVec, VecIndex, Version,
};
use crate::internal::ComputedVecValue;
/// Minimum value in an aggregation period
#[derive(Deref, DerefMut, Traversable)]
pub struct MinVec<I: VecIndex, T: ComputedVecValue + JsonSchema, M: StorageMode = Rw>(
pub M::Stored<EagerVec<PcoVec<I, T>>>,
);
impl<I: VecIndex, T: ComputedVecValue + JsonSchema> MinVec<I, T> {
pub(crate) fn forced_import(db: &Database, name: &str, version: Version) -> Result<Self> {
Ok(Self(EagerVec::forced_import(
db,
&format!("{name}_min"),
version,
)?))
}
pub fn read_only_clone(&self) -> MinVec<I, T, Ro> {
MinVec(StoredVec::read_only_clone(&self.0))
}
}

View File

@@ -1,13 +0,0 @@
mod average;
mod cumulative;
mod max;
mod min;
mod percentiles;
mod sum;
pub use average::*;
pub use cumulative::*;
pub use max::*;
pub use min::*;
pub use percentiles::*;
pub use sum::*;

View File

@@ -1,65 +0,0 @@
//! Percentile vec types for aggregation periods.
use brk_error::Result;
use brk_traversable::Traversable;
use derive_more::{Deref, DerefMut};
use schemars::JsonSchema;
use vecdb::{
Database, EagerVec, ImportableVec, PcoVec, Ro, Rw, StorageMode, StoredVec, VecIndex, Version,
};
use crate::internal::ComputedVecValue;
macro_rules! define_percentile_vec {
($name:ident, $suffix:literal, $doc:literal) => {
#[doc = $doc]
#[derive(Deref, DerefMut, Traversable)]
pub struct $name<I: VecIndex, T: ComputedVecValue + JsonSchema, M: StorageMode = Rw>(
pub M::Stored<EagerVec<PcoVec<I, T>>>,
);
impl<I: VecIndex, T: ComputedVecValue + JsonSchema> $name<I, T> {
pub(crate) fn forced_import(
db: &Database,
name: &str,
version: Version,
) -> Result<Self> {
Ok(Self(EagerVec::forced_import(
db,
&format!("{name}_{}", $suffix),
version,
)?))
}
pub fn read_only_clone(&self) -> $name<I, T, Ro> {
$name(StoredVec::read_only_clone(&self.0))
}
}
};
}
define_percentile_vec!(
Pct10Vec,
"pct10",
"10th percentile in an aggregation period"
);
define_percentile_vec!(
Pct25Vec,
"pct25",
"25th percentile in an aggregation period"
);
define_percentile_vec!(
MedianVec,
"median",
"Median (50th percentile) in an aggregation period"
);
define_percentile_vec!(
Pct75Vec,
"pct75",
"75th percentile in an aggregation period"
);
define_percentile_vec!(
Pct90Vec,
"pct90",
"90th percentile in an aggregation period"
);

View File

@@ -1,35 +0,0 @@
use brk_error::Result;
use brk_traversable::Traversable;
use derive_more::{Deref, DerefMut};
use schemars::JsonSchema;
use vecdb::{
Database, EagerVec, ImportableVec, PcoVec, Ro, Rw, StorageMode, StoredVec, VecIndex, Version,
};
use crate::internal::ComputedVecValue;
/// Sum of values in an aggregation period
#[derive(Deref, DerefMut, Traversable)]
#[traversable(transparent)]
pub struct SumVec<I: VecIndex, T: ComputedVecValue + JsonSchema, M: StorageMode = Rw>(
pub M::Stored<EagerVec<PcoVec<I, T>>>,
);
impl<I: VecIndex, T: ComputedVecValue + JsonSchema> SumVec<I, T> {
pub(crate) fn forced_import(db: &Database, name: &str, version: Version) -> Result<Self> {
Ok(Self(EagerVec::forced_import(
db,
&format!("{name}_sum"),
version,
)?))
}
#[inline]
pub(crate) fn inner(&self) -> &EagerVec<PcoVec<I, T>> {
&self.0
}
pub fn read_only_clone(&self) -> SumVec<I, T, Ro> {
SumVec(StoredVec::read_only_clone(&self.0))
}
}

View File

@@ -5,7 +5,7 @@ use vecdb::{
WritableVec,
};
use crate::internal::sliding_window::SlidingWindowSorted;
use crate::internal::algo::sliding_window::SlidingWindowSorted;
pub trait ComputeRollingMedianFromStarts<I: VecIndex, T> {
fn compute_rolling_median_from_starts<A>(