global: snapshot

This commit is contained in:
nym21
2026-03-02 19:44:45 +01:00
parent 4e7cd9ab6f
commit ccb2db2309
37 changed files with 337 additions and 1412 deletions

View File

@@ -1,7 +1,7 @@
use brk_error::Result;
use brk_indexer::Indexer;
use brk_types::{Height, StoredU32, Timestamp};
use vecdb::{EagerVec, Exit, PcoVec, ReadableVec, VecIndex};
use vecdb::{AnyVec, Cursor, EagerVec, Exit, PcoVec, ReadableVec, VecIndex};
use crate::ComputeIndexes;
@@ -28,135 +28,134 @@ impl Vecs {
exit,
)?;
// Compute rolling window starts (collect monotonic data once for all windows)
let monotonic_data: Vec<Timestamp> = time.timestamp_monotonic.collect();
self.compute_rolling_start_hours(&monotonic_data, time, starting_indexes, exit, 1, |s| {
// Compute rolling window starts
self.compute_rolling_start_hours(time, starting_indexes, exit, 1, |s| {
&mut s.height_1h_ago
})?;
self.compute_rolling_start(&monotonic_data, time, starting_indexes, exit, 1, |s| {
self.compute_rolling_start(time, starting_indexes, exit, 1, |s| {
&mut s.height_24h_ago
})?;
self.compute_rolling_start(&monotonic_data, time, starting_indexes, exit, 3, |s| {
self.compute_rolling_start(time, starting_indexes, exit, 3, |s| {
&mut s.height_3d_ago
})?;
self.compute_rolling_start(&monotonic_data, time, starting_indexes, exit, 7, |s| {
self.compute_rolling_start(time, starting_indexes, exit, 7, |s| {
&mut s.height_1w_ago
})?;
self.compute_rolling_start(&monotonic_data, time, starting_indexes, exit, 8, |s| {
self.compute_rolling_start(time, starting_indexes, exit, 8, |s| {
&mut s.height_8d_ago
})?;
self.compute_rolling_start(&monotonic_data, time, starting_indexes, exit, 9, |s| {
self.compute_rolling_start(time, starting_indexes, exit, 9, |s| {
&mut s.height_9d_ago
})?;
self.compute_rolling_start(&monotonic_data, time, starting_indexes, exit, 12, |s| {
self.compute_rolling_start(time, starting_indexes, exit, 12, |s| {
&mut s.height_12d_ago
})?;
self.compute_rolling_start(&monotonic_data, time, starting_indexes, exit, 13, |s| {
self.compute_rolling_start(time, starting_indexes, exit, 13, |s| {
&mut s.height_13d_ago
})?;
self.compute_rolling_start(&monotonic_data, time, starting_indexes, exit, 14, |s| {
self.compute_rolling_start(time, starting_indexes, exit, 14, |s| {
&mut s.height_2w_ago
})?;
self.compute_rolling_start(&monotonic_data, time, starting_indexes, exit, 21, |s| {
self.compute_rolling_start(time, starting_indexes, exit, 21, |s| {
&mut s.height_21d_ago
})?;
self.compute_rolling_start(&monotonic_data, time, starting_indexes, exit, 26, |s| {
self.compute_rolling_start(time, starting_indexes, exit, 26, |s| {
&mut s.height_26d_ago
})?;
self.compute_rolling_start(&monotonic_data, time, starting_indexes, exit, 30, |s| {
self.compute_rolling_start(time, starting_indexes, exit, 30, |s| {
&mut s.height_1m_ago
})?;
self.compute_rolling_start(&monotonic_data, time, starting_indexes, exit, 34, |s| {
self.compute_rolling_start(time, starting_indexes, exit, 34, |s| {
&mut s.height_34d_ago
})?;
self.compute_rolling_start(&monotonic_data, time, starting_indexes, exit, 55, |s| {
self.compute_rolling_start(time, starting_indexes, exit, 55, |s| {
&mut s.height_55d_ago
})?;
self.compute_rolling_start(&monotonic_data, time, starting_indexes, exit, 60, |s| {
self.compute_rolling_start(time, starting_indexes, exit, 60, |s| {
&mut s.height_2m_ago
})?;
self.compute_rolling_start(&monotonic_data, time, starting_indexes, exit, 63, |s| {
self.compute_rolling_start(time, starting_indexes, exit, 63, |s| {
&mut s.height_9w_ago
})?;
self.compute_rolling_start(&monotonic_data, time, starting_indexes, exit, 84, |s| {
self.compute_rolling_start(time, starting_indexes, exit, 84, |s| {
&mut s.height_12w_ago
})?;
self.compute_rolling_start(&monotonic_data, time, starting_indexes, exit, 89, |s| {
self.compute_rolling_start(time, starting_indexes, exit, 89, |s| {
&mut s.height_89d_ago
})?;
self.compute_rolling_start(&monotonic_data, time, starting_indexes, exit, 90, |s| {
self.compute_rolling_start(time, starting_indexes, exit, 90, |s| {
&mut s.height_3m_ago
})?;
self.compute_rolling_start(&monotonic_data, time, starting_indexes, exit, 98, |s| {
self.compute_rolling_start(time, starting_indexes, exit, 98, |s| {
&mut s.height_14w_ago
})?;
self.compute_rolling_start(&monotonic_data, time, starting_indexes, exit, 111, |s| {
self.compute_rolling_start(time, starting_indexes, exit, 111, |s| {
&mut s.height_111d_ago
})?;
self.compute_rolling_start(&monotonic_data, time, starting_indexes, exit, 144, |s| {
self.compute_rolling_start(time, starting_indexes, exit, 144, |s| {
&mut s.height_144d_ago
})?;
self.compute_rolling_start(&monotonic_data, time, starting_indexes, exit, 180, |s| {
self.compute_rolling_start(time, starting_indexes, exit, 180, |s| {
&mut s.height_6m_ago
})?;
self.compute_rolling_start(&monotonic_data, time, starting_indexes, exit, 182, |s| {
self.compute_rolling_start(time, starting_indexes, exit, 182, |s| {
&mut s.height_26w_ago
})?;
self.compute_rolling_start(&monotonic_data, time, starting_indexes, exit, 200, |s| {
self.compute_rolling_start(time, starting_indexes, exit, 200, |s| {
&mut s.height_200d_ago
})?;
self.compute_rolling_start(&monotonic_data, time, starting_indexes, exit, 270, |s| {
self.compute_rolling_start(time, starting_indexes, exit, 270, |s| {
&mut s.height_9m_ago
})?;
self.compute_rolling_start(&monotonic_data, time, starting_indexes, exit, 350, |s| {
self.compute_rolling_start(time, starting_indexes, exit, 350, |s| {
&mut s.height_350d_ago
})?;
self.compute_rolling_start(&monotonic_data, time, starting_indexes, exit, 360, |s| {
self.compute_rolling_start(time, starting_indexes, exit, 360, |s| {
&mut s.height_12m_ago
})?;
self.compute_rolling_start(&monotonic_data, time, starting_indexes, exit, 365, |s| {
self.compute_rolling_start(time, starting_indexes, exit, 365, |s| {
&mut s.height_1y_ago
})?;
self.compute_rolling_start(&monotonic_data, time, starting_indexes, exit, 420, |s| {
self.compute_rolling_start(time, starting_indexes, exit, 420, |s| {
&mut s.height_14m_ago
})?;
self.compute_rolling_start(&monotonic_data, time, starting_indexes, exit, 730, |s| {
self.compute_rolling_start(time, starting_indexes, exit, 730, |s| {
&mut s.height_2y_ago
})?;
self.compute_rolling_start(&monotonic_data, time, starting_indexes, exit, 780, |s| {
self.compute_rolling_start(time, starting_indexes, exit, 780, |s| {
&mut s.height_26m_ago
})?;
self.compute_rolling_start(&monotonic_data, time, starting_indexes, exit, 1095, |s| {
self.compute_rolling_start(time, starting_indexes, exit, 1095, |s| {
&mut s.height_3y_ago
})?;
self.compute_rolling_start(&monotonic_data, time, starting_indexes, exit, 1400, |s| {
self.compute_rolling_start(time, starting_indexes, exit, 1400, |s| {
&mut s.height_200w_ago
})?;
self.compute_rolling_start(&monotonic_data, time, starting_indexes, exit, 1460, |s| {
self.compute_rolling_start(time, starting_indexes, exit, 1460, |s| {
&mut s.height_4y_ago
})?;
self.compute_rolling_start(&monotonic_data, time, starting_indexes, exit, 1825, |s| {
self.compute_rolling_start(time, starting_indexes, exit, 1825, |s| {
&mut s.height_5y_ago
})?;
self.compute_rolling_start(&monotonic_data, time, starting_indexes, exit, 2190, |s| {
self.compute_rolling_start(time, starting_indexes, exit, 2190, |s| {
&mut s.height_6y_ago
})?;
self.compute_rolling_start(&monotonic_data, time, starting_indexes, exit, 2920, |s| {
self.compute_rolling_start(time, starting_indexes, exit, 2920, |s| {
&mut s.height_8y_ago
})?;
self.compute_rolling_start(&monotonic_data, time, starting_indexes, exit, 3285, |s| {
self.compute_rolling_start(time, starting_indexes, exit, 3285, |s| {
&mut s.height_9y_ago
})?;
self.compute_rolling_start(&monotonic_data, time, starting_indexes, exit, 3650, |s| {
self.compute_rolling_start(time, starting_indexes, exit, 3650, |s| {
&mut s.height_10y_ago
})?;
self.compute_rolling_start(&monotonic_data, time, starting_indexes, exit, 4380, |s| {
self.compute_rolling_start(time, starting_indexes, exit, 4380, |s| {
&mut s.height_12y_ago
})?;
self.compute_rolling_start(&monotonic_data, time, starting_indexes, exit, 5110, |s| {
self.compute_rolling_start(time, starting_indexes, exit, 5110, |s| {
&mut s.height_14y_ago
})?;
self.compute_rolling_start(&monotonic_data, time, starting_indexes, exit, 9490, |s| {
self.compute_rolling_start(time, starting_indexes, exit, 9490, |s| {
&mut s.height_26y_ago
})?;
@@ -185,7 +184,6 @@ impl Vecs {
fn compute_rolling_start<F>(
&mut self,
monotonic_data: &[Timestamp],
time: &time::Vecs,
starting_indexes: &ComputeIndexes,
exit: &Exit,
@@ -195,13 +193,23 @@ impl Vecs {
where
F: FnOnce(&mut Self) -> &mut EagerVec<PcoVec<Height, Height>>,
{
let mut prev = Height::ZERO;
Ok(get_field(self).compute_transform(
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 t.difference_in_days_between(monotonic_data[prev.to_usize()]) >= days {
while t.difference_in_days_between(prev_ts) >= days {
prev.increment();
prev_ts = cursor.next().unwrap();
if prev > h {
unreachable!()
}
@@ -214,7 +222,6 @@ impl Vecs {
fn compute_rolling_start_hours<F>(
&mut self,
monotonic_data: &[Timestamp],
time: &time::Vecs,
starting_indexes: &ComputeIndexes,
exit: &Exit,
@@ -224,13 +231,23 @@ impl Vecs {
where
F: FnOnce(&mut Self) -> &mut EagerVec<PcoVec<Height, Height>>,
{
let mut prev = Height::ZERO;
Ok(get_field(self).compute_transform(
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 t.difference_in_hours_between(monotonic_data[prev.to_usize()]) >= hours {
while t.difference_in_hours_between(prev_ts) >= hours {
prev.increment();
prev_ts = cursor.next().unwrap();
if prev > h {
unreachable!()
}

View File

@@ -22,7 +22,7 @@ pub struct Vecs<M: StorageMode = Rw> {
/// Time-based periods (minute10year10) are lazy: `idx.to_timestamp()` is a pure
/// function of the index, so no storage or decompression is needed.
/// Epoch-based periods (halvingepoch, difficultyepoch) are eager: their timestamps
/// come from block data via `compute_indirect`.
/// come from block data via `compute_indirect_sequential`.
#[derive(Deref, DerefMut, Traversable)]
#[traversable(transparent)]
pub struct TimestampIndexes<M: StorageMode = Rw>(
@@ -56,13 +56,13 @@ impl TimestampIndexes {
starting_indexes: &ComputeIndexes,
exit: &Exit,
) -> Result<()> {
self.halvingepoch.compute_indirect(
self.halvingepoch.compute_indirect_sequential(
starting_indexes.halvingepoch,
&indexes.halvingepoch.first_height,
&indexer.vecs.blocks.timestamp,
exit,
)?;
self.difficultyepoch.compute_indirect(
self.difficultyepoch.compute_indirect_sequential(
starting_indexes.difficultyepoch,
&indexes.difficultyepoch.first_height,
&indexer.vecs.blocks.timestamp,