id_arena/
rayon.rs

1extern crate rayon;
2
3use self::rayon::iter::plumbing::{Consumer, UnindexedConsumer};
4use self::rayon::iter::plumbing::ProducerCallback;
5use self::rayon::prelude::*;
6use super::*;
7
8impl<T, A> Arena<T, A>
9where
10    A: ArenaBehavior,
11{
12    /// Returns an iterator of shared references which can be used to iterate
13    /// over this arena in parallel with the `rayon` crate.
14    ///
15    /// # Features
16    ///
17    /// This API requires the `rayon` feature of this crate to be enabled.
18    pub fn par_iter(&self) -> ParIter<T, A>
19    where
20        T: Sync,
21        A::Id: Send,
22    {
23        ParIter {
24            arena_id: self.arena_id,
25            iter: self.items.par_iter().enumerate(),
26            _phantom: PhantomData,
27        }
28    }
29
30    /// Returns an iterator of mutable references which can be used to iterate
31    /// over this arena in parallel with the `rayon` crate.
32    ///
33    /// # Features
34    ///
35    /// This API requires the `rayon` feature of this crate to be enabled.
36    pub fn par_iter_mut(&mut self) -> ParIterMut<T, A>
37    where
38        T: Send + Sync,
39        A::Id: Send,
40    {
41        ParIterMut {
42            arena_id: self.arena_id,
43            iter: self.items.par_iter_mut().enumerate(),
44            _phantom: PhantomData,
45        }
46    }
47}
48
49/// A parallel iterator over shared references in an arena.
50///
51/// See `Arena::par_iter` for more information.
52#[derive(Debug)]
53pub struct ParIter<'a, T, A>
54where
55    T: Sync,
56{
57    arena_id: u32,
58    iter: rayon::iter::Enumerate<rayon::slice::Iter<'a, T>>,
59    _phantom: PhantomData<fn() -> A>,
60}
61
62impl<'a, T, A> ParallelIterator for ParIter<'a, T, A>
63where
64    T: Sync,
65    A: ArenaBehavior,
66    A::Id: Send,
67{
68    type Item = (A::Id, &'a T);
69
70    fn drive_unindexed<C>(self, consumer: C) -> C::Result
71    where
72        C: UnindexedConsumer<Self::Item>,
73    {
74        let arena_id = self.arena_id;
75        self.iter.map(|(i, item)| (A::new_id(arena_id, i), item))
76            .drive_unindexed(consumer)
77    }
78
79    fn opt_len(&self) -> Option<usize> {
80        self.iter.opt_len()
81    }
82}
83
84impl<'a, T, A> IndexedParallelIterator for ParIter<'a, T, A>
85where
86    T: Sync,
87    A: ArenaBehavior,
88    A::Id: Send,
89{
90    fn drive<C>(self, consumer: C) -> C::Result
91    where
92        C: Consumer<Self::Item>,
93    {
94        let arena_id = self.arena_id;
95        self.iter.map(|(i, item)| (A::new_id(arena_id, i), item))
96            .drive(consumer)
97    }
98
99    fn len(&self) -> usize {
100        self.iter.len()
101    }
102
103    fn with_producer<CB>(self, callback: CB) -> CB::Output
104    where
105        CB: ProducerCallback<Self::Item>,
106    {
107        let arena_id = self.arena_id;
108        self.iter.map(|(i, item)| (A::new_id(arena_id, i), item))
109            .with_producer(callback)
110    }
111}
112
113impl<'data, T, A> IntoParallelIterator for &'data Arena<T, A>
114    where A: ArenaBehavior,
115          A::Id: Send,
116          T: Sync,
117{
118    type Item = (A::Id, &'data T);
119    type Iter = ParIter<'data, T, A>;
120
121    fn into_par_iter(self) -> Self::Iter {
122        self.par_iter()
123    }
124}
125
126/// A parallel iterator over mutable references in an arena.
127///
128/// See `Arena::par_iter_mut` for more information.
129#[derive(Debug)]
130pub struct ParIterMut<'a, T, A>
131where
132    T: Send + Sync,
133{
134    arena_id: u32,
135    iter: rayon::iter::Enumerate<rayon::slice::IterMut<'a, T>>,
136    _phantom: PhantomData<fn() -> A>,
137}
138
139impl<'a, T, A> ParallelIterator for ParIterMut<'a, T, A>
140where
141    T: Send + Sync,
142    A: ArenaBehavior,
143    A::Id: Send,
144{
145    type Item = (A::Id, &'a mut T);
146
147    fn drive_unindexed<C>(self, consumer: C) -> C::Result
148    where
149        C: UnindexedConsumer<Self::Item>,
150    {
151        let arena_id = self.arena_id;
152        self.iter.map(|(i, item)| (A::new_id(arena_id, i), item))
153            .drive_unindexed(consumer)
154    }
155
156    fn opt_len(&self) -> Option<usize> {
157        self.iter.opt_len()
158    }
159}
160
161impl<'a, T, A> IndexedParallelIterator for ParIterMut<'a, T, A>
162where
163    T: Send + Sync,
164    A: ArenaBehavior,
165    A::Id: Send,
166{
167    fn drive<C>(self, consumer: C) -> C::Result
168    where
169        C: Consumer<Self::Item>,
170    {
171        let arena_id = self.arena_id;
172        self.iter.map(|(i, item)| (A::new_id(arena_id, i), item))
173            .drive(consumer)
174    }
175
176    fn len(&self) -> usize {
177        self.iter.len()
178    }
179
180    fn with_producer<CB>(self, callback: CB) -> CB::Output
181    where
182        CB: ProducerCallback<Self::Item>,
183    {
184        let arena_id = self.arena_id;
185        self.iter.map(|(i, item)| (A::new_id(arena_id, i), item))
186            .with_producer(callback)
187    }
188}
189
190impl<'data, T, A> IntoParallelIterator for &'data mut Arena<T, A>
191    where A: ArenaBehavior,
192          A::Id: Send,
193          T: Send + Sync,
194{
195    type Item = (A::Id, &'data mut T);
196    type Iter = ParIterMut<'data, T, A>;
197
198    fn into_par_iter(self) -> Self::Iter {
199        self.par_iter_mut()
200    }
201}
202
203/// A parallel iterator over items in an arena.
204///
205/// See `Arena::into_par_iter` for more information.
206#[derive(Debug)]
207pub struct IntoParIter<T, A>
208where
209    T: Send,
210{
211    arena_id: u32,
212    iter: rayon::iter::Enumerate<rayon::vec::IntoIter<T>>,
213    _phantom: PhantomData<fn() -> A>,
214}
215
216impl<T, A> ParallelIterator for IntoParIter<T, A>
217where
218    T: Send,
219    A: ArenaBehavior,
220    A::Id: Send,
221{
222    type Item = (A::Id, T);
223
224    fn drive_unindexed<C>(self, consumer: C) -> C::Result
225    where
226        C: UnindexedConsumer<Self::Item>,
227    {
228        let arena_id = self.arena_id;
229        self.iter.map(|(i, item)| (A::new_id(arena_id, i), item))
230            .drive_unindexed(consumer)
231    }
232
233    fn opt_len(&self) -> Option<usize> {
234        self.iter.opt_len()
235    }
236}
237
238impl<T, A> IndexedParallelIterator for IntoParIter<T, A>
239where
240    T: Send,
241    A: ArenaBehavior,
242    A::Id: Send,
243{
244    fn drive<C>(self, consumer: C) -> C::Result
245    where
246        C: Consumer<Self::Item>,
247    {
248        let arena_id = self.arena_id;
249        self.iter.map(|(i, item)| (A::new_id(arena_id, i), item))
250            .drive(consumer)
251    }
252
253    fn len(&self) -> usize {
254        self.iter.len()
255    }
256
257    fn with_producer<CB>(self, callback: CB) -> CB::Output
258    where
259        CB: ProducerCallback<Self::Item>,
260    {
261        let arena_id = self.arena_id;
262        self.iter.map(|(i, item)| (A::new_id(arena_id, i), item))
263            .with_producer(callback)
264    }
265}
266
267impl<T, A> IntoParallelIterator for Arena<T, A>
268    where A: ArenaBehavior,
269          A::Id: Send,
270          T: Send,
271{
272    type Item = (A::Id, T);
273    type Iter = IntoParIter<T, A>;
274
275    fn into_par_iter(self) -> Self::Iter {
276        IntoParIter {
277            arena_id: self.arena_id,
278            iter: self.items.into_par_iter().enumerate(),
279            _phantom: PhantomData,
280        }
281    }
282}