use rayon::prelude::*;
use crate::{Block, ChainError};
use super::common::{ChainMeta, parse_chain_in_range};
use super::locate_chain_ranges;
pub(crate) fn parse_chains_parallel(
bytes: &[u8],
) -> Result<(Vec<ChainMeta>, Vec<Block>), ChainError> {
let ranges = locate_chain_ranges(bytes)?;
let parsed: Result<Vec<(ChainMeta, Vec<Block>)>, ChainError> = ranges
.into_par_iter()
.map(|range| parse_chain_in_range(bytes, range))
.collect();
let parsed = parsed?;
let mut metas = Vec::with_capacity(parsed.len());
let total_blocks = parsed.iter().map(|(_, blocks)| blocks.len()).sum();
let mut all_blocks = Vec::with_capacity(total_blocks);
for (mut meta, mut blocks) in parsed {
let start = all_blocks.len();
all_blocks.append(&mut blocks);
let end = all_blocks.len();
meta.blocks = start..end;
metas.push(meta);
}
Ok((metas, all_blocks))
}