pvec/
iter.rs

1//! A module providing implementation of the standard
2//! [Iterator](https://doc.rust-lang.org/std/iter/trait.Iterator.html),
3//! as well as [Rayon's ParallelIterator](https://docs.rs/rayon/1.3.0/rayon/iter/trait.ParallelIterator.html)
4//! if the `rayon_iter` feature flag is specified.
5
6use super::PVec;
7use super::Representation;
8
9use std::fmt::Debug;
10
11#[cfg(all(test, not(feature = "small_branch")))]
12pub const BRANCH_FACTOR: usize = 32;
13
14#[cfg(all(test, feature = "small_branch"))]
15pub const BRANCH_FACTOR: usize = 4;
16
17use crate::core::iter::RrbVecIter;
18use crate::core::RrbVec;
19use std::iter::FromIterator;
20use std::vec::IntoIter as VecIter;
21
22#[cfg(all(feature = "arc", feature = "rayon_iter"))]
23use rayon::iter::plumbing::{bridge, Consumer, Producer, ProducerCallback, UnindexedConsumer};
24
25#[cfg(all(feature = "arc", feature = "rayon_iter"))]
26use rayon::prelude::{
27    FromParallelIterator, IndexedParallelIterator, IntoParallelIterator, ParallelIterator,
28};
29
30/// This struct owns another, actual iterator
31/// either of the standard vector or RrbVec and is
32/// used to implement [Iterator](https://doc.rust-lang.org/std/iter/trait.Iterator.html)
33/// trait.
34#[derive(Debug, Clone)]
35pub struct PVecIter<T> {
36    iter_vec: Option<VecIter<T>>,
37    iter_rrbvec: Option<RrbVecIter<T>>,
38}
39
40impl<T: Clone + Debug> PVecIter<T> {
41    fn from_vec(vec: Vec<T>) -> Self {
42        PVecIter {
43            iter_vec: Some(vec.into_iter()),
44            iter_rrbvec: None,
45        }
46    }
47
48    fn from_rrbvec(rrbvec: RrbVec<T>) -> Self {
49        PVecIter {
50            iter_vec: None,
51            iter_rrbvec: Some(rrbvec.into_iter()),
52        }
53    }
54}
55
56impl<T: Clone + Debug> Iterator for PVecIter<T> {
57    type Item = T;
58
59    fn next(&mut self) -> Option<Self::Item> {
60        if let Some(iter_vec) = self.iter_vec.as_mut() {
61            iter_vec.next()
62        } else if let Some(iter_rrbvec) = self.iter_rrbvec.as_mut() {
63            iter_rrbvec.next()
64        } else {
65            None
66        }
67    }
68
69    fn size_hint(&self) -> (usize, Option<usize>) {
70        if let Some(iter_vec) = self.iter_vec.as_ref() {
71            iter_vec.size_hint()
72        } else if let Some(iter_rrbvec) = self.iter_rrbvec.as_ref() {
73            iter_rrbvec.size_hint()
74        } else {
75            (0, None)
76        }
77    }
78}
79
80impl<T: Clone + Debug> ExactSizeIterator for PVecIter<T> {
81    fn len(&self) -> usize {
82        if let Some(iter_vec) = self.iter_vec.as_ref() {
83            iter_vec.len()
84        } else if let Some(iter_rrbvec) = self.iter_rrbvec.as_ref() {
85            iter_rrbvec.len()
86        } else {
87            0
88        }
89    }
90}
91
92impl<T: Clone + Debug> DoubleEndedIterator for PVecIter<T> {
93    fn next_back(&mut self) -> Option<Self::Item> {
94        if let Some(iter_vec) = self.iter_vec.as_mut() {
95            iter_vec.next_back()
96        } else if let Some(iter_rrbvec) = self.iter_rrbvec.as_mut() {
97            iter_rrbvec.next_back()
98        } else {
99            None
100        }
101    }
102}
103
104impl<T: Clone + Debug> IntoIterator for PVec<T> {
105    type Item = T;
106    type IntoIter = PVecIter<T>;
107
108    fn into_iter(self) -> Self::IntoIter {
109        match self.0 {
110            Representation::Flat(vec) => PVecIter::from_vec(vec),
111            Representation::Tree(vec) => PVecIter::from_rrbvec(vec),
112        }
113    }
114}
115
116/// This struct is used to implement the
117/// [parallel iterator](https://docs.rs/rayon/1.3.0/rayon/iter/trait.ParallelIterator.html)
118#[derive(Debug, Clone)]
119#[cfg(all(feature = "arc", feature = "rayon_iter"))]
120pub struct PVecParIter<T: Send + Sync + Debug + Clone> {
121    vec: PVec<T>,
122}
123
124#[cfg(all(feature = "arc", feature = "rayon_iter"))]
125impl<T: Send + Sync + Debug + Clone> IntoParallelIterator for PVec<T> {
126    type Item = T;
127    type Iter = PVecParIter<T>;
128
129    fn into_par_iter(self) -> Self::Iter {
130        PVecParIter { vec: self }
131    }
132}
133
134#[cfg(all(feature = "arc", feature = "rayon_iter"))]
135impl<T: Send + Sync + Debug + Clone> ParallelIterator for PVecParIter<T> {
136    type Item = T;
137
138    fn drive_unindexed<C>(self, consumer: C) -> C::Result
139    where
140        C: UnindexedConsumer<Self::Item>,
141    {
142        bridge(self, consumer)
143    }
144
145    fn opt_len(&self) -> Option<usize> {
146        Some(self.vec.len())
147    }
148}
149
150#[cfg(all(feature = "arc", feature = "rayon_iter"))]
151impl<T: Send + Sync + Debug + Clone> IndexedParallelIterator for PVecParIter<T> {
152    fn drive<C>(self, consumer: C) -> C::Result
153    where
154        C: Consumer<Self::Item>,
155    {
156        bridge(self, consumer)
157    }
158
159    fn len(&self) -> usize {
160        self.vec.len()
161    }
162
163    fn with_producer<CB>(self, callback: CB) -> CB::Output
164    where
165        CB: ProducerCallback<Self::Item>,
166    {
167        callback.callback(VecProducer { vec: self.vec })
168    }
169}
170
171#[cfg(all(feature = "arc", feature = "rayon_iter"))]
172struct VecProducer<T: Send + Sync + Debug + Clone> {
173    vec: PVec<T>,
174}
175
176#[cfg(all(feature = "arc", feature = "rayon_iter"))]
177impl<T: Send + Sync + Debug + Clone> Producer for VecProducer<T> {
178    type Item = T;
179    type IntoIter = PVecIter<T>;
180
181    fn into_iter(mut self) -> Self::IntoIter {
182        std::mem::replace(&mut self.vec, PVec::new()).into_iter()
183    }
184
185    fn split_at(mut self, index: usize) -> (Self, Self) {
186        let mut vec = std::mem::replace(&mut self.vec, PVec::new());
187
188        let right = vec.split_off(index);
189        let left = vec;
190
191        (VecProducer { vec: left }, VecProducer { vec: right })
192    }
193}
194
195#[cfg(all(feature = "arc", feature = "rayon_iter"))]
196impl<T: Clone + Debug + Send + Sync> FromParallelIterator<T> for PVec<T>
197where
198    T: Send,
199{
200    fn from_par_iter<I>(par_iter: I) -> Self
201    where
202        I: IntoParallelIterator<Item = T>,
203    {
204        par_iter
205            .into_par_iter()
206            .fold(PVec::new, |mut vec, elem| {
207                vec.push(elem);
208                vec
209            })
210            .reduce(PVec::new, |mut list1, mut list2| {
211                list1.append(&mut list2);
212                list1
213            })
214    }
215}
216
217impl<T: Clone + Debug> FromIterator<T> for PVec<T> {
218    fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
219        let mut vec = PVec::new();
220        for i in iter {
221            vec.push(i);
222        }
223        vec
224    }
225}
226
227#[cfg(test)]
228#[macro_use]
229mod test {
230    use super::PVec;
231    use super::BRANCH_FACTOR;
232
233    #[test]
234    fn empty_pvec() {
235        let pvec: PVec<usize> = PVec::new();
236        let mut iter = pvec.into_iter();
237
238        let size = iter.size_hint();
239        let next = iter.next();
240
241        assert_eq!(next, None);
242        assert_eq!(size, (0, Some(0)));
243    }
244
245    #[test]
246    fn pvec_has_tail_only() {
247        let mut pvec = PVec::new();
248
249        for i in 0..BRANCH_FACTOR {
250            pvec.push(i);
251        }
252
253        for (i, val) in pvec.into_iter().enumerate() {
254            assert_eq!(i, val);
255        }
256    }
257
258    #[test]
259    fn underlying_tree_has_multiple_levels() {
260        let mut pvec = PVec::new();
261
262        let mut val = 0;
263        for _ in 0..(BRANCH_FACTOR * BRANCH_FACTOR * BRANCH_FACTOR) {
264            pvec.push(val);
265            val += 1;
266        }
267
268        for _ in 0..(BRANCH_FACTOR / 2) {
269            pvec.push(val);
270            val += 1;
271        }
272
273        for (i, val) in pvec.into_iter().enumerate() {
274            assert_eq!(i, val);
275        }
276    }
277
278    #[test]
279    fn underlying_tree_is_relaxed() {
280        let vec_size = 33;
281
282        let mut vec = PVec::new();
283        let mut vec_item = 0;
284
285        for i in 0..128 {
286            if i % 2 == 0 {
287                let mut vec_temp = PVec::new();
288
289                for _ in 0..vec_size {
290                    vec_temp.push(vec_item);
291                    vec_item += 1;
292                }
293
294                assert_eq!(vec_temp.len(), vec_size);
295
296                vec.append(&mut vec_temp);
297
298                assert_eq!(vec_temp.len(), 0);
299            } else {
300                for _ in 0..(vec_size + vec_size) {
301                    vec.push(vec_item);
302                    vec_item += 1;
303                }
304            }
305
306            assert_eq!(vec.len(), vec_item);
307
308            for i in 0..vec.len() {
309                assert_eq!(*vec.get(i).unwrap(), i);
310                assert_eq!(*vec.get_mut(i).unwrap(), i);
311            }
312
313            let mut vec_one_clone = vec.clone();
314            for i in (0..vec_item).rev() {
315                assert_eq!(vec_one_clone.pop().unwrap(), i);
316            }
317
318            assert_eq!(vec_one_clone.len(), 0);
319            assert_eq!(vec.len(), vec_item);
320
321            let vec_clone = vec.clone();
322            for (i, val) in vec_clone.into_iter().enumerate() {
323                assert_eq!(i, val);
324            }
325        }
326    }
327}