TLDR
How to write a function which can accept anything that can be converted into rayon::iter::IndexedParallelIterator
?
Details
I have a prototype function that looks roughly like this:
fn doit(data: &[XXX], job_size: usize) -> T {
data
.par_iter()
.with_min_len(job_size)
.with_max_len(job_size)
...
}
The with_{max,min}_len
are needed because creating and combining the
accumulators is rather expensive, so we need to inhibit rayon's tendency to
create many small sub-jobs.
Passing in &[XXX]
is OK for prototyping purposes, but in real life we have
cases where the data don't fit into memory. So we want to replace the &[XXX]
parameter with an iterator, which I can get to work along these lines
fn doit<F, A, R, T, D>(
data: D,
fold_op: F,
redc_op: R,
job_size: usize,
) -> A
where
F: Fn(A, &T) -> A + Send + Sync,
A: Send + Sync + Default,
R: Send + Sync + Fn(A, A) -> A,
for <'a> &'a D: IntoParallelIterator<Item = &'a T>,
{
data
.par_iter()
//.with_min_len(job_size)
.fold (A::default, fold_op)
.reduce(A::default, redc_op)
}
at the cost of losing with_{max,min}_len_
: these require
rayon::iter::IndexedParallelIterator
.
In many cases we do know exactly how many data there will be, so we can
implement std::iter::ExactSizedIterator
to generate them, but I don't see a
link between this and IndexedParallelIterator
, and there doesn't seem to be an
IntoIndexedParallelIterator
.