mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-05-02 10:30:00 -07:00
computer: add positions
This commit is contained in:
133
crates/brk_computer/src/positions.rs
Normal file
133
crates/brk_computer/src/positions.rs
Normal file
@@ -0,0 +1,133 @@
|
||||
use std::path::Path;
|
||||
|
||||
use brk_error::Result;
|
||||
use brk_indexer::Indexer;
|
||||
use brk_parser::Parser;
|
||||
use brk_structs::{BlkPosition, Height, TxIndex, Version};
|
||||
use log::info;
|
||||
use vecdb::{
|
||||
AnyCollectableVec, AnyIterableVec, AnyStoredVec, AnyVec, CompressedVec, Database, Exit,
|
||||
GenericStoredVec, PAGE_SIZE, VecIterator,
|
||||
};
|
||||
|
||||
use super::{Indexes, indexes};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Vecs {
|
||||
db: Database,
|
||||
|
||||
pub height_to_position: CompressedVec<Height, BlkPosition>,
|
||||
pub txindex_to_position: CompressedVec<TxIndex, BlkPosition>,
|
||||
}
|
||||
|
||||
impl Vecs {
|
||||
pub fn forced_import(parent_path: &Path, parent_version: Version) -> Result<Self> {
|
||||
let db = Database::open(&parent_path.join("positions"))?;
|
||||
db.set_min_len(PAGE_SIZE * 1_000_000)?;
|
||||
|
||||
let version = parent_version + Version::ZERO;
|
||||
|
||||
let this = Self {
|
||||
height_to_position: CompressedVec::forced_import(
|
||||
&db,
|
||||
"position",
|
||||
version + Version::ZERO,
|
||||
)?,
|
||||
txindex_to_position: CompressedVec::forced_import(
|
||||
&db,
|
||||
"position",
|
||||
version + Version::ZERO,
|
||||
)?,
|
||||
|
||||
db,
|
||||
};
|
||||
|
||||
this.db.retain_regions(
|
||||
this.iter_any_collectable()
|
||||
.flat_map(|v| v.region_names())
|
||||
.collect(),
|
||||
)?;
|
||||
|
||||
Ok(this)
|
||||
}
|
||||
|
||||
pub fn compute(
|
||||
&mut self,
|
||||
indexer: &Indexer,
|
||||
indexes: &indexes::Vecs,
|
||||
starting_indexes: &Indexes,
|
||||
parser: &Parser,
|
||||
exit: &Exit,
|
||||
) -> Result<()> {
|
||||
self.compute_(indexer, indexes, starting_indexes, parser, exit)?;
|
||||
self.db.flush_then_punch()?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn compute_(
|
||||
&mut self,
|
||||
indexer: &Indexer,
|
||||
indexes: &indexes::Vecs,
|
||||
starting_indexes: &Indexes,
|
||||
parser: &Parser,
|
||||
exit: &Exit,
|
||||
) -> Result<()> {
|
||||
let min_txindex =
|
||||
TxIndex::from(self.txindex_to_position.len()).min(starting_indexes.txindex);
|
||||
|
||||
let min_height = indexes
|
||||
.txindex_to_height
|
||||
.iter()
|
||||
.unwrap_get_inner(min_txindex)
|
||||
.min(starting_indexes.height);
|
||||
|
||||
let mut height_to_first_txindex_iter = indexer.vecs.height_to_first_txindex.iter();
|
||||
|
||||
parser
|
||||
.parse(Some(min_height), None)
|
||||
.iter()
|
||||
.try_for_each(|block| -> Result<()> {
|
||||
let height = block.height();
|
||||
|
||||
info!("{height}");
|
||||
|
||||
self.height_to_position
|
||||
.forced_push_at(height, *block.position(), exit)?;
|
||||
|
||||
let txindex = height_to_first_txindex_iter.unwrap_get_inner(height);
|
||||
|
||||
block.tx_positions().iter().enumerate().try_for_each(
|
||||
|(index, position)| -> Result<()> {
|
||||
let txindex = txindex + index;
|
||||
self.txindex_to_position
|
||||
.forced_push_at(txindex, *position, exit)?;
|
||||
Ok(())
|
||||
},
|
||||
)?;
|
||||
|
||||
// Stuck, why ??
|
||||
if *height % 1_000 == 0 {
|
||||
let _lock = exit.lock();
|
||||
self.height_to_position.flush()?;
|
||||
self.txindex_to_position.flush()?;
|
||||
}
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
let _lock = exit.lock();
|
||||
self.height_to_position.flush()?;
|
||||
self.txindex_to_position.flush()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn iter_any_collectable(&self) -> impl Iterator<Item = &dyn AnyCollectableVec> {
|
||||
Box::new(
|
||||
[
|
||||
&self.height_to_position as &dyn AnyCollectableVec,
|
||||
&self.txindex_to_position,
|
||||
]
|
||||
.into_iter(),
|
||||
)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user