global: snapshot

This commit is contained in:
nym21
2026-03-10 19:33:50 +01:00
parent 3e29328949
commit 6a728a3357
48 changed files with 889 additions and 710 deletions

View File

@@ -9,153 +9,153 @@ 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
pub _1h: M::Stored<EagerVec<PcoVec<Height, Height>>>,
pub _24h: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 1d
pub _3d: M::Stored<EagerVec<PcoVec<Height, Height>>>,
pub _1w: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 7d
pub _8d: M::Stored<EagerVec<PcoVec<Height, Height>>>,
pub _9d: M::Stored<EagerVec<PcoVec<Height, Height>>>,
pub _12d: M::Stored<EagerVec<PcoVec<Height, Height>>>,
pub _13d: M::Stored<EagerVec<PcoVec<Height, Height>>>,
pub _2w: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 14d
pub _21d: M::Stored<EagerVec<PcoVec<Height, Height>>>,
pub _26d: M::Stored<EagerVec<PcoVec<Height, Height>>>,
pub _1m: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 30d
pub _34d: M::Stored<EagerVec<PcoVec<Height, Height>>>,
pub _55d: M::Stored<EagerVec<PcoVec<Height, Height>>>,
pub _2m: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 60d
pub _9w: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 63d
pub _12w: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 84d
pub _89d: M::Stored<EagerVec<PcoVec<Height, Height>>>,
pub _3m: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 90d
pub _14w: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 98d
pub _111d: M::Stored<EagerVec<PcoVec<Height, Height>>>,
pub _144d: M::Stored<EagerVec<PcoVec<Height, Height>>>,
pub _6m: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 180d
pub _26w: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 182d
pub _200d: M::Stored<EagerVec<PcoVec<Height, Height>>>,
pub _9m: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 270d
pub _350d: M::Stored<EagerVec<PcoVec<Height, Height>>>,
pub _12m: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 360d
pub _1y: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 365d
pub _14m: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 420d
pub _2y: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 730d
pub _26m: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 780d
pub _3y: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 1095d
pub _200w: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 1400d
pub _4y: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 1460d
pub _5y: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 1825d
pub _6y: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 2190d
pub _8y: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 2920d
pub _9y: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 3285d
pub _10y: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 3650d
pub _12y: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 4380d
pub _14y: M::Stored<EagerVec<PcoVec<Height, Height>>>, // 5110d
pub _26y: 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)?,
_1h: ImportableVec::forced_import(db, "height_1h_ago", version)?,
_24h: ImportableVec::forced_import(db, "height_24h_ago", version)?,
_3d: ImportableVec::forced_import(db, "height_3d_ago", version)?,
_1w: ImportableVec::forced_import(db, "height_1w_ago", version)?,
_8d: ImportableVec::forced_import(db, "height_8d_ago", version)?,
_9d: ImportableVec::forced_import(db, "height_9d_ago", version)?,
_12d: ImportableVec::forced_import(db, "height_12d_ago", version)?,
_13d: ImportableVec::forced_import(db, "height_13d_ago", version)?,
_2w: ImportableVec::forced_import(db, "height_2w_ago", version)?,
_21d: ImportableVec::forced_import(db, "height_21d_ago", version)?,
_26d: ImportableVec::forced_import(db, "height_26d_ago", version)?,
_1m: ImportableVec::forced_import(db, "height_1m_ago", version)?,
_34d: ImportableVec::forced_import(db, "height_34d_ago", version)?,
_55d: ImportableVec::forced_import(db, "height_55d_ago", version)?,
_2m: ImportableVec::forced_import(db, "height_2m_ago", version)?,
_9w: ImportableVec::forced_import(db, "height_9w_ago", version)?,
_12w: ImportableVec::forced_import(db, "height_12w_ago", version)?,
_89d: ImportableVec::forced_import(db, "height_89d_ago", version)?,
_3m: ImportableVec::forced_import(db, "height_3m_ago", version)?,
_14w: ImportableVec::forced_import(db, "height_14w_ago", version)?,
_111d: ImportableVec::forced_import(db, "height_111d_ago", version)?,
_144d: ImportableVec::forced_import(db, "height_144d_ago", version)?,
_6m: ImportableVec::forced_import(db, "height_6m_ago", version)?,
_26w: ImportableVec::forced_import(db, "height_26w_ago", version)?,
_200d: ImportableVec::forced_import(db, "height_200d_ago", version)?,
_9m: ImportableVec::forced_import(db, "height_9m_ago", version)?,
_350d: ImportableVec::forced_import(db, "height_350d_ago", version)?,
_12m: ImportableVec::forced_import(db, "height_12m_ago", version)?,
_1y: ImportableVec::forced_import(db, "height_1y_ago", version)?,
_14m: ImportableVec::forced_import(db, "height_14m_ago", version)?,
_2y: ImportableVec::forced_import(db, "height_2y_ago", version)?,
_26m: ImportableVec::forced_import(db, "height_26m_ago", version)?,
_3y: ImportableVec::forced_import(db, "height_3y_ago", version)?,
_200w: ImportableVec::forced_import(db, "height_200w_ago", version)?,
_4y: ImportableVec::forced_import(db, "height_4y_ago", version)?,
_5y: ImportableVec::forced_import(db, "height_5y_ago", version)?,
_6y: ImportableVec::forced_import(db, "height_6y_ago", version)?,
_8y: ImportableVec::forced_import(db, "height_8y_ago", version)?,
_9y: ImportableVec::forced_import(db, "height_9y_ago", version)?,
_10y: ImportableVec::forced_import(db, "height_10y_ago", version)?,
_12y: ImportableVec::forced_import(db, "height_12y_ago", version)?,
_14y: ImportableVec::forced_import(db, "height_14y_ago", version)?,
_26y: 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,
_24h: &self._24h,
_1w: &self._1w,
_1m: &self._1m,
_1y: &self._1y,
}
}
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,
1 => &self._24h,
3 => &self._3d,
7 => &self._1w,
8 => &self._8d,
9 => &self._9d,
12 => &self._12d,
13 => &self._13d,
14 => &self._2w,
21 => &self._21d,
26 => &self._26d,
30 => &self._1m,
34 => &self._34d,
55 => &self._55d,
60 => &self._2m,
63 => &self._9w,
84 => &self._12w,
89 => &self._89d,
90 => &self._3m,
98 => &self._14w,
111 => &self._111d,
144 => &self._144d,
180 => &self._6m,
182 => &self._26w,
200 => &self._200d,
270 => &self._9m,
350 => &self._350d,
360 => &self._12m,
365 => &self._1y,
420 => &self._14m,
730 => &self._2y,
780 => &self._26m,
1095 => &self._3y,
1400 => &self._200w,
1460 => &self._4y,
1825 => &self._5y,
2190 => &self._6y,
2920 => &self._8y,
3285 => &self._9y,
3650 => &self._10y,
4380 => &self._12y,
5110 => &self._14y,
9490 => &self._26y,
_ => panic!("No start vec for {days} days"),
}
}
@@ -167,67 +167,67 @@ impl Vecs {
exit: &Exit,
) -> Result<()> {
self.compute_rolling_start_hours(time, starting_indexes, exit, 1, |s| {
&mut s.height_1h_ago
&mut s._1h
})?;
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, 1, |s| &mut s._24h)?;
self.compute_rolling_start(time, starting_indexes, exit, 3, |s| &mut s._3d)?;
self.compute_rolling_start(time, starting_indexes, exit, 7, |s| &mut s._1w)?;
self.compute_rolling_start(time, starting_indexes, exit, 8, |s| &mut s._8d)?;
self.compute_rolling_start(time, starting_indexes, exit, 9, |s| &mut s._9d)?;
self.compute_rolling_start(time, starting_indexes, exit, 12, |s| &mut s._12d)?;
self.compute_rolling_start(time, starting_indexes, exit, 13, |s| &mut s._13d)?;
self.compute_rolling_start(time, starting_indexes, exit, 14, |s| &mut s._2w)?;
self.compute_rolling_start(time, starting_indexes, exit, 21, |s| &mut s._21d)?;
self.compute_rolling_start(time, starting_indexes, exit, 26, |s| &mut s._26d)?;
self.compute_rolling_start(time, starting_indexes, exit, 30, |s| &mut s._1m)?;
self.compute_rolling_start(time, starting_indexes, exit, 34, |s| &mut s._34d)?;
self.compute_rolling_start(time, starting_indexes, exit, 55, |s| &mut s._55d)?;
self.compute_rolling_start(time, starting_indexes, exit, 60, |s| &mut s._2m)?;
self.compute_rolling_start(time, starting_indexes, exit, 63, |s| &mut s._9w)?;
self.compute_rolling_start(time, starting_indexes, exit, 84, |s| &mut s._12w)?;
self.compute_rolling_start(time, starting_indexes, exit, 89, |s| &mut s._89d)?;
self.compute_rolling_start(time, starting_indexes, exit, 90, |s| &mut s._3m)?;
self.compute_rolling_start(time, starting_indexes, exit, 98, |s| &mut s._14w)?;
self.compute_rolling_start(time, starting_indexes, exit, 111, |s| {
&mut s.height_111d_ago
&mut s._111d
})?;
self.compute_rolling_start(time, starting_indexes, exit, 144, |s| {
&mut s.height_144d_ago
&mut s._144d
})?;
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, 180, |s| &mut s._6m)?;
self.compute_rolling_start(time, starting_indexes, exit, 182, |s| &mut s._26w)?;
self.compute_rolling_start(time, starting_indexes, exit, 200, |s| {
&mut s.height_200d_ago
&mut s._200d
})?;
self.compute_rolling_start(time, starting_indexes, exit, 270, |s| &mut s.height_9m_ago)?;
self.compute_rolling_start(time, starting_indexes, exit, 270, |s| &mut s._9m)?;
self.compute_rolling_start(time, starting_indexes, exit, 350, |s| {
&mut s.height_350d_ago
&mut s._350d
})?;
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, 360, |s| &mut s._12m)?;
self.compute_rolling_start(time, starting_indexes, exit, 365, |s| &mut s._1y)?;
self.compute_rolling_start(time, starting_indexes, exit, 420, |s| &mut s._14m)?;
self.compute_rolling_start(time, starting_indexes, exit, 730, |s| &mut s._2y)?;
self.compute_rolling_start(time, starting_indexes, exit, 780, |s| &mut s._26m)?;
self.compute_rolling_start(time, starting_indexes, exit, 1095, |s| &mut s._3y)?;
self.compute_rolling_start(time, starting_indexes, exit, 1400, |s| {
&mut s.height_200w_ago
&mut s._200w
})?;
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, 1460, |s| &mut s._4y)?;
self.compute_rolling_start(time, starting_indexes, exit, 1825, |s| &mut s._5y)?;
self.compute_rolling_start(time, starting_indexes, exit, 2190, |s| &mut s._6y)?;
self.compute_rolling_start(time, starting_indexes, exit, 2920, |s| &mut s._8y)?;
self.compute_rolling_start(time, starting_indexes, exit, 3285, |s| &mut s._9y)?;
self.compute_rolling_start(time, starting_indexes, exit, 3650, |s| {
&mut s.height_10y_ago
&mut s._10y
})?;
self.compute_rolling_start(time, starting_indexes, exit, 4380, |s| {
&mut s.height_12y_ago
&mut s._12y
})?;
self.compute_rolling_start(time, starting_indexes, exit, 5110, |s| {
&mut s.height_14y_ago
&mut s._14y
})?;
self.compute_rolling_start(time, starting_indexes, exit, 9490, |s| {
&mut s.height_26y_ago
&mut s._26y
})?;
Ok(())

