diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
commit | 36d22d82aa202bb199967e9512281e9a53db42c9 (patch) | |
tree | 105e8c98ddea1c1e4784a60a5a6410fa416be2de /third_party/rust/id-arena/src/rayon.rs | |
parent | Initial commit. (diff) | |
download | firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.tar.xz firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.zip |
Adding upstream version 115.7.0esr.upstream/115.7.0esr
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/id-arena/src/rayon.rs')
-rw-r--r-- | third_party/rust/id-arena/src/rayon.rs | 282 |
1 files changed, 282 insertions, 0 deletions
diff --git a/third_party/rust/id-arena/src/rayon.rs b/third_party/rust/id-arena/src/rayon.rs new file mode 100644 index 0000000000..7bea702247 --- /dev/null +++ b/third_party/rust/id-arena/src/rayon.rs @@ -0,0 +1,282 @@ +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, + } + } +} |