roaring/bitmap/cmp.rs
1use core::borrow::Borrow;
2use core::cmp::Ordering;
3use core::iter::Peekable;
4
5use super::container::Container;
6use crate::RoaringBitmap;
7
8impl RoaringBitmap {
9 /// Returns true if the set has no elements in common with other. This is equivalent to
10 /// checking for an empty intersection.
11 ///
12 /// # Examples
13 ///
14 /// ```rust
15 /// use roaring::RoaringBitmap;
16 ///
17 /// let mut rb1 = RoaringBitmap::new();
18 /// let mut rb2 = RoaringBitmap::new();
19 ///
20 /// rb1.insert(1);
21 ///
22 /// assert_eq!(rb1.is_disjoint(&rb2), true);
23 ///
24 /// rb2.insert(1);
25 ///
26 /// assert_eq!(rb1.is_disjoint(&rb2), false);
27 ///
28 /// ```
29 pub fn is_disjoint(&self, other: &Self) -> bool {
30 Pairs::new(&self.containers, &other.containers)
31 .filter_map(|(c1, c2)| c1.zip(c2))
32 .all(|(c1, c2)| c1.is_disjoint(c2))
33 }
34
35 /// Returns `true` if this set is a subset of `other`.
36 ///
37 /// # Examples
38 ///
39 /// ```rust
40 /// use roaring::RoaringBitmap;
41 ///
42 /// let mut rb1 = RoaringBitmap::new();
43 /// let mut rb2 = RoaringBitmap::new();
44 ///
45 /// rb1.insert(1);
46 ///
47 /// assert_eq!(rb1.is_subset(&rb2), false);
48 ///
49 /// rb2.insert(1);
50 ///
51 /// assert_eq!(rb1.is_subset(&rb2), true);
52 ///
53 /// rb1.insert(2);
54 ///
55 /// assert_eq!(rb1.is_subset(&rb2), false);
56 /// ```
57 pub fn is_subset(&self, other: &Self) -> bool {
58 for pair in Pairs::new(&self.containers, &other.containers) {
59 match pair {
60 (None, _) => (),
61 (_, None) => return false,
62 (Some(c1), Some(c2)) => {
63 if !c1.is_subset(c2) {
64 return false;
65 }
66 }
67 }
68 }
69 true
70 }
71
72 /// Returns `true` if this set is a superset of `other`.
73 ///
74 /// # Examples
75 ///
76 /// ```rust
77 /// use roaring::RoaringBitmap;
78 ///
79 /// let mut rb1 = RoaringBitmap::new();
80 /// let mut rb2 = RoaringBitmap::new();
81 ///
82 /// rb1.insert(1);
83 ///
84 /// assert_eq!(rb2.is_superset(&rb1), false);
85 ///
86 /// rb2.insert(1);
87 ///
88 /// assert_eq!(rb2.is_superset(&rb1), true);
89 ///
90 /// rb1.insert(2);
91 ///
92 /// assert_eq!(rb2.is_superset(&rb1), false);
93 /// ```
94 pub fn is_superset(&self, other: &Self) -> bool {
95 other.is_subset(self)
96 }
97}
98
99/// An helping Iterator over pairs of containers.
100///
101/// Returns the smallest container according to its key
102/// or both if the key is the same. It is useful when you need
103/// to iterate over two containers to do operations on them.
104pub(crate) struct Pairs<I, J, L, R>
105where
106 I: Iterator<Item = L>,
107 J: Iterator<Item = R>,
108 L: Borrow<Container>,
109 R: Borrow<Container>,
110{
111 left: Peekable<I>,
112 right: Peekable<J>,
113}
114
115impl<I, J, L, R> Pairs<I, J, L, R>
116where
117 I: Iterator<Item = L>,
118 J: Iterator<Item = R>,
119 L: Borrow<Container>,
120 R: Borrow<Container>,
121{
122 pub fn new<A, B>(left: A, right: B) -> Pairs<I, J, L, R>
123 where
124 A: IntoIterator<Item = L, IntoIter = I>,
125 B: IntoIterator<Item = R, IntoIter = J>,
126 {
127 Pairs { left: left.into_iter().peekable(), right: right.into_iter().peekable() }
128 }
129}
130
131impl<I, J, L, R> Iterator for Pairs<I, J, L, R>
132where
133 I: Iterator<Item = L>,
134 J: Iterator<Item = R>,
135 L: Borrow<Container>,
136 R: Borrow<Container>,
137{
138 type Item = (Option<L>, Option<R>);
139
140 fn next(&mut self) -> Option<Self::Item> {
141 match (self.left.peek(), self.right.peek()) {
142 (None, None) => None,
143 (Some(_), None) => Some((self.left.next(), None)),
144 (None, Some(_)) => Some((None, self.right.next())),
145 (Some(c1), Some(c2)) => match c1.borrow().key.cmp(&c2.borrow().key) {
146 Ordering::Equal => Some((self.left.next(), self.right.next())),
147 Ordering::Less => Some((self.left.next(), None)),
148 Ordering::Greater => Some((None, self.right.next())),
149 },
150 }
151 }
152}