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 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 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#[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#[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#[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}