use crate::parameters::Params;
use crate::pools::{ThreadPool, max_num_threads_for_computation};
#[cfg(feature = "std")]
use crate::runner::runner_variants::WithDiagnostics;
use orx_concurrent_iter::ConcurrentIter;
pub trait ParRunner: Sized + Sync {
type Pool: ThreadPool;
type State: Send + Sync;
type ChunkState;
fn pool(&self) -> &Self::Pool;
fn pool_mut(&mut self) -> &mut Self::Pool;
fn do_spawn_new(spawned: usize, state: &Self::State) -> Option<usize>;
fn new_state(
&mut self,
params: Params,
max_num_threads: usize,
size_hint: (usize, Option<usize>),
) -> Self::State;
fn configure_for_serialized_input(state: &mut Self::State, size_hint: (usize, Option<usize>));
fn begin_thread(state: &Self::State, th_idx: usize);
fn next_chunk_size(state: &Self::State, size_hint: (usize, Option<usize>)) -> usize;
fn begin_chunk(th_idx: usize, chunk_size: usize) -> Self::ChunkState;
fn complete_chunk(state: &Self::State, chunk_state: Self::ChunkState);
fn complete_thread(state: &Self::State, th_idx: usize);
fn complete_computation(state: Self::State);
#[cfg(feature = "std")]
fn with_diagnostics(self) -> WithDiagnostics<Self> {
WithDiagnostics::new(self)
}
fn nt_state(
&mut self,
params: Params,
is_source_serialized: bool,
size_hint: (usize, Option<usize>),
computation_max_nt: Option<usize>,
) -> (usize, Self::State) {
let max_nt = max_num_threads_for_computation(self.pool(), params, size_hint);
let max_nt = match computation_max_nt {
Some(0) => 1,
Some(comp_nt) if comp_nt < max_nt => comp_nt,
_ => max_nt,
};
let mut state = self.new_state(params, max_nt, size_hint);
if is_source_serialized {
Self::configure_for_serialized_input(&mut state, size_hint);
}
(max_nt, state)
}
fn broadcast_stop<I: ConcurrentIter>(
iter: &I,
state: &Self::State,
chunk_state: Self::ChunkState,
) {
iter.skip_to_end();
Self::complete_chunk(state, chunk_state);
}
}
impl<P: ParRunner> ParRunner for &mut P {
type Pool = P::Pool;
type State = P::State;
type ChunkState = P::ChunkState;
fn pool(&self) -> &Self::Pool {
<P as ParRunner>::pool(self)
}
fn pool_mut(&mut self) -> &mut Self::Pool {
<P as ParRunner>::pool_mut(self)
}
fn do_spawn_new(spawned: usize, state: &Self::State) -> Option<usize> {
<P as ParRunner>::do_spawn_new(spawned, state)
}
fn new_state(
&mut self,
params: Params,
max_num_threads: usize,
size_hint: (usize, Option<usize>),
) -> Self::State {
<P as ParRunner>::new_state(self, params, max_num_threads, size_hint)
}
fn begin_thread(state: &Self::State, th_idx: usize) {
<P as ParRunner>::begin_thread(state, th_idx);
}
fn next_chunk_size(state: &Self::State, size_hint: (usize, Option<usize>)) -> usize {
<P as ParRunner>::next_chunk_size(state, size_hint)
}
fn begin_chunk(th_idx: usize, chunk_size: usize) -> Self::ChunkState {
<P as ParRunner>::begin_chunk(th_idx, chunk_size)
}
fn complete_chunk(state: &Self::State, chunk_state: Self::ChunkState) {
<P as ParRunner>::complete_chunk(state, chunk_state);
}
fn complete_thread(state: &Self::State, th_idx: usize) {
<P as ParRunner>::complete_thread(state, th_idx);
}
fn complete_computation(state: Self::State) {
<P as ParRunner>::complete_computation(state);
}
fn configure_for_serialized_input(state: &mut Self::State, size_hint: (usize, Option<usize>)) {
<P as ParRunner>::configure_for_serialized_input(state, size_hint);
}
}