use crate::geometry::grid::BlockId;
use rayon::iter::{IndexedParallelIterator, IntoParallelRefMutIterator, ParallelIterator};
pub trait Scheduler: Send + Sync {
fn for_each_block_mut<Item, Sc, Init, F>(&self, items: &mut [Item], scratch: Init, f: F)
where
Item: Send,
Init: Fn() -> Sc + Send + Sync,
F: Fn(BlockId, &mut Item, &mut Sc) + Send + Sync;
fn max_concurrency(&self) -> usize;
}
#[derive(Debug, Clone, Copy, Default)]
pub struct SerialScheduler;
impl Scheduler for SerialScheduler {
fn for_each_block_mut<Item, Sc, Init, F>(&self, items: &mut [Item], scratch: Init, f: F)
where
Item: Send,
Init: Fn() -> Sc + Send + Sync,
F: Fn(BlockId, &mut Item, &mut Sc) + Send + Sync,
{
let mut sc = scratch();
for (i, item) in items.iter_mut().enumerate() {
f(BlockId(i as u32), item, &mut sc);
}
}
fn max_concurrency(&self) -> usize {
1
}
}
#[derive(Debug, Clone, Copy, Default)]
pub struct RayonScheduler;
impl Scheduler for RayonScheduler {
fn for_each_block_mut<Item, Sc, Init, F>(&self, items: &mut [Item], scratch: Init, f: F)
where
Item: Send,
Init: Fn() -> Sc + Send + Sync,
F: Fn(BlockId, &mut Item, &mut Sc) + Send + Sync,
{
items
.par_iter_mut()
.panic_fuse()
.enumerate()
.for_each_init(&scratch, |sc, (i, item)| f(BlockId(i as u32), item, sc));
}
fn max_concurrency(&self) -> usize {
rayon::current_num_threads()
}
}