computer: snapshot

This commit is contained in:
nym21
2026-03-09 11:16:50 +01:00
parent 0bff57fb43
commit 3e8cf4a975
92 changed files with 853 additions and 825 deletions

View File

@@ -0,0 +1,36 @@
use std::{env, fs, path::Path};
use brk_computer::Computer;
use brk_indexer::Indexer;
use brk_traversable::{Traversable, TreeNode};
pub fn main() -> color_eyre::Result<()> {
color_eyre::install()?;
let tmp = env::temp_dir().join("brk_tree_gen");
fs::create_dir_all(&tmp)?;
let indexer = Indexer::forced_import(&tmp)?;
let computer = Computer::forced_import(&tmp, &indexer)?;
let tree = TreeNode::Branch(
[
("indexed".to_string(), indexer.vecs.to_tree_node()),
("computed".to_string(), computer.to_tree_node()),
]
.into_iter()
.collect(),
)
.merge_branches()
.expect("Tree merge failed");
let json = serde_json::to_string_pretty(&tree)?;
let out_path = Path::new(env!("CARGO_MANIFEST_DIR")).join("tree.json");
fs::write(&out_path, &json)?;
eprintln!("Wrote {} bytes to {}", json.len(), out_path.display());
fs::remove_dir_all(&tmp)?;
Ok(())
}

View File

@@ -18,14 +18,16 @@ impl Vecs {
self.time
.timestamp
.compute(indexer, indexes, starting_indexes, exit)?;
self.lookback
.compute(&self.time, starting_indexes, exit)?;
self.count
.compute(indexer, &self.time, starting_indexes, exit)?;
.compute(indexer, &self.lookback, starting_indexes, exit)?;
self.interval
.compute(indexer, &self.count, starting_indexes, exit)?;
.compute(indexer, &self.lookback, starting_indexes, exit)?;
self.size
.compute(indexer, &self.count, starting_indexes, exit)?;
.compute(indexer, &self.lookback, starting_indexes, exit)?;
self.weight
.compute(indexer, &self.count, starting_indexes, exit)?;
.compute(indexer, &self.lookback, starting_indexes, exit)?;
self.difficulty
.compute(indexer, indexes, starting_indexes, exit)?;
self.halving.compute(indexes, starting_indexes, exit)?;

View File

@@ -1,21 +1,21 @@
use brk_error::Result;
use brk_indexer::Indexer;
use brk_types::{Height, Indexes, StoredU32, Timestamp};
use vecdb::{AnyVec, Cursor, EagerVec, Exit, PcoVec, ReadableVec, VecIndex};
use brk_types::{Indexes, StoredU32};
use vecdb::Exit;
use crate::internal::WindowStarts;
use super::Vecs;
use super::{super::time, Vecs};
use crate::blocks::lookback;
impl Vecs {
pub(crate) fn compute(
&mut self,
indexer: &Indexer,
time: &time::Vecs,
lookback: &lookback::Vecs,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
// Block count height + cumulative first (rolling computed after window starts)
// Block count height + cumulative
self.block_count.height.compute_range(
starting_indexes.height,
&indexer.vecs.blocks.weight,
@@ -28,162 +28,15 @@ impl Vecs {
exit,
)?;
// Compute rolling window starts
self.compute_rolling_start_hours(time, starting_indexes, exit, 1, |s| {
&mut s.height_1h_ago
})?;
self.compute_rolling_start(time, starting_indexes, exit, 1, |s| &mut s.height_24h_ago)?;
self.compute_rolling_start(time, starting_indexes, exit, 3, |s| &mut s.height_3d_ago)?;
self.compute_rolling_start(time, starting_indexes, exit, 7, |s| &mut s.height_1w_ago)?;
self.compute_rolling_start(time, starting_indexes, exit, 8, |s| &mut s.height_8d_ago)?;
self.compute_rolling_start(time, starting_indexes, exit, 9, |s| &mut s.height_9d_ago)?;
self.compute_rolling_start(time, starting_indexes, exit, 12, |s| &mut s.height_12d_ago)?;
self.compute_rolling_start(time, starting_indexes, exit, 13, |s| &mut s.height_13d_ago)?;
self.compute_rolling_start(time, starting_indexes, exit, 14, |s| &mut s.height_2w_ago)?;
self.compute_rolling_start(time, starting_indexes, exit, 21, |s| &mut s.height_21d_ago)?;
self.compute_rolling_start(time, starting_indexes, exit, 26, |s| &mut s.height_26d_ago)?;
self.compute_rolling_start(time, starting_indexes, exit, 30, |s| &mut s.height_1m_ago)?;
self.compute_rolling_start(time, starting_indexes, exit, 34, |s| &mut s.height_34d_ago)?;
self.compute_rolling_start(time, starting_indexes, exit, 55, |s| &mut s.height_55d_ago)?;
self.compute_rolling_start(time, starting_indexes, exit, 60, |s| &mut s.height_2m_ago)?;
self.compute_rolling_start(time, starting_indexes, exit, 63, |s| &mut s.height_9w_ago)?;
self.compute_rolling_start(time, starting_indexes, exit, 84, |s| &mut s.height_12w_ago)?;
self.compute_rolling_start(time, starting_indexes, exit, 89, |s| &mut s.height_89d_ago)?;
self.compute_rolling_start(time, starting_indexes, exit, 90, |s| &mut s.height_3m_ago)?;
self.compute_rolling_start(time, starting_indexes, exit, 98, |s| &mut s.height_14w_ago)?;
self.compute_rolling_start(time, starting_indexes, exit, 111, |s| {
&mut s.height_111d_ago
})?;
self.compute_rolling_start(time, starting_indexes, exit, 144, |s| {
&mut s.height_144d_ago
})?;
self.compute_rolling_start(time, starting_indexes, exit, 180, |s| &mut s.height_6m_ago)?;
self.compute_rolling_start(time, starting_indexes, exit, 182, |s| &mut s.height_26w_ago)?;
self.compute_rolling_start(time, starting_indexes, exit, 200, |s| {
&mut s.height_200d_ago
})?;
self.compute_rolling_start(time, starting_indexes, exit, 270, |s| &mut s.height_9m_ago)?;
self.compute_rolling_start(time, starting_indexes, exit, 350, |s| {
&mut s.height_350d_ago
})?;
self.compute_rolling_start(time, starting_indexes, exit, 360, |s| &mut s.height_12m_ago)?;
self.compute_rolling_start(time, starting_indexes, exit, 365, |s| &mut s.height_1y_ago)?;
self.compute_rolling_start(time, starting_indexes, exit, 420, |s| &mut s.height_14m_ago)?;
self.compute_rolling_start(time, starting_indexes, exit, 730, |s| &mut s.height_2y_ago)?;
self.compute_rolling_start(time, starting_indexes, exit, 780, |s| &mut s.height_26m_ago)?;
self.compute_rolling_start(time, starting_indexes, exit, 1095, |s| &mut s.height_3y_ago)?;
self.compute_rolling_start(time, starting_indexes, exit, 1400, |s| {
&mut s.height_200w_ago
})?;
self.compute_rolling_start(time, starting_indexes, exit, 1460, |s| &mut s.height_4y_ago)?;
self.compute_rolling_start(time, starting_indexes, exit, 1825, |s| &mut s.height_5y_ago)?;
self.compute_rolling_start(time, starting_indexes, exit, 2190, |s| &mut s.height_6y_ago)?;
self.compute_rolling_start(time, starting_indexes, exit, 2920, |s| &mut s.height_8y_ago)?;
self.compute_rolling_start(time, starting_indexes, exit, 3285, |s| &mut s.height_9y_ago)?;
self.compute_rolling_start(time, starting_indexes, exit, 3650, |s| {
&mut s.height_10y_ago
})?;
self.compute_rolling_start(time, starting_indexes, exit, 4380, |s| {
&mut s.height_12y_ago
})?;
self.compute_rolling_start(time, starting_indexes, exit, 5110, |s| {
&mut s.height_14y_ago
})?;
self.compute_rolling_start(time, starting_indexes, exit, 9490, |s| {
&mut s.height_26y_ago
})?;
// Compute rolling window block counts (both block_count's own rolling + separate block_count_sum)
let ws = WindowStarts {
_24h: &self.height_24h_ago,
_1w: &self.height_1w_ago,
_1m: &self.height_1m_ago,
_1y: &self.height_1y_ago,
};
// Rolling window block counts
let ws = lookback.window_starts();
self.block_count.sum.compute_rolling_sum(
starting_indexes.height,
&ws,
&self.block_count.height,
exit,
)?;
self.block_count_sum.compute_rolling_sum(
starting_indexes.height,
&ws,
&self.block_count.height,
exit,
)?;
Ok(())
}
fn compute_rolling_start<F>(
&mut self,
time: &time::Vecs,
starting_indexes: &Indexes,
exit: &Exit,
days: usize,
get_field: F,
) -> Result<()>
where
F: FnOnce(&mut Self) -> &mut EagerVec<PcoVec<Height, Height>>,
{
self.compute_rolling_start_inner(time, starting_indexes, exit, get_field, |t, prev_ts| {
t.difference_in_days_between(prev_ts) >= days
})
}
fn compute_rolling_start_hours<F>(
&mut self,
time: &time::Vecs,
starting_indexes: &Indexes,
exit: &Exit,
hours: usize,
get_field: F,
) -> Result<()>
where
F: FnOnce(&mut Self) -> &mut EagerVec<PcoVec<Height, Height>>,
{
self.compute_rolling_start_inner(time, starting_indexes, exit, get_field, |t, prev_ts| {
t.difference_in_hours_between(prev_ts) >= hours
})
}
fn compute_rolling_start_inner<F, D>(
&mut self,
time: &time::Vecs,
starting_indexes: &Indexes,
exit: &Exit,
get_field: F,
expired: D,
) -> Result<()>
where
F: FnOnce(&mut Self) -> &mut EagerVec<PcoVec<Height, Height>>,
D: Fn(Timestamp, Timestamp) -> bool,
{
let field = get_field(self);
let resume_from = field.len().min(starting_indexes.height.to_usize());
let mut prev = if resume_from > 0 {
field.collect_one_at(resume_from - 1).unwrap()
} else {
Height::ZERO
};
let mut cursor = Cursor::new(&time.timestamp_monotonic);
cursor.advance(prev.to_usize());
let mut prev_ts = cursor.next().unwrap();
Ok(field.compute_transform(
starting_indexes.height,
&time.timestamp_monotonic,
|(h, t, ..)| {
while expired(t, prev_ts) {
prev.increment();
prev_ts = cursor.next().unwrap();
if prev > h {
unreachable!()
}
}
(h, prev)
},
exit,
)?)
}
}

View File

@@ -1,11 +1,11 @@
use brk_error::Result;
use brk_types::Version;
use vecdb::{Database, ImportableVec};
use vecdb::Database;
use super::Vecs;
use crate::{
indexes,
internal::{BlockCountTarget, ComputedFromHeightCumulativeSum, ConstantVecs, RollingWindows},
internal::{BlockCountTarget, ComputedFromHeightCumulativeSum, ConstantVecs},
};
impl Vecs {
@@ -26,55 +26,6 @@ impl Vecs {
version,
indexes,
)?,
height_1h_ago: ImportableVec::forced_import(db, "height_1h_ago", version)?,
height_24h_ago: ImportableVec::forced_import(db, "height_24h_ago", version)?,
height_3d_ago: ImportableVec::forced_import(db, "height_3d_ago", version)?,
height_1w_ago: ImportableVec::forced_import(db, "height_1w_ago", version)?,
height_8d_ago: ImportableVec::forced_import(db, "height_8d_ago", version)?,
height_9d_ago: ImportableVec::forced_import(db, "height_9d_ago", version)?,
height_12d_ago: ImportableVec::forced_import(db, "height_12d_ago", version)?,
height_13d_ago: ImportableVec::forced_import(db, "height_13d_ago", version)?,
height_2w_ago: ImportableVec::forced_import(db, "height_2w_ago", version)?,
height_21d_ago: ImportableVec::forced_import(db, "height_21d_ago", version)?,
height_26d_ago: ImportableVec::forced_import(db, "height_26d_ago", version)?,
height_1m_ago: ImportableVec::forced_import(db, "height_1m_ago", version)?,
height_34d_ago: ImportableVec::forced_import(db, "height_34d_ago", version)?,
height_55d_ago: ImportableVec::forced_import(db, "height_55d_ago", version)?,
height_2m_ago: ImportableVec::forced_import(db, "height_2m_ago", version)?,
height_9w_ago: ImportableVec::forced_import(db, "height_9w_ago", version)?,
height_12w_ago: ImportableVec::forced_import(db, "height_12w_ago", version)?,
height_89d_ago: ImportableVec::forced_import(db, "height_89d_ago", version)?,
height_3m_ago: ImportableVec::forced_import(db, "height_3m_ago", version)?,
height_14w_ago: ImportableVec::forced_import(db, "height_14w_ago", version)?,
height_111d_ago: ImportableVec::forced_import(db, "height_111d_ago", version)?,
height_144d_ago: ImportableVec::forced_import(db, "height_144d_ago", version)?,
height_6m_ago: ImportableVec::forced_import(db, "height_6m_ago", version)?,
height_26w_ago: ImportableVec::forced_import(db, "height_26w_ago", version)?,
height_200d_ago: ImportableVec::forced_import(db, "height_200d_ago", version)?,
height_9m_ago: ImportableVec::forced_import(db, "height_9m_ago", version)?,
height_350d_ago: ImportableVec::forced_import(db, "height_350d_ago", version)?,
height_12m_ago: ImportableVec::forced_import(db, "height_12m_ago", version)?,
height_1y_ago: ImportableVec::forced_import(db, "height_1y_ago", version)?,
height_14m_ago: ImportableVec::forced_import(db, "height_14m_ago", version)?,
height_2y_ago: ImportableVec::forced_import(db, "height_2y_ago", version)?,
height_26m_ago: ImportableVec::forced_import(db, "height_26m_ago", version)?,
height_3y_ago: ImportableVec::forced_import(db, "height_3y_ago", version)?,
height_200w_ago: ImportableVec::forced_import(db, "height_200w_ago", version)?,
height_4y_ago: ImportableVec::forced_import(db, "height_4y_ago", version)?,
height_5y_ago: ImportableVec::forced_import(db, "height_5y_ago", version)?,
height_6y_ago: ImportableVec::forced_import(db, "height_6y_ago", version)?,
height_8y_ago: ImportableVec::forced_import(db, "height_8y_ago", version)?,
height_9y_ago: ImportableVec::forced_import(db, "height_9y_ago", version)?,
height_10y_ago: ImportableVec::forced_import(db, "height_10y_ago", version)?,
height_12y_ago: ImportableVec::forced_import(db, "height_12y_ago", version)?,
height_14y_ago: ImportableVec::forced_import(db, "height_14y_ago", version)?,
height_26y_ago: ImportableVec::forced_import(db, "height_26y_ago", version)?,
block_count_sum: RollingWindows::forced_import(
db,
"block_count_sum",
version,
indexes,
)?,
})
}
}

View File

