283 lines
6.6 KiB
Rust
283 lines
6.6 KiB
Rust
|
|
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,
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|