use crate::{get_num_chunks, get_start_end_positions};
use bytes::Bytes;
use rayon::prelude::*;
use xor_name::XorName;
#[derive(Clone)]
pub(crate) struct EncryptionBatch {
pub(crate) raw_chunks: Vec<RawChunk>,
}
#[derive(Clone)]
pub struct RawChunk {
pub index: usize,
pub data: Bytes,
pub hash: XorName,
}
pub(crate) fn batch_chunks(bytes: Bytes) -> (usize, Vec<EncryptionBatch>) {
let data_size = bytes.len();
let num_chunks = get_num_chunks(data_size);
let raw_chunks: Vec<_> = (0..num_chunks)
.into_iter()
.map(|index| (index, bytes.clone()))
.par_bridge()
.map(|(index, bytes)| {
let (start, end) = get_start_end_positions(data_size, index);
let data = bytes.slice(start..end);
let hash = XorName::from_content(data.as_ref());
RawChunk { index, data, hash }
})
.collect();
let mut raw_chunks = raw_chunks.into_iter().peekable();
let cpus = num_cpus::get();
let chunks_per_batch = usize::max(1, (num_chunks as f64 / cpus as f64).ceil() as usize);
let mut batches = vec![];
while raw_chunks.peek().is_some() {
batches.push(EncryptionBatch {
raw_chunks: raw_chunks.by_ref().take(chunks_per_batch).collect(),
});
}
(num_chunks, batches)
}