use crate::policy::ExecutionPolicy;
pub const UNIT_TASK_BYTES: usize = 64 * 1024;
#[must_use]
pub const fn units_per_task(unit_bytes: usize) -> usize {
let per_task = UNIT_TASK_BYTES / if unit_bytes == 0 { 1 } else { unit_bytes };
if per_task == 0 { 1 } else { per_task }
}
#[derive(Clone, Copy)]
pub(super) struct UnitTaskPlan {
pub(super) per_task: usize,
pub(super) task_len: usize,
pub(super) tasks: usize,
pub(super) parallel: bool,
}
#[track_caller]
pub(super) fn assert_whole_units(len: usize, unit_len: usize) {
assert!(
unit_len > 0 && len.is_multiple_of(unit_len),
"unit tasks need whole units: data length {len} is not a multiple of unit length {unit_len}",
);
}
pub(super) fn plan_unit_tasks<P: ExecutionPolicy>(
len: usize,
unit_len: usize,
unit_bytes: usize,
) -> Option<UnitTaskPlan> {
let units = len / unit_len;
if units == 0 {
return None;
}
let per_task = units_per_task(unit_bytes);
let tasks = units.div_ceil(per_task);
Some(UnitTaskPlan {
per_task,
task_len: per_task * unit_len,
tasks,
parallel: tasks > 1 && P::parallelize_work(len, tasks, units.saturating_mul(unit_bytes)),
})
}