use brk_error::Result;
use brk_types::TxIndex;
use vecdb::VecIndex;
pub(crate) struct BlockAggregate {
pub entries_all: u64,
pub entries_per_type: [u64; 12],
pub txs_all: u64,
pub txs_per_type: [u64; 12],
}
#[derive(Clone, Copy)]
pub(crate) enum CoinbasePolicy {
Include,
Skip,
}
#[inline]
pub(crate) fn walk_blocks(
fi_batch: &[TxIndex],
txid_len: usize,
coinbase: CoinbasePolicy,
mut scan_tx: impl FnMut(usize, &mut [u32; 12]) -> Result<()>,
mut store: impl FnMut(BlockAggregate) -> Result<()>,
) -> Result<()> {
for (j, first_tx) in fi_batch.iter().enumerate() {
let fi = first_tx.to_usize();
let next_fi = fi_batch
.get(j + 1)
.map(|v| v.to_usize())
.unwrap_or(txid_len);
let start_tx = match coinbase {
CoinbasePolicy::Include => fi,
CoinbasePolicy::Skip => fi + 1,
};
let mut entries_per_type = [0u64; 12];
let mut txs_per_type = [0u64; 12];
let mut entries_all = 0u64;
let mut txs_all = 0u64;
for tx_pos in start_tx..next_fi {
let mut per_tx = [0u32; 12];
scan_tx(tx_pos, &mut per_tx)?;
let mut tx_has_any = false;
for (i, &n) in per_tx.iter().enumerate() {
if n > 0 {
entries_per_type[i] += u64::from(n);
txs_per_type[i] += 1;
entries_all += u64::from(n);
tx_has_any = true;
}
}
if tx_has_any {
txs_all += 1;
}
}
store(BlockAggregate {
entries_all,
entries_per_type,
txs_all,
txs_per_type,
})?;
}
Ok(())
}