1use deepsize::DeepSizeOf;
5
6use super::{RowAddrMask, RowAddrTreeMap, RowSetOps};
7
8#[derive(Clone, Debug, Default, DeepSizeOf)]
18pub struct NullableRowAddrSet {
19 selected: RowAddrTreeMap,
20 nulls: RowAddrTreeMap,
22}
23
24impl NullableRowAddrSet {
25 pub fn new(selected: RowAddrTreeMap, nulls: RowAddrTreeMap) -> Self {
30 Self { selected, nulls }
31 }
32
33 pub fn with_nulls(mut self, nulls: RowAddrTreeMap) -> Self {
34 self.nulls = nulls;
35 self
36 }
37
38 pub fn empty() -> Self {
40 Default::default()
41 }
42
43 pub fn len(&self) -> Option<u64> {
48 self.true_rows().len()
49 }
50
51 pub fn is_empty(&self) -> bool {
52 self.selected.is_empty()
53 }
54
55 pub fn selected(&self, row_id: u64) -> bool {
57 self.selected.contains(row_id) && !self.nulls.contains(row_id)
58 }
59
60 pub fn null_rows(&self) -> &RowAddrTreeMap {
62 &self.nulls
63 }
64
65 pub fn true_rows(&self) -> RowAddrTreeMap {
67 self.selected.clone() - self.nulls.clone()
68 }
69
70 pub fn union_all(selections: &[Self]) -> Self {
71 let true_rows = selections
72 .iter()
73 .map(|s| s.true_rows())
74 .collect::<Vec<RowAddrTreeMap>>();
75 let true_rows_refs = true_rows.iter().collect::<Vec<&RowAddrTreeMap>>();
76 let selected = RowAddrTreeMap::union_all(&true_rows_refs);
77 let nulls = RowAddrTreeMap::union_all(
78 &selections
79 .iter()
80 .map(|s| &s.nulls)
81 .collect::<Vec<&RowAddrTreeMap>>(),
82 );
83 let nulls = nulls - &selected;
85 Self { selected, nulls }
86 }
87}
88
89impl PartialEq for NullableRowAddrSet {
90 fn eq(&self, other: &Self) -> bool {
91 self.true_rows() == other.true_rows() && self.nulls == other.nulls
92 }
93}
94
95impl std::ops::BitAndAssign<&Self> for NullableRowAddrSet {
96 fn bitand_assign(&mut self, rhs: &Self) {
97 self.nulls = if self.nulls.is_empty() && rhs.nulls.is_empty() {
98 RowAddrTreeMap::new() } else {
100 (self.nulls.clone() & &rhs.nulls) | (self.nulls.clone() & &rhs.selected) | (rhs.nulls.clone() & &self.selected) };
104
105 self.selected &= &rhs.selected;
106 }
107}
108
109impl std::ops::BitOrAssign<&Self> for NullableRowAddrSet {
110 fn bitor_assign(&mut self, rhs: &Self) {
111 self.nulls = if self.nulls.is_empty() && rhs.nulls.is_empty() {
112 RowAddrTreeMap::new() } else {
114 let true_rows =
116 (self.selected.clone() - &self.nulls) | (rhs.selected.clone() - &rhs.nulls);
117 (self.nulls.clone() | &rhs.nulls) - true_rows
118 };
119
120 self.selected |= &rhs.selected;
121 }
122}
123
124#[derive(Clone, Debug)]
130pub enum NullableRowAddrMask {
131 AllowList(NullableRowAddrSet),
132 BlockList(NullableRowAddrSet),
133}
134
135impl NullableRowAddrMask {
136 pub fn selected(&self, row_id: u64) -> bool {
137 match self {
138 Self::AllowList(NullableRowAddrSet { selected, nulls }) => {
139 selected.contains(row_id) && !nulls.contains(row_id)
140 }
141 Self::BlockList(NullableRowAddrSet { selected, nulls }) => {
142 !selected.contains(row_id) && !nulls.contains(row_id)
143 }
144 }
145 }
146
147 pub fn drop_nulls(self) -> RowAddrMask {
148 match self {
149 Self::AllowList(NullableRowAddrSet { selected, nulls }) => {
150 RowAddrMask::AllowList(selected - nulls)
151 }
152 Self::BlockList(NullableRowAddrSet { selected, nulls }) => {
153 RowAddrMask::BlockList(selected | nulls)
154 }
155 }
156 }
157}
158
159impl std::ops::Not for NullableRowAddrMask {
160 type Output = Self;
161
162 fn not(self) -> Self::Output {
163 match self {
164 Self::AllowList(set) => Self::BlockList(set),
165 Self::BlockList(set) => Self::AllowList(set),
166 }
167 }
168}
169
170impl std::ops::BitAnd for NullableRowAddrMask {
171 type Output = Self;
172
173 fn bitand(self, rhs: Self) -> Self::Output {
174 match (self, rhs) {
179 (Self::AllowList(a), Self::AllowList(b)) => {
180 let nulls = if a.nulls.is_empty() && b.nulls.is_empty() {
181 RowAddrTreeMap::new() } else {
183 (a.nulls.clone() & &b.nulls) | (a.nulls & &b.selected) | (b.nulls & &a.selected) };
187 let selected = a.selected & b.selected;
188 Self::AllowList(NullableRowAddrSet { selected, nulls })
189 }
190 (Self::AllowList(allow), Self::BlockList(block))
191 | (Self::BlockList(block), Self::AllowList(allow)) => {
192 let nulls = if allow.nulls.is_empty() && block.nulls.is_empty() {
193 RowAddrTreeMap::new() } else {
195 (allow.nulls.clone() & &block.nulls) | (allow.nulls - &block.selected) | (block.nulls & &allow.selected) };
199 let selected = allow.selected - block.selected;
200 Self::AllowList(NullableRowAddrSet { selected, nulls })
201 }
202 (Self::BlockList(a), Self::BlockList(b)) => {
203 let nulls = if a.nulls.is_empty() && b.nulls.is_empty() {
204 RowAddrTreeMap::new() } else {
206 (a.nulls.clone() & &b.nulls) | (a.nulls - &b.selected) | (b.nulls - &a.selected) };
210 let selected = a.selected | b.selected;
211 Self::BlockList(NullableRowAddrSet { selected, nulls })
212 }
213 }
214 }
215}
216
217impl std::ops::BitOr for NullableRowAddrMask {
218 type Output = Self;
219
220 fn bitor(self, rhs: Self) -> Self::Output {
221 match (self, rhs) {
226 (Self::AllowList(a), Self::AllowList(b)) => {
227 let nulls = if a.nulls.is_empty() && b.nulls.is_empty() {
228 RowAddrTreeMap::new() } else {
230 let true_rows =
232 (a.selected.clone() - &a.nulls) | (b.selected.clone() - &b.nulls);
233 (a.nulls | b.nulls) - true_rows
234 };
235 let selected = (a.selected | b.selected) | &nulls;
236 Self::AllowList(NullableRowAddrSet { selected, nulls })
237 }
238 (Self::AllowList(allow), Self::BlockList(block))
239 | (Self::BlockList(block), Self::AllowList(allow)) => {
240 let allow_true = allow.selected.clone() - &allow.nulls;
241 let block_false = block.selected.clone() - &block.nulls;
242
243 let nulls = if allow.nulls.is_empty() && block.nulls.is_empty() {
244 RowAddrTreeMap::new() } else {
246 (allow.nulls & &block_false) | (block.nulls - &allow_true)
249 };
250 let selected = (block_false - &allow_true) | &nulls;
251 Self::BlockList(NullableRowAddrSet { selected, nulls })
252 }
253 (Self::BlockList(a), Self::BlockList(b)) => {
254 let a_false = a.selected.clone() - &a.nulls;
255 let b_false = b.selected.clone() - &b.nulls;
256 let nulls = if a.nulls.is_empty() && b.nulls.is_empty() {
257 RowAddrTreeMap::new() } else {
259 (a.nulls.clone() & &b_false)
261 | (b.nulls.clone() & &a_false)
262 | (a.nulls & &b.nulls)
263 };
264 let selected = (a_false & b_false) | &nulls;
265 Self::BlockList(NullableRowAddrSet { selected, nulls })
266 }
267 }
268 }
269}
270
271#[cfg(test)]
272mod tests {
273 use super::*;
274
275 fn rows(ids: &[u64]) -> RowAddrTreeMap {
276 RowAddrTreeMap::from_iter(ids)
277 }
278
279 fn nullable_set(selected: &[u64], nulls: &[u64]) -> NullableRowAddrSet {
280 NullableRowAddrSet::new(rows(selected), rows(nulls))
281 }
282
283 fn allow(selected: &[u64], nulls: &[u64]) -> NullableRowAddrMask {
284 NullableRowAddrMask::AllowList(nullable_set(selected, nulls))
285 }
286
287 fn block(selected: &[u64], nulls: &[u64]) -> NullableRowAddrMask {
288 NullableRowAddrMask::BlockList(nullable_set(selected, nulls))
289 }
290
291 fn assert_mask_selects(mask: &NullableRowAddrMask, selected: &[u64], not_selected: &[u64]) {
292 for &id in selected {
293 assert!(mask.selected(id), "Expected row {} to be selected", id);
294 }
295 for &id in not_selected {
296 assert!(!mask.selected(id), "Expected row {} to NOT be selected", id);
297 }
298 }
299
300 #[test]
301 fn test_not_with_nulls() {
302 let mask = allow(&[1, 2], &[2]);
307 let not_mask = !mask;
308
309 assert_mask_selects(¬_mask, &[0], &[1, 2]);
313 }
314
315 #[test]
316 fn test_and_with_nulls() {
317 let true_mask = allow(&[0, 1, 2, 3, 4], &[]);
321 let null_mask = allow(&[0, 1, 2, 3, 4], &[1, 3]);
322 let result = true_mask & null_mask.clone();
323
324 assert_mask_selects(&result, &[0, 2, 4], &[1, 3]);
326
327 let false_mask = block(&[0, 1, 2, 3, 4], &[]);
329 let result = false_mask & null_mask;
330
331 assert_mask_selects(&result, &[], &[0, 1, 2, 3, 4]);
333
334 let mask1 = allow(&[0, 1, 2], &[1]);
336 let mask2 = allow(&[0, 2, 3], &[2]);
337 let result = mask1 & mask2;
338
339 assert_mask_selects(&result, &[0], &[1, 2, 3]);
341 }
342
343 #[test]
344 fn test_or_with_nulls() {
345 let false_mask = block(&[0, 1, 2], &[]);
349 let null_mask = allow(&[0, 1, 2], &[1, 2]);
350 let result = false_mask | null_mask.clone();
351
352 assert_mask_selects(&result, &[0], &[1, 2]);
354
355 let true_mask = allow(&[0, 1, 2], &[]);
357 let result = true_mask | null_mask;
358
359 assert_mask_selects(&result, &[0, 1, 2], &[]);
361
362 let mask1 = block(&[0, 1, 2, 3], &[1, 2]);
364 let mask2 = block(&[0, 1, 2, 3], &[2, 3]);
365 let result = mask1 | mask2;
366
367 assert_mask_selects(&result, &[], &[0, 1, 2, 3]);
369 }
370
371 #[test]
372 fn test_or_allow_block_keeps_block_nulls() {
373 let allow_mask = allow(&[1], &[0]);
376 let block_mask = block(&[], &[0]);
377 let result = allow_mask | block_mask;
378
379 assert_mask_selects(&result, &[1], &[0]);
381 }
382
383 #[test]
384 fn test_or_allow_block_keeps_block_nulls_with_false_rows() {
385 let allow_mask = allow(&[2], &[]);
388 let block_mask = block(&[1], &[0]);
389 let result = allow_mask | block_mask;
390
391 assert_mask_selects(&result, &[2], &[0, 1]);
393 }
394
395 #[test]
396 fn test_or_block_block_true_overrides_null() {
397 let true_mask = block(&[], &[]);
399 let null_mask = block(&[], &[0]);
400 let result = true_mask | null_mask;
401
402 assert_mask_selects(&result, &[0], &[]);
404 }
405
406 #[test]
407 fn test_row_selection_bit_or() {
408 let left = nullable_set(&[1, 2, 3, 4], &[2, 4]);
410 let right = nullable_set(&[3, 4, 5, 6], &[4, 6, 7]);
412 let expected_true = rows(&[1, 3, 5]);
414 let expected_nulls = rows(&[2, 4, 6, 7]);
415
416 let mut result = left.clone();
417 result |= &right;
418 assert_eq!(&result.true_rows(), &expected_true);
419 assert_eq!(result.null_rows(), &expected_nulls);
420
421 let mut result = right.clone();
423 result |= &left;
424 assert_eq!(&result.true_rows(), &expected_true);
425 assert_eq!(result.null_rows(), &expected_nulls);
426 }
427
428 #[test]
429 fn test_row_selection_bit_and() {
430 let left = nullable_set(&[1, 2, 3, 4], &[2, 4]);
432 let right = nullable_set(&[3, 4, 5, 6], &[4, 6, 7]);
434 let expected_true = rows(&[3]);
436 let expected_nulls = rows(&[4]);
437
438 let mut result = left.clone();
439 result &= &right;
440 assert_eq!(&result.true_rows(), &expected_true);
441 assert_eq!(result.null_rows(), &expected_nulls);
442
443 let mut result = right.clone();
445 result &= &left;
446 assert_eq!(&result.true_rows(), &expected_true);
447 assert_eq!(result.null_rows(), &expected_nulls);
448 }
449
450 #[test]
451 fn test_union_all() {
452 let set1 = nullable_set(&[1, 2, 3, 4], &[4, 5, 6]);
455 let set2 = nullable_set(&[1, 4, 7, 8], &[2, 5, 8]);
457 let set3 = NullableRowAddrSet::empty();
458
459 let result = NullableRowAddrSet::union_all(&[set1, set2, set3]);
460
461 assert_eq!(&result.true_rows(), &rows(&[1, 2, 3, 4, 7]));
463 assert_eq!(result.null_rows(), &rows(&[5, 6, 8]));
464 }
465
466 #[test]
467 fn test_nullable_row_addr_set_with_nulls() {
468 let set = NullableRowAddrSet::new(rows(&[1, 2, 3]), RowAddrTreeMap::new());
469 let set_with_nulls = set.with_nulls(rows(&[2]));
470
471 assert!(set_with_nulls.selected(1) && set_with_nulls.selected(3));
472 assert!(!set_with_nulls.selected(2)); }
474
475 #[test]
476 fn test_nullable_row_addr_set_len_and_is_empty() {
477 let set = nullable_set(&[1, 2, 3, 4, 5], &[2, 4]);
478
479 assert_eq!(set.len(), Some(3)); assert!(!set.is_empty());
482
483 let empty_set = NullableRowAddrSet::empty();
484 assert!(empty_set.is_empty());
485 assert_eq!(empty_set.len(), Some(0));
486 }
487
488 #[test]
489 fn test_nullable_row_addr_set_selected() {
490 let set = nullable_set(&[1, 2, 3], &[2]);
491
492 assert!(set.selected(1) && set.selected(3));
494 assert!(!set.selected(2)); assert!(!set.selected(4)); }
497
498 #[test]
499 fn test_nullable_row_addr_set_partial_eq() {
500 let set1 = nullable_set(&[1, 2, 3], &[2]);
501 let set2 = nullable_set(&[1, 2, 3], &[2]);
502 let set3 = nullable_set(&[1, 3], &[3]);
504
505 assert_eq!(set1, set2);
506 assert_ne!(set1, set3); }
508
509 #[test]
510 fn test_nullable_row_addr_set_bitand_fast_path() {
511 let set1 = nullable_set(&[1, 2, 3], &[]);
513 let set2 = nullable_set(&[2, 3, 4], &[]);
514
515 let mut result = set1;
516 result &= &set2;
517
518 assert!(result.selected(2) && result.selected(3));
520 assert!(!result.selected(1) && !result.selected(4));
521 assert!(result.null_rows().is_empty());
522 }
523
524 #[test]
525 fn test_nullable_row_addr_set_bitor_fast_path() {
526 let set1 = nullable_set(&[1, 2], &[]);
528 let set2 = nullable_set(&[3, 4], &[]);
529
530 let mut result = set1;
531 result |= &set2;
532
533 for id in [1, 2, 3, 4] {
535 assert!(result.selected(id));
536 }
537 assert!(result.null_rows().is_empty());
538 }
539
540 #[test]
541 fn test_nullable_row_id_mask_drop_nulls() {
542 let allow_mask = allow(&[1, 2, 3, 4], &[2, 4]);
544 let dropped = allow_mask.drop_nulls();
545 assert!(dropped.selected(1) && dropped.selected(3));
547 assert!(!dropped.selected(2) && !dropped.selected(4));
548
549 let block_mask = block(&[1, 2], &[3]);
551 let dropped = block_mask.drop_nulls();
552 assert!(!dropped.selected(1) && !dropped.selected(2) && !dropped.selected(3));
554 assert!(dropped.selected(4) && dropped.selected(5));
555 }
556
557 #[test]
558 fn test_nullable_row_id_mask_not_blocklist() {
559 let block_mask = block(&[1, 2], &[2]);
560 let not_mask = !block_mask;
561
562 assert!(matches!(not_mask, NullableRowAddrMask::AllowList(_)));
564 }
565
566 #[test]
567 fn test_nullable_row_id_mask_bitand_allow_allow_fast_path() {
568 let mask1 = allow(&[1, 2, 3], &[]);
570 let mask2 = allow(&[2, 3, 4], &[]);
571
572 let result = mask1 & mask2;
573 assert_mask_selects(&result, &[2, 3], &[1, 4]);
574 }
575
576 #[test]
577 fn test_nullable_row_id_mask_bitand_allow_block() {
578 let allow_mask = allow(&[1, 2, 3, 4, 5], &[2]);
579 let block_mask = block(&[3, 4], &[4]);
580
581 let result = allow_mask & block_mask;
582 assert_mask_selects(&result, &[1, 5], &[2, 3, 4]);
586 }
587
588 #[test]
589 fn test_nullable_row_id_mask_bitand_allow_block_fast_path() {
590 let allow_mask = allow(&[1, 2, 3], &[]);
592 let block_mask = block(&[2], &[]);
593
594 let result = allow_mask & block_mask;
595 assert_mask_selects(&result, &[1, 3], &[2]);
596 }
597
598 #[test]
599 fn test_nullable_row_id_mask_bitand_block_block() {
600 let block1 = block(&[1, 2], &[2]);
601 let block2 = block(&[2, 3], &[3]);
602
603 let result = block1 & block2;
604 assert_mask_selects(&result, &[4], &[1, 2, 3]);
607 }
608
609 #[test]
610 fn test_nullable_row_id_mask_bitand_block_block_fast_path() {
611 let block1 = block(&[1], &[]);
613 let block2 = block(&[2], &[]);
614
615 let result = block1 & block2;
616 assert_mask_selects(&result, &[3], &[1, 2]);
617 }
618
619 #[test]
620 fn test_nullable_row_id_mask_bitor_allow_allow_fast_path() {
621 let mask1 = allow(&[1, 2], &[]);
623 let mask2 = allow(&[3, 4], &[]);
624
625 let result = mask1 | mask2;
626 assert_mask_selects(&result, &[1, 2, 3, 4], &[5]);
627 }
628
629 #[test]
630 fn test_nullable_row_id_mask_bitor_allow_block() {
631 let allow_mask = allow(&[1, 2, 3], &[2]);
632 let block_mask = block(&[1, 4], &[4]);
633
634 let result = allow_mask | block_mask;
635 assert_mask_selects(&result, &[1, 2, 3], &[]);
638 }
639
640 #[test]
641 fn test_nullable_row_id_mask_bitor_allow_block_fast_path() {
642 let allow_mask = allow(&[1], &[]);
644 let block_mask = block(&[2], &[]);
645
646 let result = allow_mask | block_mask;
647 assert_mask_selects(&result, &[1, 3], &[2]);
649 }
650
651 #[test]
652 fn test_nullable_row_id_mask_bitor_block_block_fast_path() {
653 let block1 = block(&[1, 2], &[]);
655 let block2 = block(&[2, 3], &[]);
656
657 let result = block1 | block2;
658 assert_mask_selects(&result, &[1, 3, 4], &[2]);
660 }
661}