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