@@ -1,117 +1,11 @@
use brk_traversable::Traversable;
use brk_types::{Height, StoredU32, StoredU64};
use vecdb::{EagerVec, PcoVec, Rw, StorageMode};
use brk_types::{StoredU32, StoredU64};
use vecdb::{Rw, StorageMode};
use crate::internal::{
ComputedFromHeightCumulativeSum, ConstantVecs, RollingWindows, WindowStarts,
};
use crate::internal::{ComputedFromHeightCumulativeSum, ConstantVecs};
#[derive(Traversable)]
pub struct Vecs<M: StorageMode = Rw> {
pub block_count_target: ConstantVecs<StoredU64>,
pub block_count: ComputedFromHeightCumulativeSum<StoredU32, M>,
pub block_count_sum: RollingWindows<StoredU32, M>,
pub height_1h_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>,
pub height_24h_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 1d
pub height_3d_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>,
pub height_1w_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 7d
pub height_8d_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>,
pub height_9d_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>,
pub height_12d_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>,
pub height_13d_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>,
pub height_2w_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 14d
pub height_21d_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>,
pub height_26d_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>,
pub height_1m_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 30d
pub height_34d_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>,
pub height_55d_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>,
pub height_2m_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 60d
pub height_9w_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 63d
pub height_12w_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 84d
pub height_89d_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>,
pub height_3m_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 90d
pub height_14w_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 98d
pub height_111d_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>,
pub height_144d_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>,
pub height_6m_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 180d
pub height_26w_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 182d
pub height_200d_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>,
pub height_9m_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 270d
pub height_350d_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>,
pub height_12m_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 360d
pub height_1y_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 365d
pub height_14m_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 420d
pub height_2y_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 730d
pub height_26m_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 780d
pub height_3y_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 1095d
pub height_200w_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 1400d
pub height_4y_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 1460d
pub height_5y_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 1825d
pub height_6y_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 2190d
pub height_8y_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 2920d
pub height_9y_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 3285d
pub height_10y_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 3650d
pub height_12y_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 4380d
pub height_14y_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 5110d
pub height_26y_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 9490d
}
impl Vecs {
pub fn window_starts(&self) -> WindowStarts<'_> {
WindowStarts {
_24h: &self.height_24h_ago,
_1w: &self.height_1w_ago,
_1m: &self.height_1m_ago,
_1y: &self.height_1y_ago,
}
}
pub fn start_vec(&self, days: usize) -> &EagerVec<PcoVec<Height, Height>> {
match days {
1 => &self.height_24h_ago,
3 => &self.height_3d_ago,
7 => &self.height_1w_ago,
8 => &self.height_8d_ago,
9 => &self.height_9d_ago,
12 => &self.height_12d_ago,
13 => &self.height_13d_ago,
14 => &self.height_2w_ago,
21 => &self.height_21d_ago,
26 => &self.height_26d_ago,
30 => &self.height_1m_ago,
34 => &self.height_34d_ago,
55 => &self.height_55d_ago,
60 => &self.height_2m_ago,
63 => &self.height_9w_ago,
84 => &self.height_12w_ago,
89 => &self.height_89d_ago,
90 => &self.height_3m_ago,
98 => &self.height_14w_ago,
111 => &self.height_111d_ago,
144 => &self.height_144d_ago,
180 => &self.height_6m_ago,
182 => &self.height_26w_ago,
200 => &self.height_200d_ago,
270 => &self.height_9m_ago,
350 => &self.height_350d_ago,
360 => &self.height_12m_ago,
365 => &self.height_1y_ago,
420 => &self.height_14m_ago,
730 => &self.height_2y_ago,
780 => &self.height_26m_ago,
1095 => &self.height_3y_ago,
1400 => &self.height_200w_ago,
1460 => &self.height_4y_ago,
1825 => &self.height_5y_ago,
2190 => &self.height_6y_ago,
2920 => &self.height_8y_ago,
3285 => &self.height_9y_ago,
3650 => &self.height_10y_ago,
4380 => &self.height_12y_ago,
5110 => &self.height_14y_ago,
9490 => &self.height_26y_ago,
_ => panic!("No start vec for {days} days"),
}
}
}

View File

