mod address; mod dateindex; mod decadeindex; mod difficultyepoch; mod halvingepoch; mod height; mod monthindex; mod quarterindex; mod semesterindex; mod txindex; mod txinindex; mod txoutindex; mod weekindex; mod yearindex; use std::path::Path; use brk_error::Result; use brk_indexer::Indexer; use brk_traversable::Traversable; use brk_types::{Date, DateIndex, Indexes, MonthIndex, Version, WeekIndex}; use vecdb::{Database, Exit, IterableVec, PAGE_SIZE, TypedVecIterator}; use crate::blocks; pub use address::Vecs as AddressVecs; pub use brk_types::ComputeIndexes; pub use dateindex::Vecs as DateIndexVecs; pub use decadeindex::Vecs as DecadeIndexVecs; pub use difficultyepoch::Vecs as DifficultyEpochVecs; pub use halvingepoch::Vecs as HalvingEpochVecs; pub use height::Vecs as HeightVecs; pub use monthindex::Vecs as MonthIndexVecs; pub use quarterindex::Vecs as QuarterIndexVecs; pub use semesterindex::Vecs as SemesterIndexVecs; pub use txindex::Vecs as TxIndexVecs; pub use txinindex::Vecs as TxInIndexVecs; pub use txoutindex::Vecs as TxOutIndexVecs; pub use weekindex::Vecs as WeekIndexVecs; pub use yearindex::Vecs as YearIndexVecs; const VERSION: Version = Version::ZERO; pub const DB_NAME: &str = "indexes"; #[derive(Clone, Traversable)] pub struct Vecs { db: Database, pub address: AddressVecs, pub height: HeightVecs, pub difficultyepoch: DifficultyEpochVecs, pub halvingepoch: HalvingEpochVecs, pub dateindex: DateIndexVecs, pub weekindex: WeekIndexVecs, pub monthindex: MonthIndexVecs, pub quarterindex: QuarterIndexVecs, pub semesterindex: SemesterIndexVecs, pub yearindex: YearIndexVecs, pub decadeindex: DecadeIndexVecs, pub txindex: TxIndexVecs, pub txinindex: TxInIndexVecs, pub txoutindex: TxOutIndexVecs, } impl Vecs { pub fn forced_import( parent: &Path, parent_version: Version, indexer: &Indexer, ) -> Result { let db = Database::open(&parent.join(DB_NAME))?; db.set_min_len(PAGE_SIZE * 10_000_000)?; let version = parent_version + VERSION; let this = Self { address: AddressVecs::forced_import(version, indexer), height: HeightVecs::forced_import(&db, version)?, difficultyepoch: DifficultyEpochVecs::forced_import(&db, version)?, halvingepoch: HalvingEpochVecs::forced_import(&db, version)?, dateindex: DateIndexVecs::forced_import(&db, version)?, weekindex: WeekIndexVecs::forced_import(&db, version)?, monthindex: MonthIndexVecs::forced_import(&db, version)?, quarterindex: QuarterIndexVecs::forced_import(&db, version)?, semesterindex: SemesterIndexVecs::forced_import(&db, version)?, yearindex: YearIndexVecs::forced_import(&db, version)?, decadeindex: DecadeIndexVecs::forced_import(&db, version)?, txindex: TxIndexVecs::forced_import(&db, version, indexer)?, txinindex: TxInIndexVecs::forced_import(version, indexer), txoutindex: TxOutIndexVecs::forced_import(version, indexer), db, }; this.db.retain_regions( this.iter_any_exportable() .flat_map(|v| v.region_names()) .collect(), )?; this.db.compact()?; Ok(this) } pub fn compute( &mut self, indexer: &Indexer, blocks_time: &blocks::time::Vecs, starting_indexes: Indexes, exit: &Exit, ) -> Result { let indexes = self.compute_(indexer, blocks_time, starting_indexes, exit)?; let _lock = exit.lock(); self.db.compact()?; Ok(indexes) } fn compute_( &mut self, indexer: &Indexer, blocks_time: &blocks::time::Vecs, starting_indexes: Indexes, exit: &Exit, ) -> Result { // Transaction indexes - compute input/output counts self.txindex.input_count.compute_count_from_indexes( starting_indexes.txindex, &indexer.vecs.transactions.first_txinindex, &indexer.vecs.inputs.outpoint, exit, )?; self.txindex.output_count.compute_count_from_indexes( starting_indexes.txindex, &indexer.vecs.transactions.first_txoutindex, &indexer.vecs.outputs.value, exit, )?; // Height indexes self.height.txindex_count.compute_count_from_indexes( starting_indexes.height, &indexer.vecs.transactions.first_txindex, &indexer.vecs.transactions.txid, exit, )?; self.height.identity.compute_from_index( starting_indexes.height, &indexer.vecs.blocks.weight, exit, )?; let decremented_starting_height = starting_indexes.height.decremented().unwrap_or_default(); // DateIndex (uses blocks_time.date_monotonic computed in blocks::time::compute_early) let starting_dateindex = self .height .dateindex .into_iter() .get(decremented_starting_height) .unwrap_or_default(); self.height.dateindex.compute_transform( starting_indexes.height, &blocks_time.date, |(h, d, ..)| (h, DateIndex::try_from(d).unwrap()), exit, )?; let starting_dateindex = if let Some(dateindex) = self .height .dateindex .into_iter() .get(decremented_starting_height) { starting_dateindex.min(dateindex) } else { starting_dateindex }; // Difficulty epoch let starting_difficultyepoch = self .height .difficultyepoch .into_iter() .get(decremented_starting_height) .unwrap_or_default(); self.height.difficultyepoch.compute_from_index( starting_indexes.height, &indexer.vecs.blocks.weight, exit, )?; self.difficultyepoch.first_height.compute_coarser( starting_indexes.height, &self.height.difficultyepoch, exit, )?; self.difficultyepoch.identity.compute_from_index( starting_difficultyepoch, &self.difficultyepoch.first_height, exit, )?; self.difficultyepoch .height_count .compute_count_from_indexes( starting_difficultyepoch, &self.difficultyepoch.first_height, &blocks_time.date, exit, )?; // Halving epoch let starting_halvingepoch = self .height .halvingepoch .into_iter() .get(decremented_starting_height) .unwrap_or_default(); self.height.halvingepoch.compute_from_index( starting_indexes.height, &indexer.vecs.blocks.weight, exit, )?; self.halvingepoch.first_height.compute_coarser( starting_indexes.height, &self.height.halvingepoch, exit, )?; self.halvingepoch.identity.compute_from_index( starting_halvingepoch, &self.halvingepoch.first_height, exit, )?; // Time indexes (depends on height.dateindex) self.dateindex.first_height.compute_coarser( starting_indexes.height, &self.height.dateindex, exit, )?; self.dateindex.identity.compute_from_index( starting_dateindex, &self.dateindex.first_height, exit, )?; self.dateindex.date.compute_transform( starting_dateindex, &self.dateindex.identity, |(di, ..)| (di, Date::from(di)), exit, )?; self.dateindex.height_count.compute_count_from_indexes( starting_dateindex, &self.dateindex.first_height, &indexer.vecs.blocks.weight, exit, )?; // Week let starting_weekindex = self .dateindex .weekindex .into_iter() .get(starting_dateindex) .unwrap_or_default(); self.dateindex.weekindex.compute_range( starting_dateindex, &self.dateindex.identity, |i| (i, WeekIndex::from(i)), exit, )?; self.weekindex.first_dateindex.compute_coarser( starting_dateindex, &self.dateindex.weekindex, exit, )?; self.weekindex.identity.compute_from_index( starting_weekindex, &self.weekindex.first_dateindex, exit, )?; self.weekindex.date.compute_transform( starting_weekindex, &self.weekindex.first_dateindex, |(wi, first_di, ..)| (wi, Date::from(first_di)), exit, )?; self.weekindex.dateindex_count.compute_count_from_indexes( starting_weekindex, &self.weekindex.first_dateindex, &self.dateindex.date, exit, )?; // Month let starting_monthindex = self .dateindex .monthindex .into_iter() .get(starting_dateindex) .unwrap_or_default(); self.dateindex.monthindex.compute_range( starting_dateindex, &self.dateindex.identity, |i| (i, MonthIndex::from(i)), exit, )?; self.monthindex.first_dateindex.compute_coarser( starting_dateindex, &self.dateindex.monthindex, exit, )?; self.monthindex.identity.compute_from_index( starting_monthindex, &self.monthindex.first_dateindex, exit, )?; self.monthindex.date.compute_transform( starting_monthindex, &self.monthindex.first_dateindex, |(mi, first_di, ..)| (mi, Date::from(first_di)), exit, )?; self.monthindex.dateindex_count.compute_count_from_indexes( starting_monthindex, &self.monthindex.first_dateindex, &self.dateindex.date, exit, )?; // Quarter let starting_quarterindex = self .monthindex .quarterindex .into_iter() .get(starting_monthindex) .unwrap_or_default(); self.monthindex.quarterindex.compute_from_index( starting_monthindex, &self.monthindex.first_dateindex, exit, )?; self.quarterindex.first_monthindex.compute_coarser( starting_monthindex, &self.monthindex.quarterindex, exit, )?; self.quarterindex.identity.compute_from_index( starting_quarterindex, &self.quarterindex.first_monthindex, exit, )?; let monthindex_first_dateindex = &self.monthindex.first_dateindex; self.quarterindex.date.compute_transform( starting_quarterindex, &self.quarterindex.first_monthindex, |(qi, first_mi, _)| { let first_di = monthindex_first_dateindex.iter().get_unwrap(first_mi); (qi, Date::from(first_di)) }, exit, )?; self.quarterindex .monthindex_count .compute_count_from_indexes( starting_quarterindex, &self.quarterindex.first_monthindex, &self.monthindex.identity, exit, )?; // Semester let starting_semesterindex = self .monthindex .semesterindex .into_iter() .get(starting_monthindex) .unwrap_or_default(); self.monthindex.semesterindex.compute_from_index( starting_monthindex, &self.monthindex.first_dateindex, exit, )?; self.semesterindex.first_monthindex.compute_coarser( starting_monthindex, &self.monthindex.semesterindex, exit, )?; self.semesterindex.identity.compute_from_index( starting_semesterindex, &self.semesterindex.first_monthindex, exit, )?; let monthindex_first_dateindex = &self.monthindex.first_dateindex; self.semesterindex.date.compute_transform( starting_semesterindex, &self.semesterindex.first_monthindex, |(si, first_mi, _)| { let first_di = monthindex_first_dateindex.iter().get_unwrap(first_mi); (si, Date::from(first_di)) }, exit, )?; self.semesterindex .monthindex_count .compute_count_from_indexes( starting_semesterindex, &self.semesterindex.first_monthindex, &self.monthindex.identity, exit, )?; // Year let starting_yearindex = self .monthindex .yearindex .into_iter() .get(starting_monthindex) .unwrap_or_default(); self.monthindex.yearindex.compute_from_index( starting_monthindex, &self.monthindex.first_dateindex, exit, )?; self.yearindex.first_monthindex.compute_coarser( starting_monthindex, &self.monthindex.yearindex, exit, )?; self.yearindex.identity.compute_from_index( starting_yearindex, &self.yearindex.first_monthindex, exit, )?; let monthindex_first_dateindex = &self.monthindex.first_dateindex; self.yearindex.date.compute_transform( starting_yearindex, &self.yearindex.first_monthindex, |(yi, first_mi, _)| { let first_di = monthindex_first_dateindex.iter().get_unwrap(first_mi); (yi, Date::from(first_di)) }, exit, )?; self.yearindex.monthindex_count.compute_count_from_indexes( starting_yearindex, &self.yearindex.first_monthindex, &self.monthindex.identity, exit, )?; // Decade let starting_decadeindex = self .yearindex .decadeindex .into_iter() .get(starting_yearindex) .unwrap_or_default(); self.yearindex.decadeindex.compute_from_index( starting_yearindex, &self.yearindex.first_monthindex, exit, )?; self.decadeindex.first_yearindex.compute_coarser( starting_yearindex, &self.yearindex.decadeindex, exit, )?; self.decadeindex.identity.compute_from_index( starting_decadeindex, &self.decadeindex.first_yearindex, exit, )?; let yearindex_first_monthindex = &self.yearindex.first_monthindex; let monthindex_first_dateindex = &self.monthindex.first_dateindex; self.decadeindex.date.compute_transform( starting_decadeindex, &self.decadeindex.first_yearindex, |(di, first_yi, _)| { let first_mi = yearindex_first_monthindex.iter().get_unwrap(first_yi); let first_di = monthindex_first_dateindex.iter().get_unwrap(first_mi); (di, Date::from(first_di)) }, exit, )?; self.decadeindex .yearindex_count .compute_count_from_indexes( starting_decadeindex, &self.decadeindex.first_yearindex, &self.yearindex.identity, exit, )?; Ok(ComputeIndexes::new( starting_indexes, starting_dateindex, starting_weekindex, starting_monthindex, starting_quarterindex, starting_semesterindex, starting_yearindex, starting_decadeindex, starting_difficultyepoch, starting_halvingepoch, )) } }