mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-07-19 06:58:11 -07:00
global: snapshot
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::{Height, Version};
|
||||
use schemars::JsonSchema;
|
||||
use vecdb::{LazyVecFrom1, ReadableCloneableVec, UnaryTransform, VecIndex};
|
||||
|
||||
use crate::internal::{ComputedVecValue, Distribution, DistributionStats};
|
||||
|
||||
/// Lazy analog of `Distribution<I, T>`: 8 `LazyVecFrom1` fields,
|
||||
/// each derived by transforming the corresponding field of a source `Distribution<I, S1T>`.
|
||||
#[derive(Clone, Traversable)]
|
||||
pub struct LazyDistribution<I, T, S1T>
|
||||
where
|
||||
I: VecIndex,
|
||||
T: ComputedVecValue + JsonSchema,
|
||||
S1T: ComputedVecValue,
|
||||
{
|
||||
pub average: LazyVecFrom1<I, T, I, S1T>,
|
||||
pub min: LazyVecFrom1<I, T, I, S1T>,
|
||||
pub max: LazyVecFrom1<I, T, I, S1T>,
|
||||
pub pct10: LazyVecFrom1<I, T, I, S1T>,
|
||||
pub pct25: LazyVecFrom1<I, T, I, S1T>,
|
||||
pub median: LazyVecFrom1<I, T, I, S1T>,
|
||||
pub pct75: LazyVecFrom1<I, T, I, S1T>,
|
||||
pub pct90: LazyVecFrom1<I, T, I, S1T>,
|
||||
}
|
||||
|
||||
impl<T, S1T> LazyDistribution<Height, T, S1T>
|
||||
where
|
||||
T: ComputedVecValue + JsonSchema + 'static,
|
||||
S1T: ComputedVecValue + JsonSchema,
|
||||
{
|
||||
pub(crate) fn from_distribution<F: UnaryTransform<S1T, T>>(
|
||||
name: &str,
|
||||
version: Version,
|
||||
source: &Distribution<Height, S1T>,
|
||||
) -> Self {
|
||||
let s = DistributionStats::<()>::SUFFIXES;
|
||||
Self {
|
||||
average: LazyVecFrom1::transformed::<F>(
|
||||
&format!("{name}_{}", s[0]),
|
||||
version,
|
||||
source.average.read_only_boxed_clone(),
|
||||
),
|
||||
min: LazyVecFrom1::transformed::<F>(
|
||||
&format!("{name}_{}", s[1]),
|
||||
version,
|
||||
source.min.read_only_boxed_clone(),
|
||||
),
|
||||
max: LazyVecFrom1::transformed::<F>(
|
||||
&format!("{name}_{}", s[2]),
|
||||
version,
|
||||
source.max.read_only_boxed_clone(),
|
||||
),
|
||||
pct10: LazyVecFrom1::transformed::<F>(
|
||||
&format!("{name}_{}", s[3]),
|
||||
version,
|
||||
source.pct10.read_only_boxed_clone(),
|
||||
),
|
||||
pct25: LazyVecFrom1::transformed::<F>(
|
||||
&format!("{name}_{}", s[4]),
|
||||
version,
|
||||
source.pct25.read_only_boxed_clone(),
|
||||
),
|
||||
median: LazyVecFrom1::transformed::<F>(
|
||||
&format!("{name}_{}", s[5]),
|
||||
version,
|
||||
source.median.read_only_boxed_clone(),
|
||||
),
|
||||
pct75: LazyVecFrom1::transformed::<F>(
|
||||
&format!("{name}_{}", s[6]),
|
||||
version,
|
||||
source.pct75.read_only_boxed_clone(),
|
||||
),
|
||||
pct90: LazyVecFrom1::transformed::<F>(
|
||||
&format!("{name}_{}", s[7]),
|
||||
version,
|
||||
source.pct90.read_only_boxed_clone(),
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
mod distribution;
|
||||
mod full;
|
||||
mod lazy_distribution;
|
||||
|
||||
pub use distribution::*;
|
||||
pub use full::*;
|
||||
pub use lazy_distribution::*;
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::Version;
|
||||
use schemars::JsonSchema;
|
||||
use vecdb::{ReadableCloneableVec, UnaryTransform};
|
||||
|
||||
use crate::{
|
||||
indexes,
|
||||
internal::{
|
||||
CachedWindowStarts, ComputedPerBlockFull, ComputedVecValue, LazyPerBlock, LazyRollingFull,
|
||||
NumericValue,
|
||||
},
|
||||
};
|
||||
|
||||
/// Lazy analog of `ResolutionsFull<T>`: lazy cumulative + lazy rolling full.
|
||||
/// Derived by transforming a `ComputedPerBlockFull<S1T>`. Zero stored vecs.
|
||||
#[derive(Clone, Traversable)]
|
||||
pub struct LazyResolutionsFull<T, S1T>
|
||||
where
|
||||
T: NumericValue + JsonSchema,
|
||||
S1T: ComputedVecValue + JsonSchema,
|
||||
{
|
||||
pub cumulative: LazyPerBlock<T, S1T>,
|
||||
#[traversable(flatten)]
|
||||
pub rolling: LazyRollingFull<T, S1T>,
|
||||
}
|
||||
|
||||
impl<T, S1T> LazyResolutionsFull<T, S1T>
|
||||
where
|
||||
T: NumericValue + JsonSchema + 'static,
|
||||
S1T: NumericValue + JsonSchema,
|
||||
{
|
||||
pub(crate) fn from_computed_per_block_full<F: UnaryTransform<S1T, T>>(
|
||||
name: &str,
|
||||
version: Version,
|
||||
source: &ComputedPerBlockFull<S1T>,
|
||||
cached_starts: &CachedWindowStarts,
|
||||
indexes: &indexes::Vecs,
|
||||
) -> Self {
|
||||
let cumulative = LazyPerBlock::from_computed::<F>(
|
||||
&format!("{name}_cumulative"),
|
||||
version,
|
||||
source.cumulative.height.read_only_boxed_clone(),
|
||||
&source.cumulative,
|
||||
);
|
||||
|
||||
let rolling = LazyRollingFull::from_rolling_full::<F>(
|
||||
name,
|
||||
version,
|
||||
&cumulative.height,
|
||||
&source.rolling,
|
||||
cached_starts,
|
||||
indexes,
|
||||
);
|
||||
|
||||
Self {
|
||||
cumulative,
|
||||
rolling,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@ mod cumulative;
|
||||
mod cumulative_sum;
|
||||
mod resolutions;
|
||||
mod resolutions_full;
|
||||
mod lazy_resolutions_full;
|
||||
mod full;
|
||||
mod rolling_average;
|
||||
mod with_deltas;
|
||||
@@ -16,6 +17,7 @@ pub use cumulative::*;
|
||||
pub use cumulative_sum::*;
|
||||
pub use resolutions::*;
|
||||
pub use resolutions_full::*;
|
||||
pub use lazy_resolutions_full::*;
|
||||
pub use full::*;
|
||||
pub use rolling_average::*;
|
||||
pub use with_deltas::*;
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::Version;
|
||||
use derive_more::{Deref, DerefMut};
|
||||
use schemars::JsonSchema;
|
||||
use vecdb::{ReadableCloneableVec, UnaryTransform};
|
||||
|
||||
use crate::internal::{
|
||||
ComputedVecValue, DistributionStats, LazyPerBlock, NumericValue, RollingDistribution, Windows,
|
||||
};
|
||||
|
||||
/// Lazy analog of `RollingDistribution<T>`: `DistributionStats<Windows<LazyPerBlock<T, S1T>>>`.
|
||||
/// 8 stats × 4 windows = 32 lazy vecs, zero stored.
|
||||
#[derive(Clone, Deref, DerefMut, Traversable)]
|
||||
#[traversable(transparent)]
|
||||
pub struct LazyRollingDistribution<T, S1T>(pub DistributionStats<Windows<LazyPerBlock<T, S1T>>>)
|
||||
where
|
||||
T: ComputedVecValue + PartialOrd + JsonSchema,
|
||||
S1T: ComputedVecValue + JsonSchema;
|
||||
|
||||
impl<T, S1T> LazyRollingDistribution<T, S1T>
|
||||
where
|
||||
T: ComputedVecValue + JsonSchema + 'static,
|
||||
S1T: NumericValue + JsonSchema,
|
||||
{
|
||||
pub(crate) fn from_rolling_distribution<F: UnaryTransform<S1T, T>>(
|
||||
name: &str,
|
||||
version: Version,
|
||||
source: &RollingDistribution<S1T>,
|
||||
) -> Self {
|
||||
let s = &source.0;
|
||||
|
||||
macro_rules! map_stat {
|
||||
($field:ident, $suffix:expr) => {{
|
||||
let src = &s.$field;
|
||||
Windows {
|
||||
_24h: LazyPerBlock::from_computed::<F>(
|
||||
&format!("{name}_{}_24h", $suffix),
|
||||
version,
|
||||
src._24h.height.read_only_boxed_clone(),
|
||||
&src._24h,
|
||||
),
|
||||
_1w: LazyPerBlock::from_computed::<F>(
|
||||
&format!("{name}_{}_1w", $suffix),
|
||||
version,
|
||||
src._1w.height.read_only_boxed_clone(),
|
||||
&src._1w,
|
||||
),
|
||||
_1m: LazyPerBlock::from_computed::<F>(
|
||||
&format!("{name}_{}_1m", $suffix),
|
||||
version,
|
||||
src._1m.height.read_only_boxed_clone(),
|
||||
&src._1m,
|
||||
),
|
||||
_1y: LazyPerBlock::from_computed::<F>(
|
||||
&format!("{name}_{}_1y", $suffix),
|
||||
version,
|
||||
src._1y.height.read_only_boxed_clone(),
|
||||
&src._1y,
|
||||
),
|
||||
}
|
||||
}};
|
||||
}
|
||||
|
||||
Self(DistributionStats {
|
||||
average: map_stat!(average, "average"),
|
||||
min: map_stat!(min, "min"),
|
||||
max: map_stat!(max, "max"),
|
||||
pct10: map_stat!(pct10, "pct10"),
|
||||
pct25: map_stat!(pct25, "pct25"),
|
||||
median: map_stat!(median, "median"),
|
||||
pct75: map_stat!(pct75, "pct75"),
|
||||
pct90: map_stat!(pct90, "pct90"),
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::Version;
|
||||
use schemars::JsonSchema;
|
||||
use vecdb::{ReadableCloneableVec, UnaryTransform};
|
||||
|
||||
use brk_types::Height;
|
||||
|
||||
use crate::{
|
||||
indexes,
|
||||
internal::{
|
||||
CachedWindowStarts, ComputedVecValue, LazyRollingDistribution, LazyRollingSumsFromHeight,
|
||||
NumericValue, RollingFull,
|
||||
},
|
||||
};
|
||||
|
||||
/// Lazy analog of `RollingFull<T>`: lazy rolling sums + lazy rolling distribution.
|
||||
/// Zero stored vecs.
|
||||
#[derive(Clone, Traversable)]
|
||||
pub struct LazyRollingFull<T, S1T>
|
||||
where
|
||||
T: NumericValue + JsonSchema,
|
||||
S1T: ComputedVecValue + JsonSchema,
|
||||
{
|
||||
pub sum: LazyRollingSumsFromHeight<T>,
|
||||
#[traversable(flatten)]
|
||||
pub distribution: LazyRollingDistribution<T, S1T>,
|
||||
}
|
||||
|
||||
impl<T, S1T> LazyRollingFull<T, S1T>
|
||||
where
|
||||
T: NumericValue + JsonSchema + 'static,
|
||||
S1T: NumericValue + JsonSchema,
|
||||
{
|
||||
pub(crate) fn from_rolling_full<F: UnaryTransform<S1T, T>>(
|
||||
name: &str,
|
||||
version: Version,
|
||||
cumulative: &(impl ReadableCloneableVec<Height, T> + 'static),
|
||||
source: &RollingFull<S1T>,
|
||||
cached_starts: &CachedWindowStarts,
|
||||
indexes: &indexes::Vecs,
|
||||
) -> Self {
|
||||
let sum = LazyRollingSumsFromHeight::new(
|
||||
&format!("{name}_sum"),
|
||||
version,
|
||||
cumulative,
|
||||
cached_starts,
|
||||
indexes,
|
||||
);
|
||||
let distribution = LazyRollingDistribution::from_rolling_distribution::<F>(
|
||||
name,
|
||||
version,
|
||||
&source.distribution,
|
||||
);
|
||||
Self { sum, distribution }
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,8 @@ mod avgs;
|
||||
mod delta;
|
||||
mod distribution;
|
||||
mod full;
|
||||
mod lazy_distribution;
|
||||
mod lazy_full;
|
||||
mod sum;
|
||||
mod sums;
|
||||
mod windows;
|
||||
@@ -12,6 +14,8 @@ pub use avgs::*;
|
||||
pub use delta::*;
|
||||
pub use distribution::*;
|
||||
pub use full::*;
|
||||
pub use lazy_distribution::*;
|
||||
pub use lazy_full::*;
|
||||
pub use sum::*;
|
||||
pub use sums::*;
|
||||
pub use windows::*;
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::{Height, Version};
|
||||
use schemars::JsonSchema;
|
||||
use vecdb::UnaryTransform;
|
||||
|
||||
use crate::internal::{ComputedVecValue, LazyDistribution, TxDerivedDistribution};
|
||||
|
||||
#[derive(Clone, Traversable)]
|
||||
pub struct LazyBlockRollingDistribution<T, S1T>
|
||||
where
|
||||
T: ComputedVecValue + JsonSchema,
|
||||
S1T: ComputedVecValue,
|
||||
{
|
||||
pub _6b: LazyDistribution<Height, T, S1T>,
|
||||
}
|
||||
|
||||
/// Lazy analog of `TxDerivedDistribution<T>`: per-block + 6-block rolling,
|
||||
/// each derived by transforming the corresponding source distribution.
|
||||
#[derive(Clone, Traversable)]
|
||||
pub struct LazyTxDerivedDistribution<T, S1T>
|
||||
where
|
||||
T: ComputedVecValue + JsonSchema,
|
||||
S1T: ComputedVecValue,
|
||||
{
|
||||
pub block: LazyDistribution<Height, T, S1T>,
|
||||
#[traversable(flatten)]
|
||||
pub rolling: LazyBlockRollingDistribution<T, S1T>,
|
||||
}
|
||||
|
||||
impl<T, S1T> LazyTxDerivedDistribution<T, S1T>
|
||||
where
|
||||
T: ComputedVecValue + JsonSchema + 'static,
|
||||
S1T: ComputedVecValue + JsonSchema,
|
||||
{
|
||||
pub(crate) fn from_tx_derived<F: UnaryTransform<S1T, T>>(
|
||||
name: &str,
|
||||
version: Version,
|
||||
source: &TxDerivedDistribution<S1T>,
|
||||
) -> Self {
|
||||
let block = LazyDistribution::from_distribution::<F>(name, version, &source.block);
|
||||
let rolling = LazyBlockRollingDistribution {
|
||||
_6b: LazyDistribution::from_distribution::<F>(
|
||||
&format!("{name}_6b"),
|
||||
version,
|
||||
&source.rolling._6b,
|
||||
),
|
||||
};
|
||||
Self { block, rolling }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::{TxIndex, Version};
|
||||
use schemars::JsonSchema;
|
||||
use vecdb::{LazyVecFrom2, UnaryTransform};
|
||||
|
||||
use crate::internal::{ComputedVecValue, LazyTxDerivedDistribution, TxDerivedDistribution};
|
||||
|
||||
/// Like `LazyPerTxDistribution` but with a lazy-derived distribution
|
||||
/// (transformed from another type's distribution rather than eagerly computed).
|
||||
#[derive(Clone, Traversable)]
|
||||
pub struct LazyPerTxDistributionDerived<T, S1, S2, DSource>
|
||||
where
|
||||
T: ComputedVecValue + JsonSchema,
|
||||
S1: ComputedVecValue,
|
||||
S2: ComputedVecValue,
|
||||
DSource: ComputedVecValue,
|
||||
{
|
||||
pub txindex: LazyVecFrom2<TxIndex, T, TxIndex, S1, TxIndex, S2>,
|
||||
#[traversable(flatten)]
|
||||
pub distribution: LazyTxDerivedDistribution<T, DSource>,
|
||||
}
|
||||
|
||||
impl<T, S1, S2, DSource> LazyPerTxDistributionDerived<T, S1, S2, DSource>
|
||||
where
|
||||
T: ComputedVecValue + JsonSchema + 'static,
|
||||
S1: ComputedVecValue + JsonSchema,
|
||||
S2: ComputedVecValue + JsonSchema,
|
||||
DSource: ComputedVecValue + JsonSchema,
|
||||
{
|
||||
pub(crate) fn new<F: UnaryTransform<DSource, T>>(
|
||||
name: &str,
|
||||
version: Version,
|
||||
txindex: LazyVecFrom2<TxIndex, T, TxIndex, S1, TxIndex, S2>,
|
||||
source_distribution: &TxDerivedDistribution<DSource>,
|
||||
) -> Self {
|
||||
let distribution =
|
||||
LazyTxDerivedDistribution::from_tx_derived::<F>(name, version, source_distribution);
|
||||
Self {
|
||||
txindex,
|
||||
distribution,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,11 @@
|
||||
mod derived;
|
||||
mod distribution;
|
||||
mod lazy_derived;
|
||||
mod lazy_distribution;
|
||||
mod lazy_distribution_derived;
|
||||
|
||||
pub use derived::*;
|
||||
pub use distribution::*;
|
||||
pub use lazy_derived::*;
|
||||
pub use lazy_distribution::*;
|
||||
pub use lazy_distribution_derived::*;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use std::marker::PhantomData;
|
||||
|
||||
use brk_types::{Bitcoin, Cents, Dollars, Sats, StoredF32, StoredI8, StoredU16, StoredU32};
|
||||
use brk_types::{Bitcoin, Cents, Dollars, Sats, StoredF32, StoredI8, StoredU16, StoredU32, StoredU64, VSize, Weight};
|
||||
use vecdb::{BinaryTransform, UnaryTransform, VecValue};
|
||||
|
||||
pub struct Identity<T>(PhantomData<T>);
|
||||
@@ -87,3 +87,21 @@ impl<S, const V: i8> UnaryTransform<S, StoredI8> for ReturnI8<V> {
|
||||
StoredI8::new(V)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct VBytesToWeight;
|
||||
|
||||
impl UnaryTransform<StoredU64, Weight> for VBytesToWeight {
|
||||
#[inline(always)]
|
||||
fn apply(vbytes: StoredU64) -> Weight {
|
||||
Weight::from(VSize::new(*vbytes))
|
||||
}
|
||||
}
|
||||
|
||||
pub struct VSizeToWeight;
|
||||
|
||||
impl UnaryTransform<VSize, Weight> for VSizeToWeight {
|
||||
#[inline(always)]
|
||||
fn apply(vsize: VSize) -> Weight {
|
||||
Weight::from(vsize)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ mod specialized;
|
||||
|
||||
pub use arithmetic::{
|
||||
HalveCents, HalveDollars, HalveSats, HalveSatsToBitcoin, Identity, MaskSats, ReturnF32Tenths,
|
||||
ReturnI8, ReturnU16,
|
||||
ReturnI8, ReturnU16, VBytesToWeight, VSizeToWeight,
|
||||
};
|
||||
pub use bps::{
|
||||
Bp16ToFloat, Bp16ToPercent, Bp32ToFloat, Bp32ToPercent, Bps16ToFloat, Bps16ToPercent, Bps32ToFloat,
|
||||
|
||||
Reference in New Issue
Block a user