global: snapshot

This commit is contained in:
nym21
2026-02-28 00:22:55 +01:00
parent 85c7933ad6
commit a2bd7ca299
38 changed files with 279 additions and 166 deletions

View File

@@ -14,49 +14,9 @@ impl Vecs {
starting_indexes: &ComputeIndexes,
exit: &Exit,
) -> Result<()> {
{
let ts = &mut self.time.timestamp;
macro_rules! period {
($field:ident) => {
ts.$field.compute_transform(
starting_indexes.$field,
&indexes.$field.first_height,
|(idx, _, _)| (idx, idx.to_timestamp()),
exit,
)?;
};
}
period!(minute1);
period!(minute5);
period!(minute10);
period!(minute30);
period!(hour1);
period!(hour4);
period!(hour12);
period!(day1);
period!(day3);
period!(week1);
period!(month1);
period!(month3);
period!(month6);
period!(year1);
period!(year10);
ts.halvingepoch.compute_indirect(
starting_indexes.halvingepoch,
&indexes.halvingepoch.first_height,
&indexer.vecs.blocks.timestamp,
exit,
)?;
ts.difficultyepoch.compute_indirect(
starting_indexes.difficultyepoch,
&indexes.difficultyepoch.first_height,
&indexer.vecs.blocks.timestamp,
exit,
)?;
}
self.time
.timestamp
.compute(indexer, indexes, starting_indexes, exit)?;
self.count
.compute(indexer, &self.time, starting_indexes, exit)?;
self.interval

View File

@@ -29,7 +29,7 @@ impl Vecs {
let interval = IntervalVecs::forced_import(&db, version, indexes)?;
let size = SizeVecs::forced_import(&db, version, indexes)?;
let weight = WeightVecs::forced_import(&db, version, indexes)?;
let time = TimeVecs::forced_import(&db, version)?;
let time = TimeVecs::forced_import(&db, version, indexes)?;
let difficulty = DifficultyVecs::forced_import(&db, version, indexer, indexes)?;
let halving = HalvingVecs::forced_import(&db, version, indexes)?;

View File

@@ -2,11 +2,15 @@ use brk_error::Result;
use brk_types::{Date, Height, Version};
use vecdb::{Database, EagerVec, ImportableVec, LazyVecFrom1, ReadableCloneableVec};
use super::Vecs;
use crate::internal::EagerIndexes;
use super::{TimestampIndexes, Vecs};
use crate::indexes;
impl Vecs {
pub(crate) fn forced_import(db: &Database, version: Version) -> Result<Self> {
pub(crate) fn forced_import(
db: &Database,
version: Version,
indexes: &indexes::Vecs,
) -> Result<Self> {
let timestamp_monotonic =
EagerVec::forced_import(db, "timestamp_monotonic", version)?;
@@ -18,7 +22,34 @@ impl Vecs {
|_height: Height, timestamp| Date::from(timestamp),
),
timestamp_monotonic,
timestamp: EagerIndexes::forced_import(db, "timestamp", version)?,
timestamp: TimestampIndexes::forced_import(db, version, indexes)?,
})
}
}
impl TimestampIndexes {
fn forced_import(
db: &Database,
version: Version,
indexes: &indexes::Vecs,
) -> Result<Self> {
macro_rules! period {
($field:ident) => {
LazyVecFrom1::init(
"timestamp",
version,
indexes.$field.first_height.read_only_boxed_clone(),
|idx, _: Height| idx.to_timestamp(),
)
};
}
macro_rules! epoch {
($field:ident) => {
ImportableVec::forced_import(db, "timestamp", version)?
};
}
Ok(Self(crate::indexes_from!(period, epoch)))
}
}

View File

@@ -2,4 +2,4 @@ mod compute;
mod import;
mod vecs;
pub use vecs::Vecs;
pub use vecs::{TimestampIndexes, Vecs};

View File

@@ -1,13 +1,75 @@
use brk_error::Result;
use brk_traversable::Traversable;
use brk_types::{Date, Height, Timestamp};
use vecdb::{EagerVec, LazyVecFrom1, PcoVec, Rw, StorageMode};
use brk_types::{
Date, Day1, Day3, DifficultyEpoch, HalvingEpoch, Height, Hour1, Hour12, Hour4, Minute1,
Minute10, Minute30, Minute5, Month1, Month3, Month6, Timestamp, Week1, Year1, Year10,
};
use derive_more::{Deref, DerefMut};
use vecdb::{EagerVec, Exit, LazyVecFrom1, PcoVec, Rw, StorageMode};
use crate::internal::EagerIndexes;
use crate::{ComputeIndexes, indexes, internal::Indexes};
/// Timestamp and date metrics for blocks
#[derive(Traversable)]
pub struct Vecs<M: StorageMode = Rw> {
pub date: LazyVecFrom1<Height, Date, Height, Timestamp>,
pub timestamp_monotonic: M::Stored<EagerVec<PcoVec<Height, Timestamp>>>,
pub timestamp: EagerIndexes<Timestamp, M>,
pub timestamp: TimestampIndexes<M>,
}
/// Per-period timestamp indexes.
///
/// Time-based periods (minute1year10) 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`.
#[derive(Deref, DerefMut, Traversable)]
#[traversable(transparent)]
pub struct TimestampIndexes<M: StorageMode = Rw>(
#[allow(clippy::type_complexity)]
pub Indexes<
LazyVecFrom1<Minute1, Timestamp, Minute1, Height>,
LazyVecFrom1<Minute5, Timestamp, Minute5, Height>,
LazyVecFrom1<Minute10, Timestamp, Minute10, Height>,
LazyVecFrom1<Minute30, Timestamp, Minute30, Height>,
LazyVecFrom1<Hour1, Timestamp, Hour1, Height>,
LazyVecFrom1<Hour4, Timestamp, Hour4, Height>,
LazyVecFrom1<Hour12, Timestamp, Hour12, Height>,
LazyVecFrom1<Day1, Timestamp, Day1, Height>,
LazyVecFrom1<Day3, Timestamp, Day3, Height>,
LazyVecFrom1<Week1, Timestamp, Week1, Height>,
LazyVecFrom1<Month1, Timestamp, Month1, Height>,
LazyVecFrom1<Month3, Timestamp, Month3, Height>,
LazyVecFrom1<Month6, Timestamp, Month6, Height>,
LazyVecFrom1<Year1, Timestamp, Year1, Height>,
LazyVecFrom1<Year10, Timestamp, Year10, Height>,
M::Stored<EagerVec<PcoVec<HalvingEpoch, Timestamp>>>,
M::Stored<EagerVec<PcoVec<DifficultyEpoch, Timestamp>>>,
>,
);
impl TimestampIndexes {
/// Compute epoch timestamps via indirect lookup from block timestamps.
/// Time-based periods are lazy (idx.to_timestamp()) and need no compute.
pub(crate) fn compute(
&mut self,
indexer: &brk_indexer::Indexer,
indexes: &indexes::Vecs,
starting_indexes: &ComputeIndexes,
exit: &Exit,
) -> Result<()> {
self.halvingepoch.compute_indirect(
starting_indexes.halvingepoch,
&indexes.halvingepoch.first_height,
&indexer.vecs.blocks.timestamp,
exit,
)?;
self.difficultyepoch.compute_indirect(
starting_indexes.difficultyepoch,
&indexes.difficultyepoch.first_height,
&indexer.vecs.blocks.timestamp,
exit,
)?;
Ok(())
}
}