Revision control

Copy as Markdown

Other Tools

extern crate rayon;
use self::rayon::iter::plumbing::{Consumer, UnindexedConsumer};
use self::rayon::iter::plumbing::ProducerCallback;
use self::rayon::prelude::*;
use super::*;
impl<T, A> Arena<T, A>
where
A: ArenaBehavior,
{
/// Returns an iterator of shared references which can be used to iterate
/// over this arena in parallel with the `rayon` crate.
///
/// # Features
///
/// This API requires the `rayon` feature of this crate to be enabled.
pub fn par_iter(&self) -> ParIter<T, A>
where
T: Sync,
A::Id: Send,
{
ParIter {
arena_id: self.arena_id,
iter: self.items.par_iter().enumerate(),
_phantom: PhantomData,
}
}
/// Returns an iterator of mutable references which can be used to iterate
/// over this arena in parallel with the `rayon` crate.
///
/// # Features
///
/// This API requires the `rayon` feature of this crate to be enabled.
pub fn par_iter_mut(&mut self) -> ParIterMut<T, A>
where
T: Send + Sync,
A::Id: Send,
{
ParIterMut {
arena_id: self.arena_id,
iter: self.items.par_iter_mut().enumerate(),
_phantom: PhantomData,
}
}
}
/// A parallel iterator over shared references in an arena.
///
/// See `Arena::par_iter` for more information.
#[derive(Debug)]
pub struct ParIter<'a, T, A>
where
T: Sync,
{
arena_id: u32,
iter: rayon::iter::Enumerate<rayon::slice::Iter<'a, T>>,
_phantom: PhantomData<fn() -> A>,
}
impl<'a, T, A> ParallelIterator for ParIter<'a, T, A>
where
T: Sync,
A: ArenaBehavior,
A::Id: Send,
{
type Item = (A::Id, &'a T);
fn drive_unindexed<C>(self, consumer: C) -> C::Result
where
C: UnindexedConsumer<Self::Item>,
{
let arena_id = self.arena_id;
self.iter.map(|(i, item)| (A::new_id(arena_id, i), item))
.drive_unindexed(consumer)
}
fn opt_len(&self) -> Option<usize> {
self.iter.opt_len()
}
}
impl<'a, T, A> IndexedParallelIterator for ParIter<'a, T, A>
where
T: Sync,
A: ArenaBehavior,
A::Id: Send,
{
fn drive<C>(self, consumer: C) -> C::Result
where
C: Consumer<Self::Item>,
{
let arena_id = self.arena_id;
self.iter.map(|(i, item)| (A::new_id(arena_id, i), item))
.drive(consumer)
}
fn len(&self) -> usize {
self.iter.len()
}
fn with_producer<CB>(self, callback: CB) -> CB::Output
where
CB: ProducerCallback<Self::Item>,
{
let arena_id = self.arena_id;
self.iter.map(|(i, item)| (A::new_id(arena_id, i), item))
.with_producer(callback)
}
}
impl<'data, T, A> IntoParallelIterator for &'data Arena<T, A>
where A: ArenaBehavior,
A::Id: Send,
T: Sync,
{
type Item = (A::Id, &'data T);
type Iter = ParIter<'data, T, A>;
fn into_par_iter(self) -> Self::Iter {
self.par_iter()
}
}
/// A parallel iterator over mutable references in an arena.
///
/// See `Arena::par_iter_mut` for more information.
#[derive(Debug)]
pub struct ParIterMut<'a, T, A>
where
T: Send + Sync,
{
arena_id: u32,
iter: rayon::iter::Enumerate<rayon::slice::IterMut<'a, T>>,
_phantom: PhantomData<fn() -> A>,
}
impl<'a, T, A> ParallelIterator for ParIterMut<'a, T, A>
where
T: Send + Sync,
A: ArenaBehavior,
A::Id: Send,
{
type Item = (A::Id, &'a mut T);
fn drive_unindexed<C>(self, consumer: C) -> C::Result
where
C: UnindexedConsumer<Self::Item>,
{
let arena_id = self.arena_id;
self.iter.map(|(i, item)| (A::new_id(arena_id, i), item))
.drive_unindexed(consumer)
}
fn opt_len(&self) -> Option<usize> {
self.iter.opt_len()
}
}
impl<'a, T, A> IndexedParallelIterator for ParIterMut<'a, T, A>
where
T: Send + Sync,
A: ArenaBehavior,
A::Id: Send,
{
fn drive<C>(self, consumer: C) -> C::Result
where
C: Consumer<Self::Item>,
{
let arena_id = self.arena_id;
self.iter.map(|(i, item)| (A::new_id(arena_id, i), item))
.drive(consumer)
}
fn len(&self) -> usize {
self.iter.len()
}
fn with_producer<CB>(self, callback: CB) -> CB::Output
where
CB: ProducerCallback<Self::Item>,
{
let arena_id = self.arena_id;
self.iter.map(|(i, item)| (A::new_id(arena_id, i), item))
.with_producer(callback)
}
}
impl<'data, T, A> IntoParallelIterator for &'data mut Arena<T, A>
where A: ArenaBehavior,
A::Id: Send,
T: Send + Sync,
{
type Item = (A::Id, &'data mut T);
type Iter = ParIterMut<'data, T, A>;
fn into_par_iter(self) -> Self::Iter {
self.par_iter_mut()
}
}
/// A parallel iterator over items in an arena.
///
/// See `Arena::into_par_iter` for more information.
#[derive(Debug)]
pub struct IntoParIter<T, A>
where
T: Send,
{
arena_id: u32,
iter: rayon::iter::Enumerate<rayon::vec::IntoIter<T>>,
_phantom: PhantomData<fn() -> A>,
}
impl<T, A> ParallelIterator for IntoParIter<T, A>
where
T: Send,
A: ArenaBehavior,
A::Id: Send,
{
type Item = (A::Id, T);
fn drive_unindexed<C>(self, consumer: C) -> C::Result
where
C: UnindexedConsumer<Self::Item>,
{
let arena_id = self.arena_id;
self.iter.map(|(i, item)| (A::new_id(arena_id, i), item))
.drive_unindexed(consumer)
}
fn opt_len(&self) -> Option<usize> {
self.iter.opt_len()
}
}
impl<T, A> IndexedParallelIterator for IntoParIter<T, A>
where
T: Send,
A: ArenaBehavior,
A::Id: Send,
{
fn drive<C>(self, consumer: C) -> C::Result
where
C: Consumer<Self::Item>,
{
let arena_id = self.arena_id;
self.iter.map(|(i, item)| (A::new_id(arena_id, i), item))
.drive(consumer)
}
fn len(&self) -> usize {
self.iter.len()
}
fn with_producer<CB>(self, callback: CB) -> CB::Output
where
CB: ProducerCallback<Self::Item>,
{
let arena_id = self.arena_id;
self.iter.map(|(i, item)| (A::new_id(arena_id, i), item))
.with_producer(callback)
}
}
impl<T, A> IntoParallelIterator for Arena<T, A>
where A: ArenaBehavior,
A::Id: Send,
T: Send,
{
type Item = (A::Id, T);
type Iter = IntoParIter<T, A>;
fn into_par_iter(self) -> Self::Iter {
IntoParIter {
arena_id: self.arena_id,
iter: self.items.into_par_iter().enumerate(),
_phantom: PhantomData,
}
}
}