extern crate rayon; use self::rayon::iter::plumbing::{Consumer, UnindexedConsumer}; use self::rayon::iter::plumbing::ProducerCallback; use self::rayon::prelude::*; use super::*; impl Arena 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 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 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>, _phantom: PhantomData 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(self, consumer: C) -> C::Result where C: UnindexedConsumer, { 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 { self.iter.opt_len() } } impl<'a, T, A> IndexedParallelIterator for ParIter<'a, T, A> where T: Sync, A: ArenaBehavior, A::Id: Send, { fn drive(self, consumer: C) -> C::Result where C: Consumer, { 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(self, callback: CB) -> CB::Output where CB: ProducerCallback, { 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 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>, _phantom: PhantomData 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(self, consumer: C) -> C::Result where C: UnindexedConsumer, { 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 { 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(self, consumer: C) -> C::Result where C: Consumer, { 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(self, callback: CB) -> CB::Output where CB: ProducerCallback, { 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 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 where T: Send, { arena_id: u32, iter: rayon::iter::Enumerate>, _phantom: PhantomData A>, } impl ParallelIterator for IntoParIter where T: Send, A: ArenaBehavior, A::Id: Send, { type Item = (A::Id, T); fn drive_unindexed(self, consumer: C) -> C::Result where C: UnindexedConsumer, { 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 { self.iter.opt_len() } } impl IndexedParallelIterator for IntoParIter where T: Send, A: ArenaBehavior, A::Id: Send, { fn drive(self, consumer: C) -> C::Result where C: Consumer, { 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(self, callback: CB) -> CB::Output where CB: ProducerCallback, { let arena_id = self.arena_id; self.iter.map(|(i, item)| (A::new_id(arena_id, i), item)) .with_producer(callback) } } impl IntoParallelIterator for Arena where A: ArenaBehavior, A::Id: Send, T: Send, { type Item = (A::Id, T); type Iter = IntoParIter; fn into_par_iter(self) -> Self::Iter { IntoParIter { arena_id: self.arena_id, iter: self.items.into_par_iter().enumerate(), _phantom: PhantomData, } } }