1use crate::errors::ParquetError;
19use crate::file::page_index::offset_index::PageLocation;
20use arrow_array::{Array, BooleanArray};
21use arrow_buffer::{BooleanBuffer, BooleanBufferBuilder};
22use arrow_select::filter::SlicesIterator;
23use std::cmp::Ordering;
24use std::collections::VecDeque;
25use std::ops::Range;
26use std::sync::Arc;
27
28#[derive(Clone, Copy, Debug, Eq, PartialEq)]
30pub enum RowSelectionPolicy {
31 Selectors,
33 Mask,
35 Auto {
37 threshold: usize,
39 },
40}
41
42impl Default for RowSelectionPolicy {
43 fn default() -> Self {
44 Self::Auto { threshold: 32 }
45 }
46}
47
48#[derive(Clone, Copy, Debug, Eq, PartialEq)]
53pub(crate) enum RowSelectionStrategy {
54 Selectors,
56 Mask,
58}
59
60#[derive(Debug, Clone, Copy, Eq, PartialEq)]
63pub struct RowSelector {
64 pub row_count: usize,
66
67 pub skip: bool,
69}
70
71impl RowSelector {
72 pub fn select(row_count: usize) -> Self {
74 Self {
75 row_count,
76 skip: false,
77 }
78 }
79
80 pub fn skip(row_count: usize) -> Self {
82 Self {
83 row_count,
84 skip: true,
85 }
86 }
87}
88
89#[derive(Debug, Clone, Default, Eq, PartialEq)]
136pub struct RowSelection {
137 selectors: Vec<RowSelector>,
138}
139
140impl RowSelection {
141 pub fn from_filters(filters: &[BooleanArray]) -> Self {
147 let mut next_offset = 0;
148 let total_rows = filters.iter().map(|x| x.len()).sum();
149
150 let iter = filters.iter().flat_map(|filter| {
151 let offset = next_offset;
152 next_offset += filter.len();
153 assert_eq!(filter.null_count(), 0);
154 SlicesIterator::new(filter).map(move |(start, end)| start + offset..end + offset)
155 });
156
157 Self::from_consecutive_ranges(iter, total_rows)
158 }
159
160 pub fn from_consecutive_ranges<I: Iterator<Item = Range<usize>>>(
162 ranges: I,
163 total_rows: usize,
164 ) -> Self {
165 let mut selectors: Vec<RowSelector> = Vec::with_capacity(ranges.size_hint().0);
166 let mut last_end = 0;
167 for range in ranges {
168 let len = range.end - range.start;
169 if len == 0 {
170 continue;
171 }
172
173 match range.start.cmp(&last_end) {
174 Ordering::Equal => match selectors.last_mut() {
175 Some(last) => last.row_count = last.row_count.checked_add(len).unwrap(),
176 None => selectors.push(RowSelector::select(len)),
177 },
178 Ordering::Greater => {
179 selectors.push(RowSelector::skip(range.start - last_end));
180 selectors.push(RowSelector::select(len))
181 }
182 Ordering::Less => panic!("out of order"),
183 }
184 last_end = range.end;
185 }
186
187 if last_end != total_rows {
188 selectors.push(RowSelector::skip(total_rows - last_end))
189 }
190
191 Self { selectors }
192 }
193
194 pub fn scan_ranges(&self, page_locations: &[PageLocation]) -> Vec<Range<u64>> {
202 let mut ranges: Vec<Range<u64>> = vec![];
203 let mut row_offset = 0;
204
205 let mut pages = page_locations.iter().peekable();
206 let mut selectors = self.selectors.iter().cloned();
207 let mut current_selector = selectors.next();
208 let mut current_page = pages.next();
209
210 let mut current_page_included = false;
211
212 while let Some((selector, page)) = current_selector.as_mut().zip(current_page) {
213 if !(selector.skip || current_page_included) {
214 let start = page.offset as u64;
215 let end = start + page.compressed_page_size as u64;
216 ranges.push(start..end);
217 current_page_included = true;
218 }
219
220 if let Some(next_page) = pages.peek() {
221 if row_offset + selector.row_count > next_page.first_row_index as usize {
222 let remaining_in_page = next_page.first_row_index as usize - row_offset;
223 selector.row_count -= remaining_in_page;
224 row_offset += remaining_in_page;
225 current_page = pages.next();
226 current_page_included = false;
227
228 continue;
229 } else {
230 if row_offset + selector.row_count == next_page.first_row_index as usize {
231 current_page = pages.next();
232 current_page_included = false;
233 }
234 row_offset += selector.row_count;
235 current_selector = selectors.next();
236 }
237 } else {
238 if !(selector.skip || current_page_included) {
239 let start = page.offset as u64;
240 let end = start + page.compressed_page_size as u64;
241 ranges.push(start..end);
242 }
243 current_selector = selectors.next()
244 }
245 }
246
247 ranges
248 }
249
250 pub(crate) fn row_ranges_for_selected_pages(
252 &self,
253 page_locations: &[PageLocation],
254 total_rows: usize,
255 ) -> Vec<Range<usize>> {
256 let mut selected_pages = self.scan_ranges(page_locations).into_iter().peekable();
257 let mut row_ranges = Vec::new();
258
259 for (idx, page) in page_locations.iter().enumerate() {
260 let Some(selected_page) = selected_pages.peek() else {
261 break;
262 };
263 if selected_page.start != page.offset as u64 {
264 continue;
265 }
266 selected_pages.next();
267
268 let end = page_locations
269 .get(idx + 1)
270 .map(|next| next.first_row_index as usize)
271 .unwrap_or(total_rows);
272 row_ranges.push(page.first_row_index as usize..end);
273 }
274
275 row_ranges
276 }
277
278 pub fn split_off(&mut self, row_count: usize) -> Self {
280 let mut total_count = 0;
281
282 let find = self.selectors.iter().position(|selector| {
284 total_count += selector.row_count;
285 total_count > row_count
286 });
287
288 let split_idx = match find {
289 Some(idx) => idx,
290 None => {
291 let selectors = std::mem::take(&mut self.selectors);
292 return Self { selectors };
293 }
294 };
295
296 let mut remaining = self.selectors.split_off(split_idx);
297
298 let next = remaining.first_mut().unwrap();
300 let overflow = total_count - row_count;
301
302 if next.row_count != overflow {
303 self.selectors.push(RowSelector {
304 row_count: next.row_count - overflow,
305 skip: next.skip,
306 })
307 }
308 next.row_count = overflow;
309
310 std::mem::swap(&mut remaining, &mut self.selectors);
311 Self {
312 selectors: remaining,
313 }
314 }
315 pub fn and_then(&self, other: &Self) -> Self {
338 let mut selectors = vec![];
339 let mut first = self.selectors.iter().cloned().peekable();
340 let mut second = other.selectors.iter().cloned().peekable();
341
342 let mut to_skip = 0;
343 while let Some(b) = second.peek_mut() {
344 let a = first
345 .peek_mut()
346 .expect("selection exceeds the number of selected rows");
347
348 if b.row_count == 0 {
349 second.next().unwrap();
350 continue;
351 }
352
353 if a.row_count == 0 {
354 first.next().unwrap();
355 continue;
356 }
357
358 if a.skip {
359 to_skip += a.row_count;
361 first.next().unwrap();
362 continue;
363 }
364
365 let skip = b.skip;
366 let to_process = a.row_count.min(b.row_count);
367
368 a.row_count -= to_process;
369 b.row_count -= to_process;
370
371 match skip {
372 true => to_skip += to_process,
373 false => {
374 if to_skip != 0 {
375 selectors.push(RowSelector::skip(to_skip));
376 to_skip = 0;
377 }
378 selectors.push(RowSelector::select(to_process))
379 }
380 }
381 }
382
383 for v in first {
384 if v.row_count != 0 {
385 assert!(
386 v.skip,
387 "selection contains less than the number of selected rows"
388 );
389 to_skip += v.row_count
390 }
391 }
392
393 if to_skip != 0 {
394 selectors.push(RowSelector::skip(to_skip));
395 }
396
397 Self { selectors }
398 }
399
400 pub fn intersection(&self, other: &Self) -> Self {
407 intersect_row_selections(&self.selectors, &other.selectors)
408 }
409
410 pub fn union(&self, other: &Self) -> Self {
417 union_row_selections(&self.selectors, &other.selectors)
418 }
419
420 pub fn selects_any(&self) -> bool {
422 self.selectors.iter().any(|x| !x.skip)
423 }
424
425 pub(crate) fn trim(mut self) -> Self {
427 while self.selectors.last().map(|x| x.skip).unwrap_or(false) {
428 self.selectors.pop();
429 }
430 self
431 }
432
433 pub(crate) fn offset(mut self, offset: usize) -> Self {
435 if offset == 0 {
436 return self;
437 }
438
439 let mut selected_count = 0;
440 let mut skipped_count = 0;
441
442 let find = self
444 .selectors
445 .iter()
446 .position(|selector| match selector.skip {
447 true => {
448 skipped_count += selector.row_count;
449 false
450 }
451 false => {
452 selected_count += selector.row_count;
453 selected_count > offset
454 }
455 });
456
457 let split_idx = match find {
458 Some(idx) => idx,
459 None => {
460 self.selectors.clear();
461 return self;
462 }
463 };
464
465 let mut selectors = Vec::with_capacity(self.selectors.len() - split_idx + 1);
466 selectors.push(RowSelector::skip(skipped_count + offset));
467 selectors.push(RowSelector::select(selected_count - offset));
468 selectors.extend_from_slice(&self.selectors[split_idx + 1..]);
469
470 Self { selectors }
471 }
472
473 pub(crate) fn limit(mut self, mut limit: usize) -> Self {
475 if limit == 0 {
476 self.selectors.clear();
477 }
478
479 for (idx, selection) in self.selectors.iter_mut().enumerate() {
480 if !selection.skip {
481 if selection.row_count >= limit {
482 selection.row_count = limit;
483 self.selectors.truncate(idx + 1);
484 break;
485 } else {
486 limit -= selection.row_count;
487 }
488 }
489 }
490 self
491 }
492
493 pub fn iter(&self) -> impl Iterator<Item = &RowSelector> {
496 self.selectors.iter()
497 }
498
499 pub fn row_count(&self) -> usize {
501 self.iter().filter(|s| !s.skip).map(|s| s.row_count).sum()
502 }
503
504 pub fn skipped_row_count(&self) -> usize {
506 self.iter().filter(|s| s.skip).map(|s| s.row_count).sum()
507 }
508
509 pub(crate) fn expand_to_batch_boundaries(&self, batch_size: usize, total_rows: usize) -> Self {
513 if batch_size == 0 {
514 return self.clone();
515 }
516
517 let mut expanded_ranges = Vec::new();
518 let mut row_offset = 0;
519
520 for selector in &self.selectors {
521 if selector.skip {
522 row_offset += selector.row_count;
523 } else {
524 let start = row_offset;
525 let end = row_offset + selector.row_count;
526
527 let expanded_start = (start / batch_size) * batch_size;
529 let expanded_end = end.div_ceil(batch_size) * batch_size;
531 let expanded_end = expanded_end.min(total_rows);
532
533 expanded_ranges.push(expanded_start..expanded_end);
534 row_offset += selector.row_count;
535 }
536 }
537
538 expanded_ranges.sort_by_key(|range| range.start);
540
541 let mut merged_ranges: Vec<Range<usize>> = Vec::new();
543 for range in expanded_ranges {
544 if let Some(last) = merged_ranges.last_mut() {
545 if range.start <= last.end {
546 last.end = last.end.max(range.end);
548 } else {
549 merged_ranges.push(range);
551 }
552 } else {
553 merged_ranges.push(range);
555 }
556 }
557
558 Self::from_consecutive_ranges(merged_ranges.into_iter(), total_rows)
559 }
560}
561
562impl From<Vec<RowSelector>> for RowSelection {
563 fn from(selectors: Vec<RowSelector>) -> Self {
564 selectors.into_iter().collect()
565 }
566}
567
568impl FromIterator<RowSelector> for RowSelection {
569 fn from_iter<T: IntoIterator<Item = RowSelector>>(iter: T) -> Self {
570 let iter = iter.into_iter();
571
572 let mut selectors = Vec::with_capacity(iter.size_hint().0);
574
575 let mut filtered = iter.filter(|x| x.row_count != 0);
576 if let Some(x) = filtered.next() {
577 selectors.push(x);
578 }
579
580 for s in filtered {
581 if s.row_count == 0 {
582 continue;
583 }
584
585 let last = selectors.last_mut().unwrap();
587 if last.skip == s.skip {
588 last.row_count = last.row_count.checked_add(s.row_count).unwrap();
589 } else {
590 selectors.push(s)
591 }
592 }
593
594 Self { selectors }
595 }
596}
597
598impl From<RowSelection> for Vec<RowSelector> {
599 fn from(r: RowSelection) -> Self {
600 r.selectors
601 }
602}
603
604impl From<RowSelection> for VecDeque<RowSelector> {
605 fn from(r: RowSelection) -> Self {
606 r.selectors.into()
607 }
608}
609
610fn intersect_row_selections(left: &[RowSelector], right: &[RowSelector]) -> RowSelection {
617 let mut l_iter = left.iter().copied().peekable();
618 let mut r_iter = right.iter().copied().peekable();
619
620 let iter = std::iter::from_fn(move || {
621 loop {
622 let l = l_iter.peek_mut();
623 let r = r_iter.peek_mut();
624
625 match (l, r) {
626 (Some(a), _) if a.row_count == 0 => {
627 l_iter.next().unwrap();
628 }
629 (_, Some(b)) if b.row_count == 0 => {
630 r_iter.next().unwrap();
631 }
632 (Some(l), Some(r)) => {
633 return match (l.skip, r.skip) {
634 (false, false) => {
636 if l.row_count < r.row_count {
637 r.row_count -= l.row_count;
638 l_iter.next()
639 } else {
640 l.row_count -= r.row_count;
641 r_iter.next()
642 }
643 }
644 _ => {
646 if l.row_count < r.row_count {
647 let skip = l.row_count;
648 r.row_count -= l.row_count;
649 l_iter.next();
650 Some(RowSelector::skip(skip))
651 } else {
652 let skip = r.row_count;
653 l.row_count -= skip;
654 r_iter.next();
655 Some(RowSelector::skip(skip))
656 }
657 }
658 };
659 }
660 (Some(_), None) => return l_iter.next(),
661 (None, Some(_)) => return r_iter.next(),
662 (None, None) => return None,
663 }
664 }
665 });
666
667 iter.collect()
668}
669
670fn union_row_selections(left: &[RowSelector], right: &[RowSelector]) -> RowSelection {
679 let mut l_iter = left.iter().copied().peekable();
680 let mut r_iter = right.iter().copied().peekable();
681
682 let iter = std::iter::from_fn(move || {
683 loop {
684 let l = l_iter.peek_mut();
685 let r = r_iter.peek_mut();
686
687 match (l, r) {
688 (Some(a), _) if a.row_count == 0 => {
689 l_iter.next().unwrap();
690 }
691 (_, Some(b)) if b.row_count == 0 => {
692 r_iter.next().unwrap();
693 }
694 (Some(l), Some(r)) => {
695 return match (l.skip, r.skip) {
696 (true, true) => {
698 if l.row_count < r.row_count {
699 let skip = l.row_count;
700 r.row_count -= l.row_count;
701 l_iter.next();
702 Some(RowSelector::skip(skip))
703 } else {
704 let skip = r.row_count;
705 l.row_count -= skip;
706 r_iter.next();
707 Some(RowSelector::skip(skip))
708 }
709 }
710 (false, true) => {
712 if l.row_count < r.row_count {
713 r.row_count -= l.row_count;
714 l_iter.next()
715 } else {
716 let r_row_count = r.row_count;
717 l.row_count -= r_row_count;
718 r_iter.next();
719 Some(RowSelector::select(r_row_count))
720 }
721 }
722 (true, false) => {
724 if l.row_count < r.row_count {
725 let l_row_count = l.row_count;
726 r.row_count -= l_row_count;
727 l_iter.next();
728 Some(RowSelector::select(l_row_count))
729 } else {
730 l.row_count -= r.row_count;
731 r_iter.next()
732 }
733 }
734 _ => {
736 if l.row_count < r.row_count {
737 r.row_count -= l.row_count;
738 l_iter.next()
739 } else {
740 l.row_count -= r.row_count;
741 r_iter.next()
742 }
743 }
744 };
745 }
746 (Some(_), None) => return l_iter.next(),
747 (None, Some(_)) => return r_iter.next(),
748 (None, None) => return None,
749 }
750 }
751 });
752
753 iter.collect()
754}
755
756#[derive(Debug)]
780pub struct MaskCursor {
781 mask: BooleanBuffer,
782 position: usize,
784 loaded_row_ranges: Option<Arc<LoadedRowRanges>>,
786}
787
788impl MaskCursor {
789 pub fn is_empty(&self) -> bool {
791 self.position >= self.mask.len()
792 }
793
794 pub fn next_mask_chunk(&mut self, batch_size: usize) -> Option<MaskChunk> {
796 if self.is_empty() {
797 return None;
798 }
799
800 Some(self.next_mask_chunk_non_empty(batch_size))
801 }
802
803 fn next_mask_chunk_non_empty(&mut self, batch_size: usize) -> MaskChunk {
805 debug_assert!(!self.is_empty());
806
807 let (initial_skip, chunk_rows, selected_rows, mask_start, end_position) = {
808 let mask = &self.mask;
809 let start_position = self.position;
810 let mut cursor = start_position;
811 let mut initial_skip = 0;
812
813 while cursor < mask.len() && !mask.value(cursor) {
814 initial_skip += 1;
815 cursor += 1;
816 }
817 debug_assert!(
818 cursor < mask.len(),
819 "ReadPlan must remove trailing skips from Mask selections"
820 );
821
822 let mask_start = cursor;
823 let mut chunk_rows = 0;
824 let mut selected_rows = 0;
825
826 while cursor < mask.len() && selected_rows < batch_size {
830 chunk_rows += 1;
831 if mask.value(cursor) {
832 selected_rows += 1;
833 }
834 cursor += 1;
835 }
836
837 (initial_skip, chunk_rows, selected_rows, mask_start, cursor)
838 };
839
840 self.position = end_position;
841
842 MaskChunk {
843 initial_skip,
844 chunk_rows,
845 selected_rows,
846 mask_start,
847 }
848 }
849
850 pub(crate) fn next_chunk(&mut self, batch_size: usize) -> Result<MaskChunk, ParquetError> {
856 debug_assert!(batch_size > 0);
857 debug_assert!(!self.is_empty());
858
859 if self.loaded_row_ranges.is_none() {
860 return Ok(self.next_mask_chunk_non_empty(batch_size));
861 }
862
863 let start_position = self.position;
864 let mut cursor = start_position;
865 while cursor < self.mask.len() && !self.mask.value(cursor) {
866 cursor += 1;
867 }
868
869 debug_assert!(
870 cursor < self.mask.len(),
871 "ReadPlan must remove trailing skips from Mask selections"
872 );
873
874 let loaded_range_end = self
875 .loaded_row_ranges
876 .as_ref()
877 .and_then(|ranges| ranges.end_containing(cursor))
878 .ok_or_else(|| {
879 ParquetError::General(format!(
880 "Internal Error: selected row {cursor} has no loaded page range"
881 ))
882 })?;
883
884 let mask_start = cursor;
885 let mut selected_rows = 0;
886 while cursor < loaded_range_end && cursor < self.mask.len() && selected_rows < batch_size {
887 if self.mask.value(cursor) {
888 selected_rows += 1;
889 }
890 cursor += 1;
891 }
892
893 self.position = cursor;
894 Ok(MaskChunk {
895 initial_skip: mask_start - start_position,
896 chunk_rows: cursor - mask_start,
897 selected_rows,
898 mask_start,
899 })
900 }
901
902 pub fn mask_values_for(&self, chunk: &MaskChunk) -> Result<BooleanArray, ParquetError> {
904 if chunk.mask_start.saturating_add(chunk.chunk_rows) > self.mask.len() {
905 return Err(ParquetError::General(
906 "Internal Error: MaskChunk exceeds mask length".to_string(),
907 ));
908 }
909 Ok(BooleanArray::from(
910 self.mask.slice(chunk.mask_start, chunk.chunk_rows),
911 ))
912 }
913}
914
915#[derive(Debug)]
920pub struct SelectorsCursor {
921 selectors: VecDeque<RowSelector>,
922 position: usize,
924}
925
926impl SelectorsCursor {
927 pub fn is_empty(&self) -> bool {
929 self.selectors.is_empty()
930 }
931
932 pub(crate) fn selectors_mut(&mut self) -> &mut VecDeque<RowSelector> {
933 &mut self.selectors
934 }
935
936 pub(crate) fn next_selector(&mut self) -> RowSelector {
938 let selector = self.selectors.pop_front().unwrap();
939 self.position += selector.row_count;
940 selector
941 }
942
943 pub(crate) fn return_selector(&mut self, selector: RowSelector) {
945 self.position = self.position.saturating_sub(selector.row_count);
946 self.selectors.push_front(selector);
947 }
948}
949
950#[derive(Debug)]
952pub struct MaskChunk {
953 pub initial_skip: usize,
955 pub chunk_rows: usize,
957 pub selected_rows: usize,
959 pub mask_start: usize,
961}
962
963#[derive(Clone, Debug)]
965pub(crate) struct LoadedRowRanges(Vec<Range<usize>>);
966
967impl LoadedRowRanges {
968 pub(crate) fn from_selection(selection: RowSelection) -> Self {
969 let selectors: Vec<RowSelector> = selection.into();
970 let mut position = 0;
971 let ranges = selectors
972 .into_iter()
973 .filter_map(|selector| {
974 let start = position;
975 position += selector.row_count;
976 (!selector.skip).then_some(start..position)
977 })
978 .collect();
979 Self(ranges)
980 }
981
982 fn end_containing(&self, row: usize) -> Option<usize> {
983 let idx = self.0.partition_point(|range| range.end <= row);
984 self.0
985 .get(idx)
986 .filter(|range| range.start <= row)
987 .map(|range| range.end)
988 }
989
990 #[cfg(test)]
991 pub(crate) fn ranges(&self) -> &[Range<usize>] {
992 &self.0
993 }
994}
995
996#[derive(Debug)]
1002pub enum RowSelectionCursor {
1003 All,
1005 Mask(MaskCursor),
1007 Selectors(SelectorsCursor),
1009}
1010
1011impl RowSelectionCursor {
1012 pub(crate) fn new_mask_from_selectors(
1014 selectors: Vec<RowSelector>,
1015 loaded_row_ranges: Option<Arc<LoadedRowRanges>>,
1016 ) -> Self {
1017 debug_assert!(
1018 selectors
1019 .last()
1020 .map(|selector| !selector.skip)
1021 .unwrap_or(true),
1022 "Mask selectors must not end with a skip"
1023 );
1024 Self::Mask(MaskCursor {
1025 mask: boolean_mask_from_selectors(&selectors),
1026 position: 0,
1027 loaded_row_ranges,
1028 })
1029 }
1030
1031 pub(crate) fn new_selectors(selectors: Vec<RowSelector>) -> Self {
1033 Self::Selectors(SelectorsCursor {
1034 selectors: selectors.into(),
1035 position: 0,
1036 })
1037 }
1038
1039 pub(crate) fn new_all() -> Self {
1041 Self::All
1042 }
1043}
1044
1045fn boolean_mask_from_selectors(selectors: &[RowSelector]) -> BooleanBuffer {
1046 let total_rows: usize = selectors.iter().map(|s| s.row_count).sum();
1047 let mut builder = BooleanBufferBuilder::new(total_rows);
1048 for selector in selectors {
1049 builder.append_n(selector.row_count, !selector.skip);
1050 }
1051 builder.finish()
1052}
1053
1054#[cfg(test)]
1055mod tests {
1056 use super::*;
1057 use rand::{Rng, rng};
1058
1059 #[test]
1060 fn test_from_filters() {
1061 let filters = vec![
1062 BooleanArray::from(vec![false, false, false, true, true, true, true]),
1063 BooleanArray::from(vec![true, true, false, false, true, true, true]),
1064 BooleanArray::from(vec![false, false, false, false]),
1065 BooleanArray::from(Vec::<bool>::new()),
1066 ];
1067
1068 let selection = RowSelection::from_filters(&filters[..1]);
1069 assert!(selection.selects_any());
1070 assert_eq!(
1071 selection.selectors,
1072 vec![RowSelector::skip(3), RowSelector::select(4)]
1073 );
1074
1075 let selection = RowSelection::from_filters(&filters[..2]);
1076 assert!(selection.selects_any());
1077 assert_eq!(
1078 selection.selectors,
1079 vec![
1080 RowSelector::skip(3),
1081 RowSelector::select(6),
1082 RowSelector::skip(2),
1083 RowSelector::select(3)
1084 ]
1085 );
1086
1087 let selection = RowSelection::from_filters(&filters);
1088 assert!(selection.selects_any());
1089 assert_eq!(
1090 selection.selectors,
1091 vec![
1092 RowSelector::skip(3),
1093 RowSelector::select(6),
1094 RowSelector::skip(2),
1095 RowSelector::select(3),
1096 RowSelector::skip(4)
1097 ]
1098 );
1099
1100 let selection = RowSelection::from_filters(&filters[2..3]);
1101 assert!(!selection.selects_any());
1102 assert_eq!(selection.selectors, vec![RowSelector::skip(4)]);
1103 }
1104
1105 #[test]
1106 fn test_split_off() {
1107 let mut selection = RowSelection::from(vec![
1108 RowSelector::skip(34),
1109 RowSelector::select(12),
1110 RowSelector::skip(3),
1111 RowSelector::select(35),
1112 ]);
1113
1114 let split = selection.split_off(34);
1115 assert_eq!(split.selectors, vec![RowSelector::skip(34)]);
1116 assert_eq!(
1117 selection.selectors,
1118 vec![
1119 RowSelector::select(12),
1120 RowSelector::skip(3),
1121 RowSelector::select(35)
1122 ]
1123 );
1124
1125 let split = selection.split_off(5);
1126 assert_eq!(split.selectors, vec![RowSelector::select(5)]);
1127 assert_eq!(
1128 selection.selectors,
1129 vec![
1130 RowSelector::select(7),
1131 RowSelector::skip(3),
1132 RowSelector::select(35)
1133 ]
1134 );
1135
1136 let split = selection.split_off(8);
1137 assert_eq!(
1138 split.selectors,
1139 vec![RowSelector::select(7), RowSelector::skip(1)]
1140 );
1141 assert_eq!(
1142 selection.selectors,
1143 vec![RowSelector::skip(2), RowSelector::select(35)]
1144 );
1145
1146 let split = selection.split_off(200);
1147 assert_eq!(
1148 split.selectors,
1149 vec![RowSelector::skip(2), RowSelector::select(35)]
1150 );
1151 assert!(selection.selectors.is_empty());
1152 }
1153
1154 #[test]
1155 fn test_offset() {
1156 let selection = RowSelection::from(vec![
1157 RowSelector::select(5),
1158 RowSelector::skip(23),
1159 RowSelector::select(7),
1160 RowSelector::skip(33),
1161 RowSelector::select(6),
1162 ]);
1163
1164 let selection = selection.offset(2);
1165 assert_eq!(
1166 selection.selectors,
1167 vec![
1168 RowSelector::skip(2),
1169 RowSelector::select(3),
1170 RowSelector::skip(23),
1171 RowSelector::select(7),
1172 RowSelector::skip(33),
1173 RowSelector::select(6),
1174 ]
1175 );
1176
1177 let selection = selection.offset(5);
1178 assert_eq!(
1179 selection.selectors,
1180 vec![
1181 RowSelector::skip(30),
1182 RowSelector::select(5),
1183 RowSelector::skip(33),
1184 RowSelector::select(6),
1185 ]
1186 );
1187
1188 let selection = selection.offset(3);
1189 assert_eq!(
1190 selection.selectors,
1191 vec![
1192 RowSelector::skip(33),
1193 RowSelector::select(2),
1194 RowSelector::skip(33),
1195 RowSelector::select(6),
1196 ]
1197 );
1198
1199 let selection = selection.offset(2);
1200 assert_eq!(
1201 selection.selectors,
1202 vec![RowSelector::skip(68), RowSelector::select(6),]
1203 );
1204
1205 let selection = selection.offset(3);
1206 assert_eq!(
1207 selection.selectors,
1208 vec![RowSelector::skip(71), RowSelector::select(3),]
1209 );
1210 }
1211
1212 #[test]
1213 fn test_and() {
1214 let mut a = RowSelection::from(vec![
1215 RowSelector::skip(12),
1216 RowSelector::select(23),
1217 RowSelector::skip(3),
1218 RowSelector::select(5),
1219 ]);
1220
1221 let b = RowSelection::from(vec![
1222 RowSelector::select(5),
1223 RowSelector::skip(4),
1224 RowSelector::select(15),
1225 RowSelector::skip(4),
1226 ]);
1227
1228 let mut expected = RowSelection::from(vec![
1229 RowSelector::skip(12),
1230 RowSelector::select(5),
1231 RowSelector::skip(4),
1232 RowSelector::select(14),
1233 RowSelector::skip(3),
1234 RowSelector::select(1),
1235 RowSelector::skip(4),
1236 ]);
1237
1238 assert_eq!(a.and_then(&b), expected);
1239
1240 a.split_off(7);
1241 expected.split_off(7);
1242 assert_eq!(a.and_then(&b), expected);
1243
1244 let a = RowSelection::from(vec![RowSelector::select(5), RowSelector::skip(3)]);
1245
1246 let b = RowSelection::from(vec![
1247 RowSelector::select(2),
1248 RowSelector::skip(1),
1249 RowSelector::select(1),
1250 RowSelector::skip(1),
1251 ]);
1252
1253 assert_eq!(
1254 a.and_then(&b).selectors,
1255 vec![
1256 RowSelector::select(2),
1257 RowSelector::skip(1),
1258 RowSelector::select(1),
1259 RowSelector::skip(4)
1260 ]
1261 );
1262 }
1263
1264 #[test]
1265 fn test_combine() {
1266 let a = vec![
1267 RowSelector::skip(3),
1268 RowSelector::skip(3),
1269 RowSelector::select(10),
1270 RowSelector::skip(4),
1271 ];
1272
1273 let b = vec![
1274 RowSelector::skip(3),
1275 RowSelector::skip(3),
1276 RowSelector::select(10),
1277 RowSelector::skip(4),
1278 RowSelector::skip(0),
1279 ];
1280
1281 let c = vec![
1282 RowSelector::skip(2),
1283 RowSelector::skip(4),
1284 RowSelector::select(3),
1285 RowSelector::select(3),
1286 RowSelector::select(4),
1287 RowSelector::skip(3),
1288 RowSelector::skip(1),
1289 RowSelector::skip(0),
1290 ];
1291
1292 let expected = RowSelection::from(vec![
1293 RowSelector::skip(6),
1294 RowSelector::select(10),
1295 RowSelector::skip(4),
1296 ]);
1297
1298 assert_eq!(RowSelection::from_iter(a), expected);
1299 assert_eq!(RowSelection::from_iter(b), expected);
1300 assert_eq!(RowSelection::from_iter(c), expected);
1301 }
1302
1303 #[test]
1304 fn test_combine_2elements() {
1305 let a = vec![RowSelector::select(10), RowSelector::select(5)];
1306 let a_expect = vec![RowSelector::select(15)];
1307 assert_eq!(RowSelection::from_iter(a).selectors, a_expect);
1308
1309 let b = vec![RowSelector::select(10), RowSelector::skip(5)];
1310 let b_expect = vec![RowSelector::select(10), RowSelector::skip(5)];
1311 assert_eq!(RowSelection::from_iter(b).selectors, b_expect);
1312
1313 let c = vec![RowSelector::skip(10), RowSelector::select(5)];
1314 let c_expect = vec![RowSelector::skip(10), RowSelector::select(5)];
1315 assert_eq!(RowSelection::from_iter(c).selectors, c_expect);
1316
1317 let d = vec![RowSelector::skip(10), RowSelector::skip(5)];
1318 let d_expect = vec![RowSelector::skip(15)];
1319 assert_eq!(RowSelection::from_iter(d).selectors, d_expect);
1320 }
1321
1322 #[test]
1323 fn test_from_one_and_empty() {
1324 let a = vec![RowSelector::select(10)];
1325 let selection1 = RowSelection::from(a.clone());
1326 assert_eq!(selection1.selectors, a);
1327
1328 let b = vec![];
1329 let selection1 = RowSelection::from(b.clone());
1330 assert_eq!(selection1.selectors, b)
1331 }
1332
1333 #[test]
1334 #[should_panic(expected = "selection exceeds the number of selected rows")]
1335 fn test_and_longer() {
1336 let a = RowSelection::from(vec![
1337 RowSelector::select(3),
1338 RowSelector::skip(33),
1339 RowSelector::select(3),
1340 RowSelector::skip(33),
1341 ]);
1342 let b = RowSelection::from(vec![RowSelector::select(36)]);
1343 a.and_then(&b);
1344 }
1345
1346 #[test]
1347 #[should_panic(expected = "selection contains less than the number of selected rows")]
1348 fn test_and_shorter() {
1349 let a = RowSelection::from(vec![
1350 RowSelector::select(3),
1351 RowSelector::skip(33),
1352 RowSelector::select(3),
1353 RowSelector::skip(33),
1354 ]);
1355 let b = RowSelection::from(vec![RowSelector::select(3)]);
1356 a.and_then(&b);
1357 }
1358
1359 #[test]
1360 fn test_intersect_row_selection_and_combine() {
1361 let a = vec![
1363 RowSelector::select(5),
1364 RowSelector::skip(4),
1365 RowSelector::select(1),
1366 ];
1367 let b = vec![
1368 RowSelector::select(8),
1369 RowSelector::skip(1),
1370 RowSelector::select(1),
1371 ];
1372
1373 let res = intersect_row_selections(&a, &b);
1374 assert_eq!(
1375 res.selectors,
1376 vec![
1377 RowSelector::select(5),
1378 RowSelector::skip(4),
1379 RowSelector::select(1),
1380 ],
1381 );
1382
1383 let a = vec![
1385 RowSelector::select(3),
1386 RowSelector::skip(33),
1387 RowSelector::select(3),
1388 RowSelector::skip(33),
1389 ];
1390 let b = vec![RowSelector::select(36), RowSelector::skip(36)];
1391 let res = intersect_row_selections(&a, &b);
1392 assert_eq!(
1393 res.selectors,
1394 vec![RowSelector::select(3), RowSelector::skip(69)]
1395 );
1396
1397 let a = vec![RowSelector::select(3), RowSelector::skip(7)];
1399 let b = vec![
1400 RowSelector::select(2),
1401 RowSelector::skip(2),
1402 RowSelector::select(2),
1403 RowSelector::skip(2),
1404 RowSelector::select(2),
1405 ];
1406 let res = intersect_row_selections(&a, &b);
1407 assert_eq!(
1408 res.selectors,
1409 vec![RowSelector::select(2), RowSelector::skip(8)]
1410 );
1411
1412 let a = vec![RowSelector::select(3), RowSelector::skip(7)];
1413 let b = vec![
1414 RowSelector::select(2),
1415 RowSelector::skip(2),
1416 RowSelector::select(2),
1417 RowSelector::skip(2),
1418 RowSelector::select(2),
1419 ];
1420 let res = intersect_row_selections(&a, &b);
1421 assert_eq!(
1422 res.selectors,
1423 vec![RowSelector::select(2), RowSelector::skip(8)]
1424 );
1425 }
1426
1427 #[test]
1428 fn test_and_fuzz() {
1429 let mut rand = rng();
1430 for _ in 0..100 {
1431 let a_len = rand.random_range(10..100);
1432 let a_bools: Vec<_> = (0..a_len).map(|_| rand.random_bool(0.2)).collect();
1433 let a = RowSelection::from_filters(&[BooleanArray::from(a_bools.clone())]);
1434
1435 let b_len: usize = a_bools.iter().map(|x| *x as usize).sum();
1436 let b_bools: Vec<_> = (0..b_len).map(|_| rand.random_bool(0.8)).collect();
1437 let b = RowSelection::from_filters(&[BooleanArray::from(b_bools.clone())]);
1438
1439 let mut expected_bools = vec![false; a_len];
1440
1441 let mut iter_b = b_bools.iter();
1442 for (idx, b) in a_bools.iter().enumerate() {
1443 if *b && *iter_b.next().unwrap() {
1444 expected_bools[idx] = true;
1445 }
1446 }
1447
1448 let expected = RowSelection::from_filters(&[BooleanArray::from(expected_bools)]);
1449
1450 let total_rows: usize = expected.selectors.iter().map(|s| s.row_count).sum();
1451 assert_eq!(a_len, total_rows);
1452
1453 assert_eq!(a.and_then(&b), expected);
1454 }
1455 }
1456
1457 #[test]
1458 fn test_iter() {
1459 let selectors = vec![
1462 RowSelector::select(3),
1463 RowSelector::skip(33),
1464 RowSelector::select(4),
1465 ];
1466
1467 let round_tripped = RowSelection::from(selectors.clone())
1468 .iter()
1469 .cloned()
1470 .collect::<Vec<_>>();
1471 assert_eq!(selectors, round_tripped);
1472 }
1473
1474 #[test]
1475 fn test_limit() {
1476 let selection = RowSelection::from(vec![RowSelector::select(10), RowSelector::skip(90)]);
1478 let limited = selection.limit(10);
1479 assert_eq!(RowSelection::from(vec![RowSelector::select(10)]), limited);
1480
1481 let selection = RowSelection::from(vec![
1482 RowSelector::select(10),
1483 RowSelector::skip(10),
1484 RowSelector::select(10),
1485 RowSelector::skip(10),
1486 RowSelector::select(10),
1487 ]);
1488
1489 let limited = selection.clone().limit(5);
1490 let expected = vec![RowSelector::select(5)];
1491 assert_eq!(limited.selectors, expected);
1492
1493 let limited = selection.clone().limit(15);
1494 let expected = vec![
1495 RowSelector::select(10),
1496 RowSelector::skip(10),
1497 RowSelector::select(5),
1498 ];
1499 assert_eq!(limited.selectors, expected);
1500
1501 let limited = selection.clone().limit(0);
1502 let expected = vec![];
1503 assert_eq!(limited.selectors, expected);
1504
1505 let limited = selection.clone().limit(30);
1506 let expected = vec![
1507 RowSelector::select(10),
1508 RowSelector::skip(10),
1509 RowSelector::select(10),
1510 RowSelector::skip(10),
1511 RowSelector::select(10),
1512 ];
1513 assert_eq!(limited.selectors, expected);
1514
1515 let limited = selection.limit(100);
1516 let expected = vec![
1517 RowSelector::select(10),
1518 RowSelector::skip(10),
1519 RowSelector::select(10),
1520 RowSelector::skip(10),
1521 RowSelector::select(10),
1522 ];
1523 assert_eq!(limited.selectors, expected);
1524 }
1525
1526 #[test]
1527 fn test_scan_ranges() {
1528 let index = vec![
1529 PageLocation {
1530 offset: 0,
1531 compressed_page_size: 10,
1532 first_row_index: 0,
1533 },
1534 PageLocation {
1535 offset: 10,
1536 compressed_page_size: 10,
1537 first_row_index: 10,
1538 },
1539 PageLocation {
1540 offset: 20,
1541 compressed_page_size: 10,
1542 first_row_index: 20,
1543 },
1544 PageLocation {
1545 offset: 30,
1546 compressed_page_size: 10,
1547 first_row_index: 30,
1548 },
1549 PageLocation {
1550 offset: 40,
1551 compressed_page_size: 10,
1552 first_row_index: 40,
1553 },
1554 PageLocation {
1555 offset: 50,
1556 compressed_page_size: 10,
1557 first_row_index: 50,
1558 },
1559 PageLocation {
1560 offset: 60,
1561 compressed_page_size: 10,
1562 first_row_index: 60,
1563 },
1564 ];
1565
1566 let selection = RowSelection::from(vec![
1567 RowSelector::skip(10),
1569 RowSelector::select(3),
1571 RowSelector::skip(3),
1572 RowSelector::select(4),
1573 RowSelector::skip(5),
1575 RowSelector::select(5),
1576 RowSelector::skip(12),
1578 RowSelector::select(12),
1580 RowSelector::skip(12),
1582 ]);
1583
1584 let ranges = selection.scan_ranges(&index);
1585
1586 assert_eq!(ranges, vec![10..20, 20..30, 40..50, 50..60]);
1588 assert_eq!(
1589 selection.row_ranges_for_selected_pages(&index, 70),
1590 vec![10..20, 20..30, 40..50, 50..60]
1591 );
1592
1593 let selection = RowSelection::from(vec![
1594 RowSelector::skip(10),
1596 RowSelector::select(3),
1598 RowSelector::skip(3),
1599 RowSelector::select(4),
1600 RowSelector::skip(5),
1602 RowSelector::select(5),
1603 RowSelector::skip(12),
1605 RowSelector::select(12),
1607 RowSelector::skip(1),
1608 RowSelector::select(8),
1610 ]);
1611
1612 let ranges = selection.scan_ranges(&index);
1613
1614 assert_eq!(ranges, vec![10..20, 20..30, 40..50, 50..60, 60..70]);
1616
1617 let selection = RowSelection::from(vec![
1618 RowSelector::skip(10),
1620 RowSelector::select(3),
1622 RowSelector::skip(3),
1623 RowSelector::select(4),
1624 RowSelector::skip(5),
1626 RowSelector::select(5),
1627 RowSelector::skip(12),
1629 RowSelector::select(12),
1631 RowSelector::skip(1),
1632 RowSelector::skip(8),
1634 RowSelector::select(4),
1636 ]);
1637
1638 let ranges = selection.scan_ranges(&index);
1639
1640 assert_eq!(ranges, vec![10..20, 20..30, 40..50, 50..60, 60..70]);
1642
1643 let selection = RowSelection::from(vec![
1644 RowSelector::skip(10),
1646 RowSelector::select(3),
1648 RowSelector::skip(3),
1649 RowSelector::select(4),
1650 RowSelector::skip(5),
1652 RowSelector::select(6),
1653 RowSelector::skip(50),
1655 ]);
1656
1657 let ranges = selection.scan_ranges(&index);
1658
1659 assert_eq!(ranges, vec![10..20, 20..30, 30..40]);
1661 }
1662
1663 #[test]
1664 fn test_loaded_mask_chunk_stops_at_trimmed_mask_end() {
1665 let loaded = LoadedRowRanges::from_selection(RowSelection::from_consecutive_ranges(
1666 std::iter::once(0..5),
1667 10,
1668 ));
1669 let RowSelectionCursor::Mask(mut cursor) = RowSelectionCursor::new_mask_from_selectors(
1670 vec![RowSelector::select(1)],
1671 Some(loaded.into()),
1672 ) else {
1673 unreachable!()
1674 };
1675
1676 let chunk = cursor.next_chunk(10).unwrap();
1677 assert_eq!(chunk.chunk_rows, 1);
1678 assert!(cursor.is_empty());
1679 }
1680
1681 #[test]
1682 fn test_next_mask_chunk_until_cursor_is_empty() {
1683 let RowSelectionCursor::Mask(mut cursor) = RowSelectionCursor::new_mask_from_selectors(
1684 vec![
1685 RowSelector::skip(2),
1686 RowSelector::select(2),
1687 RowSelector::skip(1),
1688 RowSelector::select(1),
1689 ],
1690 None,
1691 ) else {
1692 unreachable!()
1693 };
1694
1695 let first = cursor.next_mask_chunk(2).unwrap();
1696 assert_eq!(first.initial_skip, 2);
1697 assert_eq!(first.chunk_rows, 2);
1698 assert_eq!(first.selected_rows, 2);
1699
1700 let second = cursor.next_mask_chunk(2).unwrap();
1701 assert_eq!(second.initial_skip, 1);
1702 assert_eq!(second.chunk_rows, 1);
1703 assert_eq!(second.selected_rows, 1);
1704
1705 assert!(cursor.next_mask_chunk(2).is_none());
1706 }
1707
1708 #[test]
1709 fn test_from_ranges() {
1710 let ranges = [1..3, 4..6, 6..6, 8..8, 9..10];
1711 let selection = RowSelection::from_consecutive_ranges(ranges.into_iter(), 10);
1712 assert_eq!(
1713 selection.selectors,
1714 vec![
1715 RowSelector::skip(1),
1716 RowSelector::select(2),
1717 RowSelector::skip(1),
1718 RowSelector::select(2),
1719 RowSelector::skip(3),
1720 RowSelector::select(1)
1721 ]
1722 );
1723
1724 let out_of_order_ranges = [1..3, 8..10, 4..7];
1725 let result = std::panic::catch_unwind(|| {
1726 RowSelection::from_consecutive_ranges(out_of_order_ranges.into_iter(), 10)
1727 });
1728 assert!(result.is_err());
1729 }
1730
1731 #[test]
1732 fn test_empty_selector() {
1733 let selection = RowSelection::from(vec![
1734 RowSelector::skip(0),
1735 RowSelector::select(2),
1736 RowSelector::skip(0),
1737 RowSelector::select(2),
1738 ]);
1739 assert_eq!(selection.selectors, vec![RowSelector::select(4)]);
1740
1741 let selection = RowSelection::from(vec![
1742 RowSelector::select(0),
1743 RowSelector::skip(2),
1744 RowSelector::select(0),
1745 RowSelector::skip(2),
1746 ]);
1747 assert_eq!(selection.selectors, vec![RowSelector::skip(4)]);
1748 }
1749
1750 #[test]
1751 fn test_intersection() {
1752 let selection = RowSelection::from(vec![RowSelector::select(1048576)]);
1753 let result = selection.intersection(&selection);
1754 assert_eq!(result, selection);
1755
1756 let a = RowSelection::from(vec![
1757 RowSelector::skip(10),
1758 RowSelector::select(10),
1759 RowSelector::skip(10),
1760 RowSelector::select(20),
1761 ]);
1762
1763 let b = RowSelection::from(vec![
1764 RowSelector::skip(20),
1765 RowSelector::select(20),
1766 RowSelector::skip(10),
1767 ]);
1768
1769 let result = a.intersection(&b);
1770 assert_eq!(
1771 result.selectors,
1772 vec![
1773 RowSelector::skip(30),
1774 RowSelector::select(10),
1775 RowSelector::skip(10)
1776 ]
1777 );
1778 }
1779
1780 #[test]
1781 fn test_union() {
1782 let selection = RowSelection::from(vec![RowSelector::select(1048576)]);
1783 let result = selection.union(&selection);
1784 assert_eq!(result, selection);
1785
1786 let a = RowSelection::from(vec![
1788 RowSelector::skip(10),
1789 RowSelector::select(10),
1790 RowSelector::skip(10),
1791 RowSelector::select(20),
1792 ]);
1793
1794 let b = RowSelection::from(vec![
1796 RowSelector::skip(20),
1797 RowSelector::select(20),
1798 RowSelector::skip(10),
1799 RowSelector::select(10),
1800 RowSelector::skip(10),
1801 ]);
1802
1803 let result = a.union(&b);
1804
1805 assert_eq!(
1807 result.iter().collect::<Vec<_>>(),
1808 vec![
1809 &RowSelector::skip(10),
1810 &RowSelector::select(50),
1811 &RowSelector::skip(10),
1812 ]
1813 );
1814 }
1815
1816 #[test]
1817 fn test_row_count() {
1818 let selection = RowSelection::from(vec![
1819 RowSelector::skip(34),
1820 RowSelector::select(12),
1821 RowSelector::skip(3),
1822 RowSelector::select(35),
1823 ]);
1824
1825 assert_eq!(selection.row_count(), 12 + 35);
1826 assert_eq!(selection.skipped_row_count(), 34 + 3);
1827
1828 let selection = RowSelection::from(vec![RowSelector::select(12), RowSelector::select(35)]);
1829
1830 assert_eq!(selection.row_count(), 12 + 35);
1831 assert_eq!(selection.skipped_row_count(), 0);
1832
1833 let selection = RowSelection::from(vec![RowSelector::skip(34), RowSelector::skip(3)]);
1834
1835 assert_eq!(selection.row_count(), 0);
1836 assert_eq!(selection.skipped_row_count(), 34 + 3);
1837
1838 let selection = RowSelection::from(vec![]);
1839
1840 assert_eq!(selection.row_count(), 0);
1841 assert_eq!(selection.skipped_row_count(), 0);
1842 }
1843
1844 #[test]
1845 fn test_trim() {
1846 let selection = RowSelection::from(vec![
1847 RowSelector::skip(34),
1848 RowSelector::select(12),
1849 RowSelector::skip(3),
1850 RowSelector::select(35),
1851 ]);
1852
1853 let expected = vec![
1854 RowSelector::skip(34),
1855 RowSelector::select(12),
1856 RowSelector::skip(3),
1857 RowSelector::select(35),
1858 ];
1859
1860 assert_eq!(selection.trim().selectors, expected);
1861
1862 let selection = RowSelection::from(vec![
1863 RowSelector::skip(34),
1864 RowSelector::select(12),
1865 RowSelector::skip(3),
1866 ]);
1867
1868 let expected = vec![RowSelector::skip(34), RowSelector::select(12)];
1869
1870 assert_eq!(selection.trim().selectors, expected);
1871 }
1872}