Skip to main content

roaring/treemap/
inherent.rs

1use alloc::collections::btree_map::{BTreeMap, Entry};
2use core::iter;
3use core::ops::RangeBounds;
4
5use crate::IntegerTooSmall;
6use crate::RoaringBitmap;
7use crate::RoaringTreemap;
8
9use super::util;
10
11#[cfg(not(feature = "std"))]
12use alloc::vec::Vec;
13
14impl RoaringTreemap {
15    /// Creates an empty `RoaringTreemap`.
16    ///
17    /// # Examples
18    ///
19    /// ```rust
20    /// use roaring::RoaringTreemap;
21    /// let rb = RoaringTreemap::new();
22    /// ```
23    pub fn new() -> RoaringTreemap {
24        RoaringTreemap { map: BTreeMap::new() }
25    }
26
27    /// Creates a full `RoaringTreemap`.
28    ///
29    /// # Examples
30    ///
31    /// ```rust,ignore
32    /// use roaring::RoaringTreemap;
33    /// let rb = RoaringTreemap::full();
34    /// ```
35    pub fn full() -> RoaringTreemap {
36        RoaringTreemap { map: (0..=u32::MAX).zip(iter::repeat(RoaringBitmap::full())).collect() }
37    }
38
39    /// Adds a value to the set. Returns `true` if the value was not already present in the set.
40    ///
41    /// # Examples
42    ///
43    /// ```rust
44    /// use roaring::RoaringTreemap;
45    ///
46    /// let mut rb = RoaringTreemap::new();
47    /// assert_eq!(rb.insert(3), true);
48    /// assert_eq!(rb.insert(3), false);
49    /// assert_eq!(rb.contains(3), true);
50    /// ```
51    pub fn insert(&mut self, value: u64) -> bool {
52        let (hi, lo) = util::split(value);
53        self.map.entry(hi).or_default().insert(lo)
54    }
55
56    /// Inserts a range of values.
57    ///
58    /// Returns the number of inserted values.
59    ///
60    /// # Examples
61    ///
62    /// ```rust
63    /// use roaring::RoaringTreemap;
64    ///
65    /// let mut rb = RoaringTreemap::new();
66    /// rb.insert_range(2..4);
67    /// assert!(rb.contains(2));
68    /// assert!(rb.contains(3));
69    /// assert!(!rb.contains(4));
70    /// ```
71    pub fn insert_range<R: RangeBounds<u64>>(&mut self, range: R) -> u64 {
72        let (start, end) = match util::convert_range_to_inclusive(range) {
73            Some(range) => (*range.start(), *range.end()),
74            None => return 0,
75        };
76
77        let (start_hi, start_lo) = util::split(start);
78        let (end_hi, end_lo) = util::split(end);
79
80        let mut counter = 0u64;
81
82        // Split the input range by the leading 32 bits
83        for hi in start_hi..=end_hi {
84            let entry = self.map.entry(hi);
85
86            // Calculate the sub-range from the lower 32 bits
87            counter += if hi == end_hi && hi == start_hi {
88                entry.or_default().insert_range(start_lo..=end_lo)
89            } else if hi == start_hi {
90                entry.or_default().insert_range(start_lo..=u32::MAX)
91            } else if hi == end_hi {
92                entry.or_default().insert_range(0..=end_lo)
93            } else {
94                // We insert a full bitmap if it doesn't already exist and return the size of it.
95                // But if the bitmap already exists at this spot we replace it with a full bitmap
96                // and specify that we didn't inserted the integers from the previous bitmap.
97                let full_bitmap = RoaringBitmap::full();
98                match entry {
99                    Entry::Vacant(entry) => entry.insert(full_bitmap).len(),
100                    Entry::Occupied(mut entry) => {
101                        full_bitmap.len() - entry.insert(full_bitmap).len()
102                    }
103                }
104            };
105        }
106
107        counter
108    }
109
110    /// Pushes `value` in the treemap only if it is greater than the current maximum value.
111    ///
112    /// Returns whether the value was inserted.
113    ///
114    /// # Examples
115    ///
116    /// ```rust
117    /// use roaring::RoaringTreemap;
118    ///
119    /// let mut rb = RoaringTreemap::new();
120    /// assert!(rb.push(1));
121    /// assert!(rb.push(3));
122    /// assert_eq!(rb.push(3), false);
123    /// assert!(rb.push(5));
124    ///
125    /// assert_eq!(rb.iter().collect::<Vec<u64>>(), vec![1, 3, 5]);
126    /// ```
127    #[deprecated(since = "0.11.0", note = "use `try_push` instead")]
128    pub fn push(&mut self, value: u64) -> bool {
129        let (hi, lo) = util::split(value);
130        self.map.entry(hi).or_default().try_push(lo).is_ok()
131    }
132
133    /// Pushes `value` in the treemap only if it is greater than the current maximum value.
134    ///
135    /// Returns an error if the value is not greater than the current maximum value.
136    ///
137    /// # Examples
138    ///
139    /// ```rust
140    /// use roaring::{RoaringTreemap, IntegerTooSmall};
141    ///
142    /// let mut rb = RoaringTreemap::new();
143    /// assert!(rb.try_push(1).is_ok());
144    /// assert!(rb.try_push(3).is_ok());
145    /// assert_eq!(rb.try_push(3), Err(IntegerTooSmall));
146    /// assert!(rb.try_push(5).is_ok());
147    ///
148    /// assert_eq!(rb.iter().collect::<Vec<u64>>(), vec![1, 3, 5]);
149    /// ```
150    pub fn try_push(&mut self, value: u64) -> Result<(), IntegerTooSmall> {
151        let (hi, lo) = util::split(value);
152        self.map.entry(hi).or_default().try_push(lo)
153    }
154
155    /// Pushes `value` in the treemap only if it is greater than the current maximum value.
156    /// It is up to the caller to have validated index > self.max()
157    ///
158    /// # Panics
159    ///
160    /// If debug_assertions enabled and index is > self.max()
161    pub(crate) fn push_unchecked(&mut self, value: u64) {
162        let (hi, lo) = util::split(value);
163        // BTreeMap last_mut not stabilized see https://github.com/rust-lang/rust/issues/62924
164        match self.map.iter_mut().next_back() {
165            Some((&key, bitmap)) if key == hi => bitmap.push_unchecked(lo),
166            Some((&key, _)) if cfg!(debug_assertions) && key > hi => {
167                panic!("last bitmap key > key of value")
168            }
169            _otherwise => {
170                // The tree is empty
171                let mut rb = RoaringBitmap::new();
172                rb.push_unchecked(lo);
173                self.map.insert(hi, rb);
174            }
175        }
176    }
177
178    /// Removes a value from the set. Returns `true` if the value was present in the set.
179    ///
180    /// # Examples
181    ///
182    /// ```rust
183    /// use roaring::RoaringTreemap;
184    ///
185    /// let mut rb = RoaringTreemap::new();
186    /// rb.insert(3);
187    /// assert_eq!(rb.remove(3), true);
188    /// assert_eq!(rb.remove(3), false);
189    /// assert_eq!(rb.contains(3), false);
190    /// ```
191    pub fn remove(&mut self, value: u64) -> bool {
192        let (hi, lo) = util::split(value);
193        match self.map.entry(hi) {
194            Entry::Vacant(_) => false,
195            Entry::Occupied(mut ent) => {
196                if ent.get_mut().remove(lo) {
197                    if ent.get().is_empty() {
198                        ent.remove();
199                    }
200                    true
201                } else {
202                    false
203                }
204            }
205        }
206    }
207
208    /// Removes a range of values.
209    /// Returns the number of removed values.
210    ///
211    /// # Examples
212    ///
213    /// ```rust
214    /// use roaring::RoaringTreemap;
215    ///
216    /// let mut rb = RoaringTreemap::new();
217    /// rb.insert(2);
218    /// rb.insert(3);
219    /// assert_eq!(rb.remove_range(2..4), 2);
220    /// ```
221    pub fn remove_range<R>(&mut self, range: R) -> u64
222    where
223        R: RangeBounds<u64>,
224    {
225        let (start, end) = match util::convert_range_to_inclusive(range) {
226            Some(range) => (*range.start(), *range.end()),
227            None => return 0,
228        };
229
230        let (start_container_key, start_index) = util::split(start);
231        let (end_container_key, end_index) = util::split(end);
232
233        let mut keys_to_remove = Vec::new();
234        let mut removed = 0;
235
236        for (&key, rb) in &mut self.map {
237            if key >= start_container_key && key <= end_container_key {
238                let a = if key == start_container_key { start_index } else { 0 };
239                let b = if key == end_container_key { end_index } else { u32::MAX };
240                removed += rb.remove_range(a..=b);
241                if rb.is_empty() {
242                    keys_to_remove.push(key);
243                }
244            }
245        }
246
247        for key in keys_to_remove {
248            self.map.remove(&key);
249        }
250
251        removed
252    }
253
254    /// Returns `true` if this set contains the specified integer.
255    ///
256    /// # Examples
257    ///
258    /// ```rust
259    /// use roaring::RoaringTreemap;
260    ///
261    /// let mut rb = RoaringTreemap::new();
262    /// rb.insert(1);
263    /// assert_eq!(rb.contains(0), false);
264    /// assert_eq!(rb.contains(1), true);
265    /// assert_eq!(rb.contains(100), false);
266    /// ```
267    pub fn contains(&self, value: u64) -> bool {
268        let (hi, lo) = util::split(value);
269        match self.map.get(&hi) {
270            None => false,
271            Some(r) => r.contains(lo),
272        }
273    }
274
275    /// Returns `true` if all values in the range are present in this set.
276    ///
277    /// An empty range is always contained.
278    ///
279    /// # Examples
280    ///
281    /// ```rust
282    /// use roaring::RoaringTreemap;
283    ///
284    /// let mut rb = RoaringTreemap::new();
285    /// // An empty range is always contained
286    /// assert!(rb.contains_range(7..7));
287    ///
288    /// rb.insert_range(1..0x1_0000_0000);
289    /// assert!(rb.contains_range(1..0x1_0000_0000));
290    /// assert!(rb.contains_range(2..0x1_0000_0000));
291    /// // 0 is not contained
292    /// assert!(!rb.contains_range(0..2));
293    /// // 0x1_0000_0000 is not contained
294    /// assert!(!rb.contains_range(1..=0x1_0000_0000));
295    /// ```
296    pub fn contains_range<R>(&self, range: R) -> bool
297    where
298        R: RangeBounds<u64>,
299    {
300        let (start, end) = match util::convert_range_to_inclusive(range) {
301            Some(range) => (*range.start(), *range.end()),
302            None => return true,
303        };
304        let (start_hi, start_lo) = util::split(start);
305        let (end_hi, end_lo) = util::split(end);
306
307        let mut expected_key = start_hi;
308        for (&key, bitmap) in self.map.range(start_hi..=end_hi) {
309            if key != expected_key {
310                return false;
311            }
312            let lo_start = if key == start_hi { start_lo } else { 0 };
313            let lo_end = if key == end_hi { end_lo } else { u32::MAX };
314            if !bitmap.contains_range(lo_start..=lo_end) {
315                return false;
316            }
317            match key.checked_add(1) {
318                Some(k) => expected_key = k,
319                None => return true,
320            }
321        }
322        expected_key > end_hi
323    }
324
325    /// Returns the number of elements in this set which are in the passed range.
326    ///
327    /// # Examples
328    ///
329    /// ```rust
330    /// use roaring::RoaringTreemap;
331    ///
332    /// let mut rb = RoaringTreemap::new();
333    /// rb.insert_range(0x1_0000_0000..0x4_0000_0000);
334    /// rb.insert(0x5_0000_0001);
335    /// rb.insert(0x5_0000_0005);
336    /// rb.insert(u64::MAX);
337    ///
338    /// assert_eq!(rb.range_cardinality(0..0x1_0000_0000), 0);
339    /// assert_eq!(rb.range_cardinality(0x1_0000_0000..0x4_0000_0000), 0x3_0000_0000);
340    /// assert_eq!(rb.range_cardinality(0x5_0000_0000..0x6_0000_0000), 2);
341    /// assert_eq!(rb.range_cardinality(0x1_0000_0000..0x1_0000_0000), 0);
342    /// assert_eq!(rb.range_cardinality(0x5_0000_0000..=u64::MAX), 3);
343    /// ```
344    pub fn range_cardinality<R>(&self, range: R) -> u64
345    where
346        R: RangeBounds<u64>,
347    {
348        let (start, end) = match util::convert_range_to_inclusive(range) {
349            Some(range) => (*range.start(), *range.end()),
350            None => return 0,
351        };
352        let (start_hi, start_lo) = util::split(start);
353        let (end_hi, end_lo) = util::split(end);
354
355        self.map
356            .range(start_hi..=end_hi)
357            .map(|(&key, bitmap)| {
358                let lo_start = if key == start_hi { start_lo } else { 0 };
359                let lo_end = if key == end_hi { end_lo } else { u32::MAX };
360                bitmap.range_cardinality(lo_start..=lo_end)
361            })
362            .sum::<u64>()
363    }
364
365    /// Clears all integers in this set.
366    ///
367    /// # Examples
368    ///
369    /// ```rust
370    /// use roaring::RoaringTreemap;
371    ///
372    /// let mut rb = RoaringTreemap::new();
373    /// rb.insert(1);
374    /// assert_eq!(rb.contains(1), true);
375    /// rb.clear();
376    /// assert_eq!(rb.contains(1), false);
377    /// ```
378    pub fn clear(&mut self) {
379        self.map.clear();
380    }
381
382    /// Returns `true` if there are no integers in this set.
383    ///
384    /// # Examples
385    ///
386    /// ```rust
387    /// use roaring::RoaringTreemap;
388    ///
389    /// let mut rb = RoaringTreemap::new();
390    /// assert_eq!(rb.is_empty(), true);
391    ///
392    /// rb.insert(3);
393    /// assert_eq!(rb.is_empty(), false);
394    /// ```
395    pub fn is_empty(&self) -> bool {
396        self.map.values().all(RoaringBitmap::is_empty)
397    }
398
399    /// Returns `true` if there are every possible integers in this set.
400    ///
401    /// # Examples
402    ///
403    /// ```rust,ignore
404    /// use roaring::RoaringTreemap;
405    ///
406    /// let mut rb = RoaringTreemap::full();
407    /// assert!(!rb.is_empty());
408    /// assert!(rb.is_full());
409    /// ```
410    pub fn is_full(&self) -> bool {
411        self.map.len() == (u32::MAX as u64 + 1) as usize
412            && self.map.values().all(RoaringBitmap::is_full)
413    }
414
415    /// Returns the number of distinct integers added to the set.
416    ///
417    /// # Examples
418    ///
419    /// ```rust
420    /// use roaring::RoaringTreemap;
421    ///
422    /// let mut rb = RoaringTreemap::new();
423    /// assert_eq!(rb.len(), 0);
424    ///
425    /// rb.insert(3);
426    /// assert_eq!(rb.len(), 1);
427    ///
428    /// rb.insert(3);
429    /// rb.insert(4);
430    /// assert_eq!(rb.len(), 2);
431    /// ```
432    pub fn len(&self) -> u64 {
433        self.map.values().map(RoaringBitmap::len).sum()
434    }
435
436    /// Optimizes the underlying bitmap storage and removes empty partitions.
437    ///
438    /// Returns true if the treemap storage was modified, false if not.
439    ///
440    /// # Examples
441    ///
442    /// ```
443    /// use roaring::RoaringTreemap;
444    ///
445    /// let mut rb = RoaringTreemap::from_iter(1000..100000);
446    /// rb.optimize();
447    /// ```
448    pub fn optimize(&mut self) -> bool {
449        let mut changed = false;
450
451        self.map.retain(|_, bitmap| {
452            changed |= bitmap.optimize();
453
454            if bitmap.is_empty() {
455                changed = true;
456                false
457            } else {
458                true
459            }
460        });
461
462        changed
463    }
464
465    /// Returns the minimum value in the set (if the set is non-empty).
466    ///
467    /// # Examples
468    ///
469    /// ```rust
470    /// use roaring::RoaringTreemap;
471    ///
472    /// let mut rb = RoaringTreemap::new();
473    /// assert_eq!(rb.min(), None);
474    ///
475    /// rb.insert(3);
476    /// rb.insert(4);
477    /// assert_eq!(rb.min(), Some(3));
478    /// ```
479    pub fn min(&self) -> Option<u64> {
480        self.map
481            .iter()
482            .find(|&(_, rb)| rb.min().is_some())
483            .map(|(k, rb)| util::join(*k, rb.min().unwrap()))
484    }
485
486    /// Returns the maximum value in the set (if the set is non-empty).
487    ///
488    /// # Examples
489    ///
490    /// ```rust
491    /// use roaring::RoaringTreemap;
492    ///
493    /// let mut rb = RoaringTreemap::new();
494    /// assert_eq!(rb.max(), None);
495    ///
496    /// rb.insert(3);
497    /// rb.insert(4);
498    /// assert_eq!(rb.max(), Some(4));
499    /// ```
500    pub fn max(&self) -> Option<u64> {
501        self.map
502            .iter()
503            .rev()
504            .find(|&(_, rb)| rb.max().is_some())
505            .map(|(k, rb)| util::join(*k, rb.max().unwrap()))
506    }
507
508    /// Returns the number of integers that are <= value. rank(u64::MAX) == len()
509    ///
510    /// # Examples
511    ///
512    /// ```rust
513    /// use roaring::RoaringTreemap;
514    ///
515    /// let mut rb = RoaringTreemap::new();
516    /// assert_eq!(rb.rank(0), 0);
517    ///
518    /// rb.insert(3);
519    /// rb.insert(4);
520    /// assert_eq!(rb.rank(3), 1);
521    /// assert_eq!(rb.rank(10), 2)
522    /// ```
523    pub fn rank(&self, value: u64) -> u64 {
524        // if len becomes cached for RoaringTreemap: return len if len > value
525
526        let (hi, lo) = util::split(value);
527        let mut iter = self.map.range(..=hi).rev();
528
529        iter.next()
530            .map(|(&k, bitmap)| if k == hi { bitmap.rank(lo) } else { bitmap.len() })
531            .unwrap_or(0)
532            + iter.map(|(_, bitmap)| bitmap.len()).sum::<u64>()
533    }
534
535    /// Returns the `n`th integer in the set or `None` if `n >= len()`
536    ///
537    /// # Examples
538    ///
539    /// ```rust
540    /// use roaring::RoaringTreemap;
541    ///
542    /// let mut rb = RoaringTreemap::new();
543    /// assert_eq!(rb.select(0), None);
544    ///
545    /// rb.append(vec![0, 10, 100]);
546    ///
547    /// assert_eq!(rb.select(0), Some(0));
548    /// assert_eq!(rb.select(1), Some(10));
549    /// assert_eq!(rb.select(2), Some(100));
550    /// assert_eq!(rb.select(3), None);
551    /// ```
552    pub fn select(&self, mut n: u64) -> Option<u64> {
553        for (&key, bitmap) in &self.map {
554            let len = bitmap.len();
555            if len > n {
556                return Some(((key as u64) << 32) | bitmap.select(n as u32).unwrap() as u64);
557            }
558            n -= len;
559        }
560
561        None
562    }
563}
564
565impl Default for RoaringTreemap {
566    fn default() -> RoaringTreemap {
567        RoaringTreemap::new()
568    }
569}
570
571impl Clone for RoaringTreemap {
572    fn clone(&self) -> Self {
573        RoaringTreemap { map: self.map.clone() }
574    }
575
576    fn clone_from(&mut self, other: &Self) {
577        self.map.clone_from(&other.map);
578    }
579}
580
581#[cfg(test)]
582mod test {
583    use crate::{RoaringBitmap, RoaringTreemap};
584    use alloc::vec::Vec;
585    use proptest::collection::btree_map;
586    use proptest::prelude::*;
587
588    proptest! {
589        #[test]
590        fn optimize_preserves_values(mut treemap in RoaringTreemap::arbitrary()) {
591            let before = treemap.iter().collect::<Vec<_>>();
592
593            treemap.optimize();
594
595            let after = treemap.iter().collect::<Vec<_>>();
596            prop_assert_eq!(before, after);
597        }
598
599        #[test]
600        fn optimize_prunes_empty_partitions_from_bitmaps(
601            bitmaps in btree_map(0u32..=16, RoaringBitmap::arbitrary(), 0usize..=16)
602        ) {
603            let mut treemap = RoaringTreemap::from_bitmaps(bitmaps);
604            let before = treemap.iter().collect::<Vec<_>>();
605            let had_empty_partition = treemap.bitmaps().any(|(_, bitmap)| bitmap.is_empty());
606
607            let changed = treemap.optimize();
608
609            prop_assert_eq!(treemap.iter().collect::<Vec<_>>(), before);
610            prop_assert!(treemap.bitmaps().all(|(_, bitmap)| !bitmap.is_empty()));
611
612            if had_empty_partition {
613                prop_assert!(changed);
614            }
615        }
616    }
617}