use brk_error::Result;
use brk_indexer::Indexer;
use brk_types::{Height, Indexes, OutputType, Sats, TxOutIndex};
use vecdb::{AnyStoredVec, AnyVec, Exit, ReadableVec, VecIndex, WritableVec};
use super::Vecs;
use crate::prices;
impl Vecs {
pub(crate) fn compute(
&mut self,
indexer: &Indexer,
prices: &prices::Vecs,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
self.op_return
.compute_with(starting_indexes.height, prices, exit, |height_vec| {
let dep_version = indexer.vecs.outputs.first_txout_index.version()
+ indexer.vecs.outputs.output_type.version()
+ indexer.vecs.outputs.value.version();
height_vec.validate_computed_version_or_reset(dep_version)?;
let target_len = indexer.vecs.outputs.first_txout_index.len();
if target_len == 0 {
return Ok(());
}
let target_height = Height::from(target_len - 1);
let current_len = height_vec.len();
let starting_height =
Height::from(current_len.min(starting_indexes.height.to_usize()));
if starting_height > target_height {
return Ok(());
}
let first_txout_indexes: Vec<TxOutIndex> =
indexer.vecs.outputs.first_txout_index.collect_range_at(
starting_height.to_usize(),
target_height.to_usize()
+ 2.min(indexer.vecs.outputs.first_txout_index.len()),
);
let mut output_types_buf: Vec<OutputType> = Vec::new();
let mut values_buf: Vec<Sats> = Vec::new();
height_vec.truncate_if_needed(starting_height)?;
for h in starting_height.to_usize()..=target_height.to_usize() {
let local_idx = h - starting_height.to_usize();
let first_txout_index = first_txout_indexes[local_idx];
let next_first_txout_index =
if let Some(&next) = first_txout_indexes.get(local_idx + 1) {
next
} else {
TxOutIndex::from(indexer.vecs.outputs.value.len())
};
let out_start = first_txout_index.to_usize();
let out_end = next_first_txout_index.to_usize();
indexer.vecs.outputs.output_type.collect_range_into_at(
out_start,
out_end,
&mut output_types_buf,
);
indexer.vecs.outputs.value.collect_range_into_at(
out_start,
out_end,
&mut values_buf,
);
let mut op_return_value = Sats::ZERO;
for (ot, val) in output_types_buf.iter().zip(values_buf.iter()) {
if *ot == OutputType::OpReturn {
op_return_value += *val;
}
}
height_vec.push(op_return_value);
}
height_vec.write()?;
Ok(())
})?;
Ok(())
}
}