sui_sdk_types/bitmap.rs
1/// A compressed bitmap using the [Roaring bitmap compression scheme](https://roaringbitmap.org/).
2///
3/// # BCS
4///
5/// The BCS serialized form for this type is defined by the following ABNF:
6///
7/// ```text
8/// roaring-bitmap = bytes ; where the contents of the bytes are valid
9/// ; according to the serialized spec for
10/// ; roaring bitmaps
11/// ```
12#[derive(Clone, Debug, Default, PartialEq)]
13pub struct Bitmap(roaring::RoaringBitmap);
14
15impl Bitmap {
16 /// Creates an empty `Bitmap`.
17 ///
18 /// # Examples
19 ///
20 /// ```rust
21 /// use sui_sdk_types::Bitmap;
22 /// let bitmap = Bitmap::new();
23 /// ```
24 pub fn new() -> Self {
25 Self::default()
26 }
27
28 /// Returns the number of distinct integers added to the set.
29 ///
30 /// # Examples
31 ///
32 /// ```rust
33 /// use sui_sdk_types::Bitmap;
34 ///
35 /// let mut bitmap = Bitmap::new();
36 /// assert_eq!(bitmap.len(), 0);
37 ///
38 /// bitmap.insert(3);
39 /// assert_eq!(bitmap.len(), 1);
40 ///
41 /// bitmap.insert(3);
42 /// bitmap.insert(4);
43 /// assert_eq!(bitmap.len(), 2);
44 /// ```
45 pub fn len(&self) -> u64 {
46 self.0.len()
47 }
48
49 /// Clears all integers in this set.
50 ///
51 /// # Examples
52 ///
53 /// ```rust
54 /// use sui_sdk_types::Bitmap;
55 ///
56 /// let mut bitmap = Bitmap::new();
57 /// bitmap.insert(1);
58 /// assert_eq!(bitmap.contains(1), true);
59 /// bitmap.clear();
60 /// assert_eq!(bitmap.contains(1), false);
61 /// ```
62 pub fn clear(&mut self) {
63 self.0.clear()
64 }
65
66 /// Returns `true` if there are no integers in this set.
67 ///
68 /// # Examples
69 ///
70 /// ```rust
71 /// use sui_sdk_types::Bitmap;
72 ///
73 /// let mut bitmap = Bitmap::new();
74 /// assert_eq!(bitmap.is_empty(), true);
75 ///
76 /// bitmap.insert(3);
77 /// assert_eq!(bitmap.is_empty(), false);
78 /// ```
79 pub fn is_empty(&self) -> bool {
80 self.0.is_empty()
81 }
82
83 /// Adds a value to the set.
84 ///
85 /// Returns whether the value was absent from the set.
86 ///
87 /// # Examples
88 ///
89 /// ```rust
90 /// use sui_sdk_types::Bitmap;
91 ///
92 /// let mut bitmap = Bitmap::new();
93 /// assert_eq!(bitmap.insert(3), true);
94 /// assert_eq!(bitmap.insert(3), false);
95 /// assert_eq!(bitmap.contains(3), true);
96 /// ```
97 pub fn insert(&mut self, value: u32) -> bool {
98 self.0.insert(value)
99 }
100
101 /// Inserts a range of values.
102 /// Returns the number of inserted values.
103 ///
104 /// # Examples
105 ///
106 /// ```rust
107 /// use sui_sdk_types::Bitmap;
108 ///
109 /// let mut bitmap = Bitmap::new();
110 /// bitmap.insert_range(2..4);
111 /// assert!(bitmap.contains(2));
112 /// assert!(bitmap.contains(3));
113 /// assert!(!bitmap.contains(4));
114 /// ```
115 pub fn insert_range<R>(&mut self, range: R) -> u64
116 where
117 R: std::ops::RangeBounds<u32>,
118 {
119 self.0.insert_range(range)
120 }
121
122 /// Removes a value from the set. Returns `true` if the value was present in the set.
123 ///
124 /// # Examples
125 ///
126 /// ```rust
127 /// use sui_sdk_types::Bitmap;
128 ///
129 /// let mut bitmap = Bitmap::new();
130 /// bitmap.insert(3);
131 /// assert_eq!(bitmap.remove(3), true);
132 /// assert_eq!(bitmap.remove(3), false);
133 /// assert_eq!(bitmap.contains(3), false);
134 /// ```
135 pub fn remove(&mut self, value: u32) -> bool {
136 self.0.remove(value)
137 }
138
139 /// Returns `true` if this set contains the specified integer.
140 ///
141 /// # Examples
142 ///
143 /// ```rust
144 /// use sui_sdk_types::Bitmap;
145 ///
146 /// let mut bitmap = Bitmap::new();
147 /// bitmap.insert(1);
148 /// assert_eq!(bitmap.contains(0), false);
149 /// assert_eq!(bitmap.contains(1), true);
150 /// assert_eq!(bitmap.contains(100), false);
151 /// ```
152 pub fn contains(&self, value: u32) -> bool {
153 self.0.contains(value)
154 }
155
156 /// Iterator over each value stored in the Bitmap, guarantees values are ordered by value.
157 ///
158 /// # Examples
159 ///
160 /// ```rust
161 /// use core::iter::FromIterator;
162 /// use sui_sdk_types::Bitmap;
163 ///
164 /// let bitmap = (1..3).collect::<Bitmap>();
165 /// let mut iter = bitmap.iter();
166 ///
167 /// assert_eq!(iter.next(), Some(1));
168 /// assert_eq!(iter.next(), Some(2));
169 /// assert_eq!(iter.next(), None);
170 /// ```
171 pub fn iter(&self) -> impl Iterator<Item = u32> + use<'_> {
172 self.0.iter()
173 }
174
175 /// Deserialize a bitmap into memory from [the standard Roaring on-disk
176 /// format][format]. This is compatible with the official C/C++, Java and
177 /// Go implementations. This method checks that all of the internal values
178 /// are valid.
179 ///
180 /// [format]: https://github.com/RoaringBitmap/RoaringFormatSpec
181 ///
182 /// # Examples
183 ///
184 /// ```rust
185 /// use sui_sdk_types::Bitmap;
186 ///
187 /// let bitmap1: Bitmap = (1..4).collect();
188 /// let mut bytes = vec![];
189 /// bitmap1.serialize_into(&mut bytes).unwrap();
190 /// let bitmap2 = Bitmap::deserialize_from(&bytes[..]).unwrap();
191 ///
192 /// assert_eq!(bitmap1, bitmap2);
193 /// ```
194 #[cfg(feature = "serde")]
195 #[cfg_attr(doc_cfg, doc(cfg(feature = "serde")))]
196 pub fn deserialize_from<R: std::io::Read>(reader: R) -> std::io::Result<Self> {
197 let rb = roaring::RoaringBitmap::deserialize_from(reader)?;
198
199 // Need to explicilty build by iterating the read bitmap to enforce uniquness since the
200 // deserialization path doesn't guarantee it.
201 let mut bitmap = Self::new();
202 bitmap.extend(rb);
203 Ok(bitmap)
204 }
205
206 /// Serialize this bitmap into [the standard Roaring on-disk format][format].
207 /// This is compatible with the official C/C++, Java and Go implementations.
208 ///
209 /// [format]: https://github.com/RoaringBitmap/RoaringFormatSpec
210 ///
211 /// # Examples
212 ///
213 /// ```rust
214 /// use sui_sdk_types::Bitmap;
215 ///
216 /// let bitmap1: Bitmap = (1..4).collect();
217 /// let mut bytes = vec![];
218 /// bitmap1.serialize_into(&mut bytes).unwrap();
219 /// let bitmap2 = Bitmap::deserialize_from(&bytes[..]).unwrap();
220 ///
221 /// assert_eq!(bitmap1, bitmap2);
222 /// ```
223 #[cfg(feature = "serde")]
224 #[cfg_attr(doc_cfg, doc(cfg(feature = "serde")))]
225 pub fn serialize_into<W: std::io::Write>(&self, writer: W) -> std::io::Result<()> {
226 self.0.serialize_into(writer)
227 }
228}
229
230impl FromIterator<u32> for Bitmap {
231 fn from_iter<I: IntoIterator<Item = u32>>(iterator: I) -> Bitmap {
232 let mut bitmap = Self::new();
233 bitmap.extend(iterator);
234 bitmap
235 }
236}
237
238impl<'a> FromIterator<&'a u32> for Bitmap {
239 fn from_iter<I: IntoIterator<Item = &'a u32>>(iterator: I) -> Bitmap {
240 let mut bitmap = Self::new();
241 bitmap.extend(iterator);
242 bitmap
243 }
244}
245
246impl Extend<u32> for Bitmap {
247 fn extend<I: IntoIterator<Item = u32>>(&mut self, values: I) {
248 self.0.extend(values)
249 }
250}
251
252impl<'a> Extend<&'a u32> for Bitmap {
253 fn extend<I: IntoIterator<Item = &'a u32>>(&mut self, values: I) {
254 self.extend(values.into_iter().copied());
255 }
256}
257
258#[cfg(feature = "serde")]
259#[cfg_attr(doc_cfg, doc(cfg(feature = "serde")))]
260impl serde::Serialize for Bitmap {
261 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
262 where
263 S: serde::Serializer,
264 {
265 use serde_with::SerializeAs;
266
267 let mut bytes = vec![];
268
269 self.serialize_into(&mut bytes)
270 .map_err(serde::ser::Error::custom)?;
271
272 if serializer.is_human_readable() {
273 let b64 = <base64ct::Base64 as base64ct::Encoding>::encode_string(&bytes);
274 serde::Serialize::serialize(&b64, serializer)
275 } else {
276 serde_with::Bytes::serialize_as(&bytes, serializer)
277 }
278 }
279}
280
281#[cfg(feature = "serde")]
282#[cfg_attr(doc_cfg, doc(cfg(feature = "serde")))]
283impl<'de> serde::Deserialize<'de> for Bitmap {
284 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
285 where
286 D: serde::Deserializer<'de>,
287 {
288 use serde_with::DeserializeAs;
289
290 if deserializer.is_human_readable() {
291 let b64: std::borrow::Cow<'de, str> = serde::Deserialize::deserialize(deserializer)?;
292 let bytes = <base64ct::Base64 as base64ct::Encoding>::decode_vec(&b64)
293 .map_err(serde::de::Error::custom)?;
294 Self::deserialize_from(&bytes[..]).map_err(serde::de::Error::custom)
295 } else {
296 let bytes: std::borrow::Cow<'de, [u8]> =
297 serde_with::Bytes::deserialize_as(deserializer)?;
298 Self::deserialize_from(&bytes[..]).map_err(serde::de::Error::custom)
299 }
300 }
301}
302
303#[cfg(feature = "proptest")]
304#[cfg_attr(doc_cfg, doc(cfg(feature = "proptest")))]
305impl proptest::arbitrary::Arbitrary for Bitmap {
306 type Parameters = ();
307 type Strategy = proptest::strategy::BoxedStrategy<Self>;
308
309 fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy {
310 use proptest::collection::vec;
311 use proptest::prelude::*;
312
313 vec(any::<u32>(), 0..32).prop_map(Self::from_iter).boxed()
314 }
315}
316
317#[cfg(test)]
318mod test {
319 use super::*;
320
321 use base64ct::Encoding;
322
323 #[test]
324 fn test_unique_deserialize() {
325 let raw = "OjAAAAoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWAAAAFoAAABcAAAAXgAAAGAAAABiAAAAZAAAAGYAAABoAAAAagAAAAEAAQABAAEAAQABAAEAAQABAAEA";
326 let bytes = base64ct::Base64::decode_vec(raw).unwrap();
327
328 let rb = roaring::RoaringBitmap::deserialize_from(&bytes[..]).unwrap();
329 assert_eq!(rb.len(), 10);
330 let bitmap_values: Vec<u32> = rb.iter().collect();
331 assert_eq!(bitmap_values, vec![1; 10]);
332
333 let bitmap = Bitmap::deserialize_from(&bytes[..]).unwrap();
334 assert_eq!(bitmap.len(), 1);
335 let bitmap_values: Vec<u32> = bitmap.iter().collect();
336 assert_eq!(bitmap_values, vec![1]);
337 }
338}