use std::vec::Vec;
use super::driver_core::drive;
use super::plan::PartitionPlan;
pub fn partition_read_map<T, R, F>(slice: &[T], parts: usize, f: F) -> Vec<R>
where
T: Sync,
R: Send,
F: Fn(usize, &[T]) -> R + Sync,
{
partition_read_map_with(slice, PartitionPlan::parts(parts), f)
}
#[inline]
pub fn partition_read_map_with<T, R, F>(slice: &[T], plan: PartitionPlan, f: F) -> Vec<R>
where
T: Sync,
R: Send,
F: Fn(usize, &[T]) -> R + Sync,
{
let chunk = plan.resolve(slice.len());
let chunk_size = chunk.max(1);
let slice_len = slice.len();
let num_chunks = if slice_len == 0 {
0
} else {
1 + (slice_len - 1) / chunk_size
};
if num_chunks == 0 {
return Vec::new();
}
drive(num_chunks, |index| {
let start = index * chunk_size;
let end = (start + chunk_size).min(slice_len);
f(start, &slice[start..end])
})
}
#[inline]
pub fn partition_read_map_available<T, R, F>(slice: &[T], f: F) -> Vec<R>
where
T: Sync,
R: Send,
F: Fn(usize, &[T]) -> R + Sync,
{
partition_read_map_with(slice, PartitionPlan::available_parallelism(), f)
}
#[inline]
pub fn partition_read_for_each<T, F>(slice: &[T], parts: usize, f: F)
where
T: Sync,
F: Fn(usize, &[T]) + Sync,
{
partition_read_map(slice, parts, f);
}
#[inline]
pub fn partition_read_for_each_with<T, F>(slice: &[T], plan: PartitionPlan, f: F)
where
T: Sync,
F: Fn(usize, &[T]) + Sync,
{
partition_read_map_with(slice, plan, f);
}
#[inline]
pub fn partition_read_for_each_available<T, F>(slice: &[T], f: F)
where
T: Sync,
F: Fn(usize, &[T]) + Sync,
{
partition_read_map_available(slice, f);
}