View File

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

View File

@@ -106,7 +106,7 @@ impl ActivityCountVecs {
})
}
pub(crate) fn min_stateful_height(&self) -> usize {
pub(crate) fn min_stateful_len(&self) -> usize {
self.reactivated
.height
.len()
@@ -197,10 +197,10 @@ impl AddressTypeToActivityCountVecs {
))
}
pub(crate) fn min_stateful_height(&self) -> usize {
pub(crate) fn min_stateful_len(&self) -> usize {
self.0
.values()
.map(|v| v.min_stateful_height())
.map(|v| v.min_stateful_len())
.min()
.unwrap_or(0)
}
@@ -272,10 +272,10 @@ impl AddressActivityVecs {
})
}
pub(crate) fn min_stateful_height(&self) -> usize {
pub(crate) fn min_stateful_len(&self) -> usize {
self.all
.min_stateful_height()
.min(self.by_addresstype.min_stateful_height())
.min_stateful_len()
.min(self.by_addresstype.min_stateful_len())
}
pub(crate) fn par_iter_height_mut(

View File

@@ -125,7 +125,7 @@ impl AddressTypeToAddrCountVecs {
)?))
}
pub(crate) fn min_stateful_height(&self) -> usize {
pub(crate) fn min_stateful_len(&self) -> usize {
self.0.values().map(|v| v.height.len()).min().unwrap()
}
@@ -181,8 +181,8 @@ impl AddrCountsVecs {
})
}
pub(crate) fn min_stateful_height(&self) -> usize {
self.all.height.len().min(self.by_addresstype.min_stateful_height())
pub(crate) fn min_stateful_len(&self) -> usize {
self.all.height.len().min(self.by_addresstype.min_stateful_len())
}
pub(crate) fn par_iter_height_mut(

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.lookback.height_1m_ago,
&blocks.lookback._1m,
&v.addr_count.height,
exit,
)
@@ -141,9 +141,9 @@ impl AddressCohorts {
}
/// Get minimum height from all separate cohorts' height-indexed vectors.
pub(crate) fn min_separate_stateful_height_len(&self) -> Height {
pub(crate) fn min_stateful_len(&self) -> Height {
self.iter_separate()
.map(|v| Height::from(v.min_stateful_height_len()))
.map(|v| Height::from(v.min_stateful_len()))
.min()
.unwrap_or_default()
}

View File

@@ -102,11 +102,11 @@ impl Filtered for AddressCohortVecs {
}
impl DynCohortVecs for AddressCohortVecs {
fn min_stateful_height_len(&self) -> usize {
fn min_stateful_len(&self) -> usize {
self.addr_count
.height
.len()
.min(self.metrics.min_stateful_height_len())
.min(self.metrics.min_stateful_len())
}
fn reset_state_starting_height(&mut self) {

View File

@@ -9,7 +9,7 @@ use crate::{blocks, prices};
/// This trait enables heterogeneous cohort processing via trait objects.
pub trait DynCohortVecs: Send + Sync {
/// Get minimum length across height-indexed vectors written in block loop.
fn min_stateful_height_len(&self) -> usize;
fn min_stateful_len(&self) -> usize;
/// Reset the starting height for state tracking.
fn reset_state_starting_height(&mut self);

View File

@@ -712,10 +712,9 @@ impl UTXOCohorts<Rw> {
.try_for_each(|v| v.write_state(height, cleanup))
}
/// Get minimum height from all separate cohorts' + profitability + overlapping realized height-indexed vectors.
pub(crate) fn min_separate_stateful_height_len(&self) -> Height {
pub(crate) fn min_stateful_len(&self) -> Height {
self.iter_separate()
.map(|v| Height::from(v.min_stateful_height_len()))
.map(|v| Height::from(v.min_stateful_len()))
.chain(
self.matured
.iter()
@@ -723,15 +722,15 @@ impl UTXOCohorts<Rw> {
)
.min()
.unwrap_or_default()
.min(Height::from(self.profitability.min_stateful_height_len()))
.min(Height::from(self.profitability.min_stateful_len()))
.min(Height::from(
self.all.metrics.realized.min_stateful_height_len(),
self.all.metrics.realized.min_stateful_len(),
))
.min(Height::from(
self.sth.metrics.realized.min_stateful_height_len(),
self.sth.metrics.realized.min_stateful_len(),
))
.min(Height::from(
self.lth.metrics.realized.min_stateful_height_len(),
self.lth.metrics.realized.min_stateful_len(),
))
}

View File

@@ -14,8 +14,8 @@ impl Filtered for UTXOCohortVecs<CoreCohortMetrics> {
}
impl DynCohortVecs for UTXOCohortVecs<CoreCohortMetrics> {
fn min_stateful_height_len(&self) -> usize {
self.metrics.min_stateful_height_len()
fn min_stateful_len(&self) -> usize {
self.metrics.min_stateful_len()
}
fn reset_state_starting_height(&mut self) {

View File

@@ -18,8 +18,8 @@ impl Filtered for UTXOCohortVecs<MinimalCohortMetrics> {
}
impl DynCohortVecs for UTXOCohortVecs<MinimalCohortMetrics> {
fn min_stateful_height_len(&self) -> usize {
self.metrics.min_stateful_height_len()
fn min_stateful_len(&self) -> usize {
self.metrics.min_stateful_len()
}
fn reset_state_starting_height(&mut self) {

View File

@@ -116,8 +116,8 @@ impl<M: CohortMetricsBase + Traversable> Filtered for UTXOCohortVecs<M> {
}
impl<M: CohortMetricsBase + Traversable> DynCohortVecs for UTXOCohortVecs<M> {
fn min_stateful_height_len(&self) -> usize {
self.metrics.min_stateful_height_len()
fn min_stateful_len(&self) -> usize {
self.metrics.min_stateful_len()
}
fn reset_state_starting_height(&mut self) {

View File

@@ -14,8 +14,8 @@ impl Filtered for UTXOCohortVecs<TypeCohortMetrics> {
}
impl DynCohortVecs for UTXOCohortVecs<TypeCohortMetrics> {
fn min_stateful_height_len(&self) -> usize {
self.metrics.min_stateful_height_len()
fn min_stateful_len(&self) -> usize {
self.metrics.min_stateful_len()
}
fn reset_state_starting_height(&mut self) {

View File

@@ -111,13 +111,13 @@ impl ActivityCore {
) -> Result<()> {
self.sent.sum.compute_rolling_sum(
starting_indexes.height,
&blocks.lookback.height_24h_ago,
&blocks.lookback._24h,
&self.sent.raw.height,
exit,
)?;
self.coindays_destroyed.sum.compute_rolling_sum(
starting_indexes.height,
&blocks.lookback.height_24h_ago,
&blocks.lookback._24h,
&self.coindays_destroyed.raw.height,
exit,
)?;
@@ -140,14 +140,14 @@ impl ActivityCore {
self.sent_in_profit.sum.compute_rolling_sum(
starting_indexes.height,
&blocks.lookback.height_24h_ago,
&blocks.lookback._24h,
&self.sent_in_profit.raw.sats.height,
&self.sent_in_profit.raw.cents.height,
exit,
)?;
self.sent_in_loss.sum.compute_rolling_sum(
starting_indexes.height,
&blocks.lookback.height_24h_ago,
&blocks.lookback._24h,
&self.sent_in_loss.raw.sats.height,
&self.sent_in_loss.raw.cents.height,
exit,

View File

@@ -55,14 +55,14 @@ impl CohortMetricsBase for AllCohortMetrics {
Ok(())
}
fn min_stateful_height_len(&self) -> usize {
fn min_stateful_len(&self) -> usize {
self.supply
.min_len()
.min(self.outputs.min_len())
.min(self.activity.min_len())
.min(self.realized.min_stateful_height_len())
.min(self.unrealized.min_stateful_height_len())
.min(self.cost_basis.min_stateful_height_len())
.min(self.realized.min_stateful_len())
.min(self.unrealized.min_stateful_len())
.min(self.cost_basis.min_stateful_len())
}
fn collect_all_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> {

View File

@@ -37,13 +37,13 @@ impl CoreCohortMetrics {
})
}
pub(crate) fn min_stateful_height_len(&self) -> usize {
pub(crate) fn min_stateful_len(&self) -> usize {
self.supply
.min_len()
.min(self.outputs.min_len())
.min(self.activity.min_len())
.min(self.realized.min_stateful_height_len())
.min(self.unrealized.min_stateful_height_len())
.min(self.realized.min_stateful_len())
.min(self.unrealized.min_stateful_len())
}
pub(crate) fn validate_computed_versions(&mut self, base_version: Version) -> Result<()> {

View File

@@ -51,14 +51,14 @@ impl CohortMetricsBase for ExtendedCohortMetrics {
Ok(())
}
fn min_stateful_height_len(&self) -> usize {
fn min_stateful_len(&self) -> usize {
self.supply
.min_len()
.min(self.outputs.min_len())
.min(self.activity.min_len())
.min(self.realized.min_stateful_height_len())
.min(self.unrealized.min_stateful_height_len())
.min(self.cost_basis.min_stateful_height_len())
.min(self.realized.min_stateful_len())
.min(self.unrealized.min_stateful_len())
.min(self.cost_basis.min_stateful_len())
}
fn collect_all_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> {

View File

@@ -37,8 +37,8 @@ impl CohortMetricsBase for ExtendedAdjustedCohortMetrics {
self.inner.validate_computed_versions(base_version)
}
fn min_stateful_height_len(&self) -> usize {
self.inner.min_stateful_height_len()
fn min_stateful_len(&self) -> usize {
self.inner.min_stateful_len()
}
fn collect_all_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> {

View File

@@ -33,11 +33,11 @@ impl MinimalCohortMetrics {
})
}
pub(crate) fn min_stateful_height_len(&self) -> usize {
pub(crate) fn min_stateful_len(&self) -> usize {
self.supply
.min_len()
.min(self.outputs.min_len())
.min(self.realized.min_stateful_height_len())
.min(self.realized.min_stateful_len())
}
pub(crate) fn collect_all_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> {

View File

@@ -34,12 +34,12 @@ impl TypeCohortMetrics {
})
}
pub(crate) fn min_stateful_height_len(&self) -> usize {
pub(crate) fn min_stateful_len(&self) -> usize {
self.supply
.min_len()
.min(self.outputs.min_len())
.min(self.realized.min_stateful_height_len())
.min(self.unrealized.min_stateful_height_len())
.min(self.realized.min_stateful_len())
.min(self.unrealized.min_stateful_len())
}
pub(crate) fn collect_all_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> {

View File

@@ -44,7 +44,7 @@ impl CostBasis {
})
}
pub(crate) fn min_stateful_height_len(&self) -> usize {
pub(crate) fn min_stateful_len(&self) -> usize {
self.min
.cents
.height

View File

@@ -155,13 +155,13 @@ pub trait CohortMetricsBase: CohortMetricsState<Realized = RealizedState, CostBa
fn collect_all_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec>;
fn min_stateful_height_len(&self) -> usize {
fn min_stateful_len(&self) -> usize {
self.supply()
.min_len()
.min(self.outputs().min_len())
.min(self.activity().min_len())
.min(self.realized().min_stateful_height_len())
.min(self.unrealized().min_stateful_height_len())
.min(self.realized().min_stateful_len())
.min(self.unrealized().min_stateful_len())
}
fn truncate_push(&mut self, height: Height, state: &CohortState<RealizedState, CostBasisData<WithCapital>>) -> Result<()> {

View File

@@ -55,7 +55,7 @@ impl OutputsFull {
) -> Result<()> {
self.utxo_count_delta.compute(
starting_indexes.height,
&blocks.lookback.height_1m_ago,
&blocks.lookback._1m,
&self.base.utxo_count.height,
exit,
)?;

View File

@@ -72,7 +72,7 @@ pub struct ProfitabilityMetrics<M: StorageMode = Rw> {
}
impl<M: StorageMode> ProfitabilityMetrics<M> {
pub(crate) fn min_stateful_height_len(&self) -> usize {
pub(crate) fn min_stateful_len(&self) -> usize {
self.range.iter()
.chain(self.profit.iter())
.chain(self.loss.iter())

View File

@@ -74,8 +74,8 @@ impl RealizedCore {
})
}
pub(crate) fn min_stateful_height_len(&self) -> usize {
self.minimal.min_stateful_height_len()
pub(crate) fn min_stateful_len(&self) -> usize {
self.minimal.min_stateful_len()
}
pub(crate) fn truncate_push(&mut self, height: Height, state: &CohortState<impl RealizedOps, impl CostBasisOps>) -> Result<()> {
@@ -149,14 +149,14 @@ impl RealizedCore {
self.cap_delta.compute(
starting_indexes.height,
&blocks.lookback.height_1m_ago,
&blocks.lookback._1m,
&self.minimal.cap.cents.height,
exit,
)?;
self.net_pnl.sum.compute_rolling_sum(
starting_indexes.height,
&blocks.lookback.height_24h_ago,
&blocks.lookback._24h,
&self.net_pnl.raw.height,
exit,
)?;

View File

@@ -263,10 +263,11 @@ impl RealizedFull {
})
}
pub(crate) fn min_stateful_height_len(&self) -> usize {
self.core
.min_stateful_height_len()
.min(self.profit.value_created.height.len())
pub(crate) fn min_stateful_len(&self) -> usize {
self.profit
.value_created
.height
.len()
.min(self.profit.value_destroyed.height.len())
.min(self.loss.value_created.height.len())
.min(self.loss.value_destroyed.height.len())
@@ -541,7 +542,7 @@ impl RealizedFull {
// Net PnL delta (1m base + 24h/1w/1y extended)
self.net_pnl.delta.compute(
starting_indexes.height,
&blocks.lookback.height_1m_ago,
&blocks.lookback._1m,
&self.net_pnl.cumulative.height,
exit,
)?;

View File

@@ -69,7 +69,7 @@ impl RealizedMinimal {
})
}
pub(crate) fn min_stateful_height_len(&self) -> usize {
pub(crate) fn min_stateful_len(&self) -> usize {
self.cap
.cents
.height
@@ -129,25 +129,25 @@ impl RealizedMinimal {
) -> Result<()> {
self.profit.sum.compute_rolling_sum(
starting_indexes.height,
&blocks.lookback.height_24h_ago,
&blocks.lookback._24h,
&self.profit.raw.cents.height,
exit,
)?;
self.loss.sum.compute_rolling_sum(
starting_indexes.height,
&blocks.lookback.height_24h_ago,
&blocks.lookback._24h,
&self.loss.raw.cents.height,
exit,
)?;
self.sopr.value_created.sum.compute_rolling_sum(
starting_indexes.height,
&blocks.lookback.height_24h_ago,
&blocks.lookback._24h,
&self.sopr.value_created.raw.height,
exit,
)?;
self.sopr.value_destroyed.sum.compute_rolling_sum(
starting_indexes.height,
&blocks.lookback.height_24h_ago,
&blocks.lookback._24h,
&self.sopr.value_destroyed.raw.height,
exit,
)?;

View File

@@ -22,7 +22,7 @@ use crate::{blocks, distribution::state::{WithCapital, CohortState, CostBasisDat
pub trait RealizedLike: Send + Sync {
fn as_core(&self) -> &RealizedCore;
fn as_core_mut(&mut self) -> &mut RealizedCore;
fn min_stateful_height_len(&self) -> usize;
fn min_stateful_len(&self) -> usize;
fn truncate_push(&mut self, height: Height, state: &CohortState<RealizedState, CostBasisData<WithCapital>>) -> Result<()>;
fn compute_rest_part1(&mut self, blocks: &blocks::Vecs, starting_indexes: &Indexes, exit: &Exit) -> Result<()>;
fn compute_from_stateful(
@@ -36,7 +36,7 @@ pub trait RealizedLike: Send + Sync {
impl RealizedLike for RealizedCore {
fn as_core(&self) -> &RealizedCore { self }
fn as_core_mut(&mut self) -> &mut RealizedCore { self }
fn min_stateful_height_len(&self) -> usize { self.min_stateful_height_len() }
fn min_stateful_len(&self) -> usize { self.min_stateful_len() }
fn truncate_push(&mut self, height: Height, state: &CohortState<RealizedState, CostBasisData<WithCapital>>) -> Result<()> {
self.truncate_push(height, state)
}
@@ -51,7 +51,7 @@ impl RealizedLike for RealizedCore {
impl RealizedLike for RealizedFull {
fn as_core(&self) -> &RealizedCore { &self.core }
fn as_core_mut(&mut self) -> &mut RealizedCore { &mut self.core }
fn min_stateful_height_len(&self) -> usize { self.min_stateful_height_len() }
fn min_stateful_len(&self) -> usize { self.min_stateful_len() }
fn truncate_push(&mut self, height: Height, state: &CohortState<RealizedState, CostBasisData<WithCapital>>) -> Result<()> {
self.truncate_push(height, state)
}

View File

@@ -56,7 +56,7 @@ impl SupplyFull {
) -> Result<()> {
self.delta.compute(
starting_indexes.height,
&blocks.lookback.height_1m_ago,
&blocks.lookback._1m,
&self.core.total.sats.height,
exit,
)

View File

@@ -46,9 +46,9 @@ impl UnrealizedBase {
})
}
pub(crate) fn min_stateful_height_len(&self) -> usize {
pub(crate) fn min_stateful_len(&self) -> usize {
self.core
.min_stateful_height_len()
.min_stateful_len()
.min(self.invested_capital_in_profit_raw.len())
.min(self.invested_capital_in_loss_raw.len())
.min(self.investor_cap_in_profit_raw.len())

View File

@@ -26,7 +26,7 @@ impl UnrealizedBasic {
})
}
pub(crate) fn min_stateful_height_len(&self) -> usize {
pub(crate) fn min_stateful_len(&self) -> usize {
self.profit
.raw
.cents
@@ -75,13 +75,13 @@ impl UnrealizedBasic {
) -> Result<()> {
self.profit.sum.compute_rolling_sum(
max_from,
&blocks.lookback.height_24h_ago,
&blocks.lookback._24h,
&self.profit.raw.cents.height,
exit,
)?;
self.loss.sum.compute_rolling_sum(
max_from,
&blocks.lookback.height_24h_ago,
&blocks.lookback._24h,
&self.loss.raw.cents.height,
exit,
)?;

View File

@@ -49,8 +49,8 @@ impl UnrealizedCore {
})
}
pub(crate) fn min_stateful_height_len(&self) -> usize {
self.basic.min_stateful_height_len()
pub(crate) fn min_stateful_len(&self) -> usize {
self.basic.min_stateful_len()
}
pub(crate) fn truncate_push(

View File

@@ -17,7 +17,7 @@ use crate::{blocks, distribution::state::UnrealizedState, prices};
pub trait UnrealizedLike: Send + Sync {
fn as_base(&self) -> &UnrealizedBase;
fn as_base_mut(&mut self) -> &mut UnrealizedBase;
fn min_stateful_height_len(&self) -> usize;
fn min_stateful_len(&self) -> usize;
fn truncate_push(&mut self, height: Height, state: &UnrealizedState) -> Result<()>;
fn compute_rest(
&mut self,
@@ -40,8 +40,8 @@ impl UnrealizedLike for UnrealizedBase {
fn as_base_mut(&mut self) -> &mut UnrealizedBase {
self
}
fn min_stateful_height_len(&self) -> usize {
self.min_stateful_height_len()
fn min_stateful_len(&self) -> usize {
self.min_stateful_len()
}
fn truncate_push(&mut self, height: Height, state: &UnrealizedState) -> Result<()> {
self.truncate_push(height, state)
@@ -71,8 +71,8 @@ impl UnrealizedLike for UnrealizedFull {
fn as_base_mut(&mut self) -> &mut UnrealizedBase {
&mut self.inner
}
fn min_stateful_height_len(&self) -> usize {
self.inner.min_stateful_height_len()
fn min_stateful_len(&self) -> usize {
self.inner.min_stateful_len()
}
fn truncate_push(&mut self, height: Height, state: &UnrealizedState) -> Result<()> {
self.truncate_push_all(height, state)

View File

@@ -23,7 +23,7 @@ use crate::{
state::BlockState,
},
indexes, inputs,
internal::{finalize_db, open_db, ComputedPerBlockCumulative},
internal::{ComputedPerBlockCumulative, finalize_db, open_db},
outputs, prices, transactions,
};
@@ -240,16 +240,7 @@ impl Vecs {
// 1. Find minimum height we have data for across stateful vecs
let current_height = Height::from(self.supply_state.len());
debug!("supply_state.len={}", self.supply_state.len());
debug!("utxo_cohorts.min={}", self.utxo_cohorts.min_separate_stateful_height_len());
debug!("address_cohorts.min={}", self.address_cohorts.min_separate_stateful_height_len());
debug!("address_indexes.min={}", self.any_address_indexes.min_stamped_height());
debug!("addresses_data.min={}", self.addresses_data.min_stamped_height());
debug!("addr_count.min={}", self.addr_count.min_stateful_height());
debug!("empty_addr_count.min={}", self.empty_addr_count.min_stateful_height());
debug!("address_activity.min={}", self.address_activity.min_stateful_height());
debug!("coinblocks_destroyed.raw.height.len={}", self.coinblocks_destroyed.raw.height.len());
let min_stateful = self.min_stateful_height_len();
let min_stateful = self.min_stateful_len();
// 2. Determine start mode and recover/reset state
// Clamp to starting_indexes.height to handle reorg (indexer may require earlier start)
@@ -423,10 +414,8 @@ impl Vecs {
)?;
// 6b. Compute address count sum (by addresstype → all)
self.addr_count
.compute_rest(starting_indexes, exit)?;
self.empty_addr_count
.compute_rest(starting_indexes, exit)?;
self.addr_count.compute_rest(starting_indexes, exit)?;
self.empty_addr_count.compute_rest(starting_indexes, exit)?;
// 6c. Compute total_addr_count = addr_count + empty_addr_count
self.total_addr_count.compute(
@@ -486,16 +475,47 @@ impl Vecs {
}
/// Get minimum length across all height-indexed stateful vectors.
fn min_stateful_height_len(&self) -> Height {
fn min_stateful_len(&self) -> Height {
debug!("supply_state.len={}", self.supply_state.len());
debug!(
"utxo_cohorts.min={}",
self.utxo_cohorts.min_stateful_len()
);
debug!(
"address_cohorts.min={}",
self.address_cohorts.min_stateful_len()
);
debug!(
"address_indexes.min={}",
self.any_address_indexes.min_stamped_height()
);
debug!(
"addresses_data.min={}",
self.addresses_data.min_stamped_height()
);
debug!("addr_count.min={}", self.addr_count.min_stateful_len());
debug!(
"empty_addr_count.min={}",
self.empty_addr_count.min_stateful_len()
);
debug!(
"address_activity.min={}",
self.address_activity.min_stateful_len()
);
debug!(
"coinblocks_destroyed.raw.height.len={}",
self.coinblocks_destroyed.raw.height.len()
);
self.utxo_cohorts
.min_separate_stateful_height_len()
.min(self.address_cohorts.min_separate_stateful_height_len())
.min_stateful_len()
.min(self.address_cohorts.min_stateful_len())
.min(Height::from(self.supply_state.len()))
.min(self.any_address_indexes.min_stamped_height())
.min(self.addresses_data.min_stamped_height())
.min(Height::from(self.addr_count.min_stateful_height()))
.min(Height::from(self.empty_addr_count.min_stateful_height()))
.min(Height::from(self.address_activity.min_stateful_height()))
.min(Height::from(self.addr_count.min_stateful_len()))
.min(Height::from(self.empty_addr_count.min_stateful_len()))
.min(Height::from(self.address_activity.min_stateful_len()))
.min(Height::from(self.coinblocks_destroyed.raw.height.len()))
}
}

View File

@@ -67,11 +67,11 @@ impl RatioSma {
// Rolling SMAs
for (sma, lookback) in [
(&mut self._1w, &blocks.lookback.height_1w_ago),
(&mut self._1m, &blocks.lookback.height_1m_ago),
(&mut self._1y, &blocks.lookback.height_1y_ago),
(&mut self._2y, &blocks.lookback.height_2y_ago),
(&mut self._4y, &blocks.lookback.height_4y_ago),
(&mut self._1w, &blocks.lookback._1w),
(&mut self._1m, &blocks.lookback._1m),
(&mut self._1y, &blocks.lookback._1y),
(&mut self._2y, &blocks.lookback._2y),
(&mut self._4y, &blocks.lookback._4y),
] {
sma.bps.height.compute_rolling_average(
starting_indexes.height,

View File

@@ -26,7 +26,7 @@ impl Vecs {
// Value = sats_from_dca(close_price) on day-boundary blocks, Sats::ZERO otherwise.
{
let mut last_di: Option<Day1> = None;
self.dca_sats_per_day.compute_transform(
self.sats_per_day.compute_transform(
starting_indexes.height,
h2d,
|(h, di, _)| {
@@ -50,12 +50,12 @@ impl Vecs {
}
// DCA by period - stack (rolling sum via _start vecs)
for (stack, days) in self.period_stack.iter_mut_with_days() {
for (stack, days) in self.period.stack.iter_mut_with_days() {
let window_starts = blocks.lookback.start_vec(days as usize);
stack.sats.height.compute_rolling_sum(
starting_indexes.height,
window_starts,
&self.dca_sats_per_day,
&self.sats_per_day,
exit,
)?;
}
@@ -63,7 +63,7 @@ impl Vecs {
// DCA by period - average price (derived from stack)
let starting_height = starting_indexes.height.to_usize();
for (average_price, stack, days) in
self.period_cost_basis.zip_mut_with_days(&self.period_stack)
self.period.cost_basis.zip_mut_with_days(&self.period.stack)
{
let days = days as usize;
let start = average_price.cents.height.len().min(starting_height);
@@ -91,9 +91,10 @@ impl Vecs {
// DCA by period - returns (compute from average price)
for (returns, (average_price, _)) in self
.period_return
.period
.r#return
.iter_mut()
.zip(self.period_cost_basis.iter_with_days())
.zip(self.period.cost_basis.iter_with_days())
{
returns.compute_binary::<Cents, Cents, RatioDiffCentsBps32>(
starting_indexes.height,
@@ -104,7 +105,7 @@ impl Vecs {
}
// DCA by period - CAGR (computed from returns at height level)
for (cagr, returns, days) in self.period_cagr.zip_mut_with_period(&self.period_return) {
for (cagr, returns, days) in self.period.cagr.zip_mut_with_period(&self.period.r#return) {
let years = days as f64 / 365.0;
cagr.bps.height.compute_transform(
starting_indexes.height,
@@ -121,7 +122,7 @@ impl Vecs {
// Lump sum by period - stack
let lookback_dca = lookback.price_lookback.as_dca_period();
for (stack, lookback_price, days) in
self.period_lump_sum_stack.zip_mut_with_days(&lookback_dca)
self.period.lump_sum_stack.zip_mut_with_days(&lookback_dca)
{
let total_invested = DCA_AMOUNT * days as usize;
let ls_start = stack.sats.height.len().min(starting_height);
@@ -147,7 +148,8 @@ impl Vecs {
// Lump sum by period - returns (compute from lookback price)
for (returns, (lookback_price, _)) in self
.period_lump_sum_return
.period
.lump_sum_return
.iter_mut()
.zip(lookback_dca.iter_with_days())
{
@@ -161,7 +163,7 @@ impl Vecs {
// DCA by year class - stack (cumulative sum from class start date)
let start_days = super::ByDcaClass::<()>::start_days();
for (stack, day1) in self.class_stack.iter_mut().zip(start_days) {
for (stack, day1) in self.class.stack.iter_mut().zip(start_days) {
let mut last_di: Option<Day1> = None;
let mut prev_value = if starting_height > 0 {
stack.sats.height.collect_one_at(starting_height - 1).unwrap_or_default()
@@ -213,9 +215,10 @@ impl Vecs {
// DCA by year class - average price (derived from stack)
let start_days = super::ByDcaClass::<()>::start_days();
for ((average_price, stack), from) in self
.class_cost_basis
.class
.cost_basis
.iter_mut()
.zip(self.class_stack.iter())
.zip(self.class.stack.iter())
.zip(start_days)
{
let from_usize = from.to_usize();
@@ -243,9 +246,10 @@ impl Vecs {
// DCA by year class - returns (compute from average price)
for (returns, average_price) in self
.class_return
.class
.r#return
.iter_mut()
.zip(self.class_cost_basis.iter())
.zip(self.class.cost_basis.iter())
{
returns.compute_binary::<Cents, Cents, RatioDiffCentsBps32>(
starting_indexes.height,

View File

@@ -3,6 +3,7 @@ use brk_types::Version;
use vecdb::{Database, ImportableVec};
use super::{ByDcaCagr, ByDcaClass, ByDcaPeriod, Vecs};
use super::vecs::{ClassVecs, PeriodVecs};
use crate::{
indexes,
internal::{AmountPerBlock, PercentPerBlock, Price},
@@ -14,27 +15,27 @@ impl Vecs {
version: Version,
indexes: &indexes::Vecs,
) -> Result<Self> {
let period_stack = ByDcaPeriod::try_new(|name, _days| {
let stack = ByDcaPeriod::try_new(|name, _days| {
AmountPerBlock::forced_import(db, &format!("dca_stack_{name}"), version, indexes)
})?;
let period_cost_basis = ByDcaPeriod::try_new(|name, _days| {
let cost_basis = ByDcaPeriod::try_new(|name, _days| {
Price::forced_import(db, &format!("dca_cost_basis_{name}"), version, indexes)
})?;
let period_return = ByDcaPeriod::try_new(|name, _days| {
let r#return = ByDcaPeriod::try_new(|name, _days| {
PercentPerBlock::forced_import(db, &format!("dca_return_{name}"), version, indexes)
})?;
let period_cagr = ByDcaCagr::try_new(|name, _days| {
let cagr = ByDcaCagr::try_new(|name, _days| {
PercentPerBlock::forced_import(db, &format!("dca_cagr_{name}"), version, indexes)
})?;
let period_lump_sum_stack = ByDcaPeriod::try_new(|name, _days| {
let lump_sum_stack = ByDcaPeriod::try_new(|name, _days| {
AmountPerBlock::forced_import(db, &format!("lump_sum_stack_{name}"), version, indexes)
})?;
let period_lump_sum_return = ByDcaPeriod::try_new(|name, _days| {
let lump_sum_return = ByDcaPeriod::try_new(|name, _days| {
PercentPerBlock::forced_import(
db,
&format!("lump_sum_return_{name}"),
@@ -56,16 +57,20 @@ impl Vecs {
})?;
Ok(Self {
dca_sats_per_day: ImportableVec::forced_import(db, "dca_sats_per_day", version)?,
period_stack,
period_cost_basis,
period_return,
period_cagr,
period_lump_sum_stack,
period_lump_sum_return,
class_stack,
class_cost_basis,
class_return,
sats_per_day: ImportableVec::forced_import(db, "dca_sats_per_day", version)?,
period: PeriodVecs {
stack,
cost_basis,
r#return,
cagr,
lump_sum_stack,
lump_sum_return,
},
class: ClassVecs {
stack: class_stack,
cost_basis: class_cost_basis,
r#return: class_return,
},
})
}
}

View File

@@ -4,24 +4,27 @@ use vecdb::{EagerVec, PcoVec, Rw, StorageMode};
use super::{ByDcaCagr, ByDcaClass, ByDcaPeriod};
use crate::internal::{AmountPerBlock, ComputedPerBlock, PercentPerBlock, Price};
#[derive(Traversable)]
pub struct PeriodVecs<M: StorageMode = Rw> {
pub stack: ByDcaPeriod<AmountPerBlock<M>>,
pub cost_basis: ByDcaPeriod<Price<ComputedPerBlock<Cents, M>>>,
pub r#return: ByDcaPeriod<PercentPerBlock<BasisPointsSigned32, M>>,
pub cagr: ByDcaCagr<PercentPerBlock<BasisPointsSigned32, M>>,
pub lump_sum_stack: ByDcaPeriod<AmountPerBlock<M>>,
pub lump_sum_return: ByDcaPeriod<PercentPerBlock<BasisPointsSigned32, M>>,
}
#[derive(Traversable)]
pub struct ClassVecs<M: StorageMode = Rw> {
pub stack: ByDcaClass<AmountPerBlock<M>>,
pub cost_basis: ByDcaClass<Price<ComputedPerBlock<Cents, M>>>,
pub r#return: ByDcaClass<PercentPerBlock<BasisPointsSigned32, M>>,
}
#[derive(Traversable)]
pub struct Vecs<M: StorageMode = Rw> {
/// Per-height DCA sats contribution: sats_from_dca(close) on day boundaries, 0 otherwise.
/// Computed once, reused by all period rolling sums.
pub dca_sats_per_day: M::Stored<EagerVec<PcoVec<Height, Sats>>>,
// DCA by period
pub period_stack: ByDcaPeriod<AmountPerBlock<M>>,
pub period_cost_basis: ByDcaPeriod<Price<ComputedPerBlock<Cents, M>>>,
pub period_return: ByDcaPeriod<PercentPerBlock<BasisPointsSigned32, M>>,
pub period_cagr: ByDcaCagr<PercentPerBlock<BasisPointsSigned32, M>>,
// Lump sum by period (for comparison with DCA)
pub period_lump_sum_stack: ByDcaPeriod<AmountPerBlock<M>>,
pub period_lump_sum_return: ByDcaPeriod<PercentPerBlock<BasisPointsSigned32, M>>,
// DCA by year class
pub class_stack: ByDcaClass<AmountPerBlock<M>>,
pub class_cost_basis: ByDcaClass<Price<ComputedPerBlock<Cents, M>>>,
pub class_return: ByDcaClass<PercentPerBlock<BasisPointsSigned32, M>>,
pub sats_per_day: M::Stored<EagerVec<PcoVec<Height, Sats>>>,
pub period: PeriodVecs<M>,
pub class: ClassVecs<M>,
}

View File

@@ -22,8 +22,11 @@ pub struct SmaVecs<M: StorageMode = Rw> {
pub _2y: PriceWithRatioPerBlock<M>,
pub _200w: PriceWithRatioPerBlock<M>,
pub _4y: PriceWithRatioPerBlock<M>,
#[traversable(wrap = "200d", rename = "x2_4")]
pub _200d_x2_4: Price<LazyPerBlock<Cents, Cents>>,
#[traversable(wrap = "200d", rename = "x0_8")]
pub _200d_x0_8: Price<LazyPerBlock<Cents, Cents>>,
#[traversable(wrap = "350d", rename = "x2")]
pub _350d_x2: Price<LazyPerBlock<Cents, Cents>>,
}

View File

@@ -19,22 +19,22 @@ impl Vecs {
(
&mut self.min._1w.cents.height,
&mut self.max._1w.cents.height,
&blocks.lookback.height_1w_ago,
&blocks.lookback._1w,
),
(
&mut self.min._2w.cents.height,
&mut self.max._2w.cents.height,
&blocks.lookback.height_2w_ago,
&blocks.lookback._2w,
),
(
&mut self.min._1m.cents.height,
&mut self.max._1m.cents.height,
&blocks.lookback.height_1m_ago,
&blocks.lookback._1m,
),
(
&mut self.min._1y.cents.height,
&mut self.max._1y.cents.height,
&blocks.lookback.height_1y_ago,
&blocks.lookback._1y,
),
] {
min_vec.compute_rolling_min_from_starts(
@@ -75,7 +75,7 @@ impl Vecs {
// 2w rolling sum of true range
self.true_range_sum_2w.height.compute_rolling_sum(
starting_indexes.height,
&blocks.lookback.height_2w_ago,
&blocks.lookback._2w,
&self.true_range.height,
exit,
)?;
@@ -88,7 +88,7 @@ impl Vecs {
&self.true_range_sum_2w.height,
&self.max._2w.cents.height,
&self.min._2w.cents.height,
&blocks.lookback.height_2w_ago,
&blocks.lookback._2w,
|(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

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

View File

@@ -38,10 +38,10 @@ impl Vecs {
let hash_rate = &self.hash_rate.height;
for (sma, window) in [
(&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),
(&mut self.hash_rate_sma._1w.height, &lookback._1w),
(&mut self.hash_rate_sma._1m.height, &lookback._1m),
(&mut self.hash_rate_sma._2m.height, &lookback._2m),
(&mut self.hash_rate_sma._1y.height, &lookback._1y),
] {
sma.compute_rolling_average(starting_indexes.height, window, hash_rate, exit)?;
}

View File

@@ -156,7 +156,7 @@ impl Vecs {
self.subsidy_sma_1y.cents.height.compute_rolling_average(
starting_indexes.height,
&lookback.height_1y_ago,
&lookback._1y,
&self.subsidy.base.cents.height,
exit,
)?;

View File

@@ -35,7 +35,7 @@ impl Vecs {
.height
.compute_rolling_ratio_change(
starting_indexes.height,
&blocks.lookback.height_1y_ago,
&blocks.lookback._1y,
&circulating_supply.height,
exit,
)?;

View File

@@ -20,7 +20,7 @@ impl Vecs {
// BTC velocity at height level
self.btc.height.compute_rolling_ratio(
starting_indexes.height,
&blocks.lookback.height_1y_ago,
&blocks.lookback._1y,
&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.lookback.height_1y_ago,
&blocks.lookback._1y,
&transactions.volume.sent_sum.usd,
&circulating_supply.usd.height,
exit,

View File

@@ -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.lookback.height_1y_ago,
&blocks.lookback._1y,
&self.sent_sum.sats,
exit,
)?;