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}