1use alloc::vec::Vec;
4use std::{hash::Hash, ops::RangeInclusive};
5
6type Element = u64;
8
9const PAGE_SIZE: u32 = 8;
11const ELEM_SIZE: u32 = std::mem::size_of::<Element>() as u32;
13const ELEM_BITS: u32 = ELEM_SIZE * 8;
15const ELEM_MASK: u32 = ELEM_BITS - 1;
17pub(crate) const PAGE_BITS: u32 = ELEM_BITS * PAGE_SIZE;
19const PAGE_MASK: u32 = PAGE_BITS - 1;
21
22#[derive(Clone)]
24#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
25pub(crate) struct BitPage {
26 storage: [Element; PAGE_SIZE as usize],
27 length: u32,
28}
29
30impl BitPage {
31 pub(crate) fn new_zeroes() -> Self {
33 Self {
34 storage: [0; PAGE_SIZE as usize],
35 length: 0,
36 }
37 }
38
39 pub(crate) fn recompute_length(&mut self) {
40 self.length = self.storage.iter().copied().map(u64::count_ones).sum();
41 }
42
43 pub(crate) fn len(&self) -> u32 {
45 self.length
46 }
47
48 pub(crate) fn is_empty(&self) -> bool {
50 self.len() == 0
51 }
52
53 pub(crate) fn intersects_set(&self, other: &BitPage) -> bool {
55 self.storage
56 .iter()
57 .zip(other.storage.iter())
58 .any(|(a, b)| (*a & *b) != 0)
59 }
60
61 pub(crate) fn is_subset(&self, other: &BitPage) -> bool {
63 if self.len() > other.len() {
64 return false;
65 }
66 self.storage
67 .iter()
68 .zip(other.storage.iter())
69 .all(|(a, b)| (*a & *b) == *a)
70 }
71
72 pub(crate) fn intersection_len(&self, other: &BitPage) -> u32 {
74 self.storage
75 .iter()
76 .zip(other.storage.iter())
77 .map(|(a, b)| (*a & *b).count_ones())
78 .sum()
79 }
80
81 pub(crate) fn iter(&self) -> impl DoubleEndedIterator<Item = u32> + '_ {
86 self.storage
87 .iter()
88 .enumerate()
89 .filter(|(_, elem)| **elem != 0)
90 .flat_map(|(i, elem)| {
91 let base = i as u32 * ELEM_BITS;
92 Iter::new(*elem).map(move |idx| base + idx)
93 })
94 }
95
96 pub(crate) fn iter_from(&self, value: u32) -> impl DoubleEndedIterator<Item = u32> + '_ {
100 let start_index = Self::element_index(value);
101 self.storage[start_index..]
102 .iter()
103 .enumerate()
104 .filter(|(_, elem)| **elem != 0)
105 .flat_map(move |(i, elem)| {
106 let i = i + start_index;
107 let base = i as u32 * ELEM_BITS;
108 let it = if start_index == i {
109 let index_in_elem = value & ELEM_MASK;
110 Iter::from(*elem, index_in_elem)
111 } else {
112 Iter::new(*elem)
113 };
114 it.map(move |idx| base + idx)
115 })
116 }
117
118 pub(crate) fn iter_ranges(&self) -> RangeIter<'_> {
120 RangeIter {
121 page: self,
122 next_value_to_check: 0,
123 }
124 }
125
126 #[inline(always)]
128 pub(crate) fn insert(&mut self, val: u32) -> bool {
129 let el_mut = self.element_mut(val);
130 let mask = elem_index_bit_mask(val);
131 let is_new = (*el_mut & mask) == 0;
132 *el_mut |= mask;
133 self.length += is_new as u32;
134 is_new
135 }
136
137 pub(crate) fn insert_range(&mut self, first: u32, last: u32) {
139 let first = first & PAGE_MASK;
140 let last = last & PAGE_MASK;
141 let first_elem_idx = first / ELEM_BITS;
142 let last_elem_idx = last / ELEM_BITS;
143
144 for elem_idx in first_elem_idx..=last_elem_idx {
145 let elem_start = first.max(elem_idx * ELEM_BITS) & ELEM_MASK;
146 let elem_last = last.min(((elem_idx + 1) * ELEM_BITS) - 1) & ELEM_MASK;
147
148 let end_shift = ELEM_BITS - elem_last - 1;
149 let mask = u64::MAX << (elem_start + end_shift);
150 let mask = mask >> end_shift;
151
152 self.storage[elem_idx as usize] |= mask;
153 }
154
155 self.recompute_length();
156 }
157
158 pub(crate) fn remove_range(&mut self, first: u32, last: u32) {
160 let first = first & PAGE_MASK;
161 let last = last & PAGE_MASK;
162 let first_elem_idx = first / ELEM_BITS;
163 let last_elem_idx = last / ELEM_BITS;
164
165 for elem_idx in first_elem_idx..=last_elem_idx {
166 let elem_start = first.max(elem_idx * ELEM_BITS) & ELEM_MASK;
167 let elem_last = last.min(((elem_idx + 1) * ELEM_BITS) - 1) & ELEM_MASK;
168
169 let end_shift = ELEM_BITS - elem_last - 1;
170 let mask = u64::MAX << (elem_start + end_shift);
171 let mask = !(mask >> end_shift);
172
173 self.storage[elem_idx as usize] &= mask;
174 }
175
176 self.recompute_length();
177 }
178
179 pub(crate) fn clear(&mut self) {
180 for elem in self.storage.iter_mut() {
181 *elem = 0;
182 }
183 self.length = 0;
184 }
185
186 pub(crate) fn remove(&mut self, val: u32) -> bool {
188 let ret = self.contains(val);
189 *self.element_mut(val) &= !elem_index_bit_mask(val);
190 self.length -= ret as u32;
191 ret
192 }
193
194 pub(crate) fn contains(&self, val: u32) -> bool {
196 (*self.element(val) & elem_index_bit_mask(val)) != 0
197 }
198
199 pub(crate) fn union(a: &BitPage, b: &BitPage) -> BitPage {
200 a.process(b, |a, b| a | b)
201 }
202
203 pub(crate) fn intersect(a: &BitPage, b: &BitPage) -> BitPage {
204 a.process(b, |a, b| a & b)
205 }
206
207 pub(crate) fn subtract(a: &BitPage, b: &BitPage) -> BitPage {
208 a.process(b, |a, b| a & !b)
209 }
210
211 fn process<Op>(&self, other: &BitPage, op: Op) -> BitPage
212 where
213 Op: Fn(Element, Element) -> Element,
214 {
215 let mut out = BitPage::new_zeroes();
216 for i in 0usize..(PAGE_SIZE as usize) {
217 out.storage[i] = op(self.storage[i], other.storage[i]);
218 }
219 out.recompute_length();
220 out
221 }
222
223 fn element(&self, value: u32) -> &Element {
224 &self.storage[Self::element_index(value)]
225 }
226
227 fn element_mut(&mut self, value: u32) -> &mut Element {
228 &mut self.storage[Self::element_index(value)]
229 }
230
231 const fn element_index(value: u32) -> usize {
232 (value as usize & PAGE_MASK as usize) / (ELEM_BITS as usize)
233 }
234}
235
236const fn elem_index_bit_mask(value: u32) -> Element {
238 1 << (value & ELEM_MASK)
239}
240
241struct Iter {
242 val: Element,
243 forward_index: i32,
244 backward_index: i32,
245}
246
247impl Iter {
248 fn new(elem: Element) -> Iter {
249 Iter {
250 val: elem,
251 forward_index: 0,
252 backward_index: ELEM_BITS as i32 - 1,
253 }
254 }
255
256 fn from(elem: Element, index: u32) -> Iter {
260 Iter {
261 val: elem,
262 forward_index: index as i32, backward_index: ELEM_BITS as i32 - 1,
264 }
265 }
266}
267
268impl Iterator for Iter {
269 type Item = u32;
270
271 fn next(&mut self) -> Option<Self::Item> {
272 if self.forward_index > self.backward_index {
273 return None;
274 }
275 let mask = (1u64 << self.forward_index) - 1;
276 let masked = self.val & !mask;
277 let next_index = masked.trailing_zeros() as i32;
278 if next_index > self.backward_index {
279 return None;
280 }
281 self.forward_index = next_index + 1;
282 Some(next_index as u32)
283 }
284}
285
286impl DoubleEndedIterator for Iter {
287 fn next_back(&mut self) -> Option<Self::Item> {
288 if self.backward_index < self.forward_index {
289 return None;
290 }
291
292 let mask = 1u64
293 .checked_shl(self.backward_index as u32 + 1)
294 .map(|v| v - 1)
295 .unwrap_or(Element::MAX);
296 let masked = self.val & mask;
297 let next_index = (ELEM_BITS as i32) - (masked.leading_zeros() as i32) - 1;
298 if next_index < self.forward_index {
299 return None;
300 }
301 self.backward_index = next_index - 1;
302 Some(next_index as u32)
303 }
304}
305
306pub(crate) struct RangeIter<'a> {
307 page: &'a BitPage,
308 next_value_to_check: u32,
309}
310
311impl RangeIter<'_> {
312 fn next_range_in_element(&self) -> Option<RangeInclusive<u32>> {
313 if self.next_value_to_check >= PAGE_BITS {
314 return None;
315 }
316
317 let element = self.page.element(self.next_value_to_check);
318 let element_bit = (self.next_value_to_check & ELEM_MASK) as u64;
319 let major = self.next_value_to_check & !ELEM_MASK;
320
321 let mask = !((1 << element_bit) - 1);
322 let range_start = (element & mask).trailing_zeros();
323 if range_start == ELEM_BITS {
324 return None;
326 }
327
328 let mask = (1 << range_start) - 1;
329 let range_end = (element | mask).trailing_ones() - 1;
330
331 Some((major + range_start)..=(major + range_end))
332 }
333}
334
335impl Iterator for RangeIter<'_> {
336 type Item = RangeInclusive<u32>;
337
338 fn next(&mut self) -> Option<Self::Item> {
339 let mut current_range = self.next_range_in_element();
340 loop {
341 let element_end = (self.next_value_to_check & !ELEM_MASK) + ELEM_BITS - 1;
342 let Some(range) = current_range.clone() else {
343 self.next_value_to_check = element_end + 1;
345 if self.next_value_to_check < PAGE_BITS {
346 current_range = self.next_range_in_element();
347 continue;
348 } else {
349 return None;
350 }
351 };
352
353 self.next_value_to_check = range.end() + 1;
354 if *range.end() == element_end {
355 let continuation = self.next_range_in_element();
356 if let Some(continuation) = continuation {
357 if *continuation.start() == element_end + 1 {
358 current_range = Some(*range.start()..=*continuation.end());
359 continue;
360 }
361 }
362 }
363
364 break;
365 }
366
367 current_range
368 }
369}
370
371impl Default for BitPage {
372 fn default() -> Self {
373 Self::new_zeroes()
374 }
375}
376
377impl std::fmt::Debug for BitPage {
378 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
379 let values: Vec<_> = self.iter().collect();
380 std::fmt::Debug::fmt(&values, f)
381 }
382}
383
384impl Hash for BitPage {
385 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
386 self.storage.hash(state);
387 }
388}
389
390impl std::cmp::PartialEq for BitPage {
391 fn eq(&self, other: &Self) -> bool {
392 self.storage == other.storage
393 }
394}
395
396impl std::cmp::Eq for BitPage {}
397
398#[cfg(test)]
399mod test {
400 use std::collections::HashSet;
401
402 use super::*;
403
404 impl BitPage {
405 fn new_ones() -> Self {
407 Self {
408 storage: [Element::MAX; PAGE_SIZE as usize],
409 length: PAGE_SIZE * ELEM_BITS,
410 }
411 }
412 }
413
414 impl FromIterator<u32> for BitPage {
415 fn from_iter<I: IntoIterator<Item = u32>>(iter: I) -> Self {
416 let mut out = BitPage::new_zeroes();
417 for v in iter {
418 out.insert(v);
419 }
420 out
421 }
422 }
423
424 #[test]
425 fn test_iter_bit_indices() {
426 let items: Vec<_> = Iter::new(0).collect();
427 assert_eq!(items.len(), 0);
428
429 let items: Vec<_> = Iter::new(1).collect();
430 assert_eq!(items, vec![0]);
431
432 let items: Vec<_> = Iter::new(0b1100).collect();
433 assert_eq!(items, vec![2, 3]);
434
435 let items: Vec<_> = Iter::new(1 << 63).collect();
436 assert_eq!(items, vec![63]);
437
438 let items: Vec<_> = Iter::new((1 << 47) | (1 << 63)).collect();
439 assert_eq!(items, vec![47, 63]);
440
441 assert_eq!(Iter::new(Element::MAX).max(), Some(ELEM_BITS - 1));
442 assert_eq!(Iter::new(Element::MAX).min(), Some(0));
443 }
444
445 #[test]
446 fn test_iter_bit_indices_backwards() {
447 let mut it = Iter::new(0);
448 assert_eq!(None, it.next());
449 assert_eq!(None, it.next_back());
450
451 let mut it = Iter::new((1 << 1) | (1 << 2) | (1 << 3) | (1 << 4) | (1 << 5) | (1 << 6));
452 assert_eq!(Some(1), it.next());
453 assert_eq!(Some(6), it.next_back());
454 assert_eq!(Some(5), it.next_back());
455 assert_eq!(Some(2), it.next());
456 assert_eq!(Some(3), it.next());
457 assert_eq!(Some(4), it.next());
458 assert_eq!(None, it.next());
459 assert_eq!(None, it.next_back());
460
461 let mut it = Iter::new(1);
462 assert_eq!(Some(0), it.next_back());
463 assert_eq!(None, it.next_back());
464
465 let mut it = Iter::new(1 << 63);
466 assert_eq!(Some(63), it.next_back());
467 assert_eq!(None, it.next_back());
468
469 let mut it = Iter::new((1 << 63) | (1 << 62));
470 assert_eq!(Some(63), it.next_back());
471 assert_eq!(Some(62), it.next_back());
472 assert_eq!(None, it.next_back());
473
474 let mut it = Iter::new((1 << 63) | (1 << 32));
475 assert_eq!(Some(63), it.next_back());
476 assert_eq!(Some(32), it.next_back());
477 assert_eq!(None, it.next_back());
478 }
479
480 #[test]
481 fn page_init() {
482 let page = BitPage::new_zeroes();
483 assert_eq!(page.len(), 0);
484 assert!(page.is_empty());
485 }
486
487 #[test]
488 fn page_init_ones() {
489 let page = BitPage::new_ones();
490 assert_eq!(page.len(), 512);
491 assert!(!page.is_empty());
492 }
493
494 #[test]
495 fn page_contains_empty() {
496 let page = BitPage::new_zeroes();
497 assert!(!page.contains(0));
498 assert!(!page.contains(1));
499 assert!(!page.contains(75475));
500 }
501
502 #[test]
503 fn page_contains_all() {
504 let page = BitPage::new_ones();
505 assert!(page.contains(0));
506 assert!(page.contains(1));
507 assert!(page.contains(75475));
508 }
509
510 #[test]
511 fn page_insert() {
512 for val in 0..=1025 {
513 let mut page = BitPage::new_zeroes();
514 assert!(!page.contains(val), "unexpected {val} (1)");
515 page.insert(val);
516 assert!(page.contains(val), "missing {val}");
517 assert!(!page.contains(val.wrapping_sub(1)), "unexpected {val} (2)");
518 }
519 }
520
521 #[test]
522 fn page_insert_range() {
523 fn page_for_range(first: u32, last: u32) -> BitPage {
524 let mut page = BitPage::new_zeroes();
525 for i in first..=last {
526 page.insert(i);
527 }
528 page
529 }
530
531 for range in [
532 (0, 0),
533 (0, 1),
534 (1, 15),
535 (5, 63),
536 (64, 67),
537 (69, 72),
538 (69, 127),
539 (32, 345),
540 (512 + 32, 512 + 345),
541 (0, 511),
542 ] {
543 let mut page = BitPage::new_zeroes();
544 page.insert_range(range.0, range.1);
545 assert_eq!(page, page_for_range(range.0, range.1), "{range:?}");
546 }
547 }
548
549 #[test]
550 fn page_insert_return() {
551 let mut page = BitPage::new_zeroes();
552 assert!(page.insert(123));
553 assert!(!page.insert(123));
554 }
555
556 #[test]
557 fn page_remove() {
558 for val in 0..=1025 {
559 let mut page = BitPage::new_ones();
560 assert!(page.contains(val), "missing {val} (1)");
561 assert!(page.remove(val));
562 assert!(!page.remove(val));
563 assert!(!page.contains(val), "unexpected {val}");
564 assert!(page.contains(val.wrapping_sub(1)), "missing {val} (2)");
565 }
566 }
567
568 #[test]
569 fn page_remove_range() {
570 fn page_for_range(first: u32, last: u32) -> BitPage {
571 let mut page = BitPage::new_ones();
572 for i in first..=last {
573 page.remove(i);
574 }
575 page
576 }
577
578 for exclude_range in [
579 (0, 0),
580 (0, 1),
581 (1, 15),
582 (5, 63),
583 (64, 67),
584 (69, 72),
585 (69, 127),
586 (32, 345),
587 (0, 511),
588 (512 + 32, 512 + 345),
589 ] {
590 let mut page = BitPage::new_ones();
591 page.remove_range(exclude_range.0, exclude_range.1);
592 assert_eq!(
593 page,
594 page_for_range(exclude_range.0, exclude_range.1),
595 "{exclude_range:?}"
596 );
597 }
598 }
599
600 #[test]
601 fn clear() {
602 let mut zeroes = BitPage::new_zeroes();
603 let mut ones = BitPage::new_ones();
604
605 zeroes.clear();
606 assert_eq!(zeroes.len(), 0);
607 assert_eq!(zeroes.iter().next(), None);
608
609 zeroes.insert_range(10, 300);
610 zeroes.clear();
611 assert_eq!(zeroes.len(), 0);
612 assert_eq!(zeroes.iter().next(), None);
613
614 ones.clear();
615 assert_eq!(ones.len(), 0);
616 assert_eq!(ones.iter().next(), None);
617 }
618
619 #[test]
620 fn remove_to_empty_page() {
621 let mut page = BitPage::new_zeroes();
622
623 page.insert(13);
624 assert!(!page.is_empty());
625
626 page.remove(13);
627 assert!(page.is_empty());
628 }
629
630 #[test]
631 fn page_iter() {
632 let mut page = BitPage::new_zeroes();
633
634 page.insert(0);
635 page.insert(12);
636 page.insert(13);
637 page.insert(63);
638 page.insert(64);
639 page.insert(511);
640 page.insert(23);
641 page.insert(400);
642 page.insert(78);
643
644 let items: Vec<_> = page.iter().collect();
645 assert_eq!(items, vec![0, 12, 13, 23, 63, 64, 78, 400, 511,])
646 }
647
648 #[test]
649 fn page_iter_overflow() {
650 let mut page = BitPage::new_zeroes();
651 page.insert(0);
652 let mut it = page.iter();
653 assert_eq!(Some(0), it.next_back());
654 assert_eq!(None, it.next());
655 }
656
657 #[test]
658 fn page_iter_from() {
659 let mut page = BitPage::new_zeroes();
660 let items: Vec<_> = page.iter_from(0).collect();
661 assert!(items.is_empty());
662 let items: Vec<_> = page.iter_from(256).collect();
663 assert!(items.is_empty());
664
665 page.insert(1);
666 page.insert(12);
667 page.insert(13);
668 page.insert(63);
669 page.insert(64);
670 page.insert(511);
671 page.insert(23);
672 page.insert(400);
673 page.insert(78);
674
675 let items: Vec<_> = page.iter_from(0).collect();
676 assert_eq!(items, vec![1, 12, 13, 23, 63, 64, 78, 400, 511,]);
677
678 page.insert(0);
679 let items: Vec<_> = page.iter_from(0).collect();
680 assert_eq!(items, vec![0, 1, 12, 13, 23, 63, 64, 78, 400, 511,]);
681
682 let items: Vec<_> = page.iter_from(1).collect();
683 assert_eq!(items, vec![1, 12, 13, 23, 63, 64, 78, 400, 511,]);
684
685 let items: Vec<_> = page.iter_from(2).collect();
686 assert_eq!(items, vec![12, 13, 23, 63, 64, 78, 400, 511,]);
687
688 let items: Vec<_> = page.iter_from(63).collect();
689 assert_eq!(items, vec![63, 64, 78, 400, 511,]);
690
691 let items: Vec<_> = page.iter_from(256).collect();
692 assert_eq!(items, vec![400, 511]);
693
694 let items: Vec<_> = page.iter_from(511).collect();
695 assert_eq!(items, vec![511]);
696
697 let items: Vec<_> = page.iter_from(512).collect(); assert_eq!(items, vec![0, 1, 12, 13, 23, 63, 64, 78, 400, 511,]);
699
700 let items: Vec<_> = page.iter_from(515).collect(); assert_eq!(items, vec![12, 13, 23, 63, 64, 78, 400, 511,]);
702
703 let items: Vec<_> = page.iter_from(390).collect();
704 assert_eq!(items, vec![400, 511]);
705
706 let items: Vec<_> = page.iter_from(400).collect();
707 assert_eq!(items, vec![400, 511]);
708
709 let items: Vec<_> = page.iter_from(401).collect();
710 assert_eq!(items, vec![511]);
711 }
712
713 #[test]
714 fn page_iter_after_rev() {
715 let mut page = BitPage::new_zeroes();
716 let items: Vec<_> = page.iter_from(0).collect();
717 assert!(items.is_empty());
718 let items: Vec<_> = page.iter_from(256).collect();
719 assert!(items.is_empty());
720
721 page.insert(1);
722 page.insert(12);
723 page.insert(13);
724 page.insert(63);
725 page.insert(64);
726 page.insert(511);
727 page.insert(23);
728 page.insert(400);
729 page.insert(78);
730
731 let items: Vec<_> = page.iter_from(0).rev().collect();
732 assert_eq!(items, vec![511, 400, 78, 64, 63, 23, 13, 12, 1]);
733
734 page.insert(0);
735 let items: Vec<_> = page.iter_from(0).rev().collect();
736 assert_eq!(items, vec![511, 400, 78, 64, 63, 23, 13, 12, 1, 0]);
737
738 let items: Vec<_> = page.iter_from(1).rev().collect();
739 assert_eq!(items, vec![511, 400, 78, 64, 63, 23, 13, 12, 1]);
740
741 let items: Vec<_> = page.iter_from(63).rev().collect();
742 assert_eq!(items, vec![511, 400, 78, 64, 63]);
743
744 let items: Vec<_> = page.iter_from(256).rev().collect();
745 assert_eq!(items, vec![511, 400]);
746
747 let items: Vec<_> = page.iter_from(512).rev().collect();
748 assert_eq!(items, vec![511, 400, 78, 64, 63, 23, 13, 12, 1, 0]);
749
750 let items: Vec<_> = page.iter_from(390).rev().collect();
751 assert_eq!(items, vec![511, 400]);
752
753 let items: Vec<_> = page.iter_from(400).rev().collect();
754 assert_eq!(items, vec![511, 400]);
755
756 let items: Vec<_> = page.iter_from(401).rev().collect();
757 assert_eq!(items, vec![511]);
758 }
759
760 fn check_iter_ranges(ranges: Vec<RangeInclusive<u32>>) {
761 let mut page = BitPage::new_zeroes();
762 for range in ranges.iter() {
763 page.insert_range(*range.start(), *range.end());
764 }
765 let items: Vec<_> = page.iter_ranges().collect();
766 assert_eq!(items, ranges);
767 }
768
769 #[test]
770 fn iter_ranges() {
771 check_iter_ranges(vec![]);
773 check_iter_ranges(vec![0..=5]);
774 check_iter_ranges(vec![0..=0, 5..=5, 10..=10]);
775 check_iter_ranges(vec![0..=5, 12..=31]);
776 check_iter_ranges(vec![12..=31]);
777 check_iter_ranges(vec![71..=84]);
778 check_iter_ranges(vec![273..=284]);
779 check_iter_ranges(vec![0..=511]);
780
781 check_iter_ranges(vec![511..=511]);
783 check_iter_ranges(vec![500..=511]);
784 check_iter_ranges(vec![400..=511]);
785 check_iter_ranges(vec![0..=511]);
786
787 check_iter_ranges(vec![64..=127]);
789 check_iter_ranges(vec![64..=127, 129..=135]);
790 check_iter_ranges(vec![64..=135]);
791 check_iter_ranges(vec![71..=135]);
792 check_iter_ranges(vec![71..=435]);
793 }
794
795 #[test]
796 fn union() {
797 let a = BitPage::new_zeroes();
798 let b = BitPage::from_iter([32, 400]);
799 let c = BitPage::from_iter([32, 200]);
800 let d = BitPage::from_iter([32, 200, 400]);
801
802 assert_eq!(BitPage::union(&a, &b), b);
803 assert_eq!(BitPage::union(&b, &a), b);
804 assert_eq!(BitPage::union(&b, &c), d);
805 assert_eq!(BitPage::union(&c, &b), d);
806 }
807
808 #[test]
809 fn intersect() {
810 let a = BitPage::new_zeroes();
811 let b = BitPage::from_iter([32, 400]);
812 let c = BitPage::from_iter([32, 200]);
813 let d = BitPage::from_iter([32]);
814
815 assert_eq!(BitPage::intersect(&a, &b), a);
816 assert_eq!(BitPage::intersect(&b, &a), a);
817 assert_eq!(BitPage::intersect(&b, &c), d);
818 assert_eq!(BitPage::intersect(&c, &b), d);
819 }
820
821 #[test]
822 fn subtract() {
823 let a = BitPage::new_zeroes();
824 let b = BitPage::from_iter([32, 400]);
825 let c = BitPage::from_iter([32, 200]);
826 let d = BitPage::from_iter([400]);
827 let e = BitPage::from_iter([200]);
828
829 assert_eq!(BitPage::subtract(&a, &b), a);
830 assert_eq!(BitPage::subtract(&b, &a), b);
831 assert_eq!(BitPage::subtract(&b, &c), d);
832 assert_eq!(BitPage::subtract(&c, &b), e);
833 }
834
835 #[test]
836 fn hash_and_eq() {
837 let mut page1 = BitPage::new_zeroes();
838 let mut page2 = BitPage::new_zeroes();
839 let mut page3 = BitPage::new_zeroes();
840
841 page1.insert(12);
842 page1.insert(300);
843
844 page2.insert(300);
845 page2.insert(12);
846 page2.len();
847
848 page3.insert(300);
849 page3.insert(12);
850 page3.insert(23);
851
852 assert_eq!(page1, page2);
853 assert_ne!(page1, page3);
854 assert_ne!(page2, page3);
855
856 let set = HashSet::from([page1]);
857 assert!(set.contains(&page2));
858 assert!(!set.contains(&page3));
859 }
860
861 #[test]
862 fn intersects() {
863 macro_rules! assert_intersects {
864 ($lhs:path, $rhs:path, $expected:expr) => {
865 assert_eq!($lhs.intersects_set(&$rhs), $expected);
866 assert_eq!($rhs.intersects_set(&$lhs), $expected);
867 };
868 }
869
870 let a = BitPage::new_zeroes();
871 let b = BitPage::from_iter([32, 400]);
872 let c = BitPage::from_iter([400]);
873 let d = BitPage::from_iter([401]);
874
875 assert_intersects!(a, b, false);
876 assert_intersects!(a, c, false);
877 assert_intersects!(a, d, false);
878
879 assert_intersects!(b, c, true);
880 assert_intersects!(b, d, false);
881
882 assert_intersects!(c, d, false);
883 }
884
885 #[test]
886 fn is_subset() {
887 let a = BitPage::new_zeroes();
888 let b = BitPage::from_iter([32, 400]);
889 let c = BitPage::from_iter([32]);
890 let d = BitPage::from_iter([32, 200, 400]);
891 let e = BitPage::from_iter([32, 300]);
892 let f = BitPage::from_iter([32, 200, 300]);
893
894 assert!(a.is_subset(&a));
895 assert!(a.is_subset(&b));
896 assert!(a.is_subset(&c));
897 assert!(a.is_subset(&d));
898
899 assert!(b.is_subset(&b));
901 assert!(c.is_subset(&c));
902 assert!(d.is_subset(&d));
903 assert!(e.is_subset(&e));
904 assert!(f.is_subset(&f));
905
906 assert!(c.is_subset(&b));
908 assert!(c.is_subset(&d));
909 assert!(b.is_subset(&d));
910
911 assert!(!b.is_subset(&c));
913 assert!(!d.is_subset(&b));
914 assert!(!d.is_subset(&c));
915 assert!(!b.is_subset(&a));
916
917 assert!(!b.is_subset(&e));
919 assert!(!e.is_subset(&b));
920 assert!(!b.is_subset(&f));
921 }
922
923 #[test]
924 fn intersection_len() {
925 let a = BitPage::new_zeroes();
926 let b = BitPage::from_iter([32, 400]);
927 let c = BitPage::from_iter([32, 200]);
928 let d = BitPage::from_iter([32]);
929
930 assert_eq!(a.intersection_len(&b), 0);
931 assert_eq!(b.intersection_len(&a), 0);
932
933 assert_eq!(b.intersection_len(&c), 1);
934 assert_eq!(c.intersection_len(&b), 1);
935 assert_eq!(b.intersection_len(&d), 1);
936 assert_eq!(d.intersection_len(&b), 1);
937
938 assert_eq!(b.intersection_len(&b), 2);
939 }
940}