Skip to main content

read_fonts/collections/int_set/
bitset.rs

1//! A fast, efficient, sparse, & ordered unsigned integer (`u32`) bit set.
2//!
3//! There are a couple of differences with [`super::IntSet`]:
4//! - This set is not invertible and can only record the set of integers which are members.
5//! - This set works only with `u32` values, unlike [`super::IntSet`] which supports custom integer types.
6//!
7//! When dealing with only `u32`'s and invertibility is not needed then this set is slightly faster
8//! than the more generic [`super::IntSet`].
9//!
10//! The bitset is implemented using fixed size pages which allows it to compactly
11//! represent sparse membership. However, the set excels when set members are typically
12//! clustered together. For example when representing glyph id or unicode codepoint values
13//! in a font.
14//!
15//! When constructing a new [`U32Set`] from an existing list of integer values the most efficient
16//! way to create the set is to initialize it from a sorted list of values via the extend() method.
17
18use super::bitpage::BitPage;
19use super::bitpage::RangeIter;
20use super::bitpage::PAGE_BITS;
21use alloc::vec::Vec;
22use core::sync::atomic::AtomicUsize;
23use std::cmp::Ordering;
24use std::hash::Hash;
25use std::ops::RangeInclusive;
26
27// log_2(PAGE_BITS)
28const PAGE_BITS_LOG_2: u32 = PAGE_BITS.ilog2();
29
30/// A fast, efficient, sparse, & ordered `u32` set.
31///
32/// For a higher-level API that supports inversion and generic int types, use [`super::IntSet`]
33#[derive(Debug)]
34#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
35pub struct U32Set {
36    // TODO(garretrieger): consider a "small array" type instead of Vec.
37    pages: Vec<BitPage>,
38    page_map: Vec<PageInfo>,
39    length: u64,
40
41    #[cfg_attr(feature = "serde", serde(skip))]
42    #[cfg_attr(feature = "serde", serde(default = "default_last_page_map_index"))]
43    last_page_map_index: AtomicUsize,
44}
45
46const fn default_last_page_map_index() -> AtomicUsize {
47    AtomicUsize::new(usize::MAX)
48}
49
50impl Default for U32Set {
51    fn default() -> Self {
52        Self {
53            pages: Default::default(),
54            page_map: Default::default(),
55            length: Default::default(),
56            last_page_map_index: default_last_page_map_index(),
57        }
58    }
59}
60
61impl Clone for U32Set {
62    fn clone(&self) -> Self {
63        Self {
64            pages: self.pages.clone(),
65            page_map: self.page_map.clone(),
66            length: self.length,
67            // last_page_map_index has no effect on the externally visible state of the set
68            // so it can just be reset to the default value.
69            last_page_map_index: default_last_page_map_index(),
70        }
71    }
72}
73
74impl FromIterator<u32> for U32Set {
75    fn from_iter<I: IntoIterator<Item = u32>>(iter: I) -> Self {
76        let mut s = U32Set::empty();
77        s.extend(iter);
78        s
79    }
80}
81
82impl U32Set {
83    /// Add val as a member of this set.
84    ///
85    /// If the set did not previously contain this value, returns `true`.
86    #[inline]
87    pub fn insert(&mut self, val: u32) -> bool {
88        let page = self.ensure_page_for_mut(val);
89        let ret = page.insert(val);
90        self.length += ret as u64;
91        ret
92    }
93
94    /// Add all values in range as members of this set.
95    pub fn insert_range(&mut self, range: RangeInclusive<u32>) {
96        let start = *range.start();
97        let end = *range.end();
98        if start > end {
99            return;
100        }
101
102        let major_start = Self::get_major_value(start);
103        let major_end = Self::get_major_value(end);
104
105        let mut total_added = 0;
106
107        for major in major_start..=major_end {
108            let page_start = start.max(Self::major_start(major));
109            let page_end = end.min(Self::major_start(major) + (PAGE_BITS - 1));
110            let page = self.ensure_page_for_major_mut(major);
111            let pre_len = page.len();
112            page.insert_range(page_start, page_end);
113            let delta_len = page.len() - pre_len;
114            total_added += delta_len as u64;
115        }
116        self.length += total_added;
117    }
118
119    /// An alternate version of [`extend()`] which is optimized for inserting an unsorted
120    /// iterator of values.
121    ///
122    /// [`extend()`]: Self::extend
123    #[inline]
124    pub fn extend_unsorted<U: IntoIterator<Item = u32>>(&mut self, iter: U) {
125        // Unsorted values from real workloads (e.g. the glyph ids of a
126        // shaping buffer) still tend to arrive in runs that stay within a
127        // single page. Memoizing the page index of the last value in loop
128        // locals skips the page_map search for all but the first value of
129        // each run.
130        let mut last_major_value = u32::MAX;
131        let mut last_page_index = usize::MAX;
132        let mut added = 0u64;
133        for val in iter {
134            let major_value = Self::get_major_value(val);
135            if major_value != last_major_value {
136                last_page_index = self.ensure_page_index_for_major(major_value);
137                last_major_value = major_value;
138            }
139            if let Some(page) = self.pages.get_mut(last_page_index) {
140                added += page.insert(val) as u64;
141            }
142        }
143        self.length += added;
144    }
145
146    /// Remove val from this set.
147    ///
148    /// Returns `true` if the value was present.
149    pub fn remove(&mut self, val: u32) -> bool {
150        let maybe_page = self.page_for_mut(val);
151        if let Some(page) = maybe_page {
152            let ret = page.remove(val);
153            self.length -= ret as u64;
154            ret
155        } else {
156            false
157        }
158    }
159
160    // Remove all values in iter from this set.
161    pub fn remove_all<U: IntoIterator<Item = u32>>(&mut self, iter: U) {
162        let mut last_page_index: Option<usize> = None;
163        let mut last_major_value = u32::MAX;
164        let mut total_removed = 0;
165        for val in iter {
166            let major_value = Self::get_major_value(val);
167            if major_value != last_major_value {
168                last_page_index = self.page_index_for_major(major_value);
169                last_major_value = major_value;
170            };
171
172            let Some(page_index) = last_page_index else {
173                continue;
174            };
175
176            if let Some(page) = self.pages.get_mut(page_index) {
177                total_removed += page.remove(val) as u64;
178            }
179        }
180        self.length -= total_removed;
181    }
182
183    /// Removes all values in range as members of this set.
184    pub fn remove_range(&mut self, range: RangeInclusive<u32>) {
185        let start = *(range.start());
186        let end = *(range.end());
187        if start > end {
188            return;
189        }
190
191        let start_major = Self::get_major_value(start);
192        let end_major = Self::get_major_value(end);
193        let mut info_index = match self
194            .page_map
195            .binary_search_by(|probe| probe.major_value.cmp(&start_major))
196        {
197            Ok(info_index) => info_index,
198            Err(info_index) => info_index,
199        };
200
201        loop {
202            let Some(info) = self.page_map.get(info_index) else {
203                break;
204            };
205            let Some(page) = self.pages.get_mut(info.index as usize) else {
206                break;
207            };
208
209            if info.major_value > end_major {
210                break;
211            } else if info.major_value == start_major {
212                page.remove_range(start, Self::major_end(start_major).min(end));
213            } else if info.major_value == end_major {
214                page.remove_range(Self::major_start(end_major), end);
215                break;
216            } else {
217                page.clear();
218            }
219            info_index += 1;
220        }
221
222        self.recompute_length();
223    }
224
225    /// Returns true if val is a member of this set.
226    pub fn contains(&self, val: u32) -> bool {
227        let new_major = U32Set::get_major_value(val);
228
229        let lookup_result = self
230            .page_map
231            .get(
232                self.last_page_map_index
233                    .load(std::sync::atomic::Ordering::Relaxed),
234            )
235            .filter(|info| info.major_value == new_major)
236            .map(|info| Some(info.index as usize))
237            .unwrap_or(None);
238
239        let page_index = match lookup_result {
240            None => {
241                // Cached value needs an update, lookup the actual page map index.
242                let Some(page_map_index) = self.page_map_index_for_major(new_major) else {
243                    // No page exists for this value so it's not present and we don't need to update cached values.
244                    return false;
245                };
246
247                self.last_page_map_index
248                    .store(page_map_index, std::sync::atomic::Ordering::Relaxed);
249                self.page_map[page_map_index].index as usize
250            }
251            Some(page_index) => page_index,
252        };
253
254        self.pages
255            .get(page_index)
256            .map(|page| page.contains(val))
257            .unwrap_or(false)
258    }
259
260    pub fn intersects_set(&self, other: &U32Set) -> bool {
261        let mut a_index = 0;
262        let mut b_index = 0;
263
264        while a_index < self.page_map.len() && b_index < other.page_map.len() {
265            let a = &self.page_map[a_index];
266            let b = &other.page_map[b_index];
267            match a.major_value.cmp(&b.major_value) {
268                Ordering::Equal => {
269                    if self.pages[a.index as usize].intersects_set(&other.pages[b.index as usize]) {
270                        return true;
271                    }
272                    a_index += 1;
273                    b_index += 1;
274                }
275                Ordering::Less => {
276                    a_index += 1;
277                }
278                Ordering::Greater => {
279                    b_index += 1;
280                }
281            }
282        }
283
284        false
285    }
286
287    /// Returns true if this set is a subset of `other`.
288    pub fn is_subset(&self, other: &U32Set) -> bool {
289        if self.len() > other.len() {
290            return false;
291        }
292        let mut a_index = 0;
293        let mut b_index = 0;
294
295        while a_index < self.page_map.len() {
296            let a_info = &self.page_map[a_index];
297            let page_a = &self.pages[a_info.index as usize];
298            if page_a.is_empty() {
299                a_index += 1;
300                continue;
301            }
302
303            while b_index < other.page_map.len() {
304                if other.page_map[b_index].major_value < a_info.major_value {
305                    b_index += 1;
306                } else {
307                    break;
308                }
309            }
310
311            let Some(b_info) = &other.page_map.get(b_index) else {
312                return false;
313            };
314            if b_info.major_value == a_info.major_value {
315                let page_b = &other.pages[b_info.index as usize];
316                if !page_a.is_subset(page_b) {
317                    return false;
318                }
319                a_index += 1;
320                b_index += 1;
321            } else {
322                return false;
323            }
324        }
325
326        true
327    }
328
329    /// Returns the number of members present in both `self` and `other`.
330    pub fn intersection_len(&self, other: &U32Set) -> u64 {
331        let mut a_index = 0;
332        let mut b_index = 0;
333        let mut count = 0u64;
334
335        while a_index < self.page_map.len() && b_index < other.page_map.len() {
336            let a = &self.page_map[a_index];
337            let b = &other.page_map[b_index];
338            match a.major_value.cmp(&b.major_value) {
339                Ordering::Equal => {
340                    count += self.pages[a.index as usize]
341                        .intersection_len(&other.pages[b.index as usize])
342                        as u64;
343                    a_index += 1;
344                    b_index += 1;
345                }
346                Ordering::Less => {
347                    a_index += 1;
348                }
349                Ordering::Greater => {
350                    b_index += 1;
351                }
352            }
353        }
354
355        count
356    }
357
358    pub const fn empty() -> U32Set {
359        U32Set {
360            pages: Vec::new(),
361            page_map: Vec::new(),
362            length: 0,
363            last_page_map_index: default_last_page_map_index(),
364        }
365    }
366
367    /// Remove all members from this set.
368    pub fn clear(&mut self) {
369        self.pages.clear();
370        self.page_map.clear();
371        self.length = 0;
372    }
373
374    /// Return true if there are no members in this set.
375    pub fn is_empty(&self) -> bool {
376        self.len() == 0
377    }
378
379    fn recompute_length(&mut self) {
380        self.length = self.pages.iter().map(|page| page.len() as u64).sum();
381    }
382
383    /// Returns the number of members in this set.
384    pub fn len(&self) -> u64 {
385        self.length
386    }
387
388    pub(crate) fn num_pages(&self) -> usize {
389        self.pages.len()
390    }
391
392    /// Sets the members of this set to the union of self and other.
393    pub fn union(&mut self, other: &U32Set) {
394        self.process(BitPage::union, other);
395    }
396
397    /// Sets the members of this set to the intersection of self and other.
398    pub fn intersect(&mut self, other: &U32Set) {
399        self.process(BitPage::intersect, other);
400    }
401
402    /// Sets the members of this set to self - other.
403    pub fn subtract(&mut self, other: &U32Set) {
404        self.process(BitPage::subtract, other);
405    }
406
407    /// Sets the members of this set to other - self.
408    pub fn reversed_subtract(&mut self, other: &U32Set) {
409        self.process(|a, b| BitPage::subtract(b, a), other);
410    }
411
412    /// Iterator over the members of this set. In sorted order (ascending).
413    pub fn iter(&self) -> impl DoubleEndedIterator<Item = u32> + '_ {
414        self.iter_non_empty_pages().flat_map(|(major, page)| {
415            let base = Self::major_start(major);
416            page.iter().map(move |v| base + v)
417        })
418    }
419
420    /// Iterator over the members of this set starting from value.
421    ///
422    /// So value is included in the iterator if it's in the set.
423    pub fn iter_from(&self, value: u32) -> impl Iterator<Item = u32> + '_ {
424        let major_value = Self::get_major_value(value);
425        let result = self
426            .page_map
427            .binary_search_by(|probe| probe.major_value.cmp(&major_value));
428
429        let (page_map_index, partial_first_page) = match result {
430            Ok(page_map_index) => (page_map_index, true),
431            Err(page_map_index) => (page_map_index, false),
432        };
433
434        let page = self
435            .page_map
436            .get(page_map_index)
437            .and_then(move |page_info| {
438                self.pages
439                    .get(page_info.index as usize)
440                    .map(|page| (page, page_info.major_value))
441            });
442
443        let init_it =
444            page.filter(|_| partial_first_page)
445                .into_iter()
446                .flat_map(move |(page, major)| {
447                    let base = Self::major_start(major);
448                    page.iter_from(value).map(move |v| base + v)
449                });
450
451        let follow_on_page_map_index = if partial_first_page {
452            page_map_index + 1
453        } else {
454            page_map_index
455        };
456
457        let follow_on_it = self.page_map[follow_on_page_map_index..]
458            .iter()
459            .flat_map(|info| {
460                self.pages
461                    .get(info.index as usize)
462                    .map(|page| (info.major_value, page))
463            })
464            .filter(|(_, page)| !page.is_empty())
465            .flat_map(|(major, page)| {
466                let base = Self::major_start(major);
467                page.iter().map(move |v| base + v)
468            });
469
470        init_it.chain(follow_on_it)
471    }
472
473    /// Iterate over the ranges of contiguous values in this set.
474    pub fn iter_ranges(&self) -> impl Iterator<Item = RangeInclusive<u32>> + '_ {
475        U32SetRangeIter::new(self)
476    }
477
478    fn iter_pages(&self) -> impl DoubleEndedIterator<Item = (u32, &BitPage)> + '_ {
479        self.page_map.iter().flat_map(|info| {
480            self.pages
481                .get(info.index as usize)
482                .map(|page| (info.major_value, page))
483        })
484    }
485
486    fn iter_non_empty_pages(&self) -> impl DoubleEndedIterator<Item = (u32, &BitPage)> + '_ {
487        self.iter_pages().filter(|(_, page)| !page.is_empty())
488    }
489
490    /// Determine the passthrough behaviour of the operator.
491    ///
492    /// The passthrough behaviour is what happens to a page on one side of the operation if the other side is 0.
493    /// For example union passes through both left and right sides since it preserves the left or right side when
494    /// the other side is 0. Knowing this lets us optimize some cases when only one page is present on one side.
495    fn passthrough_behavior<Op>(op: &Op) -> (bool, bool)
496    where
497        Op: Fn(&BitPage, &BitPage) -> BitPage,
498    {
499        let mut one: BitPage = BitPage::new_zeroes();
500        one.insert(0);
501        let zero: BitPage = BitPage::new_zeroes();
502
503        let passthrough_left: bool = op(&one, &zero).contains(0);
504        let passthrough_right: bool = op(&zero, &one).contains(0);
505
506        (passthrough_left, passthrough_right)
507    }
508
509    fn process<Op>(&mut self, op: Op, other: &U32Set)
510    where
511        Op: Fn(&BitPage, &BitPage) -> BitPage,
512    {
513        let (passthrough_left, passthrough_right) = U32Set::passthrough_behavior(&op);
514
515        let mut len_a = self.pages.len();
516        let len_b = other.pages.len();
517        let mut idx_a = 0;
518        let mut idx_b = 0;
519        let mut count = 0;
520        let mut write_idx = 0;
521
522        // Step 1: Estimate the new size of this set (in number of pages) after processing, and remove left side
523        //         pages that won't be needed.
524        while idx_a < len_a && idx_b < len_b {
525            let a_major = self.page_map[idx_a].major_value;
526            let b_major = other.page_map[idx_b].major_value;
527
528            match a_major.cmp(&b_major) {
529                Ordering::Equal => {
530                    if !passthrough_left {
531                        // If we don't passthrough the left side, then the only case where we
532                        // keep a page from the left is when there is also a page at the same major
533                        // on the right side. In this case move page_map entries that we're keeping
534                        // on the left side set to the front of the page_map vector. Otherwise if
535                        // we do passthrough left, then we we keep all left hand side pages and this
536                        // isn't necessary.
537                        if write_idx < idx_a {
538                            self.page_map[write_idx] = self.page_map[idx_a];
539                        }
540                        write_idx += 1;
541                    }
542
543                    count += 1;
544                    idx_a += 1;
545                    idx_b += 1;
546                }
547                Ordering::Less => {
548                    if passthrough_left {
549                        count += 1;
550                    }
551                    idx_a += 1;
552                }
553                Ordering::Greater => {
554                    if passthrough_right {
555                        count += 1;
556                    }
557                    idx_b += 1;
558                }
559            }
560        }
561
562        if passthrough_left {
563            count += len_a - idx_a;
564        }
565
566        if passthrough_right {
567            count += len_b - idx_b;
568        }
569
570        // Step 2: compact and resize for the new estimated left side size.
571        let mut next_page = len_a;
572        if !passthrough_left {
573            len_a = write_idx;
574            next_page = write_idx;
575            self.compact(write_idx);
576        }
577
578        self.resize(count);
579        let new_count = count;
580
581        // Step 3: process and apply op in-place from the last to first page.
582        idx_a = len_a;
583        idx_b = len_b;
584        while idx_a > 0 && idx_b > 0 {
585            match self.page_map[idx_a - 1]
586                .major_value
587                .cmp(&other.page_map[idx_b - 1].major_value)
588            {
589                Ordering::Equal => {
590                    idx_a -= 1;
591                    idx_b -= 1;
592                    count -= 1;
593                    self.page_map[count] = self.page_map[idx_a];
594                    *self.page_for_index_mut(count).unwrap() = op(
595                        self.page_for_index(idx_a).unwrap(),
596                        other.page_for_index(idx_b).unwrap(),
597                    );
598                }
599                Ordering::Greater => {
600                    idx_a -= 1;
601                    if passthrough_left {
602                        count -= 1;
603                        self.page_map[count] = self.page_map[idx_a];
604                    }
605                }
606                Ordering::Less => {
607                    idx_b -= 1;
608                    if passthrough_right {
609                        count -= 1;
610                        self.page_map[count].major_value = other.page_map[idx_b].major_value;
611                        self.page_map[count].index = next_page as u32;
612                        next_page += 1;
613                        *self.page_for_index_mut(count).unwrap() =
614                            other.page_for_index(idx_b).unwrap().clone();
615                    }
616                }
617            }
618        }
619
620        // Step 4: there are only pages left on one side now, finish processing them if the appropriate passthrough is
621        //         enabled.
622        if passthrough_left {
623            while idx_a > 0 {
624                idx_a -= 1;
625                count -= 1;
626                self.page_map[count] = self.page_map[idx_a];
627            }
628        }
629
630        if passthrough_right {
631            while idx_b > 0 {
632                idx_b -= 1;
633                count -= 1;
634                self.page_map[count].major_value = other.page_map[idx_b].major_value;
635                self.page_map[count].index = next_page as u32;
636                next_page += 1;
637                *self.page_for_index_mut(count).unwrap() =
638                    other.page_for_index(idx_b).unwrap().clone();
639            }
640        }
641
642        self.resize(new_count);
643        self.recompute_length();
644    }
645
646    fn compact(&mut self, new_len: usize) {
647        let mut old_index_to_page_map_index = Vec::<usize>::with_capacity(self.pages.len());
648        old_index_to_page_map_index.resize(self.pages.len(), usize::MAX);
649
650        for i in 0usize..new_len {
651            old_index_to_page_map_index[self.page_map[i].index as usize] = i;
652        }
653
654        self.compact_pages(old_index_to_page_map_index);
655    }
656
657    fn compact_pages(&mut self, old_index_to_page_map_index: Vec<usize>) {
658        let mut write_index = 0;
659        for (i, page_map_index) in old_index_to_page_map_index
660            .iter()
661            .enumerate()
662            .take(self.pages.len())
663        {
664            if *page_map_index == usize::MAX {
665                continue;
666            }
667
668            if write_index < i {
669                self.pages[write_index] = self.pages[i].clone();
670            }
671
672            self.page_map[*page_map_index].index = write_index as u32;
673            write_index += 1;
674        }
675    }
676
677    fn resize(&mut self, new_len: usize) {
678        self.page_map.resize(
679            new_len,
680            PageInfo {
681                major_value: 0,
682                index: 0,
683            },
684        );
685        self.pages.resize(new_len, BitPage::new_zeroes());
686    }
687
688    /// Return the major value (top 23 bits) of the page associated with value.
689    const fn get_major_value(value: u32) -> u32 {
690        value >> PAGE_BITS_LOG_2
691    }
692
693    const fn major_start(major: u32) -> u32 {
694        major << PAGE_BITS_LOG_2
695    }
696
697    const fn major_end(major: u32) -> u32 {
698        // Note: (PAGE_BITS - 1) must be grouped to prevent overflow on addition for the largest page.
699        Self::major_start(major) + (PAGE_BITS - 1)
700    }
701
702    /// Returns the index in `self.pages` (if it exists) for the page with the same major as `major_value`.
703    fn page_index_for_major(&self, major_value: u32) -> Option<usize> {
704        self.page_map_index_for_major(major_value)
705            .map(|info_idx| self.page_map[info_idx].index as usize)
706    }
707
708    fn page_map_index_for_major(&self, major_value: u32) -> Option<usize> {
709        self.page_map
710            .binary_search_by(|probe| probe.major_value.cmp(&major_value))
711            .ok()
712    }
713
714    /// Returns the index in `self.pages` for the page with the same major as `major_value`. Will create
715    /// the page if it does not yet exist.
716    #[inline(always)]
717    fn ensure_page_index_for_major(&mut self, major_value: u32) -> usize {
718        match self
719            .page_map
720            .binary_search_by(|probe| probe.major_value.cmp(&major_value))
721        {
722            Ok(map_index) => self.page_map[map_index].index as usize,
723            Err(map_index_to_insert) => {
724                self.insert_page_for_major(map_index_to_insert, major_value)
725            }
726        }
727    }
728
729    /// The miss path of `ensure_page_index_for_major`: allocate and
730    /// link a new page. Kept out of line so the hit path stays small
731    /// enough to inline into the per-value insert loops.
732    #[cold]
733    #[inline(never)]
734    fn insert_page_for_major(&mut self, map_index_to_insert: usize, major_value: u32) -> usize {
735        let page_index = self.pages.len();
736        self.pages.push(BitPage::new_zeroes());
737        let new_info = PageInfo {
738            index: page_index as u32,
739            major_value,
740        };
741        self.page_map.insert(map_index_to_insert, new_info);
742        page_index
743    }
744
745    /// Return a mutable reference to the page that `value` resides in.
746    ///
747    /// Insert a new page if it doesn't exist.
748    fn page_for_mut(&mut self, value: u32) -> Option<&mut BitPage> {
749        let major_value = Self::get_major_value(value);
750        self.page_for_major_mut(major_value)
751    }
752
753    /// Return a mutable reference to the page with major value equal to `major_value`.
754    fn page_for_major_mut(&mut self, major_value: u32) -> Option<&mut BitPage> {
755        let page_index = self.page_index_for_major(major_value)?;
756        self.pages.get_mut(page_index)
757    }
758
759    /// Return a mutable reference to the page that `value` resides in.
760    ///
761    /// Insert a new page if it doesn't exist.
762    #[inline(always)]
763    fn ensure_page_for_mut(&mut self, value: u32) -> &mut BitPage {
764        self.ensure_page_for_major_mut(Self::get_major_value(value))
765    }
766
767    /// Return a mutable reference to the page with major value equal to `major_value`.
768    /// Inserts a new page if it doesn't exist.
769    #[inline(always)]
770    fn ensure_page_for_major_mut(&mut self, major_value: u32) -> &mut BitPage {
771        let page_index = self.ensure_page_index_for_major(major_value);
772        self.pages.get_mut(page_index).unwrap()
773    }
774
775    /// Return the mutable page at a given index
776    fn page_for_index_mut(&mut self, index: usize) -> Option<&mut BitPage> {
777        self.page_map
778            .get(index)
779            .and_then(|info| self.pages.get_mut(info.index as usize))
780    }
781
782    fn page_for_index(&self, index: usize) -> Option<&BitPage> {
783        self.page_map
784            .get(index)
785            .and_then(|info| self.pages.get(info.index as usize))
786    }
787}
788
789impl Extend<u32> for U32Set {
790    fn extend<U: IntoIterator<Item = u32>>(&mut self, iter: U) {
791        let mut builder = U32SetBuilder::start(self);
792        for val in iter {
793            builder.insert(val);
794        }
795        builder.finish();
796    }
797}
798
799/// This helper is used to construct [`U32Set`]'s from a stream of possibly sorted values.
800/// It remembers the last page index to reduce the amount of page lookups needed when inserting
801/// sorted data. If given unsorted values it will still work correctly, but may be slower then just
802/// repeatedly calling `insert()` on the bitset.
803pub(crate) struct U32SetBuilder<'a> {
804    pub(crate) set: &'a mut U32Set,
805    last_page_index: usize,
806    last_major_value: u32,
807}
808
809impl<'a> U32SetBuilder<'a> {
810    pub(crate) fn start(set: &'a mut U32Set) -> Self {
811        Self {
812            set,
813            last_page_index: usize::MAX,
814            last_major_value: u32::MAX,
815        }
816    }
817
818    pub(crate) fn insert(&mut self, val: u32) {
819        // TODO(garretrieger): additional optimization ideas:
820        // - Assuming data is sorted accumulate a single element mask and only commit it to the element
821        //   once the next value passes the end of the element.
822        let major_value = U32Set::get_major_value(val);
823        if major_value != self.last_major_value {
824            self.last_page_index = self.set.ensure_page_index_for_major(major_value);
825            self.last_major_value = major_value;
826        };
827        if let Some(page) = self.set.pages.get_mut(self.last_page_index) {
828            self.set.length += page.insert(val) as u64;
829        }
830    }
831
832    pub(crate) fn finish(self) {
833        // we used to do some finalization and bookkeeping here, and we will
834        // want to again if we optimize the impl more.
835    }
836}
837
838#[derive(Clone, Copy, Debug, PartialEq, Eq)]
839#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
840struct PageInfo {
841    // index into pages vector of this page
842    index: u32,
843    /// the top 23 bits of values covered by this page
844    major_value: u32,
845}
846
847impl Hash for U32Set {
848    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
849        self.iter_non_empty_pages().for_each(|t| t.hash(state));
850    }
851}
852
853impl std::cmp::PartialEq for U32Set {
854    fn eq(&self, other: &Self) -> bool {
855        let mut this = self.iter_non_empty_pages();
856        let mut other = other.iter_non_empty_pages();
857
858        // Note: normally we would prefer to use zip, but we also
859        //       need to check that both iters have the same length.
860        loop {
861            match (this.next(), other.next()) {
862                (Some(a), Some(b)) if a == b => continue,
863                (None, None) => return true,
864                _ => return false,
865            }
866        }
867    }
868}
869
870impl std::cmp::Eq for U32Set {}
871
872impl std::cmp::PartialOrd for U32Set {
873    fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
874        Some(self.cmp(other))
875    }
876}
877
878impl std::cmp::Ord for U32Set {
879    fn cmp(&self, other: &Self) -> core::cmp::Ordering {
880        let this_it = self.iter();
881        let other_it = other.iter();
882
883        for (us, them) in this_it.zip(other_it) {
884            match us.cmp(&them) {
885                core::cmp::Ordering::Equal => continue,
886                other => return other,
887            }
888        }
889
890        // all items in iter are the same: is one collection longer?
891        self.len().cmp(&other.len())
892    }
893}
894
895struct U32SetRangeIter<'a> {
896    set: &'a U32Set,
897    page_info_index: usize,
898    page_iter: Option<RangeIter<'a>>,
899}
900
901impl<'a> U32SetRangeIter<'a> {
902    fn new(set: &'a U32Set) -> U32SetRangeIter<'a> {
903        U32SetRangeIter {
904            set,
905            page_info_index: 0,
906            page_iter: U32SetRangeIter::<'a>::page_iter(set, 0),
907        }
908    }
909
910    fn move_to_next_page(&mut self) -> bool {
911        self.page_info_index += 1;
912        self.reset_page_iter();
913        self.page_iter.is_some()
914    }
915
916    fn reset_page_iter(&mut self) {
917        self.page_iter = U32SetRangeIter::<'a>::page_iter(self.set, self.page_info_index);
918    }
919
920    fn page_iter(set: &'a U32Set, page_info_index: usize) -> Option<RangeIter<'a>> {
921        set.page_map
922            .get(page_info_index)
923            .map(|pi| pi.index as usize)
924            .and_then(|index| set.pages.get(index))
925            .map(|p| p.iter_ranges())
926    }
927
928    fn next_range(&mut self) -> Option<RangeInclusive<u32>> {
929        // TODO(garretrieger): don't recompute page start on each call.
930        let page = self.set.page_map.get(self.page_info_index)?;
931        let page_start = U32Set::major_start(page.major_value);
932        self.page_iter
933            .as_mut()?
934            .next()
935            .map(|r| (r.start() + page_start)..=(r.end() + page_start))
936    }
937}
938
939impl Iterator for U32SetRangeIter<'_> {
940    type Item = RangeInclusive<u32>;
941
942    fn next(&mut self) -> Option<Self::Item> {
943        self.page_iter.as_ref()?;
944        let mut current_range = self.next_range();
945        loop {
946            let page = self.set.page_map.get(self.page_info_index)?;
947            let page_end = U32Set::major_end(page.major_value);
948
949            let Some(range) = current_range.clone() else {
950                // The current page has no more ranges, but there may be more pages.
951                if !self.move_to_next_page() {
952                    return None;
953                }
954                current_range = self.next_range();
955                continue;
956            };
957
958            if *range.end() != page_end {
959                break;
960            }
961
962            // The range goes right to the end of the current page and may continue into it.
963            self.move_to_next_page();
964            let continuation = self.next_range();
965            let Some(continuation) = continuation else {
966                break;
967            };
968
969            if *continuation.start() == *range.end() + 1 {
970                current_range = Some(*range.start()..=*continuation.end());
971                continue;
972            }
973
974            // Continuation range does not touch the current range, ignore it and return what we have.
975            // Since we consumed an item from the new page iterator, reset it.
976            self.reset_page_iter();
977            break;
978        }
979
980        current_range
981    }
982}
983
984#[cfg(test)]
985mod test {
986    use super::*;
987    use std::collections::HashSet;
988
989    #[test]
990    fn len() {
991        let bitset = U32Set::empty();
992        assert_eq!(bitset.len(), 0);
993        assert!(bitset.is_empty());
994    }
995
996    #[test]
997    fn from_iter() {
998        let mut expected = U32Set::empty();
999        expected.extend([2, 8, 13]);
1000
1001        assert_eq!(U32Set::from_iter([2, 8, 13]), expected);
1002        assert_eq!(U32Set::from_iter([8, 2, 13]), expected);
1003    }
1004
1005    #[test]
1006    fn iter() {
1007        let mut bitset = U32Set::empty();
1008        bitset.insert(3);
1009        bitset.insert(8);
1010        bitset.insert(534);
1011        bitset.insert(700);
1012        bitset.insert(10000);
1013        bitset.insert(10001);
1014        bitset.insert(10002);
1015
1016        let v: Vec<u32> = bitset.iter().collect();
1017        assert_eq!(v, vec![3, 8, 534, 700, 10000, 10001, 10002]);
1018    }
1019
1020    fn check_iter_ranges(ranges: Vec<RangeInclusive<u32>>) {
1021        let mut set = U32Set::empty();
1022        for range in ranges.iter() {
1023            set.insert_range(*range.start()..=*range.end());
1024        }
1025        let items: Vec<_> = set.iter_ranges().collect();
1026        assert_eq!(items, ranges);
1027    }
1028
1029    #[test]
1030    fn iter_ranges() {
1031        check_iter_ranges(vec![0..=0]);
1032        check_iter_ranges(vec![4578..=4578]);
1033        check_iter_ranges(vec![0..=10, 4578..=4583]);
1034        check_iter_ranges(vec![0..=700]);
1035        check_iter_ranges(vec![353..=737]);
1036
1037        check_iter_ranges(vec![u32::MAX..=u32::MAX]);
1038        check_iter_ranges(vec![(u32::MAX - 10)..=u32::MAX]);
1039        check_iter_ranges(vec![0..=5, (u32::MAX - 5)..=u32::MAX]);
1040
1041        check_iter_ranges(vec![0..=511, 513..=517]);
1042        check_iter_ranges(vec![512..=1023, 1025..=1027]);
1043
1044        check_iter_ranges(vec![1792..=2650]);
1045    }
1046
1047    #[test]
1048    fn iter_ranges_zero_pages() {
1049        let mut set = U32Set::empty();
1050
1051        set.insert(1000);
1052        set.insert_range(300..=511);
1053        set.remove(1000);
1054
1055        let items: Vec<_> = set.iter_ranges().collect();
1056        assert_eq!(items, vec![300..=511]);
1057    }
1058
1059    #[test]
1060    fn iter_backwards() {
1061        let mut bitset = U32Set::empty();
1062
1063        bitset.insert_range(1..=6);
1064        {
1065            let mut it = bitset.iter();
1066            assert_eq!(Some(1), it.next());
1067            assert_eq!(Some(6), it.next_back());
1068            assert_eq!(Some(5), it.next_back());
1069            assert_eq!(Some(2), it.next());
1070            assert_eq!(Some(3), it.next());
1071            assert_eq!(Some(4), it.next());
1072            assert_eq!(None, it.next());
1073            assert_eq!(None, it.next_back());
1074        }
1075
1076        bitset.insert_range(700..=701);
1077        {
1078            let mut it = bitset.iter();
1079            assert_eq!(Some(1), it.next());
1080            assert_eq!(Some(701), it.next_back());
1081            assert_eq!(Some(700), it.next_back());
1082            assert_eq!(Some(6), it.next_back());
1083            assert_eq!(Some(5), it.next_back());
1084            assert_eq!(Some(2), it.next());
1085            assert_eq!(Some(3), it.next());
1086            assert_eq!(Some(4), it.next());
1087            assert_eq!(None, it.next());
1088            assert_eq!(None, it.next_back());
1089        }
1090
1091        let v: Vec<u32> = bitset.iter().rev().collect();
1092        assert_eq!(vec![701, 700, 6, 5, 4, 3, 2, 1], v);
1093    }
1094
1095    #[test]
1096    fn iter_from() {
1097        let mut bitset = U32Set::empty();
1098        bitset.extend([5, 7, 10, 1250, 1300, 3001]);
1099
1100        assert_eq!(
1101            bitset.iter_from(0).collect::<Vec<u32>>(),
1102            vec![5, 7, 10, 1250, 1300, 3001]
1103        );
1104
1105        assert_eq!(
1106            bitset.iter_from(4).collect::<Vec<u32>>(),
1107            vec![5, 7, 10, 1250, 1300, 3001]
1108        );
1109        assert_eq!(
1110            bitset.iter_from(5).collect::<Vec<u32>>(),
1111            vec![5, 7, 10, 1250, 1300, 3001]
1112        );
1113        assert_eq!(
1114            bitset.iter_from(6).collect::<Vec<u32>>(),
1115            vec![7, 10, 1250, 1300, 3001]
1116        );
1117
1118        assert_eq!(
1119            bitset.iter_from(10).collect::<Vec<u32>>(),
1120            vec![10, 1250, 1300, 3001]
1121        );
1122
1123        assert_eq!(
1124            bitset.iter_from(700).collect::<Vec<u32>>(),
1125            vec![1250, 1300, 3001]
1126        );
1127
1128        assert_eq!(
1129            bitset.iter_from(1250).collect::<Vec<u32>>(),
1130            vec![1250, 1300, 3001]
1131        );
1132        assert_eq!(
1133            bitset.iter_from(1251).collect::<Vec<u32>>(),
1134            vec![1300, 3001]
1135        );
1136
1137        assert_eq!(bitset.iter_from(3000).collect::<Vec<u32>>(), vec![3001]);
1138        assert_eq!(bitset.iter_from(3001).collect::<Vec<u32>>(), vec![3001]);
1139        assert_eq!(bitset.iter_from(3002).count(), 0);
1140        assert_eq!(bitset.iter_from(5000).count(), 0);
1141        assert_eq!(bitset.iter_from(u32::MAX).count(), 0);
1142
1143        bitset.insert(u32::MAX);
1144        assert_eq!(
1145            bitset.iter_from(u32::MAX).collect::<Vec<u32>>(),
1146            vec![u32::MAX]
1147        );
1148        assert_eq!(
1149            bitset.iter_from(u32::MAX - 1).collect::<Vec<u32>>(),
1150            vec![u32::MAX]
1151        );
1152
1153        let mut bitset = U32Set::empty();
1154        bitset.extend([510, 511, 512]);
1155
1156        assert_eq!(
1157            bitset.iter_from(509).collect::<Vec<u32>>(),
1158            vec![510, 511, 512]
1159        );
1160        assert_eq!(
1161            bitset.iter_from(510).collect::<Vec<u32>>(),
1162            vec![510, 511, 512]
1163        );
1164        assert_eq!(bitset.iter_from(511).collect::<Vec<u32>>(), vec![511, 512]);
1165        assert_eq!(bitset.iter_from(512).collect::<Vec<u32>>(), vec![512]);
1166        assert!(bitset.iter_from(513).collect::<Vec<u32>>().is_empty());
1167    }
1168
1169    #[test]
1170    fn extend() {
1171        let values = [3, 8, 534, 700, 10000, 10001, 10002];
1172        let values_unsorted = [10000, 3, 534, 700, 8, 10001, 10002];
1173
1174        let mut s1 = U32Set::empty();
1175        let mut s2 = U32Set::empty();
1176        let mut s3 = U32Set::empty();
1177        let mut s4 = U32Set::empty();
1178        assert_eq!(s1.len(), 0);
1179
1180        s1.extend(values.iter().copied());
1181        s2.extend_unsorted(values.iter().copied());
1182        s3.extend(values_unsorted.iter().copied());
1183        s4.extend_unsorted(values_unsorted.iter().copied());
1184
1185        assert_eq!(s1.iter().collect::<Vec<u32>>(), values);
1186        assert_eq!(s2.iter().collect::<Vec<u32>>(), values);
1187        assert_eq!(s3.iter().collect::<Vec<u32>>(), values);
1188        assert_eq!(s4.iter().collect::<Vec<u32>>(), values);
1189
1190        assert_eq!(s1.len(), 7);
1191        assert_eq!(s2.len(), 7);
1192        assert_eq!(s3.len(), 7);
1193        assert_eq!(s4.len(), 7);
1194    }
1195
1196    #[test]
1197    fn insert_unordered() {
1198        let mut bitset = U32Set::empty();
1199
1200        assert!(!bitset.contains(0));
1201        assert!(!bitset.contains(768));
1202        assert!(!bitset.contains(1678));
1203
1204        assert!(bitset.insert(0));
1205        assert!(bitset.insert(1678));
1206        assert!(bitset.insert(768));
1207
1208        assert!(bitset.contains(0));
1209        assert!(bitset.contains(768));
1210        assert!(bitset.contains(1678));
1211
1212        assert!(!bitset.contains(1));
1213        assert!(!bitset.contains(769));
1214        assert!(!bitset.contains(1679));
1215
1216        assert_eq!(bitset.len(), 3);
1217    }
1218
1219    #[test]
1220    fn remove() {
1221        let mut bitset = U32Set::empty();
1222
1223        assert!(bitset.insert(0));
1224        assert!(bitset.insert(511));
1225        assert!(bitset.insert(512));
1226        assert!(bitset.insert(1678));
1227        assert!(bitset.insert(768));
1228
1229        assert_eq!(bitset.len(), 5);
1230
1231        assert!(!bitset.remove(12));
1232        assert!(bitset.remove(511));
1233        assert!(bitset.remove(512));
1234        assert!(!bitset.remove(512));
1235
1236        assert_eq!(bitset.len(), 3);
1237        assert!(bitset.contains(0));
1238        assert!(!bitset.contains(511));
1239        assert!(!bitset.contains(512));
1240    }
1241
1242    #[test]
1243    fn remove_all() {
1244        let mut bitset = U32Set::empty();
1245        bitset.extend([5, 7, 11, 18, 620, 2000]);
1246
1247        assert_eq!(bitset.len(), 6);
1248
1249        bitset.remove_all([7, 11, 13, 18, 620]);
1250        assert_eq!(bitset.len(), 2);
1251        assert_eq!(bitset.iter().collect::<Vec<u32>>(), vec![5, 2000]);
1252    }
1253
1254    #[test]
1255    fn remove_range() {
1256        let mut bitset = U32Set::empty();
1257        bitset.extend([5, 7, 11, 18, 511, 620, 1023, 1024, 1200]);
1258        assert_eq!(bitset.len(), 9);
1259        bitset.remove_range(7..=620);
1260        assert_eq!(bitset.len(), 4);
1261        assert_eq!(
1262            bitset.iter().collect::<Vec<u32>>(),
1263            vec![5, 1023, 1024, 1200]
1264        );
1265
1266        let mut bitset = U32Set::empty();
1267        bitset.extend([5, 7, 11, 18, 511, 620, 1023, 1024, 1200]);
1268        bitset.remove_range(7..=1024);
1269        assert_eq!(bitset.len(), 2);
1270        assert_eq!(bitset.iter().collect::<Vec<u32>>(), vec![5, 1200]);
1271
1272        let mut bitset = U32Set::empty();
1273        bitset.extend([5, 7, 11, 18, 511, 620, 1023, 1024, 1200]);
1274        bitset.remove_range(2000..=2100);
1275        assert_eq!(bitset.len(), 9);
1276        assert_eq!(
1277            bitset.iter().collect::<Vec<u32>>(),
1278            vec![5, 7, 11, 18, 511, 620, 1023, 1024, 1200]
1279        );
1280
1281        // Remove all from one page
1282        let mut bitset = U32Set::empty();
1283        bitset.extend([1001, 1002, 1003, 1004]);
1284        bitset.remove_range(1002..=1003);
1285        assert!(bitset.contains(1001));
1286        assert!(!bitset.contains(1002));
1287        assert!(!bitset.contains(1003));
1288        assert!(bitset.contains(1004));
1289
1290        bitset.remove_range(100..=200);
1291        assert!(bitset.contains(1001));
1292        assert!(!bitset.contains(1002));
1293        assert!(!bitset.contains(1003));
1294        assert!(bitset.contains(1004));
1295
1296        bitset.remove_range(100..=1001);
1297        assert!(!bitset.contains(1001));
1298        assert!(!bitset.contains(1002));
1299        assert!(!bitset.contains(1003));
1300        assert!(bitset.contains(1004));
1301    }
1302
1303    #[test]
1304    fn remove_range_boundary() {
1305        let mut set = U32Set::empty();
1306
1307        set.remove_range(u32::MAX - 10..=u32::MAX);
1308        assert!(!set.contains(u32::MAX));
1309        set.insert_range(u32::MAX - 10..=u32::MAX);
1310        assert!(set.contains(u32::MAX));
1311        set.remove_range(u32::MAX - 10..=u32::MAX);
1312        assert!(!set.contains(u32::MAX));
1313
1314        set.remove_range(0..=10);
1315        assert!(!set.contains(0));
1316        set.insert_range(0..=10);
1317        assert!(set.contains(0));
1318        set.remove_range(0..=10);
1319        assert!(!set.contains(0));
1320    }
1321
1322    #[test]
1323    fn remove_to_empty_page() {
1324        let mut bitset = U32Set::empty();
1325
1326        bitset.insert(793);
1327        bitset.insert(43);
1328        bitset.remove(793);
1329
1330        assert!(bitset.contains(43));
1331        assert!(!bitset.contains(793));
1332        assert_eq!(bitset.len(), 1);
1333    }
1334
1335    #[test]
1336    fn insert_max_value() {
1337        let mut bitset = U32Set::empty();
1338        assert!(!bitset.contains(u32::MAX));
1339        assert!(bitset.insert(u32::MAX));
1340        assert!(bitset.contains(u32::MAX));
1341        assert!(!bitset.contains(u32::MAX - 1));
1342        assert_eq!(bitset.len(), 1);
1343    }
1344
1345    #[test]
1346    fn contains_index_cache() {
1347        let mut bitset = U32Set::from_iter([10, 11, 12, 2023]);
1348        // contains() internally uses a cache of last page index
1349        // ensure that outward contains() returns are unnaffected
1350        // by the ordering of calls.
1351        assert!(!bitset.contains(9));
1352        assert!(bitset.contains(10));
1353        assert!(bitset.contains(11));
1354        assert!(bitset.contains(12));
1355
1356        assert!(!bitset.contains(1200));
1357        assert!(!bitset.contains(2022));
1358        assert!(bitset.contains(2023));
1359        assert!(!bitset.contains(2024));
1360
1361        assert!(bitset.contains(2023));
1362        assert!(bitset.contains(11));
1363
1364        assert!(!bitset.contains(5000));
1365        assert!(bitset.contains(11));
1366        assert!(bitset.contains(2023));
1367        assert!(bitset.contains(12));
1368        assert!(!bitset.contains(2024));
1369        assert!(!bitset.contains(13));
1370
1371        // Caching should also work correctly if the page map is modified between lookups
1372        bitset.clear();
1373        bitset.insert(2024);
1374        bitset.insert(13);
1375
1376        assert!(bitset.contains(13));
1377        assert!(!bitset.contains(12));
1378
1379        assert!(bitset.contains(2024));
1380        assert!(!bitset.contains(2023));
1381    }
1382
1383    fn check_process<A, B, C, Op>(a: A, b: B, expected: C, op: Op)
1384    where
1385        A: IntoIterator<Item = u32>,
1386        B: IntoIterator<Item = u32>,
1387        C: IntoIterator<Item = u32>,
1388        Op: Fn(&mut U32Set, &U32Set),
1389    {
1390        let mut result = U32Set::from_iter(a);
1391        let b_set = U32Set::from_iter(b);
1392        let expected_set = U32Set::from_iter(expected);
1393        result.len();
1394
1395        op(&mut result, &b_set);
1396        assert_eq!(result, expected_set);
1397        assert_eq!(result.len(), expected_set.len());
1398    }
1399
1400    #[test]
1401    fn union() {
1402        check_process([], [5], [5], |a, b| a.union(b));
1403        check_process([128], [5], [128, 5], |a, b| a.union(b));
1404        check_process([128], [], [128], |a, b| a.union(b));
1405        check_process([1280], [5], [5, 1280], |a, b| a.union(b));
1406        check_process([5], [1280], [5, 1280], |a, b| a.union(b));
1407    }
1408
1409    #[test]
1410    fn intersect() {
1411        check_process([], [5], [], |a, b| a.intersect(b));
1412        check_process([5], [], [], |a, b| a.intersect(b));
1413        check_process([1, 5, 9], [5, 7], [5], |a, b| a.intersect(b));
1414        check_process([1, 1000, 2000], [1000], [1000], |a, b| a.intersect(b));
1415        check_process([1000], [1, 1000, 2000], [1000], |a, b| a.intersect(b));
1416        check_process([1, 1000, 2000], [1000, 5000], [1000], |a, b| a.intersect(b));
1417    }
1418
1419    #[test]
1420    fn subtract() {
1421        check_process([], [5], [], |a, b| a.subtract(b));
1422        check_process([5], [], [5], |a, b| a.subtract(b));
1423        check_process([5, 1000], [1000], [5], |a, b| a.subtract(b));
1424        check_process([5, 1000], [5], [1000], |a, b| a.subtract(b));
1425    }
1426
1427    #[test]
1428    fn reversed_subtract() {
1429        check_process([], [5], [5], |a, b| a.reversed_subtract(b));
1430        check_process([5], [], [], |a, b| a.reversed_subtract(b));
1431        check_process([1000], [5, 1000], [5], |a, b| a.reversed_subtract(b));
1432        check_process([5], [5, 1000], [1000], |a, b| a.reversed_subtract(b));
1433    }
1434
1435    fn set_for_range(first: u32, last: u32) -> U32Set {
1436        let mut set = U32Set::empty();
1437        for i in first..=last {
1438            set.insert(i);
1439        }
1440        set
1441    }
1442
1443    #[test]
1444    fn insert_range() {
1445        for range in [
1446            (0, 0),
1447            (0, 364),
1448            (0, 511),
1449            (512, 1023),
1450            (0, 1023),
1451            (364, 700),
1452            (364, 6000),
1453        ] {
1454            let mut set = U32Set::empty();
1455            set.len();
1456            set.insert_range(range.0..=range.1);
1457            assert_eq!(set, set_for_range(range.0, range.1), "{range:?}");
1458            assert_eq!(set.len(), (range.1 - range.0 + 1) as u64, "{range:?}");
1459        }
1460    }
1461
1462    #[test]
1463    fn insert_range_on_existing() {
1464        let mut set = U32Set::empty();
1465        set.insert(700);
1466        set.insert(2000);
1467        set.insert_range(32..=4000);
1468        assert_eq!(set, set_for_range(32, 4000));
1469        assert_eq!(set.len(), 4000 - 32 + 1);
1470    }
1471
1472    #[test]
1473    fn insert_range_max() {
1474        let mut set = U32Set::empty();
1475        set.insert_range(u32::MAX..=u32::MAX);
1476        assert!(set.contains(u32::MAX));
1477        assert_eq!(set.len(), 1);
1478    }
1479
1480    #[test]
1481    fn clear() {
1482        let mut bitset = U32Set::empty();
1483
1484        bitset.insert(13);
1485        bitset.insert(670);
1486        assert!(bitset.contains(13));
1487        assert!(bitset.contains(670));
1488
1489        bitset.clear();
1490        assert!(!bitset.contains(13));
1491        assert!(!bitset.contains(670));
1492        assert_eq!(bitset.len(), 0);
1493    }
1494
1495    #[test]
1496    fn hash_and_eq() {
1497        let mut bitset1 = U32Set::empty();
1498        let mut bitset2 = U32Set::empty();
1499        let mut bitset3 = U32Set::empty();
1500        let mut bitset4 = U32Set::empty();
1501
1502        bitset1.insert(43);
1503        bitset1.insert(793);
1504
1505        bitset2.insert(793);
1506        bitset2.insert(43);
1507        bitset2.len();
1508
1509        bitset3.insert(43);
1510        bitset3.insert(793);
1511        bitset3.insert(794);
1512
1513        bitset4.insert(0);
1514
1515        assert_eq!(U32Set::empty(), U32Set::empty());
1516        assert_eq!(bitset1, bitset2);
1517        assert_ne!(bitset1, bitset3);
1518        assert_ne!(bitset2, bitset3);
1519        assert_eq!(bitset4, bitset4);
1520
1521        let set = HashSet::from([bitset1]);
1522        assert!(set.contains(&bitset2));
1523        assert!(!set.contains(&bitset3));
1524    }
1525
1526    #[test]
1527    fn hash_and_eq_with_empty_pages() {
1528        let mut bitset1 = U32Set::empty();
1529        let mut bitset2 = U32Set::empty();
1530        let mut bitset3 = U32Set::empty();
1531
1532        bitset1.insert(43);
1533
1534        bitset2.insert(793);
1535        bitset2.insert(43);
1536        bitset2.remove(793);
1537
1538        bitset3.insert(43);
1539        bitset3.insert(793);
1540
1541        assert_eq!(bitset1, bitset2);
1542        assert_ne!(bitset1, bitset3);
1543
1544        let set = HashSet::from([bitset1]);
1545        assert!(set.contains(&bitset2));
1546    }
1547
1548    #[test]
1549    fn hash_and_eq_ignore_cache() {
1550        let bitset1 = U32Set::from_iter([5, 1027]);
1551        let bitset2 = U32Set::from_iter([5, 1027]);
1552
1553        // Modify the internal last page index cache to point at different pages.
1554        assert!(bitset1.contains(1027));
1555        assert!(bitset2.contains(5));
1556
1557        // Hash, eq, cmp should be unnaffected:
1558        assert_eq!(bitset1, bitset2);
1559        assert!(matches!(bitset1.cmp(&bitset2), Ordering::Equal));
1560        let set = HashSet::from([bitset1]);
1561        assert!(set.contains(&bitset2));
1562    }
1563
1564    #[test]
1565    fn ordering() {
1566        macro_rules! assert_ord {
1567            ($lhs:expr, $rhs:expr, $ord:path) => {
1568                assert_eq!(
1569                    U32Set::from_iter($lhs).cmp(&U32Set::from_iter($rhs)),
1570                    $ord,
1571                    "{:?}, {:?}",
1572                    $lhs,
1573                    $rhs
1574                )
1575            };
1576        }
1577
1578        const EMPTY: [u32; 0] = [];
1579        assert_ord!(EMPTY, EMPTY, Ordering::Equal);
1580        assert_ord!(EMPTY, [0], Ordering::Less);
1581        assert_ord!([0], [0], Ordering::Equal);
1582        assert_ord!([0, 1, 2], [1, 2, 3], Ordering::Less);
1583        assert_ord!([0, 1, 4], [1, 2, 3], Ordering::Less);
1584        assert_ord!([1, 2, 3], [0, 2, 4], Ordering::Greater);
1585        assert_ord!([5, 4, 0], [1, 2, 3], Ordering::Less); // out of order
1586        assert_ord!([1, 2, 3], [1, 2, 3, 4], Ordering::Less); // out of order
1587        assert_ord!([2, 3, 4], [1, 2, 3, 4, 5], Ordering::Greater); // out of order
1588
1589        assert_ord!([1000, 2000, 3000], [1000, 2000, 3000, 4000], Ordering::Less); // out of order
1590        assert_ord!([1000, 1001,], [1000, 2000], Ordering::Less); // out of order
1591        assert_ord!(
1592            [2000, 3000, 4000],
1593            [1000, 2000, 3000, 4000, 5000],
1594            Ordering::Greater
1595        ); // out of order
1596    }
1597
1598    #[test]
1599    fn intersects() {
1600        macro_rules! assert_intersects {
1601            ($lhs:path, $rhs:path, $expected:expr) => {
1602                assert_eq!($lhs.intersects_set(&$rhs), $expected);
1603                assert_eq!($rhs.intersects_set(&$lhs), $expected);
1604            };
1605        }
1606
1607        let a = U32Set::from_iter([2, 4, 5, 2057, 7000]);
1608        let b = U32Set::from_iter([3]);
1609        let c = U32Set::from_iter([2058]);
1610        let d = U32Set::from_iter([2057, 3000]);
1611        let e = U32Set::from_iter([3, 7000]);
1612
1613        assert_intersects!(a, b, false);
1614        assert_intersects!(a, c, false);
1615        assert_intersects!(e, d, false);
1616
1617        assert_intersects!(a, d, true);
1618        assert_intersects!(a, e, true);
1619        assert_intersects!(b, e, true);
1620
1621        // Check that page map population orderdoes not impact the check
1622        let mut a = U32Set::empty();
1623        a.insert(4000);
1624        a.insert(0);
1625
1626        let b = U32Set::from_iter([4000]);
1627
1628        assert_intersects!(a, b, true);
1629    }
1630
1631    #[test]
1632    fn is_subset() {
1633        let empty = U32Set::empty();
1634        let a = U32Set::from_iter([2, 4, 5, 2057, 7000]);
1635        let b = U32Set::from_iter([2, 4, 5, 2057, 7000, 8000]);
1636        let c = U32Set::from_iter([2, 4, 5]);
1637        let d = U32Set::from_iter([2, 4, 6, 2057, 7000]); // same len as a, different element on page 0
1638        let e = U32Set::from_iter([2, 4, 5, 3000, 7000]); // same len as a, different major page
1639
1640        assert!(empty.is_subset(&empty));
1641        assert!(empty.is_subset(&a));
1642        assert!(a.is_subset(&a));
1643        assert!(a.is_subset(&b));
1644        assert!(c.is_subset(&a));
1645        assert!(c.is_subset(&b));
1646
1647        // Fails via length check:
1648        assert!(!b.is_subset(&a));
1649        assert!(!a.is_subset(&c));
1650        assert!(!a.is_subset(&empty));
1651
1652        // Fails via bitwise check (same len):
1653        assert!(!a.is_subset(&d));
1654        assert!(!d.is_subset(&a));
1655
1656        // Fails via page matching check (different major page, same len):
1657        assert!(!a.is_subset(&e));
1658        assert!(!e.is_subset(&a));
1659
1660        // Test with empty pages present in self
1661        let mut a_with_empty_page = U32Set::empty();
1662        a_with_empty_page.insert(100);
1663        a_with_empty_page.insert(2057);
1664        a_with_empty_page.remove(100); // page for 100 remains in page_map but is empty
1665        assert!(a_with_empty_page.is_subset(&b));
1666    }
1667
1668    #[test]
1669    fn intersection_len() {
1670        let empty = U32Set::empty();
1671        let a = U32Set::from_iter([2, 4, 5, 2057, 7000]);
1672        let b = U32Set::from_iter([4, 5, 2057, 9000]);
1673        let c = U32Set::from_iter([1, 3, 10000]);
1674
1675        assert_eq!(empty.intersection_len(&a), 0);
1676        assert_eq!(a.intersection_len(&empty), 0);
1677        assert_eq!(a.intersection_len(&a), 5);
1678
1679        assert_eq!(a.intersection_len(&b), 3);
1680        assert_eq!(b.intersection_len(&a), 3);
1681
1682        assert_eq!(a.intersection_len(&c), 0);
1683        assert_eq!(c.intersection_len(&a), 0);
1684    }
1685}