1use std::collections::{BTreeMap, BTreeSet};
16use std::ops::Range;
17
18use index::inverted_index::search::index_apply::ApplyOutput;
19use itertools::Itertools;
20use parquet::arrow::arrow_reader::{RowSelection, RowSelector};
21
22#[derive(Debug, Clone, Default)]
24pub struct RowGroupSelection {
25 selection_in_rg: BTreeMap<usize, RowSelectionWithCount>,
27 row_count: usize,
29 selector_len: usize,
31}
32
33#[derive(Debug, Clone, Default)]
35struct RowSelectionWithCount {
36 selection: RowSelection,
38 row_count: usize,
40 selector_len: usize,
42}
43
44impl RowGroupSelection {
45 pub fn new(row_group_size: usize, total_row_count: usize) -> Self {
51 let mut selection_in_rg = BTreeMap::new();
52
53 let row_group_count = total_row_count.div_ceil(row_group_size);
54 for rg_id in 0..row_group_count {
55 let row_group_size = if rg_id == row_group_count - 1 {
57 total_row_count - (row_group_count - 1) * row_group_size
58 } else {
59 row_group_size
60 };
61
62 let selection = RowSelection::from(vec![RowSelector::select(row_group_size)]);
63 selection_in_rg.insert(
64 rg_id,
65 RowSelectionWithCount {
66 selection,
67 row_count: row_group_size,
68 selector_len: 1,
69 },
70 );
71 }
72
73 Self {
74 selection_in_rg,
75 row_count: total_row_count,
76 selector_len: row_group_count,
77 }
78 }
79
80 pub fn from_full_row_group_ids<I>(
85 row_group_ids: I,
86 row_group_size: usize,
87 total_row_count: usize,
88 ) -> Self
89 where
90 I: IntoIterator<Item = usize>,
91 {
92 if row_group_size == 0 || total_row_count == 0 {
93 return Self::default();
94 }
95
96 let row_group_count = total_row_count.div_ceil(row_group_size);
97 if row_group_count == 0 {
98 return Self::default();
99 }
100
101 let last_row_group_size = total_row_count - (row_group_count - 1) * row_group_size;
102
103 let mut selection_in_rg = BTreeMap::new();
104 let mut row_count = 0usize;
105 let mut selector_len = 0usize;
106
107 for rg_id in row_group_ids {
108 if rg_id >= row_group_count {
109 continue;
110 }
111
112 let rg_row_count = if rg_id == row_group_count - 1 {
113 last_row_group_size
114 } else {
115 row_group_size
116 };
117
118 let selection = RowSelection::from(vec![RowSelector::select(rg_row_count)]);
119 if selection_in_rg
120 .insert(
121 rg_id,
122 RowSelectionWithCount {
123 selection,
124 row_count: rg_row_count,
125 selector_len: 1,
126 },
127 )
128 .is_none()
129 {
130 row_count += rg_row_count;
131 selector_len += 1;
132 }
133 }
134
135 Self {
136 selection_in_rg,
137 row_count,
138 selector_len,
139 }
140 }
141
142 pub fn get(&self, rg_id: usize) -> Option<&RowSelection> {
146 self.selection_in_rg.get(&rg_id).map(|x| &x.selection)
147 }
148
149 pub fn from_inverted_index_apply_output(
163 row_group_size: usize,
164 num_row_groups: usize,
165 total_row_count: usize,
166 apply_output: ApplyOutput,
167 ) -> Option<Self> {
168 if apply_output.total_row_count != total_row_count {
169 return None;
170 }
171
172 let segment_row_count = apply_output.segment_row_count;
177 let row_group_ranges = apply_output
178 .matched_segment_ids
179 .iter_ones()
180 .flat_map(|seg_id| {
181 let begin_row_id = seg_id * segment_row_count;
183 let end_row_id = (begin_row_id + segment_row_count).min(total_row_count);
184
185 let mut cursor = begin_row_id;
187 std::iter::from_fn(move || {
188 if cursor >= end_row_id {
189 return None;
190 }
191 let row_group_id = cursor / row_group_size;
192 let rg_begin_row_id = cursor % row_group_size;
193 let rg_boundary = (row_group_id + 1) * row_group_size;
194 let chunk_end = end_row_id.min(rg_boundary);
195 let rg_end_row_id = rg_begin_row_id + (chunk_end - cursor);
196 cursor = chunk_end;
197 Some((row_group_id, rg_begin_row_id..rg_end_row_id))
198 })
199 });
200
201 let mut selected_row_count = 0;
203 let mut total_selector_len = 0;
204 let mut selection_in_rg = row_group_ranges
205 .chunk_by(|(row_group_id, _)| *row_group_id)
206 .into_iter()
207 .map(|(row_group_id, group)| {
208 let ranges = group.map(|(_, ranges)| ranges);
210 let selection = row_selection_from_row_ranges(ranges, row_group_size);
216 let row_count = selection.row_count();
217 let selector_len = selector_len(&selection);
218 selected_row_count += row_count;
219 total_selector_len += selector_len;
220 (
221 row_group_id,
222 RowSelectionWithCount {
223 selection,
224 row_count,
225 selector_len,
226 },
227 )
228 })
229 .collect::<BTreeMap<_, _>>();
230
231 Self::fill_missing_row_groups(&mut selection_in_rg, num_row_groups);
232
233 Some(Self {
234 selection_in_rg,
235 row_count: selected_row_count,
236 selector_len: total_selector_len,
237 })
238 }
239
240 pub fn from_row_ids(
252 row_ids: BTreeSet<u32>,
253 row_group_size: usize,
254 num_row_groups: usize,
255 ) -> Self {
256 let row_group_to_row_ids =
258 Self::group_row_ids_by_row_group(row_ids, row_group_size, num_row_groups);
259
260 let mut total_row_count = 0;
262 let mut total_selector_len = 0;
263 let mut selection_in_rg = row_group_to_row_ids
264 .into_iter()
265 .map(|(row_group_id, row_ids)| {
266 let selection =
267 row_selection_from_sorted_row_ids(row_ids.into_iter(), row_group_size);
268 let row_count = selection.row_count();
269 let selector_len = selector_len(&selection);
270 total_row_count += row_count;
271 total_selector_len += selector_len;
272 (
273 row_group_id,
274 RowSelectionWithCount {
275 selection,
276 row_count,
277 selector_len,
278 },
279 )
280 })
281 .collect::<BTreeMap<_, _>>();
282
283 Self::fill_missing_row_groups(&mut selection_in_rg, num_row_groups);
284
285 Self {
286 selection_in_rg,
287 row_count: total_row_count,
288 selector_len: total_selector_len,
289 }
290 }
291
292 pub fn from_row_ranges(
305 row_ranges: Vec<(usize, Vec<Range<usize>>)>,
306 row_group_size: usize,
307 ) -> Self {
308 let mut total_row_count = 0;
309 let mut total_selector_len = 0;
310 let selection_in_rg = row_ranges
311 .into_iter()
312 .map(|(row_group_id, ranges)| {
313 let selection = row_selection_from_row_ranges(ranges.into_iter(), row_group_size);
314 let row_count = selection.row_count();
315 let selector_len = selector_len(&selection);
316 total_row_count += row_count;
317 total_selector_len += selector_len;
318 (
319 row_group_id,
320 RowSelectionWithCount {
321 selection,
322 row_count,
323 selector_len,
324 },
325 )
326 })
327 .collect();
328
329 Self {
330 selection_in_rg,
331 row_count: total_row_count,
332 selector_len: total_selector_len,
333 }
334 }
335
336 fn group_row_ids_by_row_group(
346 row_ids: BTreeSet<u32>,
347 row_group_size: usize,
348 num_row_groups: usize,
349 ) -> Vec<(usize, Vec<usize>)> {
350 let est_rows_per_group = row_ids.len() / num_row_groups;
351 let mut row_group_to_row_ids: Vec<(usize, Vec<usize>)> = Vec::with_capacity(num_row_groups);
352
353 for row_id in row_ids {
354 let row_group_id = row_id as usize / row_group_size;
355 let row_id_in_group = row_id as usize % row_group_size;
356
357 if let Some((rg_id, row_ids)) = row_group_to_row_ids.last_mut()
358 && *rg_id == row_group_id
359 {
360 row_ids.push(row_id_in_group);
361 } else {
362 let mut row_ids = Vec::with_capacity(est_rows_per_group);
363 row_ids.push(row_id_in_group);
364 row_group_to_row_ids.push((row_group_id, row_ids));
365 }
366 }
367
368 row_group_to_row_ids
369 }
370
371 pub fn intersect(&self, other: &Self) -> Self {
373 let mut res = BTreeMap::new();
374 let mut total_row_count = 0;
375 let mut total_selector_len = 0;
376
377 for (rg_id, x) in other.selection_in_rg.iter() {
378 let Some(y) = self.selection_in_rg.get(rg_id) else {
379 continue;
380 };
381 let selection = intersect_row_selections(&x.selection, &y.selection);
382 let row_count = selection.row_count();
383 let selector_len = selector_len(&selection);
384 if row_count > 0 {
385 total_row_count += row_count;
386 total_selector_len += selector_len;
387 res.insert(
388 *rg_id,
389 RowSelectionWithCount {
390 selection,
391 row_count,
392 selector_len,
393 },
394 );
395 }
396 }
397
398 Self {
399 selection_in_rg: res,
400 row_count: total_row_count,
401 selector_len: total_selector_len,
402 }
403 }
404
405 pub fn row_group_count(&self) -> usize {
407 self.selection_in_rg.len()
408 }
409
410 pub fn row_count(&self) -> usize {
412 self.row_count
413 }
414
415 pub fn pop_first(&mut self) -> Option<(usize, RowSelection)> {
419 while let Some((
420 row_group_id,
421 RowSelectionWithCount {
422 selection,
423 row_count,
424 selector_len,
425 },
426 )) = self.selection_in_rg.pop_first()
427 {
428 if row_count > 0 {
429 self.row_count -= row_count;
430 self.selector_len -= selector_len;
431 return Some((row_group_id, selection));
432 }
433 }
434
435 None
436 }
437
438 pub fn remove_row_group(&mut self, row_group_id: usize) {
440 let Some(RowSelectionWithCount {
441 row_count,
442 selector_len,
443 ..
444 }) = self.selection_in_rg.remove(&row_group_id)
445 else {
446 return;
447 };
448 self.row_count -= row_count;
449 self.selector_len -= selector_len;
450 }
451
452 pub fn is_empty(&self) -> bool {
454 self.selection_in_rg.is_empty()
455 }
456
457 pub fn contains_row_group(&self, row_group_id: usize) -> bool {
459 self.selection_in_rg.contains_key(&row_group_id)
460 }
461
462 pub fn contains_non_empty_row_group(&self, row_group_id: usize) -> bool {
464 self.selection_in_rg
465 .get(&row_group_id)
466 .map(|r| r.row_count > 0)
467 .unwrap_or(false)
468 }
469
470 pub fn iter(&self) -> impl Iterator<Item = (&usize, &RowSelection)> {
472 self.selection_in_rg
473 .iter()
474 .map(|(row_group_id, x)| (row_group_id, &x.selection))
475 }
476
477 pub fn mem_usage(&self) -> usize {
479 self.selector_len * size_of::<RowSelector>()
480 + self.selection_in_rg.len() * size_of::<RowSelectionWithCount>()
481 }
482
483 pub fn concat(&mut self, other: &Self) {
487 for (rg_id, other_rs) in other.selection_in_rg.iter() {
488 if self.selection_in_rg.contains_key(rg_id) {
489 panic!("row group {} is already in `self`", rg_id);
490 }
491
492 self.selection_in_rg.insert(*rg_id, other_rs.clone());
493 self.row_count += other_rs.row_count;
494 self.selector_len += other_rs.selector_len;
495 }
496 }
497
498 fn fill_missing_row_groups(
501 selection_in_rg: &mut BTreeMap<usize, RowSelectionWithCount>,
502 num_row_groups: usize,
503 ) {
504 for rg_id in 0..num_row_groups {
505 selection_in_rg.entry(rg_id).or_default();
506 }
507 }
508}
509
510fn intersect_row_selections(left: &RowSelection, right: &RowSelection) -> RowSelection {
520 let mut l_iter = left.iter().copied().peekable();
521 let mut r_iter = right.iter().copied().peekable();
522
523 let iter = std::iter::from_fn(move || {
524 loop {
525 let l = l_iter.peek_mut();
526 let r = r_iter.peek_mut();
527
528 match (l, r) {
529 (Some(a), _) if a.row_count == 0 => {
530 l_iter.next().unwrap();
531 }
532 (_, Some(b)) if b.row_count == 0 => {
533 r_iter.next().unwrap();
534 }
535 (Some(l), Some(r)) => {
536 return match (l.skip, r.skip) {
537 (false, false) => {
539 if l.row_count < r.row_count {
540 r.row_count -= l.row_count;
541 l_iter.next()
542 } else {
543 l.row_count -= r.row_count;
544 r_iter.next()
545 }
546 }
547 _ => {
549 if l.row_count < r.row_count {
550 let skip = l.row_count;
551 r.row_count -= l.row_count;
552 l_iter.next();
553 Some(RowSelector::skip(skip))
554 } else {
555 let skip = r.row_count;
556 l.row_count -= skip;
557 r_iter.next();
558 Some(RowSelector::skip(skip))
559 }
560 }
561 };
562 }
563 (None, _) => return None,
564 (_, None) => return None,
565 }
566 }
567 });
568
569 iter.collect()
570}
571
572pub(crate) fn row_selection_from_row_ranges(
585 row_ranges: impl Iterator<Item = Range<usize>>,
586 total_row_count: usize,
587) -> RowSelection {
588 let (selectors, _) = build_selectors_from_row_ranges(row_ranges, total_row_count);
589 RowSelection::from(selectors)
590}
591
592fn build_selectors_from_row_ranges(
593 row_ranges: impl Iterator<Item = Range<usize>>,
594 total_row_count: usize,
595) -> (Vec<RowSelector>, usize) {
596 let mut selectors: Vec<RowSelector> = Vec::new();
597 let mut last_processed_end = 0;
598
599 for Range { start, end } in row_ranges {
600 let end = end.min(total_row_count);
601 if start > last_processed_end {
602 add_or_merge_selector(&mut selectors, start - last_processed_end, true);
603 }
604
605 add_or_merge_selector(&mut selectors, end - start, false);
606 last_processed_end = end;
607 }
608
609 (selectors, last_processed_end)
610}
611
612pub(crate) fn row_selection_from_sorted_row_ids(
617 row_ids: impl Iterator<Item = usize>,
618 total_row_count: usize,
619) -> RowSelection {
620 let mut selectors: Vec<RowSelector> = Vec::new();
621 let mut last_processed_end = 0;
622
623 for row_id in row_ids {
624 let start = row_id;
625 let end = start + 1;
626
627 if start > last_processed_end {
628 add_or_merge_selector(&mut selectors, start - last_processed_end, true);
629 }
630
631 add_or_merge_selector(&mut selectors, end - start, false);
632 last_processed_end = end;
633 }
634
635 if last_processed_end < total_row_count {
636 add_or_merge_selector(&mut selectors, total_row_count - last_processed_end, true);
637 }
638
639 RowSelection::from(selectors)
640}
641
642fn add_or_merge_selector(selectors: &mut Vec<RowSelector>, count: usize, is_skip: bool) {
645 if let Some(last) = selectors.last_mut() {
646 if last.skip == is_skip {
648 last.row_count += count;
649 return;
650 }
651 }
652 let new_selector = if is_skip {
654 RowSelector::skip(count)
655 } else {
656 RowSelector::select(count)
657 };
658 selectors.push(new_selector);
659}
660
661fn selector_len(selection: &RowSelection) -> usize {
663 selection.iter().size_hint().0
664}
665
666#[cfg(test)]
667#[allow(clippy::single_range_in_vec_init)]
668mod tests {
669 use index::bitmap::Bitmap;
670
671 use super::*;
672
673 #[test]
674 fn test_selector_len() {
675 let selection = RowSelection::from(vec![RowSelector::skip(5), RowSelector::select(5)]);
676 assert_eq!(selector_len(&selection), 2);
677
678 let selection = RowSelection::from(vec![
679 RowSelector::select(5),
680 RowSelector::skip(5),
681 RowSelector::select(5),
682 ]);
683 assert_eq!(selector_len(&selection), 3);
684
685 let selection = RowSelection::from(vec![]);
686 assert_eq!(selector_len(&selection), 0);
687 }
688
689 #[test]
690 fn test_single_contiguous_range() {
691 let selection = row_selection_from_row_ranges(Some(5..10).into_iter(), 10);
692 let expected = RowSelection::from(vec![RowSelector::skip(5), RowSelector::select(5)]);
693 assert_eq!(selection, expected);
694 }
695
696 #[test]
697 fn test_non_contiguous_ranges() {
698 let ranges = [1..3, 5..8];
699 let selection = row_selection_from_row_ranges(ranges.iter().cloned(), 10);
700 let expected = RowSelection::from(vec![
701 RowSelector::skip(1),
702 RowSelector::select(2),
703 RowSelector::skip(2),
704 RowSelector::select(3),
705 ]);
706 assert_eq!(selection, expected);
707 }
708
709 #[test]
710 fn test_empty_range() {
711 let ranges = [];
712 let selection = row_selection_from_row_ranges(ranges.iter().cloned(), 10);
713 let expected = RowSelection::from(vec![]);
714 assert_eq!(selection, expected);
715 }
716
717 #[test]
718 fn test_adjacent_ranges() {
719 let ranges = [1..2, 2..3];
720 let selection = row_selection_from_row_ranges(ranges.iter().cloned(), 10);
721 let expected = RowSelection::from(vec![RowSelector::skip(1), RowSelector::select(2)]);
722 assert_eq!(selection, expected);
723 }
724
725 #[test]
726 fn test_large_gap_between_ranges() {
727 let ranges = [1..2, 100..101];
728 let selection = row_selection_from_row_ranges(ranges.iter().cloned(), 10240);
729 let expected = RowSelection::from(vec![
730 RowSelector::skip(1),
731 RowSelector::select(1),
732 RowSelector::skip(98),
733 RowSelector::select(1),
734 ]);
735 assert_eq!(selection, expected);
736 }
737
738 fn apply_output(
739 matched: &[usize],
740 segment_row_count: usize,
741 total_row_count: usize,
742 ) -> ApplyOutput {
743 let mut matched_segment_ids = Bitmap::new_bitvec();
744 for &seg_id in matched {
745 matched_segment_ids.insert_range(seg_id..=seg_id);
746 }
747 ApplyOutput {
748 matched_segment_ids,
749 total_row_count,
750 segment_row_count,
751 }
752 }
753
754 #[test]
755 fn test_from_inverted_index_segment_within_row_group() {
756 let selection = RowGroupSelection::from_inverted_index_apply_output(
759 8,
760 2,
761 16,
762 apply_output(&[1, 2], 4, 16),
763 )
764 .unwrap();
765 assert_eq!(selection.row_count(), 8);
766 assert_eq!(
767 selection.get(0),
768 Some(&RowSelection::from(vec![
769 RowSelector::skip(4),
770 RowSelector::select(4),
771 ]))
772 );
773 assert_eq!(
774 selection.get(1),
775 Some(&RowSelection::from(vec![RowSelector::select(4)]))
776 );
777 }
778
779 #[test]
780 fn test_from_inverted_index_segment_crosses_row_group_boundary() {
781 let selection = RowGroupSelection::from_inverted_index_apply_output(
785 10,
786 2,
787 20,
788 apply_output(&[2], 4, 20),
789 )
790 .unwrap();
791 assert_eq!(selection.row_count(), 4);
792 assert_eq!(
793 selection.get(0),
794 Some(&RowSelection::from(vec![
795 RowSelector::skip(8),
796 RowSelector::select(2),
797 ]))
798 );
799 assert_eq!(
800 selection.get(1),
801 Some(&RowSelection::from(vec![RowSelector::select(2)]))
802 );
803 }
804
805 #[test]
806 fn test_from_inverted_index_last_segment_clamped_to_end() {
807 let selection = RowGroupSelection::from_inverted_index_apply_output(
810 10,
811 2,
812 18,
813 apply_output(&[4], 4, 18),
814 )
815 .unwrap();
816 assert_eq!(selection.row_count(), 2);
817 assert_eq!(selection.get(2), None);
818 assert_eq!(
820 selection.get(1),
821 Some(&RowSelection::from(vec![
822 RowSelector::skip(6),
823 RowSelector::select(2),
824 ]))
825 );
826 }
827
828 #[test]
829 fn test_from_inverted_index_rejects_mismatched_row_count() {
830 let selection = RowGroupSelection::from_inverted_index_apply_output(
831 10,
832 2,
833 20,
834 apply_output(&[0], 4, 16),
835 );
836 assert!(selection.is_none());
837 }
838
839 #[test]
840 fn test_range_end_over_total_row_count() {
841 let ranges = Some(1..10);
842 let selection = row_selection_from_row_ranges(ranges.into_iter(), 5);
843 let expected = RowSelection::from(vec![RowSelector::skip(1), RowSelector::select(4)]);
844 assert_eq!(selection, expected);
845 }
846
847 #[test]
848 fn test_row_ids_to_selection() {
849 let row_ids = [1, 3, 5, 7, 9].into_iter();
850 let selection = row_selection_from_sorted_row_ids(row_ids, 10);
851 let expected = RowSelection::from(vec![
852 RowSelector::skip(1),
853 RowSelector::select(1),
854 RowSelector::skip(1),
855 RowSelector::select(1),
856 RowSelector::skip(1),
857 RowSelector::select(1),
858 RowSelector::skip(1),
859 RowSelector::select(1),
860 RowSelector::skip(1),
861 RowSelector::select(1),
862 ]);
863 assert_eq!(selection, expected);
864 }
865
866 #[test]
867 fn test_row_ids_to_selection_full() {
868 let row_ids = 0..10;
869 let selection = row_selection_from_sorted_row_ids(row_ids, 10);
870 let expected = RowSelection::from(vec![RowSelector::select(10)]);
871 assert_eq!(selection, expected);
872 }
873
874 #[test]
875 fn test_row_ids_to_selection_empty() {
876 let selection = row_selection_from_sorted_row_ids(None.into_iter(), 10);
877 let expected = RowSelection::from(vec![RowSelector::skip(10)]);
878 assert_eq!(selection, expected);
879 }
880
881 #[test]
882 fn test_group_row_ids() {
883 let row_ids = [0, 1, 2, 5, 6, 7, 8, 12].into_iter().collect();
884 let row_group_size = 5;
885 let num_row_groups = 3;
886
887 let row_group_to_row_ids =
888 RowGroupSelection::group_row_ids_by_row_group(row_ids, row_group_size, num_row_groups);
889
890 assert_eq!(
891 row_group_to_row_ids,
892 vec![(0, vec![0, 1, 2]), (1, vec![0, 1, 2, 3]), (2, vec![2])]
893 );
894 }
895
896 #[test]
897 fn test_row_group_selection_new() {
898 let selection = RowGroupSelection::new(100, 250);
900 assert_eq!(selection.row_count(), 250);
901 assert_eq!(selection.row_group_count(), 3);
902
903 let row_selection = selection.get(0).unwrap();
905 assert_eq!(row_selection.row_count(), 100);
906
907 let row_selection = selection.get(1).unwrap();
908 assert_eq!(row_selection.row_count(), 100);
909
910 let row_selection = selection.get(2).unwrap();
911 assert_eq!(row_selection.row_count(), 50);
912
913 let selection = RowGroupSelection::new(100, 0);
915 assert_eq!(selection.row_count(), 0);
916 assert_eq!(selection.row_group_count(), 0);
917 assert!(selection.get(0).is_none());
918
919 let selection = RowGroupSelection::new(100, 50);
921 assert_eq!(selection.row_count(), 50);
922 assert_eq!(selection.row_group_count(), 1);
923
924 let row_selection = selection.get(0).unwrap();
925 assert_eq!(row_selection.row_count(), 50);
926
927 let selection = RowGroupSelection::new(100, 150);
929 assert_eq!(selection.row_count(), 150);
930 assert_eq!(selection.row_group_count(), 2);
931
932 let row_selection = selection.get(0).unwrap();
933 assert_eq!(row_selection.row_count(), 100);
934
935 let row_selection = selection.get(1).unwrap();
936 assert_eq!(row_selection.row_count(), 50);
937
938 let selection = RowGroupSelection::new(100, 101);
940 assert_eq!(selection.row_count(), 101);
941 assert_eq!(selection.row_group_count(), 2);
942
943 let row_selection = selection.get(0).unwrap();
944 assert_eq!(row_selection.row_count(), 100);
945
946 let row_selection = selection.get(1).unwrap();
947 assert_eq!(row_selection.row_count(), 1);
948 }
949
950 #[test]
951 fn test_from_full_row_group_ids_dedup_duplicates() {
952 let selection = RowGroupSelection::from_full_row_group_ids([0, 0, 2, 2], 10, 25);
953 assert_eq!(selection.row_group_count(), 2);
954 assert_eq!(selection.row_count(), 15);
955
956 assert_eq!(selection.get(0).unwrap().row_count(), 10);
957 assert_eq!(selection.get(2).unwrap().row_count(), 5);
958 }
959
960 #[test]
961 fn test_from_row_ids() {
962 let row_group_size = 100;
963 let num_row_groups = 3;
964
965 let row_ids: BTreeSet<u32> = vec![5, 15, 25, 35, 105, 115, 205, 215]
967 .into_iter()
968 .collect();
969 let selection = RowGroupSelection::from_row_ids(row_ids, row_group_size, num_row_groups);
970 assert_eq!(selection.row_count(), 8);
971 assert_eq!(selection.row_group_count(), 3);
972
973 let row_selection = selection.get(0).unwrap();
975 assert_eq!(row_selection.row_count(), 4); let row_selection = selection.get(1).unwrap();
978 assert_eq!(row_selection.row_count(), 2); let row_selection = selection.get(2).unwrap();
981 assert_eq!(row_selection.row_count(), 2); let empty_row_ids: BTreeSet<u32> = BTreeSet::new();
985 let selection =
986 RowGroupSelection::from_row_ids(empty_row_ids, row_group_size, num_row_groups);
987 assert_eq!(selection.row_count(), 0);
988 assert_eq!(selection.row_group_count(), 3);
989
990 let consecutive_row_ids: BTreeSet<u32> = vec![5, 6, 7, 8, 9].into_iter().collect();
992 let selection =
993 RowGroupSelection::from_row_ids(consecutive_row_ids, row_group_size, num_row_groups);
994 assert_eq!(selection.row_count(), 5);
995 assert_eq!(selection.row_group_count(), 3);
996
997 let row_selection = selection.get(0).unwrap();
998 assert_eq!(row_selection.row_count(), 5); let boundary_row_ids: BTreeSet<u32> = vec![0, 99, 100, 199, 200, 249].into_iter().collect();
1002 let selection =
1003 RowGroupSelection::from_row_ids(boundary_row_ids, row_group_size, num_row_groups);
1004 assert_eq!(selection.row_count(), 6);
1005 assert_eq!(selection.row_group_count(), 3);
1006
1007 let row_selection = selection.get(0).unwrap();
1008 assert_eq!(row_selection.row_count(), 2); let row_selection = selection.get(1).unwrap();
1011 assert_eq!(row_selection.row_count(), 2); let row_selection = selection.get(2).unwrap();
1014 assert_eq!(row_selection.row_count(), 2); let single_group_row_ids: BTreeSet<u32> = vec![5, 10, 15].into_iter().collect();
1018 let selection = RowGroupSelection::from_row_ids(single_group_row_ids, row_group_size, 1);
1019 assert_eq!(selection.row_count(), 3);
1020 assert_eq!(selection.row_group_count(), 1);
1021
1022 let row_selection = selection.get(0).unwrap();
1023 assert_eq!(row_selection.row_count(), 3); }
1025
1026 #[test]
1027 fn test_from_row_ranges() {
1028 let row_group_size = 100;
1029
1030 let ranges = vec![
1032 (0, vec![5..15, 25..35]), (1, vec![5..15]), (2, vec![0..5, 10..15]), ];
1036 let selection = RowGroupSelection::from_row_ranges(ranges, row_group_size);
1037 assert_eq!(selection.row_count(), 40);
1038 assert_eq!(selection.row_group_count(), 3);
1039
1040 let row_selection = selection.get(0).unwrap();
1042 assert_eq!(row_selection.row_count(), 20); let row_selection = selection.get(1).unwrap();
1045 assert_eq!(row_selection.row_count(), 10); let row_selection = selection.get(2).unwrap();
1048 assert_eq!(row_selection.row_count(), 10); let empty_ranges: Vec<(usize, Vec<Range<usize>>)> = vec![];
1052 let selection = RowGroupSelection::from_row_ranges(empty_ranges, row_group_size);
1053 assert_eq!(selection.row_count(), 0);
1054 assert_eq!(selection.row_group_count(), 0);
1055 assert!(selection.get(0).is_none());
1056
1057 let adjacent_ranges = vec![
1059 (0, vec![5..15, 15..25]), ];
1061 let selection = RowGroupSelection::from_row_ranges(adjacent_ranges, row_group_size);
1062 assert_eq!(selection.row_count(), 20);
1063 assert_eq!(selection.row_group_count(), 1);
1064
1065 let row_selection = selection.get(0).unwrap();
1066 assert_eq!(row_selection.row_count(), 20); let boundary_ranges = vec![
1070 (0, vec![0..10, 90..100]), (1, vec![0..100]), (2, vec![0..50]), ];
1074 let selection = RowGroupSelection::from_row_ranges(boundary_ranges, row_group_size);
1075 assert_eq!(selection.row_count(), 170);
1076 assert_eq!(selection.row_group_count(), 3);
1077
1078 let row_selection = selection.get(0).unwrap();
1079 assert_eq!(row_selection.row_count(), 20); let row_selection = selection.get(1).unwrap();
1082 assert_eq!(row_selection.row_count(), 100); let row_selection = selection.get(2).unwrap();
1085 assert_eq!(row_selection.row_count(), 50); let single_group_ranges = vec![
1089 (0, vec![0..50]), ];
1091 let selection = RowGroupSelection::from_row_ranges(single_group_ranges, row_group_size);
1092 assert_eq!(selection.row_count(), 50);
1093 assert_eq!(selection.row_group_count(), 1);
1094
1095 let row_selection = selection.get(0).unwrap();
1096 assert_eq!(row_selection.row_count(), 50); }
1098
1099 #[test]
1100 fn test_intersect() {
1101 let row_group_size = 100;
1102
1103 let ranges1 = vec![
1105 (0, vec![5..15, 25..35]), (1, vec![5..15]), ];
1108 let selection1 = RowGroupSelection::from_row_ranges(ranges1, row_group_size);
1109
1110 let ranges2 = vec![
1111 (0, vec![10..20]), (1, vec![10..20]), (2, vec![0..10]), ];
1115 let selection2 = RowGroupSelection::from_row_ranges(ranges2, row_group_size);
1116
1117 let intersection = selection1.intersect(&selection2);
1118 assert_eq!(intersection.row_count(), 10);
1119 assert_eq!(intersection.row_group_count(), 2);
1120
1121 let row_selection = intersection.get(0).unwrap();
1122 assert_eq!(row_selection.row_count(), 5); let row_selection = intersection.get(1).unwrap();
1125 assert_eq!(row_selection.row_count(), 5); let empty_ranges: Vec<(usize, Vec<Range<usize>>)> = vec![];
1129 let empty_selection = RowGroupSelection::from_row_ranges(empty_ranges, row_group_size);
1130 let intersection = selection1.intersect(&empty_selection);
1131 assert_eq!(intersection.row_count(), 0);
1132 assert_eq!(intersection.row_group_count(), 0);
1133 assert!(intersection.get(0).is_none());
1134
1135 let non_overlapping_ranges = vec![
1137 (3, vec![0..10]), ];
1139 let non_overlapping_selection =
1140 RowGroupSelection::from_row_ranges(non_overlapping_ranges, row_group_size);
1141 let intersection = selection1.intersect(&non_overlapping_selection);
1142 assert_eq!(intersection.row_count(), 0);
1143 assert_eq!(intersection.row_group_count(), 0);
1144 assert!(intersection.get(0).is_none());
1145
1146 let full_overlap_ranges1 = vec![
1148 (0, vec![0..50]), ];
1150 let full_overlap_ranges2 = vec![
1151 (0, vec![0..50]), ];
1153 let selection1 = RowGroupSelection::from_row_ranges(full_overlap_ranges1, row_group_size);
1154 let selection2 = RowGroupSelection::from_row_ranges(full_overlap_ranges2, row_group_size);
1155 let intersection = selection1.intersect(&selection2);
1156 assert_eq!(intersection.row_count(), 50);
1157 assert_eq!(intersection.row_group_count(), 1);
1158
1159 let row_selection = intersection.get(0).unwrap();
1160 assert_eq!(row_selection.row_count(), 50); let boundary_ranges1 = vec![
1164 (0, vec![0..10, 90..100]), (1, vec![0..100]), ];
1167 let boundary_ranges2 = vec![
1168 (0, vec![5..15, 95..100]), (1, vec![50..100]), ];
1171 let selection1 = RowGroupSelection::from_row_ranges(boundary_ranges1, row_group_size);
1172 let selection2 = RowGroupSelection::from_row_ranges(boundary_ranges2, row_group_size);
1173 let intersection = selection1.intersect(&selection2);
1174 assert_eq!(intersection.row_count(), 60);
1175 assert_eq!(intersection.row_group_count(), 2);
1176
1177 let row_selection = intersection.get(0).unwrap();
1178 assert_eq!(row_selection.row_count(), 10); let row_selection = intersection.get(1).unwrap();
1181 assert_eq!(row_selection.row_count(), 50); let complex_ranges1 = vec![
1185 (0, vec![5..15, 25..35, 45..55]), (1, vec![10..20, 30..40]), ];
1188 let complex_ranges2 = vec![
1189 (0, vec![10..20, 30..40, 50..60]), (1, vec![15..25, 35..45]), ];
1192 let selection1 = RowGroupSelection::from_row_ranges(complex_ranges1, row_group_size);
1193 let selection2 = RowGroupSelection::from_row_ranges(complex_ranges2, row_group_size);
1194 let intersection = selection1.intersect(&selection2);
1195 assert_eq!(intersection.row_count(), 25);
1196 assert_eq!(intersection.row_group_count(), 2);
1197
1198 let row_selection = intersection.get(0).unwrap();
1199 assert_eq!(row_selection.row_count(), 15); let row_selection = intersection.get(1).unwrap();
1202 assert_eq!(row_selection.row_count(), 10); let last_rg_ranges1 = vec![
1206 (2, vec![0..25, 30..40]), ];
1208 let last_rg_ranges2 = vec![
1209 (2, vec![20..30, 35..45]), ];
1211 let selection1 = RowGroupSelection::from_row_ranges(last_rg_ranges1, row_group_size);
1212 let selection2 = RowGroupSelection::from_row_ranges(last_rg_ranges2, row_group_size);
1213 let intersection = selection1.intersect(&selection2);
1214 assert_eq!(intersection.row_count(), 10);
1215 assert_eq!(intersection.row_group_count(), 1);
1216
1217 let row_selection = intersection.get(2).unwrap();
1218 assert_eq!(row_selection.row_count(), 10); let empty_ranges = vec![
1222 (0, vec![]), (1, vec![5..15]), ];
1225 let selection1 = RowGroupSelection::from_row_ranges(empty_ranges, row_group_size);
1226 let ranges2 = vec![
1227 (0, vec![5..15, 25..35]), (1, vec![5..15]), ];
1230 let selection2 = RowGroupSelection::from_row_ranges(ranges2, row_group_size);
1231 let intersection = selection1.intersect(&selection2);
1232 assert_eq!(intersection.row_count(), 10);
1233 assert_eq!(intersection.row_group_count(), 1);
1234
1235 let row_selection = intersection.get(1).unwrap();
1236 assert_eq!(row_selection.row_count(), 10); }
1238
1239 #[test]
1240 fn test_pop_first() {
1241 let row_group_size = 100;
1242 let ranges = vec![
1243 (0, vec![5..15]), (1, vec![5..15]), (2, vec![0..5]), ];
1247 let mut selection = RowGroupSelection::from_row_ranges(ranges, row_group_size);
1248
1249 let (rg_id, row_selection) = selection.pop_first().unwrap();
1251 assert_eq!(rg_id, 0);
1252 assert_eq!(row_selection.row_count(), 10); assert_eq!(selection.row_count(), 15);
1254 assert_eq!(selection.row_group_count(), 2);
1255
1256 let row_selection = selection.get(1).unwrap();
1258 assert_eq!(row_selection.row_count(), 10); let row_selection = selection.get(2).unwrap();
1261 assert_eq!(row_selection.row_count(), 5); let (rg_id, row_selection) = selection.pop_first().unwrap();
1265 assert_eq!(rg_id, 1);
1266 assert_eq!(row_selection.row_count(), 10); assert_eq!(selection.row_count(), 5);
1268 assert_eq!(selection.row_group_count(), 1);
1269
1270 let row_selection = selection.get(2).unwrap();
1272 assert_eq!(row_selection.row_count(), 5); let (rg_id, row_selection) = selection.pop_first().unwrap();
1276 assert_eq!(rg_id, 2);
1277 assert_eq!(row_selection.row_count(), 5); assert_eq!(selection.row_count(), 0);
1279 assert_eq!(selection.row_group_count(), 0);
1280 assert!(selection.is_empty());
1281
1282 let mut empty_selection = RowGroupSelection::from_row_ranges(vec![], row_group_size);
1284 assert!(empty_selection.pop_first().is_none());
1285 assert_eq!(empty_selection.row_count(), 0);
1286 assert_eq!(empty_selection.row_group_count(), 0);
1287 assert!(empty_selection.is_empty());
1288 }
1289
1290 #[test]
1291 fn test_remove_row_group() {
1292 let row_group_size = 100;
1293 let ranges = vec![
1294 (0, vec![5..15]), (1, vec![5..15]), (2, vec![0..5]), ];
1298 let mut selection = RowGroupSelection::from_row_ranges(ranges, row_group_size);
1299
1300 selection.remove_row_group(1);
1302 assert_eq!(selection.row_count(), 15);
1303 assert_eq!(selection.row_group_count(), 2);
1304 assert!(!selection.contains_row_group(1));
1305
1306 let row_selection = selection.get(0).unwrap();
1308 assert_eq!(row_selection.row_count(), 10); let row_selection = selection.get(2).unwrap();
1311 assert_eq!(row_selection.row_count(), 5); selection.remove_row_group(5);
1315 assert_eq!(selection.row_count(), 15);
1316 assert_eq!(selection.row_group_count(), 2);
1317
1318 selection.remove_row_group(0);
1320 assert_eq!(selection.row_count(), 5);
1321 assert_eq!(selection.row_group_count(), 1);
1322
1323 let row_selection = selection.get(2).unwrap();
1324 assert_eq!(row_selection.row_count(), 5); selection.remove_row_group(2);
1327 assert_eq!(selection.row_count(), 0);
1328 assert_eq!(selection.row_group_count(), 0);
1329 assert!(selection.is_empty());
1330
1331 let mut empty_selection = RowGroupSelection::from_row_ranges(vec![], row_group_size);
1333 empty_selection.remove_row_group(0);
1334 assert_eq!(empty_selection.row_count(), 0);
1335 assert_eq!(empty_selection.row_group_count(), 0);
1336 assert!(empty_selection.is_empty());
1337 }
1338
1339 #[test]
1340 fn test_contains_row_group() {
1341 let row_group_size = 100;
1342 let ranges = vec![
1343 (0, vec![5..15]), (1, vec![5..15]), ];
1346 let selection = RowGroupSelection::from_row_ranges(ranges, row_group_size);
1347
1348 assert!(selection.contains_row_group(0));
1349 assert!(selection.contains_row_group(1));
1350 assert!(!selection.contains_row_group(2));
1351
1352 let empty_selection = RowGroupSelection::from_row_ranges(vec![], row_group_size);
1354 assert!(!empty_selection.contains_row_group(0));
1355 }
1356
1357 #[test]
1358 fn test_concat() {
1359 let row_group_size = 100;
1360 let ranges1 = vec![
1361 (0, vec![5..15]), (1, vec![5..15]), ];
1364
1365 let ranges2 = vec![
1366 (2, vec![5..15]), (3, vec![5..15]), ];
1369
1370 let mut selection1 = RowGroupSelection::from_row_ranges(ranges1, row_group_size);
1371 let selection2 = RowGroupSelection::from_row_ranges(ranges2, row_group_size);
1372
1373 selection1.concat(&selection2);
1374 assert_eq!(selection1.row_count(), 40);
1375 assert_eq!(selection1.row_group_count(), 4);
1376 }
1377}