Skip to main content

roaring/treemap/
iter.rs

1use alloc::collections::{btree_map, BTreeMap};
2use core::cmp::Ordering;
3use core::iter;
4use core::ops::Add;
5
6use super::util;
7use crate::bitmap::IntoIter as IntoIter32;
8use crate::bitmap::Iter as Iter32;
9use crate::{NonSortedIntegers, RoaringBitmap, RoaringTreemap};
10
11#[derive(Clone)]
12struct To64Iter<'a> {
13    hi: u32,
14    inner: Iter32<'a>,
15}
16
17impl To64Iter<'_> {
18    fn advance_to(&mut self, n: u32) {
19        self.inner.advance_to(n)
20    }
21
22    fn advance_back_to(&mut self, n: u32) {
23        self.inner.advance_back_to(n)
24    }
25}
26
27impl Iterator for To64Iter<'_> {
28    type Item = u64;
29    fn next(&mut self) -> Option<u64> {
30        self.inner.next().map(|n| util::join(self.hi, n))
31    }
32
33    fn size_hint(&self) -> (usize, Option<usize>) {
34        self.inner.size_hint()
35    }
36
37    #[inline]
38    fn fold<B, F>(self, init: B, mut f: F) -> B
39    where
40        Self: Sized,
41        F: FnMut(B, Self::Item) -> B,
42    {
43        self.inner.fold(init, move |b, lo| f(b, ((self.hi as u64) << 32) + (lo as u64)))
44    }
45}
46
47impl DoubleEndedIterator for To64Iter<'_> {
48    fn next_back(&mut self) -> Option<Self::Item> {
49        self.inner.next_back().map(|n| util::join(self.hi, n))
50    }
51
52    #[inline]
53    fn rfold<B, F>(self, init: B, mut f: F) -> B
54    where
55        Self: Sized,
56        F: FnMut(B, Self::Item) -> B,
57    {
58        self.inner.rfold(init, move |b, lo| f(b, ((self.hi as u64) << 32) + (lo as u64)))
59    }
60}
61
62fn to64iter(t: (u32, &RoaringBitmap)) -> To64Iter<'_> {
63    To64Iter { hi: t.0, inner: t.1.iter() }
64}
65
66#[derive(Clone)]
67struct To64IntoIter {
68    hi: u32,
69    inner: IntoIter32,
70}
71
72impl Iterator for To64IntoIter {
73    type Item = u64;
74    fn next(&mut self) -> Option<u64> {
75        self.inner.next().map(|n| util::join(self.hi, n))
76    }
77
78    #[inline]
79    fn fold<B, F>(self, init: B, mut f: F) -> B
80    where
81        Self: Sized,
82        F: FnMut(B, Self::Item) -> B,
83    {
84        self.inner.fold(init, move |b, lo| f(b, ((self.hi as u64) << 32) + (lo as u64)))
85    }
86}
87
88impl DoubleEndedIterator for To64IntoIter {
89    fn next_back(&mut self) -> Option<Self::Item> {
90        self.inner.next_back().map(|n| util::join(self.hi, n))
91    }
92
93    #[inline]
94    fn rfold<B, F>(self, init: B, mut f: F) -> B
95    where
96        Self: Sized,
97        F: FnMut(B, Self::Item) -> B,
98    {
99        self.inner.rfold(init, move |b, lo| f(b, ((self.hi as u64) << 32) + (lo as u64)))
100    }
101}
102
103fn to64intoiter(t: (u32, RoaringBitmap)) -> To64IntoIter {
104    To64IntoIter { hi: t.0, inner: t.1.into_iter() }
105}
106
107type InnerIntoIter = iter::FlatMap<
108    btree_map::IntoIter<u32, RoaringBitmap>,
109    To64IntoIter,
110    fn((u32, RoaringBitmap)) -> To64IntoIter,
111>;
112
113/// An iterator for `RoaringTreemap`.
114#[derive(Clone)]
115pub struct Iter<'a> {
116    outer: BitmapIter<'a>,
117    front: Option<To64Iter<'a>>,
118    back: Option<To64Iter<'a>>,
119}
120
121/// An iterator for `RoaringTreemap`.
122pub struct IntoIter {
123    inner: InnerIntoIter,
124    size_hint: u64,
125}
126
127impl Iter<'_> {
128    fn new(map: &'_ BTreeMap<u32, RoaringBitmap>) -> Iter<'_> {
129        let outer = BitmapIter::new(map);
130        Iter { outer, front: None, back: None }
131    }
132
133    /// Advance the iterator to the first position where the item has a value >= `n`
134    ///
135    /// # Examples
136    ///
137    /// ```rust
138    /// use roaring::RoaringTreemap;
139    /// use core::iter::FromIterator;
140    ///
141    /// let bitmap = (1..3).collect::<RoaringTreemap>();
142    /// let mut iter = bitmap.iter();
143    /// iter.advance_to(2);
144    ///
145    /// assert_eq!(iter.next(), Some(2));
146    /// assert_eq!(iter.next(), None);
147    /// ```
148    pub fn advance_to(&mut self, n: u64) {
149        let (key, index) = util::split(n);
150
151        if let Some(ref mut front) = self.front {
152            match front.hi.cmp(&key) {
153                Ordering::Less => {}
154                Ordering::Equal => {
155                    front.advance_to(index);
156                    return;
157                }
158                Ordering::Greater => return,
159            }
160            self.front = None;
161        }
162
163        self.outer.advance_to(key);
164
165        let Some(next) = self.outer.next() else {
166            // if the current front iterator is empty or not yet initialized,
167            // but the outer bitmap iterator is empty, then consume the back
168            // iterator from the front if it is not also exhausted
169            if let Some(ref mut back) = self.back {
170                match back.hi.cmp(&key) {
171                    Ordering::Less => self.back = None,
172                    Ordering::Equal => back.advance_to(index),
173                    Ordering::Greater => {}
174                }
175            }
176            return;
177        };
178
179        let mut front = to64iter(next);
180        if front.hi == key {
181            front.advance_to(index);
182        }
183        self.front = Some(front);
184    }
185
186    /// Advance the back of the iterator to the first position where the item has a value <= `n`
187    ///
188    /// # Examples
189    ///
190    /// ```rust
191    /// use roaring::RoaringTreemap;
192    /// use core::iter::FromIterator;
193    ///
194    /// let bitmap = (1..3).collect::<RoaringTreemap>();
195    /// let mut iter = bitmap.iter();
196    /// iter.advance_back_to(1);
197    ///
198    /// assert_eq!(iter.next_back(), Some(1));
199    /// assert_eq!(iter.next_back(), None);
200    /// ```
201    pub fn advance_back_to(&mut self, n: u64) {
202        let (key, index) = util::split(n);
203
204        if let Some(ref mut back) = self.back {
205            match back.hi.cmp(&key) {
206                Ordering::Less => return,
207                Ordering::Equal => {
208                    back.advance_back_to(index);
209                    return;
210                }
211                Ordering::Greater => {}
212            }
213            self.back = None;
214        }
215
216        self.outer.advance_back_to(key);
217
218        let Some(next_back) = self.outer.next_back() else {
219            // if the current back iterator is empty or not yet initialized,
220            // but the outer bitmap iterator is empty, then consume the front
221            // iterator from the back if it is not also exhausted
222            if let Some(ref mut front) = self.front {
223                match front.hi.cmp(&key) {
224                    Ordering::Less => {}
225                    Ordering::Equal => front.advance_back_to(index),
226                    Ordering::Greater => self.front = None,
227                }
228            }
229            return;
230        };
231
232        let mut back = to64iter(next_back);
233        if back.hi == key {
234            back.advance_back_to(index);
235        }
236        self.back = Some(back);
237    }
238}
239
240impl IntoIter {
241    fn new(map: BTreeMap<u32, RoaringBitmap>) -> IntoIter {
242        let size_hint = map.values().map(|r| r.len()).sum();
243        let i = map.into_iter().flat_map(to64intoiter as _);
244        IntoIter { inner: i, size_hint }
245    }
246}
247
248impl Iterator for Iter<'_> {
249    type Item = u64;
250
251    fn next(&mut self) -> Option<u64> {
252        if let Some(ref mut front) = &mut self.front {
253            if let Some(inner) = front.next() {
254                return Some(inner);
255            }
256        }
257
258        let Some(outer_next) = self.outer.next() else {
259            // if the current front iterator is empty or not yet initialized,
260            // but the outer bitmap iterator is empty, then consume the back
261            // iterator from the front if it is not also exhausted
262            if let Some(ref mut back) = &mut self.back {
263                if let Some(next) = back.next() {
264                    return Some(next);
265                }
266            }
267            return None;
268        };
269
270        self.front = Some(to64iter(outer_next));
271        self.next()
272    }
273
274    fn size_hint(&self) -> (usize, Option<usize>) {
275        let front_size_hint = self.front.as_ref().map_or(0, |f| f.size_hint().0);
276        let back_size_hint = self.back.as_ref().map_or(0, |b| b.size_hint().0);
277
278        let size_hint = front_size_hint
279            .saturating_add(back_size_hint)
280            .saturating_add(self.outer.remaining() as usize);
281
282        (size_hint, Some(size_hint))
283    }
284}
285
286impl DoubleEndedIterator for Iter<'_> {
287    fn next_back(&mut self) -> Option<Self::Item> {
288        if let Some(ref mut back) = &mut self.back {
289            if let Some(inner) = back.next_back() {
290                return Some(inner);
291            }
292        }
293
294        let Some(outer_next_back) = self.outer.next_back() else {
295            // if the current back iterator is empty or not yet initialized,
296            // but the outer bitmap iterator is empty, then consume the front
297            // iterator from the back if it is not also exhausted
298            if let Some(ref mut front) = &mut self.front {
299                if let Some(next_back) = front.next_back() {
300                    return Some(next_back);
301                }
302            }
303            return None;
304        };
305
306        self.back = Some(to64iter(outer_next_back));
307        self.next_back()
308    }
309}
310
311#[cfg(target_pointer_width = "64")]
312impl ExactSizeIterator for Iter<'_> {
313    fn len(&self) -> usize {
314        self.size_hint().0
315    }
316}
317
318impl Iterator for IntoIter {
319    type Item = u64;
320
321    fn next(&mut self) -> Option<u64> {
322        self.size_hint = self.size_hint.saturating_sub(1);
323        self.inner.next()
324    }
325
326    fn size_hint(&self) -> (usize, Option<usize>) {
327        if self.size_hint < usize::MAX as u64 {
328            (self.size_hint as usize, Some(self.size_hint as usize))
329        } else {
330            (usize::MAX, None)
331        }
332    }
333
334    #[inline]
335    fn fold<B, F>(self, init: B, f: F) -> B
336    where
337        Self: Sized,
338        F: FnMut(B, Self::Item) -> B,
339    {
340        self.inner.fold(init, f)
341    }
342}
343
344impl DoubleEndedIterator for IntoIter {
345    fn next_back(&mut self) -> Option<Self::Item> {
346        self.size_hint = self.size_hint.saturating_sub(1);
347        self.inner.next_back()
348    }
349
350    #[inline]
351    fn rfold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
352    where
353        Fold: FnMut(Acc, Self::Item) -> Acc,
354    {
355        self.inner.rfold(init, fold)
356    }
357}
358
359#[cfg(target_pointer_width = "64")]
360impl ExactSizeIterator for IntoIter {
361    fn len(&self) -> usize {
362        self.size_hint as usize
363    }
364}
365
366impl RoaringTreemap {
367    /// Iterator over each value stored in the RoaringTreemap, guarantees values are ordered by
368    /// value.
369    ///
370    /// # Examples
371    ///
372    /// ```rust
373    /// use roaring::RoaringTreemap;
374    /// use core::iter::FromIterator;
375    ///
376    /// let bitmap = (1..3).collect::<RoaringTreemap>();
377    /// let mut iter = bitmap.iter();
378    ///
379    /// assert_eq!(iter.next(), Some(1));
380    /// assert_eq!(iter.next(), Some(2));
381    /// assert_eq!(iter.next(), None);
382    /// ```
383    pub fn iter(&'_ self) -> Iter<'_> {
384        Iter::new(&self.map)
385    }
386
387    /// Iterator over pairs of partition number and the corresponding RoaringBitmap.
388    /// The partition number is defined by the 32 most significant bits of the bit index.
389    ///
390    /// # Examples
391    ///
392    /// ```rust
393    /// use roaring::{RoaringBitmap, RoaringTreemap};
394    /// use core::iter::FromIterator;
395    ///
396    /// let original = (0..6000).collect::<RoaringTreemap>();
397    /// let mut bitmaps = original.bitmaps();
398    ///
399    /// assert_eq!(bitmaps.next(), Some((0, &(0..6000).collect::<RoaringBitmap>())));
400    /// assert_eq!(bitmaps.next(), None);
401    /// ```
402    pub fn bitmaps(&'_ self) -> BitmapIter<'_> {
403        BitmapIter::new(&self.map)
404    }
405
406    /// Construct a RoaringTreemap from an iterator of partition number and RoaringBitmap pairs.
407    /// The partition number is defined by the 32 most significant bits of the bit index.
408    /// Note that repeated partitions, if present, will replace previously set partitions.
409    ///
410    /// # Examples
411    ///
412    /// ```rust
413    /// use roaring::RoaringTreemap;
414    /// use core::iter::FromIterator;
415    ///
416    /// let original = (0..6000).collect::<RoaringTreemap>();
417    /// let clone = RoaringTreemap::from_bitmaps(original.bitmaps().map(|(p, b)| (p, b.clone())));
418    ///
419    /// assert_eq!(clone, original);
420    /// ```
421    pub fn from_bitmaps<I: IntoIterator<Item = (u32, RoaringBitmap)>>(iterator: I) -> Self {
422        RoaringTreemap { map: iterator.into_iter().collect() }
423    }
424}
425
426impl<'a> IntoIterator for &'a RoaringTreemap {
427    type Item = u64;
428    type IntoIter = Iter<'a>;
429
430    fn into_iter(self) -> Iter<'a> {
431        self.iter()
432    }
433}
434
435impl IntoIterator for RoaringTreemap {
436    type Item = u64;
437    type IntoIter = IntoIter;
438
439    fn into_iter(self) -> IntoIter {
440        IntoIter::new(self.map)
441    }
442}
443
444impl<const N: usize> From<[u64; N]> for RoaringTreemap {
445    fn from(arr: [u64; N]) -> Self {
446        RoaringTreemap::from_iter(arr)
447    }
448}
449
450impl FromIterator<u64> for RoaringTreemap {
451    fn from_iter<I: IntoIterator<Item = u64>>(iterator: I) -> RoaringTreemap {
452        let mut rb = RoaringTreemap::new();
453        rb.extend(iterator);
454        rb
455    }
456}
457
458impl<'a> FromIterator<&'a u64> for RoaringTreemap {
459    fn from_iter<I: IntoIterator<Item = &'a u64>>(iterator: I) -> RoaringTreemap {
460        let mut rb = RoaringTreemap::new();
461        rb.extend(iterator);
462        rb
463    }
464}
465
466impl Extend<u64> for RoaringTreemap {
467    fn extend<I: IntoIterator<Item = u64>>(&mut self, iterator: I) {
468        for value in iterator {
469            self.insert(value);
470        }
471    }
472}
473
474impl<'a> Extend<&'a u64> for RoaringTreemap {
475    fn extend<I: IntoIterator<Item = &'a u64>>(&mut self, iterator: I) {
476        for value in iterator {
477            self.insert(*value);
478        }
479    }
480}
481
482impl RoaringTreemap {
483    /// Create the set from a sorted iterator. Values must be sorted and deduplicated.
484    ///
485    /// The values of the iterator must be ordered and strictly greater than the greatest value
486    /// in the set. If a value in the iterator doesn't satisfy this requirement, it is not added
487    /// and the append operation is stopped.
488    ///
489    /// Returns `Ok` with the requested `RoaringTreemap`, `Err` with the number of elements
490    /// we tried to append before an error occurred.
491    ///
492    /// # Examples
493    ///
494    /// ```rust
495    /// use roaring::RoaringTreemap;
496    ///
497    /// let mut rb = RoaringTreemap::from_sorted_iter(0..10).unwrap();
498    ///
499    /// assert!(rb.iter().eq(0..10));
500    /// ```
501    pub fn from_sorted_iter<I: IntoIterator<Item = u64>>(
502        iterator: I,
503    ) -> Result<RoaringTreemap, NonSortedIntegers> {
504        let mut rt = RoaringTreemap::new();
505        rt.append(iterator).map(|_| rt)
506    }
507
508    /// Extend the set with a sorted iterator.
509    ///
510    /// The values of the iterator must be ordered and strictly greater than the greatest value
511    /// in the set. If a value in the iterator doesn't satisfy this requirement, it is not added
512    /// and the append operation is stopped.
513    ///
514    /// Returns `Ok` with the number of elements appended to the set, `Err` with
515    /// the number of elements we effectively appended before an error occurred.
516    ///
517    /// # Examples
518    ///
519    /// ```rust
520    /// use roaring::RoaringTreemap;
521    ///
522    /// let mut rb = RoaringTreemap::new();
523    /// rb.append(0..10);
524    ///
525    /// assert!(rb.iter().eq(0..10));
526    /// ```
527    pub fn append<I: IntoIterator<Item = u64>>(
528        &mut self,
529        iterator: I,
530    ) -> Result<u64, NonSortedIntegers> {
531        let mut iterator = iterator.into_iter();
532        let mut prev = match (iterator.next(), self.max()) {
533            (None, _) => return Ok(0),
534            (Some(first), Some(max)) if first <= max => {
535                return Err(NonSortedIntegers { valid_until: 0 })
536            }
537            (Some(first), _) => first,
538        };
539
540        // It is now guaranteed that so long as the values of the iterator are
541        // monotonically increasing they must also be the greatest in the set.
542
543        self.push_unchecked(prev);
544
545        let mut count = 1;
546        for value in iterator {
547            if value <= prev {
548                return Err(NonSortedIntegers { valid_until: count });
549            } else {
550                self.push_unchecked(value);
551                prev = value;
552                count += 1;
553            }
554        }
555
556        Ok(count)
557    }
558}
559
560/// An iterator of `RoaringBitmap`s for `RoaringTreemap`.
561#[derive(Clone)]
562pub struct BitmapIter<'a> {
563    treemap: &'a BTreeMap<u32, RoaringBitmap>,
564    range: btree_map::Range<'a, u32, RoaringBitmap>,
565    latest_front_idx: Option<u32>,
566    latest_back_idx: Option<u32>,
567}
568
569impl<'a> BitmapIter<'a> {
570    fn new(treemap: &'a BTreeMap<u32, RoaringBitmap>) -> Self {
571        let range = treemap.range(..);
572        Self { treemap, range, latest_back_idx: None, latest_front_idx: None }
573    }
574
575    fn advance_to(&mut self, new_front_idx: u32) {
576        match self.latest_back_idx {
577            Some(latest_back_idx) => match self.latest_front_idx {
578                Some(last_idx) if last_idx >= new_front_idx => {}
579                _ => {
580                    // if asked to advance to beyond the back iterator,
581                    // update the self.range iterator to be empty
582                    if new_front_idx >= latest_back_idx {
583                        self.range = self.treemap.range(0..1);
584                        self.range.next_back();
585                    } else {
586                        // otherwise shrink the remaining range from the front
587                        self.range = self.treemap.range(new_front_idx..latest_back_idx);
588                    }
589
590                    // self.range = self.treemap.range(new_front_idx..latest_back_idx);
591                }
592            },
593            None => match self.latest_front_idx {
594                Some(latest_idx) if latest_idx >= new_front_idx => {}
595                _ => {
596                    self.range = self.treemap.range(new_front_idx..);
597                }
598            },
599        }
600    }
601
602    fn advance_back_to(&mut self, new_back_idx: u32) {
603        match self.latest_front_idx {
604            Some(latest_front_idx) => match self.latest_back_idx {
605                // do nothing if asked to advance back to a higher index than the back is already at
606                Some(latest_back_idx) if latest_back_idx <= new_back_idx => {}
607                _ => {
608                    // if asked to advance back to beyond the front iterator,
609                    // update the self.range iterator to be empty
610                    if new_back_idx <= latest_front_idx {
611                        self.range = self.treemap.range(0..1);
612                        self.range.next_back();
613                    } else {
614                        // otherwise shrink the remaining range from the back
615                        self.range = self.treemap.range((latest_front_idx + 1)..new_back_idx);
616                    }
617                }
618            },
619            None => match self.latest_back_idx {
620                Some(latest_back_idx) if latest_back_idx <= new_back_idx => {}
621                _ => {
622                    self.range = self.treemap.range(..=new_back_idx);
623                }
624            },
625        }
626    }
627
628    fn remaining(&self) -> u64 {
629        let range = self.range.clone();
630        range.fold(0, |acc, (_, bitmap)| acc.add(bitmap.len()))
631    }
632}
633
634impl<'a> Iterator for BitmapIter<'a> {
635    type Item = (u32, &'a RoaringBitmap);
636
637    fn next(&mut self) -> Option<Self::Item> {
638        match self.range.next().map(|(&p, b)| (p, b)) {
639            None => {
640                self.latest_front_idx = None;
641                None
642            }
643            Some((next_idx, next_map)) => {
644                self.latest_front_idx = Some(next_idx);
645                Some((next_idx, next_map))
646            }
647        }
648    }
649
650    fn size_hint(&self) -> (usize, Option<usize>) {
651        self.range.size_hint()
652    }
653}
654
655impl FromIterator<(u32, RoaringBitmap)> for RoaringTreemap {
656    fn from_iter<I: IntoIterator<Item = (u32, RoaringBitmap)>>(iterator: I) -> RoaringTreemap {
657        Self::from_bitmaps(iterator)
658    }
659}
660
661impl DoubleEndedIterator for BitmapIter<'_> {
662    fn next_back(&mut self) -> Option<Self::Item> {
663        match self.range.next_back().map(|(&p, b)| (p, b)) {
664            None => {
665                self.latest_back_idx = None;
666                None
667            }
668            Some((next_back_idx, next_back_map)) => {
669                self.latest_back_idx = Some(next_back_idx);
670                Some((next_back_idx, next_back_map))
671            }
672        }
673    }
674}