@@ -10,7 +10,8 @@ use crate::{
};
use super::{
CountVecs, DifficultyVecs, HalvingVecs, IntervalVecs, SizeVecs, TimeVecs, Vecs, WeightVecs,
CountVecs, DifficultyVecs, HalvingVecs, IntervalVecs, LookbackVecs, SizeVecs, TimeVecs, Vecs,
WeightVecs,
};
impl Vecs {
@@ -24,6 +25,7 @@ impl Vecs {
let version = parent_version;
let count = CountVecs::forced_import(&db, version, indexes)?;
let lookback = LookbackVecs::forced_import(&db, version)?;
let interval = IntervalVecs::forced_import(&db, version, indexes)?;
let size = SizeVecs::forced_import(&db, version, indexes)?;
let weight = WeightVecs::forced_import(&db, version, indexes)?;
@@ -34,6 +36,7 @@ impl Vecs {
let this = Self {
db,
count,
lookback,
interval,
size,
weight,

View File

@@ -10,12 +10,12 @@ impl Vecs {
pub(crate) fn compute(
&mut self,
indexer: &Indexer,
count_vecs: &blocks::CountVecs,
lookback: &blocks::LookbackVecs,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
let mut prev_timestamp = None;
let window_starts = count_vecs.window_starts();
let window_starts = lookback.window_starts();
self.0
.compute(starting_indexes.height, &window_starts, exit, |vec| {
vec.compute_transform(

View File

@@ -0,0 +1,306 @@
use brk_error::Result;
use brk_traversable::Traversable;
use brk_types::{Height, Indexes, Timestamp, Version};
use vecdb::{AnyVec, Cursor, Database, EagerVec, Exit, ImportableVec, PcoVec, ReadableVec, Rw, StorageMode, VecIndex};
use crate::internal::WindowStarts;
use super::time;
#[derive(Traversable)]
pub struct Vecs<M: StorageMode = Rw> {
pub height_1h_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>,
pub height_24h_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 1d
pub height_3d_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>,
pub height_1w_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 7d
pub height_8d_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>,
pub height_9d_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>,
pub height_12d_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>,
pub height_13d_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>,
pub height_2w_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 14d
pub height_21d_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>,
pub height_26d_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>,
pub height_1m_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 30d
pub height_34d_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>,
pub height_55d_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>,
pub height_2m_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 60d
pub height_9w_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 63d
pub height_12w_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 84d
pub height_89d_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>,
pub height_3m_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 90d
pub height_14w_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 98d
pub height_111d_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>,
pub height_144d_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>,
pub height_6m_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 180d
pub height_26w_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 182d
pub height_200d_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>,
pub height_9m_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 270d
pub height_350d_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>,
pub height_12m_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 360d
pub height_1y_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 365d
pub height_14m_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 420d
pub height_2y_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 730d
pub height_26m_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 780d
pub height_3y_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 1095d
pub height_200w_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 1400d
pub height_4y_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 1460d
pub height_5y_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 1825d
pub height_6y_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 2190d
pub height_8y_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 2920d
pub height_9y_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 3285d
pub height_10y_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 3650d
pub height_12y_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 4380d
pub height_14y_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 5110d
pub height_26y_ago: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 9490d
}
impl Vecs {
pub(crate) fn forced_import(db: &Database, version: Version) -> Result<Self> {
Ok(Self {
height_1h_ago: ImportableVec::forced_import(db, "height_1h_ago", version)?,
height_24h_ago: ImportableVec::forced_import(db, "height_24h_ago", version)?,
height_3d_ago: ImportableVec::forced_import(db, "height_3d_ago", version)?,
height_1w_ago: ImportableVec::forced_import(db, "height_1w_ago", version)?,
height_8d_ago: ImportableVec::forced_import(db, "height_8d_ago", version)?,
height_9d_ago: ImportableVec::forced_import(db, "height_9d_ago", version)?,
height_12d_ago: ImportableVec::forced_import(db, "height_12d_ago", version)?,
height_13d_ago: ImportableVec::forced_import(db, "height_13d_ago", version)?,
height_2w_ago: ImportableVec::forced_import(db, "height_2w_ago", version)?,
height_21d_ago: ImportableVec::forced_import(db, "height_21d_ago", version)?,
height_26d_ago: ImportableVec::forced_import(db, "height_26d_ago", version)?,
height_1m_ago: ImportableVec::forced_import(db, "height_1m_ago", version)?,
height_34d_ago: ImportableVec::forced_import(db, "height_34d_ago", version)?,
height_55d_ago: ImportableVec::forced_import(db, "height_55d_ago", version)?,
height_2m_ago: ImportableVec::forced_import(db, "height_2m_ago", version)?,
height_9w_ago: ImportableVec::forced_import(db, "height_9w_ago", version)?,
height_12w_ago: ImportableVec::forced_import(db, "height_12w_ago", version)?,
height_89d_ago: ImportableVec::forced_import(db, "height_89d_ago", version)?,
height_3m_ago: ImportableVec::forced_import(db, "height_3m_ago", version)?,
height_14w_ago: ImportableVec::forced_import(db, "height_14w_ago", version)?,
height_111d_ago: ImportableVec::forced_import(db, "height_111d_ago", version)?,
height_144d_ago: ImportableVec::forced_import(db, "height_144d_ago", version)?,
height_6m_ago: ImportableVec::forced_import(db, "height_6m_ago", version)?,
height_26w_ago: ImportableVec::forced_import(db, "height_26w_ago", version)?,
height_200d_ago: ImportableVec::forced_import(db, "height_200d_ago", version)?,
height_9m_ago: ImportableVec::forced_import(db, "height_9m_ago", version)?,
height_350d_ago: ImportableVec::forced_import(db, "height_350d_ago", version)?,
height_12m_ago: ImportableVec::forced_import(db, "height_12m_ago", version)?,
height_1y_ago: ImportableVec::forced_import(db, "height_1y_ago", version)?,
height_14m_ago: ImportableVec::forced_import(db, "height_14m_ago", version)?,
height_2y_ago: ImportableVec::forced_import(db, "height_2y_ago", version)?,
height_26m_ago: ImportableVec::forced_import(db, "height_26m_ago", version)?,
height_3y_ago: ImportableVec::forced_import(db, "height_3y_ago", version)?,
height_200w_ago: ImportableVec::forced_import(db, "height_200w_ago", version)?,
height_4y_ago: ImportableVec::forced_import(db, "height_4y_ago", version)?,
height_5y_ago: ImportableVec::forced_import(db, "height_5y_ago", version)?,
height_6y_ago: ImportableVec::forced_import(db, "height_6y_ago", version)?,
height_8y_ago: ImportableVec::forced_import(db, "height_8y_ago", version)?,
height_9y_ago: ImportableVec::forced_import(db, "height_9y_ago", version)?,
height_10y_ago: ImportableVec::forced_import(db, "height_10y_ago", version)?,
height_12y_ago: ImportableVec::forced_import(db, "height_12y_ago", version)?,
height_14y_ago: ImportableVec::forced_import(db, "height_14y_ago", version)?,
height_26y_ago: ImportableVec::forced_import(db, "height_26y_ago", version)?,
})
}
pub fn window_starts(&self) -> WindowStarts<'_> {
WindowStarts {
_24h: &self.height_24h_ago,
_1w: &self.height_1w_ago,
_1m: &self.height_1m_ago,
_1y: &self.height_1y_ago,
}
}
pub fn start_vec(&self, days: usize) -> &EagerVec<PcoVec<Height, Height>> {
match days {
1 => &self.height_24h_ago,
3 => &self.height_3d_ago,
7 => &self.height_1w_ago,
8 => &self.height_8d_ago,
9 => &self.height_9d_ago,
12 => &self.height_12d_ago,
13 => &self.height_13d_ago,
14 => &self.height_2w_ago,
21 => &self.height_21d_ago,
26 => &self.height_26d_ago,
30 => &self.height_1m_ago,
34 => &self.height_34d_ago,
55 => &self.height_55d_ago,
60 => &self.height_2m_ago,
63 => &self.height_9w_ago,
84 => &self.height_12w_ago,
89 => &self.height_89d_ago,
90 => &self.height_3m_ago,
98 => &self.height_14w_ago,
111 => &self.height_111d_ago,
144 => &self.height_144d_ago,
180 => &self.height_6m_ago,
182 => &self.height_26w_ago,
200 => &self.height_200d_ago,
270 => &self.height_9m_ago,
350 => &self.height_350d_ago,
360 => &self.height_12m_ago,
365 => &self.height_1y_ago,
420 => &self.height_14m_ago,
730 => &self.height_2y_ago,
780 => &self.height_26m_ago,
1095 => &self.height_3y_ago,
1400 => &self.height_200w_ago,
1460 => &self.height_4y_ago,
1825 => &self.height_5y_ago,
2190 => &self.height_6y_ago,
2920 => &self.height_8y_ago,
3285 => &self.height_9y_ago,
3650 => &self.height_10y_ago,
4380 => &self.height_12y_ago,
5110 => &self.height_14y_ago,
9490 => &self.height_26y_ago,
_ => panic!("No start vec for {days} days"),
}
}
pub(crate) fn compute(
&mut self,
time: &time::Vecs,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
self.compute_rolling_start_hours(time, starting_indexes, exit, 1, |s| {
&mut s.height_1h_ago
})?;
self.compute_rolling_start(time, starting_indexes, exit, 1, |s| &mut s.height_24h_ago)?;
self.compute_rolling_start(time, starting_indexes, exit, 3, |s| &mut s.height_3d_ago)?;
self.compute_rolling_start(time, starting_indexes, exit, 7, |s| &mut s.height_1w_ago)?;
self.compute_rolling_start(time, starting_indexes, exit, 8, |s| &mut s.height_8d_ago)?;
self.compute_rolling_start(time, starting_indexes, exit, 9, |s| &mut s.height_9d_ago)?;
self.compute_rolling_start(time, starting_indexes, exit, 12, |s| &mut s.height_12d_ago)?;
self.compute_rolling_start(time, starting_indexes, exit, 13, |s| &mut s.height_13d_ago)?;
self.compute_rolling_start(time, starting_indexes, exit, 14, |s| &mut s.height_2w_ago)?;
self.compute_rolling_start(time, starting_indexes, exit, 21, |s| &mut s.height_21d_ago)?;
self.compute_rolling_start(time, starting_indexes, exit, 26, |s| &mut s.height_26d_ago)?;
self.compute_rolling_start(time, starting_indexes, exit, 30, |s| &mut s.height_1m_ago)?;
self.compute_rolling_start(time, starting_indexes, exit, 34, |s| &mut s.height_34d_ago)?;
self.compute_rolling_start(time, starting_indexes, exit, 55, |s| &mut s.height_55d_ago)?;
self.compute_rolling_start(time, starting_indexes, exit, 60, |s| &mut s.height_2m_ago)?;
self.compute_rolling_start(time, starting_indexes, exit, 63, |s| &mut s.height_9w_ago)?;
self.compute_rolling_start(time, starting_indexes, exit, 84, |s| &mut s.height_12w_ago)?;
self.compute_rolling_start(time, starting_indexes, exit, 89, |s| &mut s.height_89d_ago)?;
self.compute_rolling_start(time, starting_indexes, exit, 90, |s| &mut s.height_3m_ago)?;
self.compute_rolling_start(time, starting_indexes, exit, 98, |s| &mut s.height_14w_ago)?;
self.compute_rolling_start(time, starting_indexes, exit, 111, |s| {
&mut s.height_111d_ago
})?;
self.compute_rolling_start(time, starting_indexes, exit, 144, |s| {
&mut s.height_144d_ago
})?;
self.compute_rolling_start(time, starting_indexes, exit, 180, |s| &mut s.height_6m_ago)?;
self.compute_rolling_start(time, starting_indexes, exit, 182, |s| &mut s.height_26w_ago)?;
self.compute_rolling_start(time, starting_indexes, exit, 200, |s| {
&mut s.height_200d_ago
})?;
self.compute_rolling_start(time, starting_indexes, exit, 270, |s| &mut s.height_9m_ago)?;
self.compute_rolling_start(time, starting_indexes, exit, 350, |s| {
&mut s.height_350d_ago
})?;
self.compute_rolling_start(time, starting_indexes, exit, 360, |s| &mut s.height_12m_ago)?;
self.compute_rolling_start(time, starting_indexes, exit, 365, |s| &mut s.height_1y_ago)?;
self.compute_rolling_start(time, starting_indexes, exit, 420, |s| &mut s.height_14m_ago)?;
self.compute_rolling_start(time, starting_indexes, exit, 730, |s| &mut s.height_2y_ago)?;
self.compute_rolling_start(time, starting_indexes, exit, 780, |s| &mut s.height_26m_ago)?;
self.compute_rolling_start(time, starting_indexes, exit, 1095, |s| &mut s.height_3y_ago)?;
self.compute_rolling_start(time, starting_indexes, exit, 1400, |s| {
&mut s.height_200w_ago
})?;
self.compute_rolling_start(time, starting_indexes, exit, 1460, |s| &mut s.height_4y_ago)?;
self.compute_rolling_start(time, starting_indexes, exit, 1825, |s| &mut s.height_5y_ago)?;
self.compute_rolling_start(time, starting_indexes, exit, 2190, |s| &mut s.height_6y_ago)?;
self.compute_rolling_start(time, starting_indexes, exit, 2920, |s| &mut s.height_8y_ago)?;
self.compute_rolling_start(time, starting_indexes, exit, 3285, |s| &mut s.height_9y_ago)?;
self.compute_rolling_start(time, starting_indexes, exit, 3650, |s| {
&mut s.height_10y_ago
})?;
self.compute_rolling_start(time, starting_indexes, exit, 4380, |s| {
&mut s.height_12y_ago
})?;
self.compute_rolling_start(time, starting_indexes, exit, 5110, |s| {
&mut s.height_14y_ago
})?;
self.compute_rolling_start(time, starting_indexes, exit, 9490, |s| {
&mut s.height_26y_ago
})?;
Ok(())
}
fn compute_rolling_start<F>(
&mut self,
time: &time::Vecs,
starting_indexes: &Indexes,
exit: &Exit,
days: usize,
get_field: F,
) -> Result<()>
where
F: FnOnce(&mut Self) -> &mut EagerVec<PcoVec<Height, Height>>,
{
self.compute_rolling_start_inner(time, starting_indexes, exit, get_field, |t, prev_ts| {
t.difference_in_days_between(prev_ts) >= days
})
}
fn compute_rolling_start_hours<F>(
&mut self,
time: &time::Vecs,
starting_indexes: &Indexes,
exit: &Exit,
hours: usize,
get_field: F,
) -> Result<()>
where
F: FnOnce(&mut Self) -> &mut EagerVec<PcoVec<Height, Height>>,
{
self.compute_rolling_start_inner(time, starting_indexes, exit, get_field, |t, prev_ts| {
t.difference_in_hours_between(prev_ts) >= hours
})
}
fn compute_rolling_start_inner<F, D>(
&mut self,
time: &time::Vecs,
starting_indexes: &Indexes,
exit: &Exit,
get_field: F,
expired: D,
) -> Result<()>
where
F: FnOnce(&mut Self) -> &mut EagerVec<PcoVec<Height, Height>>,
D: Fn(Timestamp, Timestamp) -> bool,
{
let field = get_field(self);
let resume_from = field.len().min(starting_indexes.height.to_usize());
let mut prev = if resume_from > 0 {
field.collect_one_at(resume_from - 1).unwrap()
} else {
Height::ZERO
};
let mut cursor = Cursor::new(&time.timestamp_monotonic);
cursor.advance(prev.to_usize());
let mut prev_ts = cursor.next().unwrap();
Ok(field.compute_transform(
starting_indexes.height,
&time.timestamp_monotonic,
|(h, t, ..)| {
while expired(t, prev_ts) {
prev.increment();
prev_ts = cursor.next().unwrap();
if prev > h {
unreachable!()
}
}
(h, prev)
},
exit,
)?)
}
}

View File

@@ -2,6 +2,7 @@ pub mod count;
pub mod difficulty;
pub mod halving;
pub mod interval;
pub mod lookback;
pub mod size;
pub mod time;
pub mod weight;
@@ -16,6 +17,7 @@ pub use count::Vecs as CountVecs;
pub use difficulty::Vecs as DifficultyVecs;
pub use halving::Vecs as HalvingVecs;
pub use interval::Vecs as IntervalVecs;
pub use lookback::Vecs as LookbackVecs;
pub use size::Vecs as SizeVecs;
pub use time::Vecs as TimeVecs;
pub use weight::Vecs as WeightVecs;
@@ -46,6 +48,7 @@ pub struct Vecs<M: StorageMode = Rw> {
pub(crate) db: Database,
pub count: CountVecs<M>,
pub lookback: LookbackVecs<M>,
pub interval: IntervalVecs<M>,
#[traversable(flatten)]
pub size: SizeVecs<M>,

View File

@@ -10,11 +10,11 @@ impl Vecs {
pub(crate) fn compute(
&mut self,
indexer: &Indexer,
count_vecs: &blocks::CountVecs,
lookback: &blocks::LookbackVecs,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
let window_starts = count_vecs.window_starts();
let window_starts = lookback.window_starts();
// vbytes = floor(weight / 4), stored at height level
self.vbytes

View File

@@ -10,11 +10,11 @@ impl Vecs {
pub(crate) fn compute(
&mut self,
indexer: &Indexer,
count_vecs: &blocks::CountVecs,
lookback: &blocks::LookbackVecs,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
let window_starts = count_vecs.window_starts();
let window_starts = lookback.window_starts();
self.weight.compute(
starting_indexes.height,

View File

@@ -13,7 +13,7 @@ impl Vecs {
distribution: &distribution::Vecs,
exit: &Exit,
) -> Result<()> {
let window_starts = blocks.count.window_starts();
let window_starts = blocks.lookback.window_starts();
let all_metrics = &distribution.utxo_cohorts.all.metrics;
let circulating_supply = &all_metrics.supply.total.sats.height;

View File

@@ -16,7 +16,7 @@ impl Vecs {
) -> Result<()> {
self.vocdd_median_1y.compute_rolling_median_from_starts(
starting_indexes.height,
&blocks.count.height_1y_ago,
&blocks.lookback.height_1y_ago,
&value.vocdd.height,
exit,
)?;

View File

@@ -3,7 +3,7 @@ use brk_types::Version;
use vecdb::Database;
use super::Vecs;
use crate::{indexes, internal::ValueFromHeight};
use crate::{indexes, internal::AmountFromHeight};
impl Vecs {
pub(crate) fn forced_import(
@@ -12,8 +12,13 @@ impl Vecs {
indexes: &indexes::Vecs,
) -> Result<Self> {
Ok(Self {
vaulted_supply: ValueFromHeight::forced_import(db, "vaulted_supply", version, indexes)?,
active_supply: ValueFromHeight::forced_import(db, "active_supply", version, indexes)?,
vaulted_supply: AmountFromHeight::forced_import(
db,
"vaulted_supply",
version,
indexes,
)?,
active_supply: AmountFromHeight::forced_import(db, "active_supply", version, indexes)?,
})
}
}

View File

@@ -1,10 +1,10 @@
use brk_traversable::Traversable;
use vecdb::{Rw, StorageMode};
use crate::internal::ValueFromHeight;
use crate::internal::AmountFromHeight;
#[derive(Traversable)]
pub struct Vecs<M: StorageMode = Rw> {
pub vaulted_supply: ValueFromHeight<M>,
pub active_supply: ValueFromHeight<M>,
pub vaulted_supply: AmountFromHeight<M>,
pub active_supply: AmountFromHeight<M>,
}

View File

@@ -16,7 +16,7 @@ impl Vecs {
activity: &activity::Vecs,
exit: &Exit,
) -> Result<()> {
let window_starts = blocks.count.window_starts();
let window_starts = blocks.lookback.window_starts();
let all_metrics = &distribution.utxo_cohorts.all.metrics;
let coinblocks_destroyed = &all_metrics.activity.coinblocks_destroyed;

View File

@@ -98,7 +98,7 @@ impl AddressCohorts {
self.par_iter_mut().try_for_each(|v| {
v.addr_count_delta.compute(
starting_indexes.height,
&blocks.count.height_1m_ago,
&blocks.lookback.height_1m_ago,
&v.addr_count.height,
exit,
)

View File

@@ -8,7 +8,9 @@ use brk_error::Result;
use brk_traversable::Traversable;
use brk_types::{Dollars, Height, Indexes, Sats, Version};
use rayon::prelude::*;
use vecdb::{AnyStoredVec, Database, Exit, ReadOnlyClone, ReadableVec, Rw, StorageMode, WritableVec};
use vecdb::{
AnyStoredVec, Database, Exit, ReadOnlyClone, ReadableVec, Rw, StorageMode, WritableVec,
};
use crate::{
blocks,
@@ -22,7 +24,7 @@ use crate::{
state::UTXOCohortState,
},
indexes,
internal::ValueFromHeight,
internal::AmountFromHeight,
prices,
};
@@ -47,7 +49,7 @@ pub struct UTXOCohorts<M: StorageMode = Rw> {
#[traversable(rename = "type")]
pub type_: BySpendableType<UTXOCohortVecs<MinimalCohortMetrics<M>>>,
pub profitability: ProfitabilityMetrics<M>,
pub matured: ByAgeRange<ValueFromHeight<M>>,
pub matured: ByAgeRange<AmountFromHeight<M>>,
#[traversable(skip)]
pub(super) fenwick: CostBasisFenwick,
/// Cached partition_point positions for tick_tock boundary searches.
@@ -226,8 +228,10 @@ impl UTXOCohorts<Rw> {
let lt_amount = ByLowerThanAmount::try_new(&minimal_no_state)?;
let ge_amount = ByGreatEqualAmount::try_new(&minimal_no_state)?;
let matured = ByAgeRange::try_new(&|_f: Filter, name: &'static str| -> Result<ValueFromHeight> {
ValueFromHeight::forced_import(db, &format!("utxo_{name}_matured"), v, indexes)
let matured = ByAgeRange::try_new(&|_f: Filter,
name: &'static str|
-> Result<AmountFromHeight> {
AmountFromHeight::forced_import(db, &format!("utxo_{name}_matured"), v, indexes)
})?;
Ok(Self {
@@ -257,7 +261,10 @@ impl UTXOCohorts<Rw> {
return;
}
let Self {
sth, fenwick, age_range, ..
sth,
fenwick,
age_range,
..
} = self;
fenwick.compute_is_sth(&sth.metrics.filter, age_range.iter().map(|v| v.filter()));
@@ -334,9 +341,7 @@ impl UTXOCohorts<Rw> {
/// Sequential mutable iterator over all separate (stateful) cohorts.
/// Use instead of `par_iter_separate_mut` when per-item work is trivial.
pub(crate) fn iter_separate_mut(
&mut self,
) -> impl Iterator<Item = &mut dyn DynCohortVecs> {
pub(crate) fn iter_separate_mut(&mut self) -> impl Iterator<Item = &mut dyn DynCohortVecs> {
let Self {
age_range,
epoch,
@@ -575,35 +580,20 @@ impl UTXOCohorts<Rw> {
}),
Box::new(|| {
age_range.par_iter_mut().try_for_each(|v| {
v.metrics.compute_rest_part2(
blocks,
prices,
starting_indexes,
ss,
exit,
)
v.metrics
.compute_rest_part2(blocks, prices, starting_indexes, ss, exit)
})
}),
Box::new(|| {
max_age.par_iter_mut().try_for_each(|v| {
v.metrics.compute_rest_part2(
blocks,
prices,
starting_indexes,
ss,
exit,
)
v.metrics
.compute_rest_part2(blocks, prices, starting_indexes, ss, exit)
})
}),
Box::new(|| {
min_age.par_iter_mut().try_for_each(|v| {
v.metrics.compute_rest_part2(
blocks,
prices,
starting_indexes,
ss,
exit,
)
v.metrics
.compute_rest_part2(blocks, prices, starting_indexes, ss, exit)
})
}),
Box::new(|| {
@@ -613,24 +603,14 @@ impl UTXOCohorts<Rw> {
}),
Box::new(|| {
epoch.par_iter_mut().try_for_each(|v| {
v.metrics.compute_rest_part2(
blocks,
prices,
starting_indexes,
ss,
exit,
)
v.metrics
.compute_rest_part2(blocks, prices, starting_indexes, ss, exit)
})
}),
Box::new(|| {
class.par_iter_mut().try_for_each(|v| {
v.metrics.compute_rest_part2(
blocks,
prices,
starting_indexes,
ss,
exit,
)
v.metrics
.compute_rest_part2(blocks, prices, starting_indexes, ss, exit)
})
}),
Box::new(|| {
@@ -695,9 +675,8 @@ impl UTXOCohorts<Rw> {
}
vecs.extend(self.profitability.collect_all_vecs_mut());
for v in self.matured.iter_mut() {
let base = &mut v.base;
vecs.push(&mut base.sats.height);
vecs.push(&mut base.cents.height);
vecs.push(&mut v.sats.height);
vecs.push(&mut v.cents.height);
}
vecs.into_par_iter()
}
@@ -712,13 +691,23 @@ impl UTXOCohorts<Rw> {
pub(crate) fn min_separate_stateful_height_len(&self) -> Height {
self.iter_separate()
.map(|v| Height::from(v.min_stateful_height_len()))
.chain(self.matured.iter().map(|v| Height::from(v.min_stateful_len())))
.chain(
self.matured
.iter()
.map(|v| Height::from(v.min_stateful_len())),
)
.min()
.unwrap_or_default()
.min(Height::from(self.profitability.min_stateful_height_len()))
.min(Height::from(self.all.metrics.realized.min_stateful_height_len()))
.min(Height::from(self.sth.metrics.realized.min_stateful_height_len()))
.min(Height::from(self.lth.metrics.realized.min_stateful_height_len()))
.min(Height::from(
self.all.metrics.realized.min_stateful_height_len(),
))
.min(Height::from(
self.sth.metrics.realized.min_stateful_height_len(),
))
.min(Height::from(
self.lth.metrics.realized.min_stateful_height_len(),
))
}
/// Import state for all separate cohorts at or before given height.
@@ -770,7 +759,11 @@ impl UTXOCohorts<Rw> {
/// Called during the block loop after separate cohorts' truncate_push but before reset.
pub(crate) fn push_overlapping_realized_full(&mut self, height: Height) -> Result<()> {
let Self {
all, sth, lth, age_range, ..
all,
sth,
lth,
age_range,
..
} = self;
let sth_filter = &sth.metrics.filter;

View File

@@ -64,7 +64,7 @@ impl ActivityCore {
) -> Result<()> {
self.sent_sum.compute_rolling_sum(
starting_indexes.height,
&blocks.count.height_24h_ago,
&blocks.lookback.height_24h_ago,
&self.sent.height,
exit,
)?;

View File

@@ -21,6 +21,7 @@ pub struct ActivityFull<M: StorageMode = Rw> {
pub coindays_destroyed_cumulative: ComputedFromHeight<StoredF64, M>,
pub coindays_destroyed_sum: RollingWindows<StoredF64, M>,
#[traversable(rename = "sent_sum")]
pub sent_sum_extended: RollingWindowsFrom1w<Sats, M>,
}
@@ -72,7 +73,7 @@ impl ActivityFull {
exit,
)?;
let window_starts = blocks.count.window_starts();
let window_starts = blocks.lookback.window_starts();
self.coindays_destroyed_sum.compute_rolling_sum(
starting_indexes.height,
&window_starts,

View File

@@ -35,7 +35,9 @@ pub struct AllCohortMetrics<M: StorageMode = Rw> {
pub dormancy: ComputedFromHeight<StoredF32, M>,
pub velocity: ComputedFromHeight<StoredF32, M>,
#[traversable(wrap = "supply", rename = "delta")]
pub supply_delta_extended: RollingDeltaExcept1m<Sats, SatsSigned, M>,
#[traversable(wrap = "outputs", rename = "utxo_count_delta")]
pub utxo_count_delta_extended: RollingDeltaExcept1m<StoredU64, StoredI64, M>,
}
@@ -147,7 +149,7 @@ impl AllCohortMetrics {
exit,
)?;
let window_starts = blocks.count.window_starts();
let window_starts = blocks.lookback.window_starts();
self.supply_delta_extended.compute(
starting_indexes.height,
&window_starts,

View File

@@ -32,7 +32,9 @@ pub struct ExtendedCohortMetrics<M: StorageMode = Rw> {
pub dormancy: ComputedFromHeight<StoredF32, M>,
pub velocity: ComputedFromHeight<StoredF32, M>,
#[traversable(wrap = "supply", rename = "delta")]
pub supply_delta_extended: RollingDeltaExcept1m<Sats, SatsSigned, M>,
#[traversable(wrap = "outputs", rename = "utxo_count_delta")]
pub utxo_count_delta_extended: RollingDeltaExcept1m<StoredU64, StoredI64, M>,
}
@@ -126,7 +128,7 @@ impl ExtendedCohortMetrics {
exit,
)?;
let window_starts = blocks.count.window_starts();
let window_starts = blocks.lookback.window_starts();
self.supply_delta_extended.compute(
starting_indexes.height,
&window_starts,

View File

@@ -1,19 +1,17 @@
use brk_cohort::Filter;
use brk_error::Result;
use brk_types::{
BasisPoints16, BasisPoints32, BasisPointsSigned32, Cents, Height, Version,
};
use brk_types::{BasisPoints16, BasisPoints32, BasisPointsSigned32, Cents, Height, Version};
use schemars::JsonSchema;
use vecdb::{BytesVec, BytesVecValue, Database, ImportableVec};
use crate::{
indexes,
internal::{
CentsType, ComputedFromHeight, ComputedFromHeightCumulative,
ComputedFromHeightCumulativeSum, ComputedFromHeightRatio, FiatFromHeight,
FiatRollingDelta1m, FiatRollingDeltaExcept1m, NumericValue, PercentFromHeight,
PercentRollingWindows, Price, RollingDelta1m, RollingDeltaExcept1m, RollingWindow24h,
RollingWindows, RollingWindowsFrom1w, ValueFromHeight, ValueFromHeightCumulative,
AmountFromHeight, AmountFromHeightCumulative, CentsType, ComputedFromHeight,
ComputedFromHeightCumulative, ComputedFromHeightCumulativeSum, ComputedFromHeightRatio,
FiatFromHeight, FiatRollingDelta1m, FiatRollingDeltaExcept1m, NumericValue,
PercentFromHeight, PercentRollingWindows, Price, RollingDelta1m, RollingDeltaExcept1m,
RollingWindow24h, RollingWindows, RollingWindowsFrom1w,
},
};
@@ -37,8 +35,8 @@ macro_rules! impl_config_import {
// Non-generic types
impl_config_import!(
ValueFromHeight,
ValueFromHeightCumulative,
AmountFromHeight,
AmountFromHeightCumulative,
ComputedFromHeightRatio,
PercentFromHeight<BasisPoints16>,
PercentFromHeight<BasisPoints32>,
@@ -83,7 +81,8 @@ impl<C: CentsType> ConfigImport for FiatFromHeight<C> {
Self::forced_import(cfg.db, &cfg.name(suffix), cfg.version + offset, cfg.indexes)
}
}
impl<S: NumericValue + JsonSchema, C: NumericValue + JsonSchema> ConfigImport for RollingDelta1m<S, C>
impl<S: NumericValue + JsonSchema, C: NumericValue + JsonSchema> ConfigImport
for RollingDelta1m<S, C>
{
fn config_import(cfg: &ImportConfig, suffix: &str, offset: Version) -> Result<Self> {
Self::forced_import(cfg.db, &cfg.name(suffix), cfg.version + offset, cfg.indexes)
@@ -136,11 +135,7 @@ impl<'a> ImportConfig<'a> {
}
}
pub(crate) fn import<T: ConfigImport>(
&self,
suffix: &str,
offset: Version,
) -> Result<T> {
pub(crate) fn import<T: ConfigImport>(&self, suffix: &str, offset: Version) -> Result<T> {
T::config_import(self, suffix, offset)
}
}

View File

@@ -67,7 +67,7 @@ impl OutputsMetrics {
) -> Result<()> {
self.utxo_count_delta.compute(
starting_indexes.height,
&blocks.count.height_1m_ago,
&blocks.lookback.height_1m_ago,
&self.utxo_count.height,
exit,
)?;

View File

@@ -12,23 +12,21 @@ use crate::distribution::metrics::ImportConfig;
#[derive(Traversable)]
pub struct RealizedAdjusted<M: StorageMode = Rw> {
pub adjusted_value_created: ComputedFromHeight<Cents, M>,
pub adjusted_value_destroyed: ComputedFromHeight<Cents, M>,
pub adjusted_value_created_sum: RollingWindows<Cents, M>,
pub adjusted_value_destroyed_sum: RollingWindows<Cents, M>,
pub adjusted_sopr: RollingWindows<StoredF64, M>,
pub value_created: ComputedFromHeight<Cents, M>,
pub value_destroyed: ComputedFromHeight<Cents, M>,
pub value_created_sum: RollingWindows<Cents, M>,
pub value_destroyed_sum: RollingWindows<Cents, M>,
pub sopr: RollingWindows<StoredF64, M>,
}
impl RealizedAdjusted {
pub(crate) fn forced_import(cfg: &ImportConfig) -> Result<Self> {
Ok(RealizedAdjusted {
adjusted_value_created: cfg.import("adjusted_value_created", Version::ZERO)?,
adjusted_value_destroyed: cfg.import("adjusted_value_destroyed", Version::ZERO)?,
adjusted_value_created_sum: cfg.import("adjusted_value_created", Version::ONE)?,
adjusted_value_destroyed_sum: cfg.import("adjusted_value_destroyed", Version::ONE)?,
adjusted_sopr: cfg.import("adjusted_sopr", Version::ONE)?,
value_created: cfg.import("adjusted_value_created", Version::ZERO)?,
value_destroyed: cfg.import("adjusted_value_destroyed", Version::ZERO)?,
value_created_sum: cfg.import("adjusted_value_created", Version::ONE)?,
value_destroyed_sum: cfg.import("adjusted_value_destroyed", Version::ONE)?,
sopr: cfg.import("adjusted_sopr", Version::ONE)?,
})
}
@@ -43,14 +41,14 @@ impl RealizedAdjusted {
up_to_1h_value_destroyed: &impl ReadableVec<Height, Cents>,
exit: &Exit,
) -> Result<()> {
// Compute adjusted_value_created = base.value_created - up_to_1h.value_created
self.adjusted_value_created.height.compute_subtract(
// Compute value_created = base.value_created - up_to_1h.value_created
self.value_created.height.compute_subtract(
starting_indexes.height,
base_value_created,
up_to_1h_value_created,
exit,
)?;
self.adjusted_value_destroyed.height.compute_subtract(
self.value_destroyed.height.compute_subtract(
starting_indexes.height,
base_value_destroyed,
up_to_1h_value_destroyed,
@@ -58,27 +56,27 @@ impl RealizedAdjusted {
)?;
// Adjusted value created/destroyed rolling sums
let window_starts = blocks.count.window_starts();
self.adjusted_value_created_sum.compute_rolling_sum(
let window_starts = blocks.lookback.window_starts();
self.value_created_sum.compute_rolling_sum(
starting_indexes.height,
&window_starts,
&self.adjusted_value_created.height,
&self.value_created.height,
exit,
)?;
self.adjusted_value_destroyed_sum.compute_rolling_sum(
self.value_destroyed_sum.compute_rolling_sum(
starting_indexes.height,
&window_starts,
&self.adjusted_value_destroyed.height,
&self.value_destroyed.height,
exit,
)?;
// SOPR ratios from rolling sums
for ((sopr, vc), vd) in self
.adjusted_sopr
.sopr
.as_mut_array()
.into_iter()
.zip(self.adjusted_value_created_sum.as_array())
.zip(self.adjusted_value_destroyed_sum.as_array())
.zip(self.value_created_sum.as_array())
.zip(self.value_destroyed_sum.as_array())
{
sopr.compute_binary::<Cents, Cents, RatioCents64>(
starting_indexes.height,

View File

@@ -91,13 +91,13 @@ impl RealizedBase {
self.core.compute_rest_part1(blocks, starting_indexes, exit)?;
self.sent_in_profit_sum.compute_rolling_sum(
starting_indexes.height,
&blocks.count.height_24h_ago,
&blocks.lookback.height_24h_ago,
&self.sent_in_profit.height,
exit,
)?;
self.sent_in_loss_sum.compute_rolling_sum(
starting_indexes.height,
&blocks.count.height_24h_ago,
&blocks.lookback.height_24h_ago,
&self.sent_in_loss.height,
exit,
)?;

View File

@@ -155,27 +155,27 @@ impl RealizedCore {
self.realized_cap_delta.compute(
starting_indexes.height,
&blocks.count.height_1m_ago,
&blocks.lookback.height_1m_ago,
&self.minimal.realized_cap_cents.height,
exit,
)?;
self.net_realized_pnl_sum.compute_rolling_sum(
starting_indexes.height,
&blocks.count.height_24h_ago,
&blocks.lookback.height_24h_ago,
&self.net_realized_pnl.height,
exit,
)?;
self.value_created_sum.compute_rolling_sum(
starting_indexes.height,
&blocks.count.height_24h_ago,
&blocks.lookback.height_24h_ago,
&self.value_created.height,
exit,
)?;
self.value_destroyed_sum.compute_rolling_sum(
starting_indexes.height,
&blocks.count.height_24h_ago,
&blocks.lookback.height_24h_ago,
&self.value_destroyed.height,
exit,
)?;

View File

@@ -57,13 +57,16 @@ pub struct RealizedFull<M: StorageMode = Rw> {
pub gross_pnl_sum: RollingWindows<Cents, M>,
pub net_realized_pnl_cumulative: ComputedFromHeight<CentsSigned, M>,
#[traversable(rename = "net_realized_pnl_sum")]
pub net_realized_pnl_sum_extended: RollingWindowsFrom1w<CentsSigned, M>,
pub net_pnl_delta: FiatRollingDelta1m<CentsSigned, CentsSigned, M>,
#[traversable(rename = "net_pnl_delta")]
pub net_pnl_delta_extended: FiatRollingDeltaExcept1m<CentsSigned, CentsSigned, M>,
pub net_pnl_change_1m_rel_to_realized_cap: PercentFromHeight<BasisPointsSigned32, M>,
pub net_pnl_change_1m_rel_to_market_cap: PercentFromHeight<BasisPointsSigned32, M>,
#[traversable(rename = "realized_cap_delta")]
pub realized_cap_delta_extended: FiatRollingDeltaExcept1m<Cents, CentsSigned, M>,
pub investor_price: Price<ComputedFromHeight<Cents, M>>,
@@ -82,15 +85,22 @@ pub struct RealizedFull<M: StorageMode = Rw> {
pub realized_cap_rel_to_own_market_cap: PercentFromHeight<BasisPoints32, M>,
#[traversable(rename = "realized_profit_sum")]
pub realized_profit_sum_extended: RollingWindowsFrom1w<Cents, M>,
#[traversable(rename = "realized_loss_sum")]
pub realized_loss_sum_extended: RollingWindowsFrom1w<Cents, M>,
pub realized_profit_to_loss_ratio: RollingWindows<StoredF64, M>,
#[traversable(rename = "value_created_sum")]
pub value_created_sum_extended: RollingWindowsFrom1w<Cents, M>,
#[traversable(rename = "value_destroyed_sum")]
pub value_destroyed_sum_extended: RollingWindowsFrom1w<Cents, M>,
#[traversable(rename = "sopr")]
pub sopr_extended: RollingWindowsFrom1w<StoredF64, M>,
#[traversable(rename = "sent_in_profit_sum")]
pub sent_in_profit_sum_extended: RollingWindowsFrom1w<Sats, M>,
#[traversable(rename = "sent_in_loss_sum")]
pub sent_in_loss_sum_extended: RollingWindowsFrom1w<Sats, M>,
pub realized_price_ratio_percentiles: ComputedFromHeightRatioPercentiles<M>,
@@ -377,7 +387,7 @@ impl RealizedFull {
exit,
)?;
let window_starts = blocks.count.window_starts();
let window_starts = blocks.lookback.window_starts();
// Extended rolling sum (1w, 1m, 1y) for net_realized_pnl
self.net_realized_pnl_sum_extended.compute_rolling_sum(
@@ -496,7 +506,7 @@ impl RealizedFull {
// Net PnL delta (1m base + 24h/1w/1y extended)
self.net_pnl_delta.compute(
starting_indexes.height,
&blocks.count.height_1m_ago,
&blocks.lookback.height_1m_ago,
&self.net_realized_pnl_cumulative.height,
exit,
)?;

View File

@@ -127,13 +127,13 @@ impl RealizedMinimal {
.compute_rest(starting_indexes.height, exit)?;
self.realized_profit_sum.compute_rolling_sum(
starting_indexes.height,
&blocks.count.height_24h_ago,
&blocks.lookback.height_24h_ago,
&self.realized_profit.height,
exit,
)?;
self.realized_loss_sum.compute_rolling_sum(
starting_indexes.height,
&blocks.count.height_24h_ago,
&blocks.lookback.height_24h_ago,
&self.realized_loss.height,
exit,
)?;

View File

@@ -6,8 +6,8 @@ use crate::{blocks, prices};
use vecdb::{AnyStoredVec, AnyVec, Exit, Rw, StorageMode, WritableVec};
use crate::internal::{
HalveCents, HalveDollars, HalveSats, HalveSatsToBitcoin, LazyValueFromHeight,
RollingDelta1m, ValueFromHeight,
AmountFromHeight, HalveCents, HalveDollars, HalveSats, HalveSatsToBitcoin,
LazyAmountFromHeight, RollingDelta1m,
};
use super::ImportConfig;
@@ -15,8 +15,8 @@ use super::ImportConfig;
/// Supply metrics for a cohort.
#[derive(Traversable)]
pub struct SupplyMetrics<M: StorageMode = Rw> {
pub total: ValueFromHeight<M>,
pub halved: LazyValueFromHeight,
pub total: AmountFromHeight<M>,
pub halved: LazyAmountFromHeight,
pub delta: RollingDelta1m<Sats, SatsSigned, M>,
}
@@ -25,7 +25,7 @@ impl SupplyMetrics {
pub(crate) fn forced_import(cfg: &ImportConfig) -> Result<Self> {
let supply = cfg.import("supply", Version::ZERO)?;
let supply_halved = LazyValueFromHeight::from_block_source::<
let supply_halved = LazyAmountFromHeight::from_block_source::<
HalveSats,
HalveSatsToBitcoin,
HalveCents,
@@ -54,8 +54,8 @@ impl SupplyMetrics {
pub(crate) fn collect_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> {
vec![
&mut self.total.base.sats.height as &mut dyn AnyStoredVec,
&mut self.total.base.cents.height as &mut dyn AnyStoredVec,
&mut self.total.sats.height as &mut dyn AnyStoredVec,
&mut self.total.cents.height as &mut dyn AnyStoredVec,
]
}
@@ -102,7 +102,7 @@ impl SupplyMetrics {
) -> Result<()> {
self.delta.compute(
starting_indexes.height,
&blocks.count.height_1m_ago,
&blocks.lookback.height_1m_ago,
&self.total.sats.height,
exit,
)

View File

@@ -5,15 +5,15 @@ use vecdb::{AnyStoredVec, AnyVec, Exit, Rw, StorageMode, WritableVec};
use crate::prices;
use crate::internal::ValueFromHeight;
use crate::internal::AmountFromHeight;
use crate::distribution::{metrics::ImportConfig, state::UnrealizedState};
/// Minimal unrealized metrics: supply in profit/loss only.
#[derive(Traversable)]
pub struct UnrealizedMinimal<M: StorageMode = Rw> {
pub supply_in_profit: ValueFromHeight<M>,
pub supply_in_loss: ValueFromHeight<M>,
pub supply_in_profit: AmountFromHeight<M>,
pub supply_in_loss: AmountFromHeight<M>,
}
impl UnrealizedMinimal {
@@ -46,10 +46,10 @@ impl UnrealizedMinimal {
pub(crate) fn collect_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> {
vec![
&mut self.supply_in_profit.base.sats.height as &mut dyn AnyStoredVec,
&mut self.supply_in_profit.base.cents.height as &mut dyn AnyStoredVec,
&mut self.supply_in_loss.base.sats.height as &mut dyn AnyStoredVec,
&mut self.supply_in_loss.base.cents.height as &mut dyn AnyStoredVec,
&mut self.supply_in_profit.sats.height as &mut dyn AnyStoredVec,
&mut self.supply_in_profit.cents.height as &mut dyn AnyStoredVec,
&mut self.supply_in_loss.sats.height as &mut dyn AnyStoredVec,
&mut self.supply_in_loss.cents.height as &mut dyn AnyStoredVec,
]
}
@@ -59,8 +59,8 @@ impl UnrealizedMinimal {
others: &[&Self],
exit: &Exit,
) -> Result<()> {
sum_others!(self, starting_indexes, others, exit; supply_in_profit.base.sats.height);
sum_others!(self, starting_indexes, others, exit; supply_in_loss.base.sats.height);
sum_others!(self, starting_indexes, others, exit; supply_in_profit.sats.height);
sum_others!(self, starting_indexes, others, exit; supply_in_loss.sats.height);
Ok(())
}

View File

@@ -414,7 +414,7 @@ impl Vecs {
exit,
)?;
let window_starts = blocks.count.window_starts();
let window_starts = blocks.lookback.window_starts();
self.address_activity
.compute_rest(starting_indexes.height, &window_starts, exit)?;

View File

@@ -15,7 +15,7 @@ impl Vecs {
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
let window_starts = blocks.count.window_starts();
let window_starts = blocks.lookback.window_starts();
self.0
.compute(starting_indexes.height, &window_starts, exit, |full| {
full.compute_with_skip(

View File

@@ -1,4 +1,4 @@
//! Value type with height-level data only (no period-derived views).
//! Amount type with height-level data only (no period-derived views).
//!
//! Stores sats and cents per index, plus lazy btc and usd transforms.
//! Use when period views are unnecessary (e.g., rolling windows provide windowed data).
@@ -16,26 +16,23 @@ use crate::{
prices,
};
const VERSION: Version = Version::TWO; // Match ValueFromHeight versioning
const VERSION: Version = Version::TWO; // Match AmountFromHeight versioning
#[derive(Traversable)]
pub struct Value<I: VecIndex, M: StorageMode = Rw> {
pub struct Amount<I: VecIndex, M: StorageMode = Rw> {
pub sats: M::Stored<EagerVec<PcoVec<I, Sats>>>,
pub btc: LazyVecFrom1<I, Bitcoin, I, Sats>,
pub cents: M::Stored<EagerVec<PcoVec<I, Cents>>>,
pub usd: LazyVecFrom1<I, Dollars, I, Cents>,
}
impl Value<Height> {
impl Amount<Height> {
pub(crate) fn forced_import(db: &Database, name: &str, version: Version) -> Result<Self> {
let v = version + VERSION;
let sats: EagerVec<PcoVec<Height, Sats>> = EagerVec::forced_import(db, name, v)?;
let btc = LazyVecFrom1::transformed::<SatsToBitcoin>(
&format!("{name}_btc"),
v,
sats.read_only_boxed_clone(),
);
let sats: EagerVec<PcoVec<Height, Sats>> =
EagerVec::forced_import(db, &format!("{name}_sats"), v)?;
let btc = LazyVecFrom1::transformed::<SatsToBitcoin>(name, v, sats.read_only_boxed_clone());
let cents: EagerVec<PcoVec<Height, Cents>> =
EagerVec::forced_import(db, &format!("{name}_cents"), v)?;
let usd = LazyVecFrom1::transformed::<CentsUnsignedToDollars>(

View File

@@ -2,20 +2,20 @@ use brk_traversable::Traversable;
use brk_types::{Bitcoin, Cents, Dollars, Height, Sats, Version};
use vecdb::{LazyVecFrom1, ReadableCloneableVec, UnaryTransform, VecIndex};
use crate::internal::ValueFromHeight;
use crate::internal::AmountFromHeight;
/// Fully lazy value type at height level.
///
/// All fields are lazy transforms from existing sources - no storage.
#[derive(Clone, Traversable)]
pub struct LazyValue<I: VecIndex> {
pub struct LazyAmount<I: VecIndex> {
pub sats: LazyVecFrom1<I, Sats, I, Sats>,
pub btc: LazyVecFrom1<I, Bitcoin, I, Sats>,
pub cents: LazyVecFrom1<I, Cents, I, Cents>,
pub usd: LazyVecFrom1<I, Dollars, I, Dollars>,
}
impl LazyValue<Height> {
impl LazyAmount<Height> {
pub(crate) fn from_block_source<
SatsTransform,
BitcoinTransform,
@@ -23,7 +23,7 @@ impl LazyValue<Height> {
DollarsTransform,
>(
name: &str,
source: &ValueFromHeight,
source: &AmountFromHeight,
version: Version,
) -> Self
where
@@ -33,13 +33,13 @@ impl LazyValue<Height> {
DollarsTransform: UnaryTransform<Dollars, Dollars>,
{
let sats = LazyVecFrom1::transformed::<SatsTransform>(
name,
&format!("{name}_sats"),
version,
source.sats.height.read_only_boxed_clone(),
);
let btc = LazyVecFrom1::transformed::<BitcoinTransform>(
&format!("{name}_btc"),
name,
version,
source.sats.height.read_only_boxed_clone(),
);

View File

@@ -14,7 +14,7 @@ pub struct DistributionStats<A> {
impl<A> DistributionStats<A> {
pub const SUFFIXES: [&'static str; 8] = [
"average", "min", "max", "p10", "p25", "median", "p75", "p90",
"average", "min", "max", "pct10", "pct25", "median", "pct75", "pct90",
];
pub fn try_from_fn<E>(

View File

@@ -2,17 +2,17 @@ use brk_traversable::Traversable;
use brk_types::{Bitcoin, Cents, Dollars, Sats, Version};
use vecdb::UnaryTransform;
use crate::internal::{LazyHeightDerived, ValueFromHeight};
use crate::internal::{AmountFromHeight, LazyHeightDerived};
#[derive(Clone, Traversable)]
pub struct LazyValueHeightDerived {
pub struct LazyAmountHeightDerived {
pub sats: LazyHeightDerived<Sats, Sats>,
pub btc: LazyHeightDerived<Bitcoin, Sats>,
pub cents: LazyHeightDerived<Cents, Cents>,
pub usd: LazyHeightDerived<Dollars, Dollars>,
}
impl LazyValueHeightDerived {
impl LazyAmountHeightDerived {
pub(crate) fn from_block_source<
SatsTransform,
BitcoinTransform,
@@ -20,7 +20,7 @@ impl LazyValueHeightDerived {
DollarsTransform,
>(
name: &str,
source: &ValueFromHeight,
source: &AmountFromHeight,
version: Version,
) -> Self
where
@@ -30,13 +30,13 @@ impl LazyValueHeightDerived {
DollarsTransform: UnaryTransform<Dollars, Dollars>,
{
let sats = LazyHeightDerived::from_derived_computed::<SatsTransform>(
name,
&format!("{name}_sats"),
version,
&source.sats.rest,
);
let btc = LazyHeightDerived::from_derived_computed::<BitcoinTransform>(
&format!("{name}_btc"),
name,
version,
&source.sats.rest,
);

View File

@@ -1,13 +1,13 @@
mod full;
mod last;
mod lazy_last;
mod lazy_value;
mod lazy_amount;
mod map_option;
mod transform_last;
pub use full::*;
pub use last::*;
pub use lazy_last::*;
pub use lazy_value::*;
pub use lazy_amount::*;
pub use map_option::*;
pub use transform_last::*;

View File

@@ -5,19 +5,19 @@ use vecdb::{Database, EagerVec, Exit, PcoVec, Rw, StorageMode};
use crate::{
indexes,
internal::{ByUnit, SatsToCents},
internal::{AmountFromHeight, SatsToCents},
prices,
};
#[derive(Traversable)]
pub struct ValueFromHeightCumulative<M: StorageMode = Rw> {
pub base: ByUnit<M>,
pub cumulative: ByUnit<M>,
pub struct AmountFromHeightCumulative<M: StorageMode = Rw> {
pub base: AmountFromHeight<M>,
pub cumulative: AmountFromHeight<M>,
}
const VERSION: Version = Version::ONE;
impl ValueFromHeightCumulative {
impl AmountFromHeightCumulative {
pub(crate) fn forced_import(
db: &Database,
name: &str,
@@ -27,8 +27,13 @@ impl ValueFromHeightCumulative {
let v = version + VERSION;
Ok(Self {
base: ByUnit::forced_import(db, name, v, indexes)?,
cumulative: ByUnit::forced_import(db, &format!("{name}_cumulative"), v, indexes)?,
base: AmountFromHeight::forced_import(db, name, v, indexes)?,
cumulative: AmountFromHeight::forced_import(
db,
&format!("{name}_cumulative"),
v,
indexes,
)?,
})
}

View File

@@ -5,20 +5,20 @@ use vecdb::{Database, EagerVec, Exit, PcoVec, Rw, StorageMode};
use crate::{
indexes,
internal::{ByUnit, RollingSumByUnit, SatsToCents, WindowStarts},
internal::{AmountFromHeight, RollingSumAmountFromHeight, SatsToCents, WindowStarts},
prices,
};
#[derive(Traversable)]
pub struct ValueFromHeightCumulativeSum<M: StorageMode = Rw> {
pub base: ByUnit<M>,
pub cumulative: ByUnit<M>,
pub sum: RollingSumByUnit<M>,
pub struct AmountFromHeightCumulativeSum<M: StorageMode = Rw> {
pub base: AmountFromHeight<M>,
pub cumulative: AmountFromHeight<M>,
pub sum: RollingSumAmountFromHeight<M>,
}
const VERSION: Version = Version::TWO;
impl ValueFromHeightCumulativeSum {
impl AmountFromHeightCumulativeSum {
pub(crate) fn forced_import(
db: &Database,
name: &str,
@@ -28,9 +28,14 @@ impl ValueFromHeightCumulativeSum {
let v = version + VERSION;
Ok(Self {
base: ByUnit::forced_import(db, name, v, indexes)?,
cumulative: ByUnit::forced_import(db, &format!("{name}_cumulative"), v, indexes)?,
sum: RollingSumByUnit::forced_import(db, name, v, indexes)?,
base: AmountFromHeight::forced_import(db, name, v, indexes)?,
cumulative: AmountFromHeight::forced_import(
db,
&format!("{name}_cumulative"),
v,
indexes,
)?,
sum: RollingSumAmountFromHeight::forced_import(db, name, v, indexes)?,
})
}

View File

@@ -5,21 +5,21 @@ use vecdb::{Database, EagerVec, Exit, PcoVec, Rw, StorageMode};
use crate::{
indexes,
internal::{ByUnit, RollingFullByUnit, SatsToCents, WindowStarts},
internal::{AmountFromHeight, RollingFullAmountFromHeight, SatsToCents, WindowStarts},
prices,
};
#[derive(Traversable)]
pub struct ValueFromHeightFull<M: StorageMode = Rw> {
pub base: ByUnit<M>,
pub cumulative: ByUnit<M>,
pub struct AmountFromHeightFull<M: StorageMode = Rw> {
pub base: AmountFromHeight<M>,
pub cumulative: AmountFromHeight<M>,
#[traversable(flatten)]
pub rolling: RollingFullByUnit<M>,
pub rolling: RollingFullAmountFromHeight<M>,
}
const VERSION: Version = Version::TWO;
impl ValueFromHeightFull {
impl AmountFromHeightFull {
pub(crate) fn forced_import(
db: &Database,
name: &str,
@@ -29,9 +29,14 @@ impl ValueFromHeightFull {
let v = version + VERSION;
Ok(Self {
base: ByUnit::forced_import(db, name, v, indexes)?,
cumulative: ByUnit::forced_import(db, &format!("{name}_cumulative"), v, indexes)?,
rolling: RollingFullByUnit::forced_import(db, name, v, indexes)?,
base: AmountFromHeight::forced_import(db, name, v, indexes)?,
cumulative: AmountFromHeight::forced_import(
db,
&format!("{name}_cumulative"),
v,
indexes,
)?,
rolling: RollingFullAmountFromHeight::forced_import(db, name, v, indexes)?,
})
}

View File

@@ -1,25 +1,25 @@
//! Lazy value wrapper for ValueFromHeight - all transforms are lazy.
//! Lazy value wrapper for AmountFromHeight - all transforms are lazy.
use brk_traversable::Traversable;
use brk_types::{Bitcoin, Cents, Dollars, Height, Sats, Version};
use derive_more::{Deref, DerefMut};
use vecdb::UnaryTransform;
use crate::internal::{LazyValue, LazyValueHeightDerived, ValueFromHeight};
use crate::internal::{AmountFromHeight, LazyAmount, LazyAmountHeightDerived};
/// Lazy value wrapper with height + all derived last transforms from ValueFromHeight.
/// Lazy value wrapper with height + all derived last transforms from AmountFromHeight.
#[derive(Clone, Deref, DerefMut, Traversable)]
#[traversable(merge)]
pub struct LazyValueFromHeight {
pub struct LazyAmountFromHeight {
#[traversable(flatten)]
pub height: LazyValue<Height>,
pub height: LazyAmount<Height>,
#[deref]
#[deref_mut]
#[traversable(flatten)]
pub rest: Box<LazyValueHeightDerived>,
pub rest: Box<LazyAmountHeightDerived>,
}
impl LazyValueFromHeight {
impl LazyAmountFromHeight {
pub(crate) fn from_block_source<
SatsTransform,
BitcoinTransform,
@@ -27,7 +27,7 @@ impl LazyValueFromHeight {
DollarsTransform,
>(
name: &str,
source: &ValueFromHeight,
source: &AmountFromHeight,
version: Version,
) -> Self
where
@@ -36,14 +36,14 @@ impl LazyValueFromHeight {
CentsTransform: UnaryTransform<Cents, Cents>,
DollarsTransform: UnaryTransform<Dollars, Dollars>,
{
let height = LazyValue::from_block_source::<
let height = LazyAmount::from_block_source::<
SatsTransform,
BitcoinTransform,
CentsTransform,
DollarsTransform,
>(name, source, version);
let rest = LazyValueHeightDerived::from_block_source::<
let rest = LazyAmountHeightDerived::from_block_source::<
SatsTransform,
BitcoinTransform,
CentsTransform,

View File

@@ -0,0 +1,122 @@
mod cumulative;
mod cumulative_sum;
mod full;
mod lazy;
mod rolling;
mod rolling_full;
mod rolling_sum;
use brk_error::Result;
use brk_traversable::Traversable;
use brk_types::{Bitcoin, Cents, Dollars, Height, Sats, Version};
use vecdb::{AnyVec, Database, Exit, ReadableCloneableVec, ReadableVec, Rw, StorageMode};
use crate::{
indexes,
internal::{
CentsUnsignedToDollars, ComputedFromHeight, LazyFromHeight, SatsToBitcoin, SatsToCents,
Windows,
},
prices,
};
pub use cumulative::*;
pub use cumulative_sum::*;
pub use full::*;
pub use lazy::*;
pub use rolling::*;
pub use rolling_full::*;
pub use rolling_sum::*;
#[derive(Traversable)]
pub struct AmountFromHeight<M: StorageMode = Rw> {
pub sats: ComputedFromHeight<Sats, M>,
pub btc: LazyFromHeight<Bitcoin, Sats>,
pub cents: ComputedFromHeight<Cents, M>,
pub usd: LazyFromHeight<Dollars, Cents>,
}
impl AmountFromHeight {
pub(crate) fn forced_import(
db: &Database,
name: &str,
version: Version,
indexes: &indexes::Vecs,
) -> Result<Self> {
let sats =
ComputedFromHeight::forced_import(db, &format!("{name}_sats"), version, indexes)?;
let btc = LazyFromHeight::from_computed::<SatsToBitcoin>(
name,
version,
sats.height.read_only_boxed_clone(),
&sats,
);
let cents =
ComputedFromHeight::forced_import(db, &format!("{name}_cents"), version, indexes)?;
let usd = LazyFromHeight::from_computed::<CentsUnsignedToDollars>(
&format!("{name}_usd"),
version,
cents.height.read_only_boxed_clone(),
&cents,
);
Ok(Self {
sats,
btc,
cents,
usd,
})
}
pub(crate) fn min_stateful_len(&self) -> usize {
self.sats.height.len()
}
pub(crate) fn compute(
&mut self,
prices: &prices::Vecs,
max_from: Height,
exit: &Exit,
) -> Result<()> {
self.cents.compute_binary::<Sats, Cents, SatsToCents>(
max_from,
&self.sats.height,
&prices.price.cents.height,
exit,
)?;
Ok(())
}
pub(crate) fn compute_rolling_sum(
&mut self,
max_from: Height,
window_starts: &impl ReadableVec<Height, Height>,
sats_source: &impl ReadableVec<Height, Sats>,
cents_source: &impl ReadableVec<Height, Cents>,
exit: &Exit,
) -> Result<()> {
self.sats
.height
.compute_rolling_sum(max_from, window_starts, sats_source, exit)?;
self.cents
.height
.compute_rolling_sum(max_from, window_starts, cents_source, exit)?;
Ok(())
}
}
impl Windows<AmountFromHeight> {
pub(crate) fn forced_import(
db: &Database,
name: &str,
version: Version,
indexes: &indexes::Vecs,
) -> Result<Self> {
Windows::try_from_fn(|suffix| {
AmountFromHeight::forced_import(db, &format!("{name}_{suffix}"), version, indexes)
})
}
}

View File

@@ -1,7 +1,7 @@
//! Value type for Height + Rolling pattern.
//!
//! Combines Value (sats/btc/usd per height, no period views) with
//! ValueFromHeightWindows (rolling sums across 4 windows).
//! AmountFromHeightWindows (rolling sums across 4 windows).
use brk_error::Result;
use brk_traversable::Traversable;
@@ -11,21 +11,21 @@ use vecdb::{Database, EagerVec, Exit, PcoVec, Rw, StorageMode};
use crate::{
indexes,
internal::{Value, ValueFromHeightWindows, WindowStarts},
internal::{Amount, AmountFromHeightWindows, WindowStarts},
prices,
};
#[derive(Deref, DerefMut, Traversable)]
pub struct ValueFromHeightRolling<M: StorageMode = Rw> {
pub struct AmountFromHeightRolling<M: StorageMode = Rw> {
#[deref]
#[deref_mut]
#[traversable(flatten)]
pub value: Value<Height, M>,
pub amount: Amount<Height, M>,
#[traversable(flatten)]
pub rolling: ValueFromHeightWindows<M>,
pub rolling: AmountFromHeightWindows<M>,
}
impl ValueFromHeightRolling {
impl AmountFromHeightRolling {
pub(crate) fn forced_import(
db: &Database,
name: &str,
@@ -33,8 +33,8 @@ impl ValueFromHeightRolling {
indexes: &indexes::Vecs,
) -> Result<Self> {
Ok(Self {
value: Value::forced_import(db, name, version)?,
rolling: ValueFromHeightWindows::forced_import(db, name, version, indexes)?,
amount: Amount::forced_import(db, name, version)?,
rolling: AmountFromHeightWindows::forced_import(db, name, version, indexes)?,
})
}
@@ -47,13 +47,13 @@ impl ValueFromHeightRolling {
exit: &Exit,
compute_sats: impl FnOnce(&mut EagerVec<PcoVec<Height, Sats>>) -> Result<()>,
) -> Result<()> {
compute_sats(&mut self.value.sats)?;
self.value.compute_cents(prices, max_from, exit)?;
compute_sats(&mut self.amount.sats)?;
self.amount.compute_cents(prices, max_from, exit)?;
self.rolling.compute_rolling_sum(
max_from,
windows,
&self.value.sats,
&self.value.cents,
&self.amount.sats,
&self.amount.cents,
exit,
)?;
Ok(())

View File

@@ -7,18 +7,18 @@ use vecdb::{Database, Exit, ReadableVec, Rw, StorageMode};
use crate::{
indexes,
internal::{
ByUnit, DistributionStats, WindowStarts, Windows, compute_rolling_distribution_from_starts,
AmountFromHeight, DistributionStats, WindowStarts, Windows, compute_rolling_distribution_from_starts,
},
};
/// One window slot: sum + 8 distribution stats, each a ByUnit.
/// One window slot: sum + 8 distribution stats, each a AmountFromHeight.
///
/// Tree: `sum.sats.height`, `average.sats.height`, etc.
#[derive(Traversable)]
pub struct RollingFullSlot<M: StorageMode = Rw> {
pub sum: ByUnit<M>,
pub sum: AmountFromHeight<M>,
#[traversable(flatten)]
pub distribution: DistributionStats<ByUnit<M>>,
pub distribution: DistributionStats<AmountFromHeight<M>>,
}
impl RollingFullSlot {
@@ -29,9 +29,9 @@ impl RollingFullSlot {
indexes: &indexes::Vecs,
) -> Result<Self> {
Ok(Self {
sum: ByUnit::forced_import(db, &format!("{name}_sum"), version, indexes)?,
sum: AmountFromHeight::forced_import(db, &format!("{name}_sum"), version, indexes)?,
distribution: DistributionStats::try_from_fn(|suffix| {
ByUnit::forced_import(db, &format!("{name}_{suffix}"), version, indexes)
AmountFromHeight::forced_import(db, &format!("{name}_{suffix}"), version, indexes)
})?,
})
}
@@ -85,9 +85,9 @@ impl RollingFullSlot {
/// Tree: `_24h.sum.sats.height`, `_24h.average.sats.height`, etc.
#[derive(Deref, DerefMut, Traversable)]
#[traversable(transparent)]
pub struct RollingFullByUnit<M: StorageMode = Rw>(pub Windows<RollingFullSlot<M>>);
pub struct RollingFullAmountFromHeight<M: StorageMode = Rw>(pub Windows<RollingFullSlot<M>>);
impl RollingFullByUnit {
impl RollingFullAmountFromHeight {
pub(crate) fn forced_import(
db: &Database,
name: &str,

View File

@@ -6,7 +6,7 @@ use vecdb::{Database, Exit, ReadableVec, Rw, StorageMode};
use crate::{
indexes,
internal::{ByUnit, WindowStarts, Windows},
internal::{AmountFromHeight, WindowStarts, Windows},
};
/// Rolling sum only, window-first then unit.
@@ -14,16 +14,16 @@ use crate::{
/// Tree: `_24h.sats.height`, `_24h.btc.height`, etc.
#[derive(Deref, DerefMut, Traversable)]
#[traversable(transparent)]
pub struct RollingSumByUnit<M: StorageMode = Rw>(pub Windows<ByUnit<M>>);
pub struct RollingSumAmountFromHeight<M: StorageMode = Rw>(pub Windows<AmountFromHeight<M>>);
impl RollingSumByUnit {
impl RollingSumAmountFromHeight {
pub(crate) fn forced_import(
db: &Database,
name: &str,
version: Version,
indexes: &indexes::Vecs,
) -> Result<Self> {
Ok(Self(Windows::<ByUnit>::forced_import(
Ok(Self(Windows::<AmountFromHeight>::forced_import(
db,
&format!("{name}_sum"),
version,

View File

@@ -1,77 +0,0 @@
mod rolling_full;
mod rolling_sum;
use brk_error::Result;
use brk_traversable::Traversable;
use brk_types::{Bitcoin, Cents, Dollars, Sats, Version};
use vecdb::{AnyVec, Database, ReadableCloneableVec, Rw, StorageMode};
use crate::{
indexes,
internal::{
CentsUnsignedToDollars, ComputedFromHeight, LazyFromHeight, SatsToBitcoin, Windows,
},
};
pub use rolling_full::*;
pub use rolling_sum::*;
#[derive(Traversable)]
pub struct ByUnit<M: StorageMode = Rw> {
pub sats: ComputedFromHeight<Sats, M>,
pub btc: LazyFromHeight<Bitcoin, Sats>,
pub cents: ComputedFromHeight<Cents, M>,
pub usd: LazyFromHeight<Dollars, Cents>,
}
impl ByUnit {
pub(crate) fn forced_import(
db: &Database,
name: &str,
version: Version,
indexes: &indexes::Vecs,
) -> Result<Self> {
let sats = ComputedFromHeight::forced_import(db, name, version, indexes)?;
let btc = LazyFromHeight::from_computed::<SatsToBitcoin>(
&format!("{name}_btc"),
version,
sats.height.read_only_boxed_clone(),
&sats,
);
let cents =
ComputedFromHeight::forced_import(db, &format!("{name}_cents"), version, indexes)?;
let usd = LazyFromHeight::from_computed::<CentsUnsignedToDollars>(
&format!("{name}_usd"),
version,
cents.height.read_only_boxed_clone(),
&cents,
);
Ok(Self {
sats,
btc,
cents,
usd,
})
}
pub(crate) fn min_stateful_len(&self) -> usize {
self.sats.height.len()
}
}
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

@@ -41,7 +41,7 @@ impl<C: CentsType> FiatFromHeight<C> {
let cents =
ComputedFromHeight::forced_import(db, &format!("{name}_cents"), version, indexes)?;
let usd = LazyFromHeight::from_computed::<C::ToDollars>(
&format!("{name}_usd"),
name,
version,
cents.height.read_only_boxed_clone(),
&cents,

View File

@@ -31,7 +31,7 @@ impl<C: CentsType> LazyFiatFromHeight<C> {
source,
);
let usd = LazyFromHeight::from_computed::<C::ToDollars>(
&format!("{name}_usd"),
name,
version,
source.height.read_only_boxed_clone(),
source,

View File

@@ -1,5 +1,5 @@
mod base;
mod by_unit;
mod amount;
mod computed;
mod constant;
mod fiat;
@@ -10,10 +10,9 @@ mod percentiles;
mod price;
mod ratio;
mod stddev;
mod value;
pub use base::*;
pub use by_unit::*;
pub use amount::*;
pub use computed::*;
pub use constant::*;
pub use fiat::*;
@@ -24,4 +23,3 @@ pub use percentiles::*;
pub use price::*;
pub use ratio::*;
pub use stddev::*;
pub use value::*;

View File

@@ -91,14 +91,14 @@ impl ComputedFromHeightRatioPercentiles {
) -> Result<()> {
self.ratio_sma_1w.bps.height.compute_rolling_average(
starting_indexes.height,
&blocks.count.height_1w_ago,
&blocks.lookback.height_1w_ago,
ratio_source,
exit,
)?;
self.ratio_sma_1m.bps.height.compute_rolling_average(
starting_indexes.height,
&blocks.count.height_1m_ago,
&blocks.lookback.height_1m_ago,
ratio_source,
exit,
)?;

View File

@@ -65,7 +65,7 @@ impl ComputedFromHeightStdDev {
return Ok(());
}
let window_starts = blocks.count.start_vec(self.days);
let window_starts = blocks.lookback.start_vec(self.days);
self.sma.height.compute_rolling_average(
starting_indexes.height,

View File

@@ -1,69 +0,0 @@
use brk_error::Result;
use brk_traversable::Traversable;
use brk_types::{Cents, Height, Sats, Version};
use derive_more::{Deref, DerefMut};
use vecdb::{Database, Exit, ReadableVec, Rw, StorageMode};
use crate::{
indexes,
internal::{ByUnit, SatsToCents},
prices,
};
#[derive(Deref, DerefMut, Traversable)]
#[traversable(transparent)]
pub struct ValueFromHeight<M: StorageMode = Rw> {
#[deref]
#[deref_mut]
pub base: ByUnit<M>,
}
const VERSION: Version = Version::TWO;
impl ValueFromHeight {
pub(crate) fn forced_import(
db: &Database,
name: &str,
version: Version,
indexes: &indexes::Vecs,
) -> Result<Self> {
let v = version + VERSION;
Ok(Self {
base: ByUnit::forced_import(db, name, v, indexes)?,
})
}
pub(crate) fn compute(
&mut self,
prices: &prices::Vecs,
max_from: Height,
exit: &Exit,
) -> Result<()> {
self.base.cents.compute_binary::<Sats, Cents, SatsToCents>(
max_from,
&self.base.sats.height,
&prices.price.cents.height,
exit,
)?;
Ok(())
}
pub(crate) fn compute_rolling_sum(
&mut self,
max_from: Height,
window_starts: &impl ReadableVec<Height, Height>,
sats_source: &impl ReadableVec<Height, Sats>,
cents_source: &impl ReadableVec<Height, Cents>,
exit: &Exit,
) -> Result<()> {
self.base
.sats
.height
.compute_rolling_sum(max_from, window_starts, sats_source, exit)?;
self.base
.cents
.height
.compute_rolling_sum(max_from, window_starts, cents_source, exit)?;
Ok(())
}
}

View File

@@ -1,13 +0,0 @@
mod base;
mod cumulative;
mod cumulative_sum;
mod full;
mod lazy;
mod rolling;
pub use base::*;
pub use cumulative::*;
pub use cumulative_sum::*;
pub use full::*;
pub use lazy::*;
pub use rolling::*;

View File

@@ -9,7 +9,7 @@ mod indexes;
mod rolling;
mod traits;
mod transform;
mod value;
mod amount;
pub(crate) use aggregate::*;
pub(crate) use algo::*;
@@ -22,4 +22,4 @@ pub(crate) use indexes::*;
pub(crate) use rolling::*;
pub(crate) use traits::*;
pub use transform::*;
pub(crate) use value::*;
pub(crate) use amount::*;

View File

@@ -1,4 +1,4 @@
//! ValueFromHeightWindows - window-first ordering.
//! AmountFromHeightWindows - window-first ordering.
//!
//! Access pattern: `coinbase_sum._24h.sats.height`
//! Each window (24h, 7d, 30d, 1y) contains sats (stored) + btc (lazy) + usd (stored).
@@ -14,17 +14,17 @@ use brk_types::{Cents, Sats};
use crate::{
indexes,
internal::{ValueFromHeight, WindowStarts, Windows},
internal::{AmountFromHeight, WindowStarts, Windows},
};
/// Value rolling windows — window-first, currency-last.
///
/// Each window contains `ValueFromHeight` (sats + btc lazy + usd).
/// Each window contains `AmountFromHeight` (sats + btc lazy + usd).
#[derive(Deref, DerefMut, Traversable)]
#[traversable(transparent)]
pub struct ValueFromHeightWindows<M: StorageMode = Rw>(pub Windows<ValueFromHeight<M>>);
pub struct AmountFromHeightWindows<M: StorageMode = Rw>(pub Windows<AmountFromHeight<M>>);
impl ValueFromHeightWindows {
impl AmountFromHeightWindows {
pub(crate) fn forced_import(
db: &Database,
name: &str,
@@ -32,7 +32,7 @@ impl ValueFromHeightWindows {
indexes: &indexes::Vecs,
) -> Result<Self> {
Ok(Self(Windows::try_from_fn(|suffix| {
ValueFromHeight::forced_import(db, &format!("{name}_{suffix}"), version, indexes)
AmountFromHeight::forced_import(db, &format!("{name}_{suffix}"), version, indexes)
})?))
}

View File

@@ -1,11 +1,11 @@
mod distribution;
mod full;
mod percent_windows;
mod value_windows;
mod amount_windows;
mod windows;
pub use distribution::*;
pub use full::*;
pub use percent_windows::*;
pub use value_windows::*;
pub use amount_windows::*;
pub use windows::*;

View File

@@ -51,7 +51,7 @@ impl Vecs {
// DCA by period - stack (rolling sum via _start vecs)
for (stack, days) in self.period_stack.iter_mut_with_days() {
let window_starts = blocks.count.start_vec(days as usize);
let window_starts = blocks.lookback.start_vec(days as usize);
stack.sats.height.compute_rolling_sum(
starting_indexes.height,
window_starts,

View File

@@ -5,7 +5,7 @@ use vecdb::{Database, ImportableVec};
use super::{ByDcaCagr, ByDcaClass, ByDcaPeriod, Vecs};
use crate::{
indexes,
internal::{PercentFromHeight, Price, ValueFromHeight},
internal::{AmountFromHeight, PercentFromHeight, Price},
};
impl Vecs {
@@ -15,7 +15,7 @@ impl Vecs {
indexes: &indexes::Vecs,
) -> Result<Self> {
let period_stack = ByDcaPeriod::try_new(|name, _days| {
ValueFromHeight::forced_import(db, &format!("dca_stack_{name}"), version, indexes)
AmountFromHeight::forced_import(db, &format!("dca_stack_{name}"), version, indexes)
})?;
let period_cost_basis = ByDcaPeriod::try_new(|name, _days| {
@@ -31,7 +31,7 @@ impl Vecs {
})?;
let period_lump_sum_stack = ByDcaPeriod::try_new(|name, _days| {
ValueFromHeight::forced_import(db, &format!("lump_sum_stack_{name}"), version, indexes)
AmountFromHeight::forced_import(db, &format!("lump_sum_stack_{name}"), version, indexes)
})?;
let period_lump_sum_return = ByDcaPeriod::try_new(|name, _days| {
@@ -44,7 +44,7 @@ impl Vecs {
})?;
let class_stack = ByDcaClass::try_new(|name, _year, _day1| {
ValueFromHeight::forced_import(db, &format!("dca_stack_{name}"), version, indexes)
AmountFromHeight::forced_import(db, &format!("dca_stack_{name}"), version, indexes)
})?;
let class_cost_basis = ByDcaClass::try_new(|name, _year, _day1| {

View File

@@ -3,7 +3,7 @@ use brk_types::{BasisPointsSigned32, Cents, Height, Sats};
use vecdb::{EagerVec, PcoVec, Rw, StorageMode};
use super::{ByDcaCagr, ByDcaClass, ByDcaPeriod};
use crate::internal::{ComputedFromHeight, PercentFromHeight, Price, ValueFromHeight};
use crate::internal::{AmountFromHeight, ComputedFromHeight, PercentFromHeight, Price};
#[derive(Traversable)]
pub struct Vecs<M: StorageMode = Rw> {
/// Per-height DCA sats contribution: sats_from_dca(close) on day boundaries, 0 otherwise.
@@ -11,17 +11,17 @@ pub struct Vecs<M: StorageMode = Rw> {
pub dca_sats_per_day: M::Stored<EagerVec<PcoVec<Height, Sats>>>,
// DCA by period
pub period_stack: ByDcaPeriod<ValueFromHeight<M>>,
pub period_stack: ByDcaPeriod<AmountFromHeight<M>>,
pub period_cost_basis: ByDcaPeriod<Price<ComputedFromHeight<Cents, M>>>,
pub period_return: ByDcaPeriod<PercentFromHeight<BasisPointsSigned32, M>>,
pub period_cagr: ByDcaCagr<PercentFromHeight<BasisPointsSigned32, M>>,
// Lump sum by period (for comparison with DCA)
pub period_lump_sum_stack: ByDcaPeriod<ValueFromHeight<M>>,
pub period_lump_sum_stack: ByDcaPeriod<AmountFromHeight<M>>,
pub period_lump_sum_return: ByDcaPeriod<PercentFromHeight<BasisPointsSigned32, M>>,
// DCA by year class
pub class_stack: ByDcaClass<ValueFromHeight<M>>,
pub class_stack: ByDcaClass<AmountFromHeight<M>>,
pub class_cost_basis: ByDcaClass<Price<ComputedFromHeight<Cents, M>>>,
pub class_return: ByDcaClass<PercentFromHeight<BasisPointsSigned32, M>>,
}

View File

@@ -56,7 +56,7 @@ impl Vecs {
self.stoch_d.bps.height.compute_rolling_average(
starting_indexes.height,
&blocks.count.height_3d_ago,
&blocks.lookback.height_3d_ago,
&self.stoch_k.bps.height,
exit,
)?;

View File

@@ -17,9 +17,9 @@ pub(super) fn compute(
exit: &Exit,
) -> Result<()> {
let close = &prices.price.usd.height;
let ws_fast = blocks.count.start_vec(fast_days);
let ws_slow = blocks.count.start_vec(slow_days);
let ws_signal = blocks.count.start_vec(signal_days);
let ws_fast = blocks.lookback.start_vec(fast_days);
let ws_slow = blocks.lookback.start_vec(slow_days);
let ws_signal = blocks.lookback.start_vec(signal_days);
chain
.ema_fast

View File

@@ -14,8 +14,8 @@ pub(super) fn compute(
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
let ws_rma = blocks.count.start_vec(rma_days);
let ws_sma = blocks.count.start_vec(stoch_sma_days);
let ws_rma = blocks.lookback.start_vec(rma_days);
let ws_sma = blocks.lookback.start_vec(stoch_sma_days);
// Gains = max(return, 0)
chain.gains.height.compute_transform(

View File

@@ -16,7 +16,7 @@ impl Vecs {
let price = &prices.price.cents.height;
for (price_lookback, days) in self.price_lookback.iter_mut_with_days() {
let window_starts = blocks.count.start_vec(days as usize);
let window_starts = blocks.lookback.start_vec(days as usize);
price_lookback.cents.height.compute_lookback(
starting_indexes.height,
window_starts,

View File

@@ -33,7 +33,7 @@ impl Vecs {
(&mut self.price_sma_200w, 200 * 7),
(&mut self.price_sma_4y, 4 * 365),
] {
let window_starts = blocks.count.start_vec(period);
let window_starts = blocks.lookback.start_vec(period);
sma.compute_all(prices, starting_indexes, exit, |v| {
v.compute_rolling_average(starting_indexes.height, window_starts, close, exit)?;
Ok(())
@@ -58,7 +58,7 @@ impl Vecs {
(&mut self.price_ema_200w, 200 * 7),
(&mut self.price_ema_4y, 4 * 365),
] {
let window_starts = blocks.count.start_vec(period);
let window_starts = blocks.lookback.start_vec(period);
ema.compute_all(prices, starting_indexes, exit, |v| {
v.compute_rolling_ema(starting_indexes.height, window_starts, close, exit)?;
Ok(())

View File

@@ -19,22 +19,22 @@ impl Vecs {
(
&mut self.price_min_1w.cents.height,
&mut self.price_max_1w.cents.height,
&blocks.count.height_1w_ago,
&blocks.lookback.height_1w_ago,
),
(
&mut self.price_min_2w.cents.height,
&mut self.price_max_2w.cents.height,
&blocks.count.height_2w_ago,
&blocks.lookback.height_2w_ago,
),
(
&mut self.price_min_1m.cents.height,
&mut self.price_max_1m.cents.height,
&blocks.count.height_1m_ago,
&blocks.lookback.height_1m_ago,
),
(
&mut self.price_min_1y.cents.height,
&mut self.price_max_1y.cents.height,
&blocks.count.height_1y_ago,
&blocks.lookback.height_1y_ago,
),
] {
min_vec.compute_rolling_min_from_starts(
@@ -75,7 +75,7 @@ impl Vecs {
// 2w rolling sum of true range
self.price_true_range_sum_2w.height.compute_rolling_sum(
starting_indexes.height,
&blocks.count.height_2w_ago,
&blocks.lookback.height_2w_ago,
&self.price_true_range.height,
exit,
)?;
@@ -88,7 +88,7 @@ impl Vecs {
&self.price_true_range_sum_2w.height,
&self.price_max_2w.cents.height,
&self.price_min_2w.cents.height,
&blocks.count.height_2w_ago,
&blocks.lookback.height_2w_ago,
|(h, tr_sum, max, min, window_start, ..)| {
let range = f64::from(max) - f64::from(min);
let n = (h.to_usize() - window_start.to_usize() + 1) as f32;

View File

@@ -22,7 +22,7 @@ impl Vecs {
self.rewards.compute(
indexer,
indexes,
&blocks.count,
&blocks.lookback,
&transactions.fees,
prices,
starting_indexes,
@@ -31,6 +31,7 @@ impl Vecs {
self.hashrate.compute(
&blocks.count,
&blocks.lookback,
&blocks.difficulty,
&self.rewards.coinbase.sum._24h.sats.height,
&self.rewards.coinbase.sum._24h.usd.height,

View File

@@ -9,9 +9,11 @@ use crate::{
};
impl Vecs {
#[allow(clippy::too_many_arguments)]
pub(crate) fn compute(
&mut self,
count_vecs: &blocks::CountVecs,
lookback: &blocks::LookbackVecs,
difficulty_vecs: &blocks::DifficultyVecs,
coinbase_sats_24h_sum: &impl ReadableVec<Height, Sats>,
coinbase_usd_24h_sum: &impl ReadableVec<Height, Dollars>,
@@ -20,7 +22,7 @@ impl Vecs {
) -> Result<()> {
self.hash_rate.height.compute_transform2(
starting_indexes.height,
&count_vecs.block_count_sum._24h.height,
&count_vecs.block_count.sum._24h.height,
&difficulty_vecs.as_hash.height,
|(i, block_count_sum, difficulty_as_hash, ..)| {
(
@@ -36,10 +38,10 @@ impl Vecs {
let hash_rate = &self.hash_rate.height;
for (sma, window) in [
(&mut self.hash_rate_sma_1w.height, &count_vecs.height_1w_ago),
(&mut self.hash_rate_sma_1m.height, &count_vecs.height_1m_ago),
(&mut self.hash_rate_sma_2m.height, &count_vecs.height_2m_ago),
(&mut self.hash_rate_sma_1y.height, &count_vecs.height_1y_ago),
(&mut self.hash_rate_sma_1w.height, &lookback.height_1w_ago),
(&mut self.hash_rate_sma_1m.height, &lookback.height_1m_ago),
(&mut self.hash_rate_sma_2m.height, &lookback.height_2m_ago),
(&mut self.hash_rate_sma_1y.height, &lookback.height_1y_ago),
] {
sma.compute_rolling_average(starting_indexes.height, window, hash_rate, exit)?;
}

View File

@@ -12,13 +12,13 @@ impl Vecs {
&mut self,
indexer: &Indexer,
indexes: &indexes::Vecs,
count_vecs: &blocks::CountVecs,
lookback: &blocks::LookbackVecs,
transactions_fees: &transactions::FeesVecs,
prices: &prices::Vecs,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
let window_starts = count_vecs.window_starts();
let window_starts = lookback.window_starts();
self.coinbase.compute(
starting_indexes.height,
@@ -163,7 +163,7 @@ impl Vecs {
self.subsidy_sma_1y.cents.height.compute_rolling_average(
starting_indexes.height,
&count_vecs.height_1y_ago,
&lookback.height_1y_ago,
&self.subsidy.base.cents.height,
exit,
)?;

View File

@@ -6,8 +6,8 @@ use super::Vecs;
use crate::{
indexes,
internal::{
FiatFromHeight, PercentFromHeight, PercentRollingWindows, ValueFromHeightCumulative,
ValueFromHeightCumulativeSum, ValueFromHeightFull,
AmountFromHeightCumulative, AmountFromHeightCumulativeSum, AmountFromHeightFull,
FiatFromHeight, PercentFromHeight, PercentRollingWindows,
},
};
@@ -18,10 +18,12 @@ impl Vecs {
indexes: &indexes::Vecs,
) -> Result<Self> {
Ok(Self {
coinbase: ValueFromHeightCumulativeSum::forced_import(db, "coinbase", version, indexes)?,
subsidy: ValueFromHeightCumulative::forced_import(db, "subsidy", version, indexes)?,
fees: ValueFromHeightFull::forced_import(db, "fees", version, indexes)?,
unclaimed_rewards: ValueFromHeightCumulativeSum::forced_import(
coinbase: AmountFromHeightCumulativeSum::forced_import(
db, "coinbase", version, indexes,
)?,
subsidy: AmountFromHeightCumulative::forced_import(db, "subsidy", version, indexes)?,
fees: AmountFromHeightFull::forced_import(db, "fees", version, indexes)?,
unclaimed_rewards: AmountFromHeightCumulativeSum::forced_import(
db,
"unclaimed_rewards",
version,

View File

@@ -3,16 +3,16 @@ use brk_types::{BasisPoints16, Cents};
use vecdb::{Rw, StorageMode};
use crate::internal::{
FiatFromHeight, PercentFromHeight, PercentRollingWindows, ValueFromHeightCumulative,
ValueFromHeightCumulativeSum, ValueFromHeightFull,
AmountFromHeightCumulative, AmountFromHeightCumulativeSum, AmountFromHeightFull,
FiatFromHeight, PercentFromHeight, PercentRollingWindows,
};
#[derive(Traversable)]
pub struct Vecs<M: StorageMode = Rw> {
pub coinbase: ValueFromHeightCumulativeSum<M>,
pub subsidy: ValueFromHeightCumulative<M>,
pub fees: ValueFromHeightFull<M>,
pub unclaimed_rewards: ValueFromHeightCumulativeSum<M>,
pub coinbase: AmountFromHeightCumulativeSum<M>,
pub subsidy: AmountFromHeightCumulative<M>,
pub fees: AmountFromHeightFull<M>,
pub unclaimed_rewards: AmountFromHeightCumulativeSum<M>,
pub fee_dominance: PercentFromHeight<BasisPoints16, M>,
pub fee_dominance_rolling: PercentRollingWindows<BasisPoints16, M>,
pub subsidy_dominance: PercentFromHeight<BasisPoints16, M>,

View File

@@ -18,7 +18,7 @@ impl Vecs {
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
let window_starts = blocks.count.window_starts();
let window_starts = blocks.lookback.window_starts();
self.total_count
.compute(starting_indexes.height, &window_starts, exit, |full| {
full.compute_with_skip(

View File

@@ -7,8 +7,8 @@ use vecdb::{BinaryTransform, Database, Exit, ReadableVec, Rw, StorageMode, Versi
use crate::{
blocks, indexes,
internal::{
MaskSats, PercentRollingWindows, RatioU32Bp16, RollingWindows,
ValueFromHeightCumulativeSum,
AmountFromHeightCumulativeSum, MaskSats, PercentRollingWindows, RatioU32Bp16,
RollingWindows,
},
mining, prices,
};
@@ -25,7 +25,7 @@ pub struct Vecs<M: StorageMode = Rw> {
#[traversable(wrap = "blocks_mined", rename = "sum")]
pub blocks_mined_sum: RollingWindows<StoredU32, M>,
pub rewards: ValueFromHeightCumulativeSum<M>,
pub rewards: AmountFromHeightCumulativeSum<M>,
pub dominance_rolling: PercentRollingWindows<BasisPoints16, M>,
}
@@ -44,7 +44,7 @@ impl Vecs {
RollingWindows::forced_import(db, &suffix("blocks_mined"), version, indexes)?;
let rewards =
ValueFromHeightCumulativeSum::forced_import(db, &suffix("rewards"), version, indexes)?;
AmountFromHeightCumulativeSum::forced_import(db, &suffix("rewards"), version, indexes)?;
let dominance_rolling =
PercentRollingWindows::forced_import(db, &suffix("dominance"), version, indexes)?;
@@ -70,7 +70,7 @@ impl Vecs {
self.base
.compute(starting_indexes, height_to_pool, blocks, exit)?;
let window_starts = blocks.count.window_starts();
let window_starts = blocks.lookback.window_starts();
self.blocks_mined_sum.compute_rolling_sum(
starting_indexes.height,
@@ -79,17 +79,12 @@ impl Vecs {
exit,
)?;
for (dom, (mined, total)) in self
.dominance_rolling
.as_mut_array()
.into_iter()
.zip(
self.blocks_mined_sum
.as_array()
.into_iter()
.zip(blocks.count.block_count_sum.as_array()),
)
{
for (dom, (mined, total)) in self.dominance_rolling.as_mut_array().into_iter().zip(
self.blocks_mined_sum
.as_array()
.into_iter()
.zip(blocks.count.block_count.sum.as_array()),
) {
dom.compute_binary::<StoredU32, StoredU32, RatioU32Bp16>(
starting_indexes.height,
&mined.height,

View File

@@ -18,7 +18,7 @@ impl Vecs {
exit: &Exit,
) -> Result<()> {
self.count
.compute(indexer, &blocks.count, starting_indexes, exit)?;
.compute(indexer, &blocks.lookback, starting_indexes, exit)?;
self.value
.compute(indexer, prices, starting_indexes, exit)?;

View File

@@ -10,11 +10,11 @@ impl Vecs {
pub(crate) fn compute(
&mut self,
indexer: &Indexer,
count_vecs: &blocks::CountVecs,
lookback: &blocks::LookbackVecs,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
let window_starts = count_vecs.window_starts();
let window_starts = lookback.window_starts();
self.p2a
.compute(starting_indexes.height, &window_starts, exit, |v| {

View File

@@ -3,7 +3,7 @@ use brk_types::Version;
use vecdb::Database;
use super::Vecs;
use crate::{indexes, internal::ValueFromHeightCumulative};
use crate::{indexes, internal::AmountFromHeightCumulative};
impl Vecs {
pub(crate) fn forced_import(
@@ -12,7 +12,7 @@ impl Vecs {
indexes: &indexes::Vecs,
) -> Result<Self> {
Ok(Self {
opreturn: ValueFromHeightCumulative::forced_import(
opreturn: AmountFromHeightCumulative::forced_import(
db,
"opreturn_value",
version,

View File

@@ -1,9 +1,9 @@
use brk_traversable::Traversable;
use vecdb::{Rw, StorageMode};
use crate::internal::ValueFromHeightCumulative;
use crate::internal::AmountFromHeightCumulative;
#[derive(Traversable)]
pub struct Vecs<M: StorageMode = Rw> {
pub opreturn: ValueFromHeightCumulative<M>,
pub opreturn: AmountFromHeightCumulative<M>,
}

View File

@@ -10,12 +10,12 @@ impl Vecs {
&mut self,
scripts: &scripts::Vecs,
mining: &mining::Vecs,
count_vecs: &blocks::CountVecs,
lookback: &blocks::LookbackVecs,
prices: &prices::Vecs,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
let window_starts = count_vecs.window_starts();
let window_starts = lookback.window_starts();
// 1. Compute opreturn supply - copy per-block opreturn values from scripts
self.opreturn.compute(

View File

@@ -3,7 +3,7 @@ use brk_types::Version;
use vecdb::Database;
use super::Vecs;
use crate::{indexes, internal::ValueFromHeightCumulativeSum};
use crate::{indexes, internal::AmountFromHeightCumulativeSum};
impl Vecs {
pub(crate) fn forced_import(
@@ -12,13 +12,13 @@ impl Vecs {
indexes: &indexes::Vecs,
) -> Result<Self> {
Ok(Self {
opreturn: ValueFromHeightCumulativeSum::forced_import(
opreturn: AmountFromHeightCumulativeSum::forced_import(
db,
"opreturn_supply",
version,
indexes,
)?,
unspendable: ValueFromHeightCumulativeSum::forced_import(
unspendable: AmountFromHeightCumulativeSum::forced_import(
db,
"unspendable_supply",
version,

View File

@@ -1,10 +1,10 @@
use brk_traversable::Traversable;
use vecdb::{Rw, StorageMode};
use crate::internal::ValueFromHeightCumulativeSum;
use crate::internal::AmountFromHeightCumulativeSum;
#[derive(Traversable)]
pub struct Vecs<M: StorageMode = Rw> {
pub opreturn: ValueFromHeightCumulativeSum<M>,
pub unspendable: ValueFromHeightCumulativeSum<M>,
pub opreturn: AmountFromHeightCumulativeSum<M>,
pub unspendable: AmountFromHeightCumulativeSum<M>,
}

View File

@@ -22,7 +22,7 @@ impl Vecs {
self.burned.compute(
scripts,
mining,
&blocks.count,
&blocks.lookback,
prices,
starting_indexes,
exit,
@@ -35,7 +35,7 @@ impl Vecs {
.height
.compute_rolling_ratio_change(
starting_indexes.height,
&blocks.count.height_1y_ago,
&blocks.lookback.height_1y_ago,
&circulating_supply.height,
exit,
)?;
@@ -45,7 +45,7 @@ impl Vecs {
.compute(blocks, transactions, distribution, starting_indexes, exit)?;
// 4. Compute market cap delta (change + rate across 4 windows)
let window_starts = blocks.count.window_starts();
let window_starts = blocks.lookback.window_starts();
self.market_cap_delta.compute(
starting_indexes.height,

View File

@@ -6,7 +6,7 @@ use brk_types::{Cents, Dollars, Sats, Version};
use crate::{
distribution, indexes,
internal::{
FiatRollingDelta, Identity, LazyFiatFromHeight, LazyValueFromHeight, PercentFromHeight,
FiatRollingDelta, Identity, LazyFiatFromHeight, LazyAmountFromHeight, PercentFromHeight,
RollingWindows, SatsToBitcoin, finalize_db, open_db,
},
};
@@ -28,7 +28,7 @@ impl Vecs {
let supply_metrics = &distribution.utxo_cohorts.all.metrics.supply;
// Circulating supply - lazy refs to distribution
let circulating = LazyValueFromHeight::from_block_source::<
let circulating = LazyAmountFromHeight::from_block_source::<
Identity<Sats>,
SatsToBitcoin,
Identity<Cents>,

View File

@@ -4,7 +4,7 @@ use vecdb::{Database, Rw, StorageMode};
use super::{burned, velocity};
use crate::internal::{
FiatRollingDelta, LazyFiatFromHeight, LazyValueFromHeight, PercentFromHeight, RollingWindows,
FiatRollingDelta, LazyFiatFromHeight, LazyAmountFromHeight, PercentFromHeight, RollingWindows,
};
#[derive(Traversable)]
@@ -12,7 +12,7 @@ pub struct Vecs<M: StorageMode = Rw> {
#[traversable(skip)]
pub(crate) db: Database,
pub circulating: LazyValueFromHeight,
pub circulating: LazyAmountFromHeight,
pub burned: burned::Vecs<M>,
pub inflation_rate: PercentFromHeight<BasisPointsSigned32, M>,
pub velocity: velocity::Vecs<M>,

View File

@@ -20,7 +20,7 @@ impl Vecs {
// BTC velocity at height level
self.btc.height.compute_rolling_ratio(
starting_indexes.height,
&blocks.count.height_1y_ago,
&blocks.lookback.height_1y_ago,
&transactions.volume.sent_sum.sats,
&circulating_supply.sats.height,
exit,
@@ -29,7 +29,7 @@ impl Vecs {
// USD velocity at height level
self.usd.height.compute_rolling_ratio(
starting_indexes.height,
&blocks.count.height_1y_ago,
&blocks.lookback.height_1y_ago,
&transactions.volume.sent_sum.usd,
&circulating_supply.usd.height,
exit,

View File

@@ -22,11 +22,11 @@ impl Vecs {
) -> Result<()> {
// Count computes first
self.count
.compute(indexer, &blocks.count, starting_indexes, exit)?;
.compute(indexer, &blocks.lookback, starting_indexes, exit)?;
// Versions depends on count
self.versions
.compute(indexer, &blocks.count, starting_indexes, exit)?;
.compute(indexer, &blocks.lookback, starting_indexes, exit)?;
// Size computes next (uses 6-block rolling window)
self.size

View File

@@ -10,11 +10,11 @@ impl Vecs {
pub(crate) fn compute(
&mut self,
indexer: &Indexer,
count_vecs: &blocks::CountVecs,
lookback: &blocks::LookbackVecs,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
let window_starts = count_vecs.window_starts();
let window_starts = lookback.window_starts();
self.tx_count
.compute(starting_indexes.height, &window_starts, exit, |height| {
Ok(height.compute_count_from_indexes(

View File

@@ -10,11 +10,11 @@ impl Vecs {
pub(crate) fn compute(
&mut self,
indexer: &Indexer,
count_vecs: &blocks::CountVecs,
lookback: &blocks::LookbackVecs,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
let window_starts = count_vecs.window_starts();
let window_starts = lookback.window_starts();
let tx_vany = |tx_vany: &mut ComputedFromHeightCumulativeSum<StoredU64>,
txversion: TxVersion| {

View File

@@ -22,7 +22,7 @@ impl Vecs {
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
let window_starts = blocks.count.window_starts();
let window_starts = blocks.lookback.window_starts();
self.sent_sum.compute(
starting_indexes.height,
@@ -60,7 +60,7 @@ impl Vecs {
// Annualized volume: rolling 1y sum of per-block sent volume
self.annualized_volume.sats.height.compute_rolling_sum(
starting_indexes.height,
&blocks.count.height_1y_ago,
&blocks.lookback.height_1y_ago,
&self.sent_sum.sats,
exit,
)?;

View File

@@ -5,7 +5,7 @@ use vecdb::Database;
use super::Vecs;
use crate::{
indexes,
internal::{ComputedFromHeight, ValueFromHeight, ValueFromHeightRolling},
internal::{AmountFromHeight, AmountFromHeightRolling, ComputedFromHeight},
};
impl Vecs {
@@ -16,14 +16,14 @@ impl Vecs {
) -> Result<Self> {
let v2 = Version::TWO;
Ok(Self {
sent_sum: ValueFromHeightRolling::forced_import(db, "sent_sum", version, indexes)?,
received_sum: ValueFromHeightRolling::forced_import(
sent_sum: AmountFromHeightRolling::forced_import(db, "sent_sum", version, indexes)?,
received_sum: AmountFromHeightRolling::forced_import(
db,
"received_sum",
version,
indexes,
)?,
annualized_volume: ValueFromHeight::forced_import(
annualized_volume: AmountFromHeight::forced_import(
db,
"annualized_volume",
version,

View File

@@ -2,13 +2,13 @@ use brk_traversable::Traversable;
use brk_types::StoredF32;
use vecdb::{Rw, StorageMode};
use crate::internal::{ComputedFromHeight, ValueFromHeight, ValueFromHeightRolling};
use crate::internal::{AmountFromHeight, AmountFromHeightRolling, ComputedFromHeight};
#[derive(Traversable)]
pub struct Vecs<M: StorageMode = Rw> {
pub sent_sum: ValueFromHeightRolling<M>,
pub received_sum: ValueFromHeightRolling<M>,
pub annualized_volume: ValueFromHeight<M>,
pub sent_sum: AmountFromHeightRolling<M>,
pub received_sum: AmountFromHeightRolling<M>,
pub annualized_volume: AmountFromHeight<M>,
pub tx_per_sec: ComputedFromHeight<StoredF32, M>,
pub outputs_per_sec: ComputedFromHeight<StoredF32, M>,
pub inputs_per_sec: ComputedFromHeight<StoredF32, M>,

View File

@@ -16,6 +16,7 @@ pub struct BlocksVecs<M: StorageMode = Rw> {
/// Doesn't guarantee continuity due to possible reorgs and more generally the nature of mining
#[traversable(wrap = "time")]
pub timestamp: M::Stored<PcoVec<Height, Timestamp>>,
#[traversable(wrap = "size")]
pub total_size: M::Stored<PcoVec<Height, StoredU64>>,
pub weight: M::Stored<PcoVec<Height, Weight>>,
}