global: snapshot

This commit is contained in:
nym21
2025-12-19 15:25:48 +01:00
parent 7c86c803fa
commit 03b83846ef
87 changed files with 2851 additions and 470 deletions
@@ -1,6 +1,7 @@
use brk_error::{Error, Result};
use brk_traversable::Traversable;
use brk_types::{CheckedSub, StoredU64, Version};
use schemars::JsonSchema;
use vecdb::{
AnyStoredVec, Database, EagerVec, Exit, GenericStoredVec, ImportableVec, IterableVec, PcoVec,
VecIndex, VecValue,
@@ -16,7 +17,7 @@ const VERSION: Version = Version::ZERO;
pub struct EagerVecsBuilder<I, T>
where
I: VecIndex,
T: ComputedVecValue,
T: ComputedVecValue + JsonSchema,
{
pub first: Option<Box<EagerVec<PcoVec<I, T>>>>,
pub average: Option<Box<EagerVec<PcoVec<I, T>>>>,
@@ -35,7 +36,7 @@ where
impl<I, T> EagerVecsBuilder<I, T>
where
I: VecIndex,
T: ComputedVecValue,
T: ComputedVecValue + JsonSchema,
{
pub fn forced_import(
db: &Database,
@@ -159,7 +160,12 @@ where
/// Compute percentiles from sorted values (assumes values is already sorted)
fn compute_percentiles_from_sorted(&mut self, index: usize, values: &[T]) -> Result<()> {
if let Some(max) = self.max.as_mut() {
max.truncate_push_at(index, *values.last().ok_or(Error::Internal("Empty values for percentiles"))?)?;
max.truncate_push_at(
index,
*values
.last()
.ok_or(Error::Internal("Empty values for percentiles"))?,
)?;
}
if let Some(pct90) = self.pct90.as_mut() {
pct90.truncate_push_at(index, get_percentile(values, 0.90))?;
@@ -1,5 +1,6 @@
use brk_traversable::Traversable;
use brk_types::Version;
use schemars::JsonSchema;
use vecdb::{FromCoarserIndex, IterableBoxedVec, IterableCloneableVec, LazyVecFrom2, VecIndex};
use crate::grouped::{EagerVecsBuilder, VecBuilderOptions};
@@ -12,7 +13,7 @@ use super::ComputedVecValue;
pub struct LazyVecsBuilder<I, T, S1I, S2T>
where
I: VecIndex,
T: ComputedVecValue,
T: ComputedVecValue + JsonSchema,
S1I: VecIndex,
S2T: ComputedVecValue,
{
@@ -30,7 +31,7 @@ const VERSION: Version = Version::ZERO;
impl<I, T, S1I, S2T> LazyVecsBuilder<I, T, S1I, S2T>
where
I: VecIndex,
T: ComputedVecValue + 'static,
T: ComputedVecValue + JsonSchema + 'static,
S1I: VecIndex + 'static + FromCoarserIndex<I>,
S2T: ComputedVecValue,
{
@@ -4,6 +4,7 @@ use brk_traversable::Traversable;
use brk_types::{
DateIndex, DecadeIndex, MonthIndex, QuarterIndex, SemesterIndex, Version, WeekIndex, YearIndex,
};
use schemars::JsonSchema;
use vecdb::{
AnyExportableVec, Database, EagerVec, Exit, ImportableVec, IterableCloneableVec, IterableVec,
PcoVec,
@@ -16,7 +17,7 @@ use super::{ComputedVecValue, EagerVecsBuilder, Source, VecBuilderOptions};
#[derive(Clone)]
pub struct ComputedVecsFromDateIndex<T>
where
T: ComputedVecValue + PartialOrd,
T: ComputedVecValue + PartialOrd + JsonSchema,
{
pub dateindex: Option<EagerVec<PcoVec<DateIndex, T>>>,
pub dateindex_extra: EagerVecsBuilder<DateIndex, T>,
@@ -32,7 +33,7 @@ const VERSION: Version = Version::ZERO;
impl<T> ComputedVecsFromDateIndex<T>
where
T: ComputedVecValue + 'static,
T: ComputedVecValue + JsonSchema + 'static,
{
#[allow(clippy::too_many_arguments)]
pub fn forced_import(
@@ -149,7 +150,7 @@ where
impl<T> Traversable for ComputedVecsFromDateIndex<T>
where
T: ComputedVecValue,
T: ComputedVecValue + JsonSchema,
{
fn to_tree_node(&self) -> brk_traversable::TreeNode {
let dateindex_extra_node = self.dateindex_extra.to_tree_node();
@@ -5,6 +5,7 @@ use brk_types::{
DateIndex, DecadeIndex, DifficultyEpoch, Height, MonthIndex, QuarterIndex, SemesterIndex,
Version, WeekIndex, YearIndex,
};
use schemars::JsonSchema;
use vecdb::{
AnyExportableVec, Database, EagerVec, Exit, ImportableVec, IterableCloneableVec, IterableVec,
PcoVec,
@@ -22,7 +23,7 @@ use super::{ComputedVecValue, EagerVecsBuilder, VecBuilderOptions};
#[derive(Clone)]
pub struct ComputedVecsFromHeight<T>
where
T: ComputedVecValue + PartialOrd,
T: ComputedVecValue + PartialOrd + JsonSchema,
{
pub height: Option<EagerVec<PcoVec<Height, T>>>,
pub height_extra: EagerVecsBuilder<Height, T>,
@@ -41,7 +42,7 @@ const VERSION: Version = Version::ZERO;
impl<T> ComputedVecsFromHeight<T>
where
T: ComputedVecValue + Ord + From<f64> + 'static,
T: ComputedVecValue + Ord + From<f64> + JsonSchema + 'static,
f64: From<T>,
{
#[allow(clippy::too_many_arguments)]
@@ -202,7 +203,7 @@ where
impl<T> Traversable for ComputedVecsFromHeight<T>
where
T: ComputedVecValue,
T: ComputedVecValue + JsonSchema,
{
fn to_tree_node(&self) -> brk_traversable::TreeNode {
let height_extra_node = self.height_extra.to_tree_node();
@@ -2,6 +2,7 @@ use brk_error::Result;
use brk_traversable::Traversable;
use brk_types::{DifficultyEpoch, Height, Version};
use schemars::JsonSchema;
use vecdb::{AnyExportableVec, Database, EagerVec, Exit, ImportableVec, PcoVec};
use crate::{Indexes, indexes};
@@ -11,7 +12,7 @@ use super::{ComputedVecValue, EagerVecsBuilder, VecBuilderOptions};
#[derive(Clone)]
pub struct ComputedVecsFromHeightStrict<T>
where
T: ComputedVecValue + PartialOrd,
T: ComputedVecValue + PartialOrd + JsonSchema,
{
pub height: EagerVec<PcoVec<Height, T>>,
pub height_extra: EagerVecsBuilder<Height, T>,
@@ -23,7 +24,7 @@ const VERSION: Version = Version::ZERO;
impl<T> ComputedVecsFromHeightStrict<T>
where
T: ComputedVecValue + Ord + From<f64>,
T: ComputedVecValue + Ord + From<f64> + JsonSchema,
f64: From<T>,
{
pub fn forced_import(
@@ -85,7 +86,7 @@ where
impl<T> Traversable for ComputedVecsFromHeightStrict<T>
where
T: ComputedVecValue,
T: ComputedVecValue + JsonSchema,
{
fn to_tree_node(&self) -> brk_traversable::TreeNode {
let height_extra_node = self.height_extra.to_tree_node();
+31 -87
View File
@@ -5,6 +5,7 @@ use brk_types::{
Bitcoin, DateIndex, DecadeIndex, DifficultyEpoch, Dollars, Height, MonthIndex, QuarterIndex,
Sats, SemesterIndex, TxIndex, Version, WeekIndex, YearIndex,
};
use schemars::JsonSchema;
use vecdb::{
AnyExportableVec, AnyVec, CollectableVec, Database, EagerVec, Exit, GenericStoredVec,
ImportableVec, IterableCloneableVec, PcoVec, TypedVecIterator, VecIndex,
@@ -22,7 +23,7 @@ use super::{ComputedVecValue, EagerVecsBuilder, VecBuilderOptions};
#[derive(Clone)]
pub struct ComputedVecsFromTxindex<T>
where
T: ComputedVecValue + PartialOrd,
T: ComputedVecValue + PartialOrd + JsonSchema,
{
pub txindex: Option<Box<EagerVec<PcoVec<TxIndex, T>>>>,
pub height: EagerVecsBuilder<Height, T>,
@@ -41,7 +42,7 @@ const VERSION: Version = Version::ZERO;
impl<T> ComputedVecsFromTxindex<T>
where
T: ComputedVecValue + Ord + From<f64> + 'static,
T: ComputedVecValue + Ord + From<f64> + JsonSchema + 'static,
f64: From<T>,
{
#[allow(clippy::too_many_arguments)]
@@ -256,10 +257,8 @@ impl ComputedVecsFromTxindex<Bitcoin> {
.map(Height::from)
.try_for_each(|height| -> Result<()> {
if let Some(first) = self.height.first.as_mut() {
first.truncate_push(
height,
Bitcoin::from(first_iter.um().get_unwrap(height)),
)?;
first
.truncate_push(height, Bitcoin::from(first_iter.um().get_unwrap(height)))?;
}
if let Some(average) = self.height.average.as_mut() {
average.truncate_push(
@@ -268,28 +267,18 @@ impl ComputedVecsFromTxindex<Bitcoin> {
)?;
}
if let Some(sum) = self.height.sum.as_mut() {
sum.truncate_push(
height,
Bitcoin::from(sum_iter.um().get_unwrap(height)),
)?;
sum.truncate_push(height, Bitcoin::from(sum_iter.um().get_unwrap(height)))?;
}
if let Some(max) = self.height.max.as_mut() {
max.truncate_push(
height,
Bitcoin::from(max_iter.um().get_unwrap(height)),
)?;
max.truncate_push(height, Bitcoin::from(max_iter.um().get_unwrap(height)))?;
}
if let Some(pct90) = self.height.pct90.as_mut() {
pct90.truncate_push(
height,
Bitcoin::from(pct90_iter.um().get_unwrap(height)),
)?;
pct90
.truncate_push(height, Bitcoin::from(pct90_iter.um().get_unwrap(height)))?;
}
if let Some(pct75) = self.height.pct75.as_mut() {
pct75.truncate_push(
height,
Bitcoin::from(pct75_iter.um().get_unwrap(height)),
)?;
pct75
.truncate_push(height, Bitcoin::from(pct75_iter.um().get_unwrap(height)))?;
}
if let Some(median) = self.height.median.as_mut() {
median.truncate_push(
@@ -298,28 +287,18 @@ impl ComputedVecsFromTxindex<Bitcoin> {
)?;
}
if let Some(pct25) = self.height.pct25.as_mut() {
pct25.truncate_push(
height,
Bitcoin::from(pct25_iter.um().get_unwrap(height)),
)?;
pct25
.truncate_push(height, Bitcoin::from(pct25_iter.um().get_unwrap(height)))?;
}
if let Some(pct10) = self.height.pct10.as_mut() {
pct10.truncate_push(
height,
Bitcoin::from(pct10_iter.um().get_unwrap(height)),
)?;
pct10
.truncate_push(height, Bitcoin::from(pct10_iter.um().get_unwrap(height)))?;
}
if let Some(min) = self.height.min.as_mut() {
min.truncate_push(
height,
Bitcoin::from(min_iter.um().get_unwrap(height)),
)?;
min.truncate_push(height, Bitcoin::from(min_iter.um().get_unwrap(height)))?;
}
if let Some(last) = self.height.last.as_mut() {
last.truncate_push(
height,
Bitcoin::from(last_iter.um().get_unwrap(height)),
)?;
last.truncate_push(height, Bitcoin::from(last_iter.um().get_unwrap(height)))?;
}
if let Some(cumulative) = self.height.cumulative.as_mut() {
cumulative.truncate_push(
@@ -381,76 +360,41 @@ impl ComputedVecsFromTxindex<Dollars> {
let price = *close_iter.get_unwrap(height);
if let Some(first) = self.height.first.as_mut() {
first.truncate_push(
height,
price * first_iter.um().get_unwrap(height),
)?;
first.truncate_push(height, price * first_iter.um().get_unwrap(height))?;
}
if let Some(average) = self.height.average.as_mut() {
average.truncate_push(
height,
price * average_iter.um().get_unwrap(height),
)?;
average.truncate_push(height, price * average_iter.um().get_unwrap(height))?;
}
if let Some(sum) = self.height.sum.as_mut() {
sum.truncate_push(
height,
price * sum_iter.um().get_unwrap(height),
)?;
sum.truncate_push(height, price * sum_iter.um().get_unwrap(height))?;
}
if let Some(max) = self.height.max.as_mut() {
max.truncate_push(
height,
price * max_iter.um().get_unwrap(height),
)?;
max.truncate_push(height, price * max_iter.um().get_unwrap(height))?;
}
if let Some(pct90) = self.height.pct90.as_mut() {
pct90.truncate_push(
height,
price * pct90_iter.um().get_unwrap(height),
)?;
pct90.truncate_push(height, price * pct90_iter.um().get_unwrap(height))?;
}
if let Some(pct75) = self.height.pct75.as_mut() {
pct75.truncate_push(
height,
price * pct75_iter.um().get_unwrap(height),
)?;
pct75.truncate_push(height, price * pct75_iter.um().get_unwrap(height))?;
}
if let Some(median) = self.height.median.as_mut() {
median.truncate_push(
height,
price * median_iter.um().get_unwrap(height),
)?;
median.truncate_push(height, price * median_iter.um().get_unwrap(height))?;
}
if let Some(pct25) = self.height.pct25.as_mut() {
pct25.truncate_push(
height,
price * pct25_iter.um().get_unwrap(height),
)?;
pct25.truncate_push(height, price * pct25_iter.um().get_unwrap(height))?;
}
if let Some(pct10) = self.height.pct10.as_mut() {
pct10.truncate_push(
height,
price * pct10_iter.um().get_unwrap(height),
)?;
pct10.truncate_push(height, price * pct10_iter.um().get_unwrap(height))?;
}
if let Some(min) = self.height.min.as_mut() {
min.truncate_push(
height,
price * min_iter.um().get_unwrap(height),
)?;
min.truncate_push(height, price * min_iter.um().get_unwrap(height))?;
}
if let Some(last) = self.height.last.as_mut() {
last.truncate_push(
height,
price * last_iter.um().get_unwrap(height),
)?;
last.truncate_push(height, price * last_iter.um().get_unwrap(height))?;
}
if let Some(cumulative) = self.height.cumulative.as_mut() {
cumulative.truncate_push(
height,
price * cumulative_iter.um().get_unwrap(height),
)?;
cumulative
.truncate_push(height, price * cumulative_iter.um().get_unwrap(height))?;
}
Ok(())
})?;
@@ -463,7 +407,7 @@ impl ComputedVecsFromTxindex<Dollars> {
impl<T> Traversable for ComputedVecsFromTxindex<T>
where
T: ComputedVecValue,
T: ComputedVecValue + JsonSchema,
{
fn to_tree_node(&self) -> brk_traversable::TreeNode {
brk_traversable::TreeNode::Branch(
@@ -1,9 +1,11 @@
use std::mem;
use brk_error::Result;
use brk_traversable::Traversable;
use brk_types::{Date, DateIndex, Dollars, StoredF32, Version};
use vecdb::{PcoVec,
use vecdb::{
AnyStoredVec, AnyVec, BoxedVecIterator, CollectableVec, Database, EagerVec, Exit,
GenericStoredVec, IterableVec, VecIndex,
GenericStoredVec, IterableVec, PcoVec, VecIndex,
};
use crate::{Indexes, grouped::source::Source, indexes, utils::OptionExt};
@@ -109,8 +111,14 @@ impl ComputedStandardDeviationVecsFromDateIndex {
macro_rules! import {
($suffix:expr) => {
ComputedVecsFromDateIndex::forced_import(
db, &format!("{name}_{}", $suffix), Source::Compute, version, indexes, opts,
).unwrap()
db,
&format!("{name}_{}", $suffix),
Source::Compute,
version,
indexes,
opts,
)
.unwrap()
};
}
@@ -183,9 +191,7 @@ impl ComputedStandardDeviationVecsFromDateIndex {
source: &impl CollectableVec<DateIndex, StoredF32>,
price_opt: Option<&impl IterableVec<DateIndex, Dollars>>,
) -> Result<()> {
let sma = sma_opt.unwrap_or_else(|| unsafe {
std::mem::transmute(&self.sma.u().dateindex)
});
let sma = sma_opt.unwrap_or_else(|| unsafe { mem::transmute(&self.sma.u().dateindex) });
let min_date = DateIndex::try_from(Date::MIN_RATIO).unwrap();
@@ -345,7 +351,11 @@ impl ComputedStandardDeviationVecsFromDateIndex {
.try_for_each(|v| v.safe_flush(exit))?;
self.mut_stateful_computed().try_for_each(|v| {
v.compute_rest(starting_indexes, exit, None as Option<&EagerVec<PcoVec<_, _>>>)
v.compute_rest(
starting_indexes,
exit,
None as Option<&EagerVec<PcoVec<_, _>>>,
)
})?;
if let Some(zscore) = self.zscore.as_mut() {
@@ -536,7 +546,6 @@ impl ComputedStandardDeviationVecsFromDateIndex {
fn mut_stateful_date_vecs(
&mut self,
) -> impl Iterator<Item = &mut EagerVec<PcoVec<DateIndex, StoredF32>>> {
self.mut_stateful_computed()
.map(|c| c.dateindex.um())
self.mut_stateful_computed().map(|c| c.dateindex.um())
}
}