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 nulls = if allow.nulls.is_empty() && block.nulls.is_empty() {
241 RowAddrTreeMap::new() } else {
243 let allow_true = allow.selected.clone() - &allow.nulls;
245 ((allow.nulls | block.nulls) & block.selected.clone()) - allow_true
246 };
247 let selected = (block.selected - allow.selected) | &nulls;
248 Self::BlockList(NullableRowAddrSet { selected, nulls })
249 }
250 (Self::BlockList(a), Self::BlockList(b)) => {
251 let nulls = if a.nulls.is_empty() && b.nulls.is_empty() {
252 RowAddrTreeMap::new() } else {
254 let false_rows =
256 (a.selected.clone() - &a.nulls) & (b.selected.clone() - &b.nulls);
257 (a.nulls | &b.nulls) - false_rows
258 };
259 let selected = (a.selected & b.selected) | &nulls;
260 Self::BlockList(NullableRowAddrSet { selected, nulls })
261 }
262 }
263 }
264}
265
266#[cfg(test)]
267mod tests {
268 use super::*;
269
270 fn rows(ids: &[u64]) -> RowAddrTreeMap {
271 RowAddrTreeMap::from_iter(ids)
272 }
273
274 fn nullable_set(selected: &[u64], nulls: &[u64]) -> NullableRowAddrSet {
275 NullableRowAddrSet::new(rows(selected), rows(nulls))
276 }
277
278 fn allow(selected: &[u64], nulls: &[u64]) -> NullableRowAddrMask {
279 NullableRowAddrMask::AllowList(nullable_set(selected, nulls))
280 }
281
282 fn block(selected: &[u64], nulls: &[u64]) -> NullableRowAddrMask {
283 NullableRowAddrMask::BlockList(nullable_set(selected, nulls))
284 }
285
286 fn assert_mask_selects(mask: &NullableRowAddrMask, selected: &[u64], not_selected: &[u64]) {
287 for &id in selected {
288 assert!(mask.selected(id), "Expected row {} to be selected", id);
289 }
290 for &id in not_selected {
291 assert!(!mask.selected(id), "Expected row {} to NOT be selected", id);
292 }
293 }
294
295 #[test]
296 fn test_not_with_nulls() {
297 let mask = allow(&[1, 2], &[2]);
302 let not_mask = !mask;
303
304 assert_mask_selects(¬_mask, &[0], &[1, 2]);
308 }
309
310 #[test]
311 fn test_and_with_nulls() {
312 let true_mask = allow(&[0, 1, 2, 3, 4], &[]);
316 let null_mask = allow(&[0, 1, 2, 3, 4], &[1, 3]);
317 let result = true_mask & null_mask.clone();
318
319 assert_mask_selects(&result, &[0, 2, 4], &[1, 3]);
321
322 let false_mask = block(&[0, 1, 2, 3, 4], &[]);
324 let result = false_mask & null_mask;
325
326 assert_mask_selects(&result, &[], &[0, 1, 2, 3, 4]);
328
329 let mask1 = allow(&[0, 1, 2], &[1]);
331 let mask2 = allow(&[0, 2, 3], &[2]);
332 let result = mask1 & mask2;
333
334 assert_mask_selects(&result, &[0], &[1, 2, 3]);
336 }
337
338 #[test]
339 fn test_or_with_nulls() {
340 let false_mask = block(&[0, 1, 2], &[]);
344 let null_mask = allow(&[0, 1, 2], &[1, 2]);
345 let result = false_mask | null_mask.clone();
346
347 assert_mask_selects(&result, &[0], &[1, 2]);
349
350 let true_mask = allow(&[0, 1, 2], &[]);
352 let result = true_mask | null_mask;
353
354 assert_mask_selects(&result, &[0, 1, 2], &[]);
356
357 let mask1 = block(&[0, 1, 2, 3], &[1, 2]);
359 let mask2 = block(&[0, 1, 2, 3], &[2, 3]);
360 let result = mask1 | mask2;
361
362 assert_mask_selects(&result, &[], &[0, 1, 2, 3]);
364 }
365
366 #[test]
367 fn test_row_selection_bit_or() {
368 let left = nullable_set(&[1, 2, 3, 4], &[2, 4]);
370 let right = nullable_set(&[3, 4, 5, 6], &[4, 6, 7]);
372 let expected_true = rows(&[1, 3, 5]);
374 let expected_nulls = rows(&[2, 4, 6, 7]);
375
376 let mut result = left.clone();
377 result |= &right;
378 assert_eq!(&result.true_rows(), &expected_true);
379 assert_eq!(result.null_rows(), &expected_nulls);
380
381 let mut result = right.clone();
383 result |= &left;
384 assert_eq!(&result.true_rows(), &expected_true);
385 assert_eq!(result.null_rows(), &expected_nulls);
386 }
387
388 #[test]
389 fn test_row_selection_bit_and() {
390 let left = nullable_set(&[1, 2, 3, 4], &[2, 4]);
392 let right = nullable_set(&[3, 4, 5, 6], &[4, 6, 7]);
394 let expected_true = rows(&[3]);
396 let expected_nulls = rows(&[4]);
397
398 let mut result = left.clone();
399 result &= &right;
400 assert_eq!(&result.true_rows(), &expected_true);
401 assert_eq!(result.null_rows(), &expected_nulls);
402
403 let mut result = right.clone();
405 result &= &left;
406 assert_eq!(&result.true_rows(), &expected_true);
407 assert_eq!(result.null_rows(), &expected_nulls);
408 }
409
410 #[test]
411 fn test_union_all() {
412 let set1 = nullable_set(&[1, 2, 3, 4], &[4, 5, 6]);
415 let set2 = nullable_set(&[1, 4, 7, 8], &[2, 5, 8]);
417 let set3 = NullableRowAddrSet::empty();
418
419 let result = NullableRowAddrSet::union_all(&[set1, set2, set3]);
420
421 assert_eq!(&result.true_rows(), &rows(&[1, 2, 3, 4, 7]));
423 assert_eq!(result.null_rows(), &rows(&[5, 6, 8]));
424 }
425
426 #[test]
427 fn test_nullable_row_addr_set_with_nulls() {
428 let set = NullableRowAddrSet::new(rows(&[1, 2, 3]), RowAddrTreeMap::new());
429 let set_with_nulls = set.with_nulls(rows(&[2]));
430
431 assert!(set_with_nulls.selected(1) && set_with_nulls.selected(3));
432 assert!(!set_with_nulls.selected(2)); }
434
435 #[test]
436 fn test_nullable_row_addr_set_len_and_is_empty() {
437 let set = nullable_set(&[1, 2, 3, 4, 5], &[2, 4]);
438
439 assert_eq!(set.len(), Some(3)); assert!(!set.is_empty());
442
443 let empty_set = NullableRowAddrSet::empty();
444 assert!(empty_set.is_empty());
445 assert_eq!(empty_set.len(), Some(0));
446 }
447
448 #[test]
449 fn test_nullable_row_addr_set_selected() {
450 let set = nullable_set(&[1, 2, 3], &[2]);
451
452 assert!(set.selected(1) && set.selected(3));
454 assert!(!set.selected(2)); assert!(!set.selected(4)); }
457
458 #[test]
459 fn test_nullable_row_addr_set_partial_eq() {
460 let set1 = nullable_set(&[1, 2, 3], &[2]);
461 let set2 = nullable_set(&[1, 2, 3], &[2]);
462 let set3 = nullable_set(&[1, 3], &[3]);
464
465 assert_eq!(set1, set2);
466 assert_ne!(set1, set3); }
468
469 #[test]
470 fn test_nullable_row_addr_set_bitand_fast_path() {
471 let set1 = nullable_set(&[1, 2, 3], &[]);
473 let set2 = nullable_set(&[2, 3, 4], &[]);
474
475 let mut result = set1;
476 result &= &set2;
477
478 assert!(result.selected(2) && result.selected(3));
480 assert!(!result.selected(1) && !result.selected(4));
481 assert!(result.null_rows().is_empty());
482 }
483
484 #[test]
485 fn test_nullable_row_addr_set_bitor_fast_path() {
486 let set1 = nullable_set(&[1, 2], &[]);
488 let set2 = nullable_set(&[3, 4], &[]);
489
490 let mut result = set1;
491 result |= &set2;
492
493 for id in [1, 2, 3, 4] {
495 assert!(result.selected(id));
496 }
497 assert!(result.null_rows().is_empty());
498 }
499
500 #[test]
501 fn test_nullable_row_id_mask_drop_nulls() {
502 let allow_mask = allow(&[1, 2, 3, 4], &[2, 4]);
504 let dropped = allow_mask.drop_nulls();
505 assert!(dropped.selected(1) && dropped.selected(3));
507 assert!(!dropped.selected(2) && !dropped.selected(4));
508
509 let block_mask = block(&[1, 2], &[3]);
511 let dropped = block_mask.drop_nulls();
512 assert!(!dropped.selected(1) && !dropped.selected(2) && !dropped.selected(3));
514 assert!(dropped.selected(4) && dropped.selected(5));
515 }
516
517 #[test]
518 fn test_nullable_row_id_mask_not_blocklist() {
519 let block_mask = block(&[1, 2], &[2]);
520 let not_mask = !block_mask;
521
522 assert!(matches!(not_mask, NullableRowAddrMask::AllowList(_)));
524 }
525
526 #[test]
527 fn test_nullable_row_id_mask_bitand_allow_allow_fast_path() {
528 let mask1 = allow(&[1, 2, 3], &[]);
530 let mask2 = allow(&[2, 3, 4], &[]);
531
532 let result = mask1 & mask2;
533 assert_mask_selects(&result, &[2, 3], &[1, 4]);
534 }
535
536 #[test]
537 fn test_nullable_row_id_mask_bitand_allow_block() {
538 let allow_mask = allow(&[1, 2, 3, 4, 5], &[2]);
539 let block_mask = block(&[3, 4], &[4]);
540
541 let result = allow_mask & block_mask;
542 assert_mask_selects(&result, &[1, 5], &[2, 3, 4]);
546 }
547
548 #[test]
549 fn test_nullable_row_id_mask_bitand_allow_block_fast_path() {
550 let allow_mask = allow(&[1, 2, 3], &[]);
552 let block_mask = block(&[2], &[]);
553
554 let result = allow_mask & block_mask;
555 assert_mask_selects(&result, &[1, 3], &[2]);
556 }
557
558 #[test]
559 fn test_nullable_row_id_mask_bitand_block_block() {
560 let block1 = block(&[1, 2], &[2]);
561 let block2 = block(&[2, 3], &[3]);
562
563 let result = block1 & block2;
564 assert_mask_selects(&result, &[4], &[1, 2, 3]);
567 }
568
569 #[test]
570 fn test_nullable_row_id_mask_bitand_block_block_fast_path() {
571 let block1 = block(&[1], &[]);
573 let block2 = block(&[2], &[]);
574
575 let result = block1 & block2;
576 assert_mask_selects(&result, &[3], &[1, 2]);
577 }
578
579 #[test]
580 fn test_nullable_row_id_mask_bitor_allow_allow_fast_path() {
581 let mask1 = allow(&[1, 2], &[]);
583 let mask2 = allow(&[3, 4], &[]);
584
585 let result = mask1 | mask2;
586 assert_mask_selects(&result, &[1, 2, 3, 4], &[5]);
587 }
588
589 #[test]
590 fn test_nullable_row_id_mask_bitor_allow_block() {
591 let allow_mask = allow(&[1, 2, 3], &[2]);
592 let block_mask = block(&[1, 4], &[4]);
593
594 let result = allow_mask | block_mask;
595 assert_mask_selects(&result, &[1, 2, 3], &[]);
598 }
599
600 #[test]
601 fn test_nullable_row_id_mask_bitor_allow_block_fast_path() {
602 let allow_mask = allow(&[1], &[]);
604 let block_mask = block(&[2], &[]);
605
606 let result = allow_mask | block_mask;
607 assert_mask_selects(&result, &[1, 3], &[2]);
609 }
610
611 #[test]
612 fn test_nullable_row_id_mask_bitor_block_block_fast_path() {
613 let block1 = block(&[1, 2], &[]);
615 let block2 = block(&[2, 3], &[]);
616
617 let result = block1 | block2;
618 assert_mask_selects(&result, &[1, 3, 4], &[2]);
620 }
621}