Skip to main content

ParallelIterator

Trait ParallelIterator 

Source
pub trait ParallelIterator: Sized {
    type Item;

    // Required methods
    fn upper_bounded_pipeline<Output, Accum>(
        self,
        init: impl Fn() -> Accum + Sync,
        process_item: impl Fn(Accum, usize, Self::Item) -> ControlFlow<Accum, Accum> + Sync,
        finalize: impl Fn(Accum) -> Output + Sync,
        reduce: impl Fn(Output, Output) -> Output,
    ) -> Output
       where Output: Send;
    fn iter_pipeline<Output, Accum>(
        self,
        accum: impl Accumulator<Self::Item, Accum> + Sync,
        reduce: impl ExactSizeAccumulator<Accum, Output>,
    ) -> Output
       where Accum: Send;

    // Provided methods
    fn pipeline<Output, Accum>(
        self,
        init: impl Fn() -> Accum + Sync,
        process_item: impl Fn(Accum, Self::Item) -> Accum + Sync,
        finalize: impl Fn(Accum) -> Output + Sync,
        reduce: impl Fn(Output, Output) -> Output,
    ) -> Output
       where Output: Send { ... }
    fn short_circuiting_pipeline<Output, Accum, Break>(
        self,
        init: impl Fn() -> Accum + Sync,
        process_item: impl Fn(Accum, Self::Item) -> ControlFlow<Break, Accum> + Sync,
        finalize: impl Fn(ControlFlow<Break, Accum>) -> Output + Sync,
        reduce: impl Fn(Output, Output) -> Output,
    ) -> Output
       where Output: Send { ... }
}
Expand description

An iterator to process items in parallel. The ParallelIteratorExt trait provides additional methods (iterator adaptors) as an extension of this trait.

Required Associated Types§

Source

type Item

The type of items that this parallel iterator produces.

Note that this type has no particular Send nor Sync bounds, as items may be created locally on a worker thread, for example via the map() adaptor. However, initial sources of parallel iterators require the items to be Send, via the IntoParallelSource family of traits.

Required Methods§

Source

fn upper_bounded_pipeline<Output, Accum>( self, init: impl Fn() -> Accum + Sync, process_item: impl Fn(Accum, usize, Self::Item) -> ControlFlow<Accum, Accum> + Sync, finalize: impl Fn(Accum) -> Output + Sync, reduce: impl Fn(Output, Output) -> Output, ) -> Output
where Output: Send,

Runs the pipeline defined by the given functions on this iterator.

§Parameters
  • init function to create a new (per-thread) accumulator,
  • process_item function to accumulate an item into the accumulator,
  • finalize function to transform an accumulator into an output,
  • reduce function to reduce a pair of outputs into one output.

Contrary to pipeline(), the process_item function can return ControlFlow::Break to indicate that the pipeline should skip processing items at larger indices.

let input = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
let first_even = input
    .par_iter()
    .with_thread_pool(&mut thread_pool)
    .upper_bounded_pipeline(
        || None,
        |acc, i, x| {
            match acc {
                // Early return if we found something at a previous index.
                Some((j, _)) if j < i => ControlFlow::Continue(acc),
                _ => match x % 2 == 0 {
                    true => ControlFlow::Break(Some((i, x))),
                    false => ControlFlow::Continue(acc),
                },
            }
        },
        |acc| acc,
        |x, y| match (x, y) {
            (None, None) => None,
            (Some(found), None) | (None, Some(found)) => Some(found),
            (Some((i, a)), Some((j, b))) => {
                if i < j {
                    Some((i, a))
                } else {
                    Some((j, b))
                }
            }
        },
    )
    .map(|(_, x)| x);
assert_eq!(first_even, Some(&2));
Source

fn iter_pipeline<Output, Accum>( self, accum: impl Accumulator<Self::Item, Accum> + Sync, reduce: impl ExactSizeAccumulator<Accum, Output>, ) -> Output
where Accum: Send,

Runs the pipeline defined by the given functions on this iterator.

§Parameters
  • accum function to accumulate items into an output,
  • reduce function to reduce a sequence of outputs into the final output.
use std::iter::Sum;

let input = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
let sum = input
    .par_iter()
    .with_thread_pool(&mut thread_pool)
    .iter_pipeline(SumAccumulator, SumAccumulator);
assert_eq!(sum, 5 * 11);

// Definition of an accumulator that sums items into an integer.
struct SumAccumulator;

impl<Item> Accumulator<Item, i32> for SumAccumulator
where
    i32: Sum<Item>,
{
    fn accumulate(&self, iter: impl Iterator<Item = Item>) -> i32 {
        iter.sum()
    }
}

impl<Item> ExactSizeAccumulator<Item, i32> for SumAccumulator
where
    i32: Sum<Item>,
{
    fn accumulate_exact(&self, iter: impl ExactSizeIterator<Item = Item>) -> i32 {
        iter.sum()
    }
}

Provided Methods§

Source

fn pipeline<Output, Accum>( self, init: impl Fn() -> Accum + Sync, process_item: impl Fn(Accum, Self::Item) -> Accum + Sync, finalize: impl Fn(Accum) -> Output + Sync, reduce: impl Fn(Output, Output) -> Output, ) -> Output
where Output: Send,

Runs the pipeline defined by the given functions on this iterator.

§Parameters
  • init function to create a new (per-thread) accumulator,
  • process_item function to accumulate an item into the accumulator,
  • finalize function to transform an accumulator into an output,
  • reduce function to reduce a pair of outputs into one output.
let input = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
let sum = input
    .par_iter()
    .with_thread_pool(&mut thread_pool)
    .pipeline(|| 0, |acc, x| acc + x, |acc| acc, |x, y| x + y);
assert_eq!(sum, 5 * 11);
Source

fn short_circuiting_pipeline<Output, Accum, Break>( self, init: impl Fn() -> Accum + Sync, process_item: impl Fn(Accum, Self::Item) -> ControlFlow<Break, Accum> + Sync, finalize: impl Fn(ControlFlow<Break, Accum>) -> Output + Sync, reduce: impl Fn(Output, Output) -> Output, ) -> Output
where Output: Send,

Runs the pipeline defined by the given functions on this iterator.

§Parameters
  • init function to create a new (per-thread) accumulator,
  • process_item function to accumulate an item into the accumulator,
  • finalize function to transform an accumulator into an output,
  • reduce function to reduce a pair of outputs into one output.

Contrary to pipeline(), the process_item function can return ControlFlow::Break to indicate that the pipeline should terminate early.

let input = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
let any_even = input
    .par_iter()
    .with_thread_pool(&mut thread_pool)
    .short_circuiting_pipeline(
        || (),
        |_, x| {
            if x % 2 == 0 {
                ControlFlow::Break(())
            } else {
                ControlFlow::Continue(())
            }
        },
        |acc| acc.is_break(),
        |x, y| x || y,
    );
assert_eq!(any_even, true);

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§