Skip to main content

akar_storage/
roaring_bitmap.rs

1//! Roaring Bitmap — compressed bitset for node/edge ID sets.
2//!
3//! Uses the standard Roaring Bitmap layout:
4//! - High 16 bits → container key (u16)
5//! - Low 16 bits → index within the container
6//! - **Array container**: sorted `Vec<u16>` for sparse chunks (≤ `ARRAY_MAX_SIZE`)
7//! - **Bitmap container**: `[u64; 1024]` fixed bitset for dense chunks
8//! - Auto-upgrades Array → Bitmap when size exceeds `ARRAY_MAX_SIZE`
9//!
10//! Supports `u32` values (covering 4B IDs, sufficient for most graphs).
11
12use std::collections::BTreeMap;
13
14/// Maximum number of elements in an Array container before upgrading to Bitmap.
15const ARRAY_MAX_SIZE: usize = 4096;
16
17/// Bits per bitmap container (1024 × 64).
18
19// ---------------------------------------------------------------------------
20// Container enum
21// ---------------------------------------------------------------------------
22
23#[derive(Debug, Clone)]
24enum Container {
25    Array(Vec<u16>),
26    Bitmap(Box<[u64; 1024]>),
27}
28
29impl Container {
30    fn new_array() -> Self {
31        Container::Array(Vec::new())
32    }
33
34    fn len(&self) -> usize {
35        match self {
36            Container::Array(v) => v.len(),
37            Container::Bitmap(bm) => bm.iter().map(|w| w.count_ones() as usize).sum(),
38        }
39    }
40
41    fn is_empty(&self) -> bool {
42        match self {
43            Container::Array(v) => v.is_empty(),
44            Container::Bitmap(bm) => bm.iter().all(|w| *w == 0),
45        }
46    }
47
48    fn contains(&self, idx: u16) -> bool {
49        match self {
50            Container::Array(v) => v.binary_search(&idx).is_ok(),
51            Container::Bitmap(bm) => bm[idx as usize / 64] & (1u64 << (idx as u64 % 64)) != 0,
52        }
53    }
54
55    fn add(&mut self, idx: u16) -> bool {
56        match self {
57            Container::Array(v) => {
58                if let Err(pos) = v.binary_search(&idx) {
59                    v.insert(pos, idx);
60                    if v.len() > ARRAY_MAX_SIZE {
61                        *self = Container::Bitmap(Self::from_array_to_bitmap(std::mem::take(v)));
62                    }
63                    true
64                } else {
65                    false
66                }
67            }
68            Container::Bitmap(bm) => {
69                let word = &mut bm[idx as usize / 64];
70                let bit = 1u64 << (idx as u64 % 64);
71                if *word & bit == 0 {
72                    *word |= bit;
73                    true
74                } else {
75                    false
76                }
77            }
78        }
79    }
80
81    fn remove(&mut self, idx: u16) -> bool {
82        match self {
83            Container::Array(v) => {
84                if let Ok(pos) = v.binary_search(&idx) {
85                    v.remove(pos);
86                    true
87                } else {
88                    false
89                }
90            }
91            Container::Bitmap(bm) => {
92                let word = &mut bm[idx as usize / 64];
93                let bit = 1u64 << (idx as u64 % 64);
94                if *word & bit != 0 {
95                    *word &= !bit;
96                    true
97                } else {
98                    false
99                }
100            }
101        }
102    }
103
104    fn insert_all_from(&mut self, other: &Container) {
105        match self {
106            Container::Array(v) => match other {
107                Container::Array(other_v) => {
108                    let mut merged = Vec::with_capacity(v.len() + other_v.len());
109                    let mut i = 0;
110                    let mut j = 0;
111                    while i < v.len() && j < other_v.len() {
112                        if v[i] < other_v[j] {
113                            merged.push(v[i]);
114                            i += 1;
115                        } else if v[i] > other_v[j] {
116                            merged.push(other_v[j]);
117                            j += 1;
118                        } else {
119                            merged.push(v[i]);
120                            i += 1;
121                            j += 1;
122                        }
123                    }
124                    merged.extend_from_slice(&v[i..]);
125                    merged.extend_from_slice(&other_v[j..]);
126
127                    if merged.len() > ARRAY_MAX_SIZE {
128                        *self = Container::Bitmap(Self::from_array_to_bitmap(merged));
129                    } else {
130                        *v = merged;
131                    }
132                }
133                Container::Bitmap(other_bm) => {
134                    let other_count = other_bm.iter().map(|w| w.count_ones() as usize).sum::<usize>();
135                    if v.len() + other_count > ARRAY_MAX_SIZE {
136                        let mut bm = Self::from_array_to_bitmap(std::mem::take(v));
137                        for (i, w) in other_bm.iter().enumerate() {
138                            bm[i] |= w;
139                        }
140                        *self = Container::Bitmap(bm);
141                    } else {
142                        for (word_idx, word) in other_bm.iter().enumerate() {
143                            if *word == 0 {
144                                continue;
145                            }
146                            let base = (word_idx * 64) as u16;
147                            for bit in 0..64 {
148                                if word & (1u64 << bit) != 0 {
149                                    let idx = base + bit as u16;
150                                    if let Err(pos) = v.binary_search(&idx) {
151                                        v.insert(pos, idx);
152                                    }
153                                }
154                            }
155                        }
156                        if v.len() > ARRAY_MAX_SIZE {
157                            *self = Container::Bitmap(Self::from_array_to_bitmap(std::mem::take(v)));
158                        }
159                    }
160                }
161            },
162            Container::Bitmap(bm) => match other {
163                Container::Array(other_v) => {
164                    for &idx in other_v {
165                        bm[idx as usize / 64] |= 1u64 << (idx as u64 % 64);
166                    }
167                }
168                Container::Bitmap(other_bm) => {
169                    for (i, w) in other_bm.iter().enumerate() {
170                        bm[i] |= w;
171                    }
172                }
173            },
174        }
175    }
176
177    fn retain_intersection(&mut self, other: &Container) {
178        match (self, other) {
179            (Container::Array(v), Container::Array(other_v)) => {
180                v.retain(|x| other_v.binary_search(x).is_ok());
181            }
182            (Container::Array(v), Container::Bitmap(other_bm)) => {
183                v.retain(|x| other_bm[*x as usize / 64] & (1u64 << (*x as u64 % 64)) != 0);
184            }
185            (Container::Bitmap(bm), Container::Array(other_v)) => {
186                let mut bit_set = [0u64; 1024];
187                for &idx in other_v {
188                    bit_set[idx as usize / 64] |= 1u64 << (idx as u64 % 64);
189                }
190                for (i, w) in bm.iter_mut().enumerate() {
191                    *w &= bit_set[i];
192                }
193            }
194            (Container::Bitmap(bm), Container::Bitmap(other_bm)) => {
195                for (i, w) in bm.iter_mut().enumerate() {
196                    *w &= other_bm[i];
197                }
198            }
199        }
200    }
201
202    fn subtract(&mut self, other: &Container) {
203        match (self, other) {
204            (Container::Array(v), Container::Array(other_v)) => {
205                v.retain(|x| other_v.binary_search(x).is_err());
206            }
207            (Container::Array(v), Container::Bitmap(other_bm)) => {
208                v.retain(|x| other_bm[*x as usize / 64] & (1u64 << (*x as u64 % 64)) == 0);
209            }
210            (Container::Bitmap(bm), Container::Array(other_v)) => {
211                for &idx in other_v {
212                    bm[idx as usize / 64] &= !(1u64 << (idx as u64 % 64));
213                }
214            }
215            (Container::Bitmap(bm), Container::Bitmap(other_bm)) => {
216                for (i, w) in bm.iter_mut().enumerate() {
217                    *w &= !other_bm[i];
218                }
219            }
220        }
221    }
222
223    fn iter(&self) -> ContainerIter<'_> {
224        match self {
225            Container::Array(v) => ContainerIter::Array { data: v, pos: 0 },
226            Container::Bitmap(bm) => ContainerIter::Bitmap {
227                data: bm,
228                word_idx: 0,
229                bit: 0,
230            },
231        }
232    }
233
234    fn from_array_to_bitmap(v: Vec<u16>) -> Box<[u64; 1024]> {
235        let mut bm = Box::new([0u64; 1024]);
236        for &idx in &v {
237            bm[idx as usize / 64] |= 1u64 << (idx as u64 % 64);
238        }
239        bm
240    }
241}
242
243// ---------------------------------------------------------------------------
244// Container iterator
245// ---------------------------------------------------------------------------
246
247enum ContainerIter<'a> {
248    Array {
249        data: &'a Vec<u16>,
250        pos: usize,
251    },
252    Bitmap {
253        data: &'a [u64; 1024],
254        word_idx: usize,
255        bit: u32,
256    },
257}
258
259impl<'a> Iterator for ContainerIter<'a> {
260    type Item = u16;
261
262    fn next(&mut self) -> Option<Self::Item> {
263        match self {
264            ContainerIter::Array { data, pos } => {
265                let v = data.get(*pos)?.clone();
266                *pos += 1;
267                Some(v)
268            }
269            ContainerIter::Bitmap { data, word_idx, bit } => {
270                while *word_idx < 1024 {
271                    let word = data[*word_idx];
272                    if word == 0 {
273                        *word_idx += 1;
274                        *bit = 0;
275                        continue;
276                    }
277                    while *bit < 64 {
278                        if word & (1u64 << *bit) != 0 {
279                            let result = (*word_idx * 64 + *bit as usize) as u16;
280                            *bit += 1;
281                            return Some(result);
282                        }
283                        *bit += 1;
284                    }
285                    *word_idx += 1;
286                    *bit = 0;
287                }
288                None
289            }
290        }
291    }
292}
293
294// ---------------------------------------------------------------------------
295// RoaringBitmap
296// ---------------------------------------------------------------------------
297
298/// A compressed bitset for `u32` values using the Roaring Bitmap format.
299///
300/// # Example
301///
302/// ```
303/// use akar_storage::roaring_bitmap::RoaringBitmap;
304///
305/// let mut rb = RoaringBitmap::new();
306/// rb.add(42);
307/// rb.add(100000);
308/// assert!(rb.contains(42));
309/// assert!(!rb.contains(0));
310/// assert_eq!(rb.len(), 2);
311/// ```
312#[derive(Debug, Clone)]
313pub struct RoaringBitmap {
314    containers: BTreeMap<u16, Container>,
315    len: usize,
316}
317
318impl Default for RoaringBitmap {
319    fn default() -> Self {
320        Self::new()
321    }
322}
323
324impl RoaringBitmap {
325    /// Create an empty bitmap.
326    pub fn new() -> Self {
327        Self {
328            containers: BTreeMap::new(),
329            len: 0,
330        }
331    }
332
333    /// Create a bitmap from a sorted `Vec<u32>`.
334    pub fn from_sorted(values: &[u32]) -> Self {
335        let mut rb = Self::new();
336        if values.is_empty() {
337            return rb;
338        }
339        // Greedily build containers
340        let mut i = 0;
341        while i < values.len() {
342            let key = (values[i] >> 16) as u16;
343            let low = (values[i] & 0xFFFF) as u16;
344            let container = rb.containers.entry(key).or_insert_with(Container::new_array);
345            let _ = container.add(low);
346            rb.len += 1;
347            i += 1;
348            // Batch contiguous values under the same key
349            while i < values.len() && (values[i] >> 16) as u16 == key {
350                let low = (values[i] & 0xFFFF) as u16;
351                let _ = container.add(low);
352                rb.len += 1;
353                i += 1;
354            }
355        }
356        rb
357    }
358
359    /// Insert a value. Returns `true` if the value was newly added.
360    pub fn add(&mut self, value: u32) -> bool {
361        let key = (value >> 16) as u16;
362        let low = (value & 0xFFFF) as u16;
363        let container = self.containers.entry(key).or_insert_with(Container::new_array);
364        if container.add(low) {
365            self.len += 1;
366            true
367        } else {
368            false
369        }
370    }
371
372    /// Remove a value. Returns `true` if the value was present.
373    pub fn remove(&mut self, value: u32) -> bool {
374        let key = (value >> 16) as u16;
375        let low = (value & 0xFFFF) as u16;
376        if let Some(container) = self.containers.get_mut(&key) {
377            if container.remove(low) {
378                self.len = self.len.saturating_sub(1);
379                if container.is_empty() {
380                    self.containers.remove(&key);
381                }
382                return true;
383            }
384        }
385        false
386    }
387
388    /// Check if a value is present.
389    pub fn contains(&self, value: u32) -> bool {
390        let key = (value >> 16) as u16;
391        let low = (value & 0xFFFF) as u16;
392        self.containers.get(&key).is_some_and(|c| c.contains(low))
393    }
394
395    /// Number of elements in the bitmap.
396    pub fn len(&self) -> usize {
397        self.len
398    }
399
400    /// Whether the bitmap is empty.
401    pub fn is_empty(&self) -> bool {
402        self.len == 0
403    }
404
405    /// Union with another bitmap in-place.
406    pub fn union_with(&mut self, other: &RoaringBitmap) {
407        for (&key, other_c) in &other.containers {
408            let container = self.containers.entry(key).or_insert_with(Container::new_array);
409            let before = container.len();
410            container.insert_all_from(other_c);
411            self.len += container.len() - before;
412        }
413    }
414
415    /// Intersection with another bitmap in-place.
416    pub fn intersect_with(&mut self, other: &RoaringBitmap) {
417        let mut keys_to_remove = Vec::new();
418        for (&key, container) in &mut self.containers {
419            if let Some(other_c) = other.containers.get(&key) {
420                let before = container.len();
421                container.retain_intersection(other_c);
422                self.len -= before - container.len();
423                if container.is_empty() {
424                    keys_to_remove.push(key);
425                }
426            } else {
427                self.len -= container.len();
428                keys_to_remove.push(key);
429            }
430        }
431        for key in keys_to_remove {
432            self.containers.remove(&key);
433        }
434    }
435
436    /// Difference with another bitmap in-place (self = self \\ other).
437    pub fn difference_with(&mut self, other: &RoaringBitmap) {
438        let mut keys_to_remove = Vec::new();
439        for (&key, container) in &mut self.containers {
440            if let Some(other_c) = other.containers.get(&key) {
441                let before = container.len();
442                container.subtract(other_c);
443                self.len -= before - container.len();
444                if container.is_empty() {
445                    keys_to_remove.push(key);
446                }
447            }
448        }
449        for key in keys_to_remove {
450            self.containers.remove(&key);
451        }
452    }
453
454    /// Return a new bitmap as the union of `self` and `other`.
455    pub fn union(&self, other: &RoaringBitmap) -> RoaringBitmap {
456        let mut result = self.clone();
457        result.union_with(other);
458        result
459    }
460
461    /// Return a new bitmap as the intersection of `self` and `other`.
462    pub fn intersection(&self, other: &RoaringBitmap) -> RoaringBitmap {
463        let mut result = self.clone();
464        result.intersect_with(other);
465        result
466    }
467
468    /// Return a new bitmap as the difference of `self` and `other`.
469    pub fn difference(&self, other: &RoaringBitmap) -> RoaringBitmap {
470        let mut result = self.clone();
471        result.difference_with(other);
472        result
473    }
474
475    /// Iterator over all values in sorted order.
476    pub fn iter(&self) -> RoaringIter<'_> {
477        RoaringIter {
478            containers: self.containers.iter(),
479            current: None,
480        }
481    }
482
483    /// Collect all values into a sorted `Vec<u32>`.
484    pub fn to_vec(&self) -> Vec<u32> {
485        self.iter().collect()
486    }
487}
488
489// ---------------------------------------------------------------------------
490// Top-level iterator
491// ---------------------------------------------------------------------------
492
493pub struct RoaringIter<'a> {
494    containers: std::collections::btree_map::Iter<'a, u16, Container>,
495    current: Option<(u16, ContainerIter<'a>)>,
496}
497
498impl<'a> Iterator for RoaringIter<'a> {
499    type Item = u32;
500
501    fn next(&mut self) -> Option<Self::Item> {
502        loop {
503            if let Some((key, ref mut inner)) = self.current {
504                if let Some(low) = inner.next() {
505                    return Some(((key as u32) << 16) | low as u32);
506                }
507            }
508            // Advance to next container
509            let (key, container) = self.containers.next()?;
510            self.current = Some((*key, container.iter()));
511        }
512    }
513}
514
515// ---------------------------------------------------------------------------
516// Tests
517// ---------------------------------------------------------------------------
518
519#[cfg(test)]
520mod tests {
521    use super::*;
522
523    #[test]
524    fn test_empty() {
525        let rb = RoaringBitmap::new();
526        assert!(rb.is_empty());
527        assert_eq!(rb.len(), 0);
528        assert!(!rb.contains(0));
529    }
530
531    #[test]
532    fn test_add_and_contains() {
533        let mut rb = RoaringBitmap::new();
534        assert!(rb.add(42));
535        assert!(rb.contains(42));
536        assert!(!rb.contains(0));
537        assert_eq!(rb.len(), 1);
538    }
539
540    #[test]
541    fn test_add_duplicate() {
542        let mut rb = RoaringBitmap::new();
543        assert!(rb.add(100));
544        assert!(!rb.add(100)); // duplicate
545        assert_eq!(rb.len(), 1);
546    }
547
548    #[test]
549    fn test_remove() {
550        let mut rb = RoaringBitmap::new();
551        rb.add(42);
552        assert!(rb.remove(42));
553        assert!(!rb.contains(42));
554        assert!(rb.is_empty());
555    }
556
557    #[test]
558    fn test_remove_nonexistent() {
559        let mut rb = RoaringBitmap::new();
560        assert!(!rb.remove(999));
561    }
562
563    #[test]
564    fn test_multi_containers() {
565        let mut rb = RoaringBitmap::new();
566        // Values across different high 16-bit keys
567        rb.add(0);
568        rb.add(70000); // key 1
569        rb.add(200000); // key 3
570        assert_eq!(rb.len(), 3);
571        assert!(rb.contains(0));
572        assert!(rb.contains(70000));
573        assert!(rb.contains(200000));
574    }
575
576    #[test]
577    fn test_auto_upgrade_to_bitmap() {
578        let mut rb = RoaringBitmap::new();
579        // Add values in a single container to force Array→Bitmap upgrade
580        for i in 0..ARRAY_MAX_SIZE as u32 + 100 {
581            rb.add(i);
582        }
583        assert_eq!(rb.len(), ARRAY_MAX_SIZE + 100);
584        assert!(rb.contains(0));
585        assert!(rb.contains(4096));
586        assert!(rb.contains(4195));
587    }
588
589    #[test]
590    fn test_union() {
591        let mut a = RoaringBitmap::new();
592        a.add(1);
593        a.add(2);
594        a.add(3);
595
596        let mut b = RoaringBitmap::new();
597        b.add(3);
598        b.add(4);
599        b.add(5);
600
601        let c = a.union(&b);
602        assert_eq!(c.len(), 5);
603        assert!(c.contains(1));
604        assert!(c.contains(5));
605    }
606
607    #[test]
608    fn test_union_empty() {
609        let a = RoaringBitmap::new();
610        let mut b = RoaringBitmap::new();
611        b.add(10);
612
613        let c = a.union(&b);
614        assert_eq!(c.len(), 1);
615        assert!(c.contains(10));
616    }
617
618    #[test]
619    fn test_intersection() {
620        let mut a = RoaringBitmap::new();
621        a.add(1);
622        a.add(2);
623        a.add(3);
624
625        let mut b = RoaringBitmap::new();
626        b.add(2);
627        b.add(3);
628        b.add(4);
629
630        let c = a.intersection(&b);
631        assert_eq!(c.len(), 2);
632        assert!(c.contains(2));
633        assert!(c.contains(3));
634        assert!(!c.contains(1));
635        assert!(!c.contains(4));
636    }
637
638    #[test]
639    fn test_intersection_disjoint() {
640        let mut a = RoaringBitmap::new();
641        a.add(1);
642        a.add(2);
643        let mut b = RoaringBitmap::new();
644        b.add(3);
645        b.add(4);
646        let c = a.intersection(&b);
647        assert!(c.is_empty());
648    }
649
650    #[test]
651    fn test_difference() {
652        let mut a = RoaringBitmap::new();
653        a.add(1);
654        a.add(2);
655        a.add(3);
656        a.add(4);
657
658        let mut b = RoaringBitmap::new();
659        b.add(2);
660        b.add(4);
661
662        let c = a.difference(&b);
663        assert_eq!(c.len(), 2);
664        assert!(c.contains(1));
665        assert!(c.contains(3));
666    }
667
668    #[test]
669    fn test_difference_all() {
670        let mut a = RoaringBitmap::new();
671        a.add(5);
672        a.add(6);
673        let mut b = RoaringBitmap::new();
674        b.add(5);
675        b.add(6);
676        let c = a.difference(&b);
677        assert!(c.is_empty());
678    }
679
680    #[test]
681    fn test_iter() {
682        let mut rb = RoaringBitmap::new();
683        rb.add(3);
684        rb.add(1);
685        rb.add(2);
686        let vals: Vec<u32> = rb.iter().collect();
687        assert_eq!(vals, vec![1, 2, 3]);
688    }
689
690    #[test]
691    fn test_iter_multi_container() {
692        let mut rb = RoaringBitmap::new();
693        rb.add(0);
694        rb.add(100000);
695        rb.add(50000);
696        let vals: Vec<u32> = rb.iter().collect();
697        // Keys: 0, 0, 1 (sorted by key, then by low index)
698        assert_eq!(vals, vec![0, 50000, 100000]);
699    }
700
701    #[test]
702    fn test_from_sorted() {
703        let values = vec![10u32, 20, 30, 100000, 200000];
704        let rb = RoaringBitmap::from_sorted(&values);
705        assert_eq!(rb.len(), 5);
706        for v in &values {
707            assert!(rb.contains(*v));
708        }
709        let collected: Vec<u32> = rb.iter().collect();
710        assert_eq!(collected, values);
711    }
712
713    #[test]
714    fn test_from_sorted_empty() {
715        let rb = RoaringBitmap::from_sorted(&[]);
716        assert!(rb.is_empty());
717    }
718
719    #[test]
720    fn test_to_vec() {
721        let mut rb = RoaringBitmap::new();
722        rb.add(3);
723        rb.add(1);
724        rb.add(2);
725        assert_eq!(rb.to_vec(), vec![1, 2, 3]);
726    }
727
728    #[test]
729    fn test_union_dense_chunks() {
730        let mut a = RoaringBitmap::new();
731        let mut b = RoaringBitmap::new();
732        // Fill container 0 densely in both
733        for i in 0..5000u32 {
734            a.add(i);
735        }
736        for i in 3000..8000u32 {
737            b.add(i);
738        }
739        let c = a.union(&b);
740        assert_eq!(c.len(), 8000);
741        assert!(c.contains(0));
742        assert!(c.contains(7999));
743    }
744
745    #[test]
746    fn test_intersection_dense_chunks() {
747        let mut a = RoaringBitmap::new();
748        let mut b = RoaringBitmap::new();
749        for i in 0..5000u32 {
750            a.add(i);
751        }
752        for i in 3000..8000u32 {
753            b.add(i);
754        }
755        let c = a.intersection(&b);
756        assert_eq!(c.len(), 2000); // 3000..5000
757        assert!(c.contains(3000));
758        assert!(c.contains(4999));
759        assert!(!c.contains(2999));
760        assert!(!c.contains(5000));
761    }
762
763    #[test]
764    fn test_remove_after_upgrade() {
765        let mut rb = RoaringBitmap::new();
766        for i in 0..5000u32 {
767            rb.add(i);
768        }
769        // Remove some elements from the bitmap container
770        for i in 0..1000u32 {
771            rb.remove(i);
772        }
773        assert_eq!(rb.len(), 4000);
774        assert!(!rb.contains(0));
775        assert!(rb.contains(1000));
776    }
777
778    #[test]
779    fn test_union_with() {
780        let mut a = RoaringBitmap::new();
781        a.add(1);
782        a.add(2);
783        let mut b = RoaringBitmap::new();
784        b.add(2);
785        b.add(3);
786        a.union_with(&b);
787        assert_eq!(a.len(), 3);
788        assert!(a.contains(1));
789        assert!(a.contains(2));
790        assert!(a.contains(3));
791    }
792
793    #[test]
794    fn test_intersect_with() {
795        let mut a = RoaringBitmap::new();
796        a.add(1);
797        a.add(2);
798        a.add(3);
799        let mut b = RoaringBitmap::new();
800        b.add(2);
801        b.add(3);
802        b.add(4);
803        a.intersect_with(&b);
804        assert_eq!(a.len(), 2);
805        assert!(a.contains(2));
806        assert!(a.contains(3));
807        assert!(!a.contains(1));
808    }
809
810    #[test]
811    fn test_intersect_with_disjoint_containers() {
812        let mut a = RoaringBitmap::new();
813        a.add(1);
814        a.add(100000); // key 1
815        let mut b = RoaringBitmap::new();
816        b.add(2);
817        b.add(3);
818        a.intersect_with(&b);
819        assert!(a.is_empty());
820    }
821
822    #[test]
823    fn test_difference_with() {
824        let mut a = RoaringBitmap::new();
825        a.add(1);
826        a.add(2);
827        a.add(3);
828        let mut b = RoaringBitmap::new();
829        b.add(2);
830        a.difference_with(&b);
831        assert_eq!(a.len(), 2);
832        assert!(a.contains(1));
833        assert!(a.contains(3));
834        assert!(!a.contains(2));
835    }
836}