1use std::ops::{Range, RangeInclusive};
15mod bitmap;
19mod encoded_array;
20mod index;
21pub mod segment;
22mod serde;
23pub mod version;
24
25use lance_core::deepsize::DeepSizeOf;
26pub use index::FragmentRowIdIndex;
28pub use index::RowIdIndex;
29use lance_core::{Error, Result};
30use lance_io::ReadBatchParams;
31use lance_select::{RowAddrMask, RowAddrTreeMap, RowSetOps};
32pub use serde::{read_row_ids, write_row_ids};
33
34use crate::utils::LanceIteratorExtension;
35use segment::{SegmentCursorState, U64Segment};
36use tracing::instrument;
37
38#[derive(Debug, Clone, DeepSizeOf, PartialEq, Eq, Default)]
51pub struct RowIdSequence(Vec<U64Segment>);
52
53#[derive(Debug, Default)]
58pub(crate) struct RowIdSequenceCursor {
59 segment_idx: usize,
60 rows_passed: usize,
61 segment_len: Option<usize>,
62 segment_cursor: SegmentCursorState,
63 last_index: Option<usize>,
64}
65
66impl RowIdSequenceCursor {
67 fn advance_segment(&mut self) {
68 self.rows_passed += self.segment_len.unwrap_or_default();
69 self.segment_idx += 1;
70 self.segment_len = None;
71 self.segment_cursor = SegmentCursorState::default();
72 }
73
74 fn get(&mut self, sequence: &RowIdSequence, index: usize) -> Option<u64> {
75 if index < self.rows_passed || self.last_index.is_some_and(|last| index < last) {
76 *self = Self::default();
77 }
78 self.last_index = Some(index);
79
80 loop {
81 let segment = sequence.0.get(self.segment_idx)?;
82 let segment_len = *self.segment_len.get_or_insert_with(|| segment.len());
83 let local_index = index - self.rows_passed;
84 if local_index < segment_len {
85 return self.segment_cursor.get(segment, local_index);
86 }
87 self.advance_segment();
88 }
89 }
90
91 fn extend_range(
92 &mut self,
93 sequence: &RowIdSequence,
94 selection: Range<usize>,
95 row_ids: &mut Vec<u64>,
96 ) {
97 if selection.is_empty() {
98 return;
99 }
100 if selection.start < self.rows_passed
101 || self.last_index.is_some_and(|last| selection.start < last)
102 {
103 *self = Self::default();
104 }
105 self.last_index = Some(selection.end - 1);
106
107 let mut index = selection.start;
108 while index < selection.end {
109 let Some(segment) = sequence.0.get(self.segment_idx) else {
110 break;
111 };
112 let segment_len = *self.segment_len.get_or_insert_with(|| segment.len());
113 let local_start = index - self.rows_passed;
114 if local_start >= segment_len {
115 self.advance_segment();
116 continue;
117 }
118
119 let count = (selection.end - index).min(segment_len - local_start);
120 let local_end = local_start + count;
121 self.segment_cursor
122 .extend_range(segment, local_start..local_end, row_ids);
123 index += count;
124 if local_end == segment_len {
125 self.advance_segment();
126 }
127 }
128 }
129
130 fn extend_dense_range(
133 &mut self,
134 sequence: &RowIdSequence,
135 selection: Range<usize>,
136 row_ids: &mut Vec<u64>,
137 ) {
138 if selection.is_empty() {
139 return;
140 }
141 if selection.start < self.rows_passed
142 || self.last_index.is_some_and(|last| selection.start < last)
143 {
144 *self = Self::default();
145 }
146 self.last_index = Some(selection.end - 1);
147
148 let mut index = selection.start;
149 while index < selection.end {
150 let Some(segment) = sequence.0.get(self.segment_idx) else {
151 break;
152 };
153 let segment_len = *self.segment_len.get_or_insert_with(|| segment.len());
154 let local_start = index - self.rows_passed;
155 if local_start >= segment_len {
156 self.advance_segment();
157 continue;
158 }
159
160 let count = (selection.end - index).min(segment_len - local_start);
161 let local_end = local_start + count;
162 self.segment_cursor
163 .extend_dense_range(segment, local_start..local_end, row_ids);
164 index += count;
165 if local_end == segment_len {
166 self.advance_segment();
167 }
168 }
169 }
170}
171
172impl std::fmt::Display for RowIdSequence {
173 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
174 let mut iter = self.iter();
175 let mut first_10 = Vec::new();
176 let mut last_10 = Vec::new();
177 for row_id in iter.by_ref() {
178 first_10.push(row_id);
179 if first_10.len() > 10 {
180 break;
181 }
182 }
183
184 while let Some(row_id) = iter.next_back() {
185 last_10.push(row_id);
186 if last_10.len() > 10 {
187 break;
188 }
189 }
190 last_10.reverse();
191
192 let theres_more = iter.next().is_some();
193
194 write!(f, "[")?;
195 for row_id in first_10 {
196 write!(f, "{}", row_id)?;
197 }
198 if theres_more {
199 write!(f, ", ...")?;
200 }
201 for row_id in last_10 {
202 write!(f, ", {}", row_id)?;
203 }
204 write!(f, "]")
205 }
206}
207
208impl From<Range<u64>> for RowIdSequence {
209 fn from(range: Range<u64>) -> Self {
210 Self(vec![U64Segment::Range(range)])
211 }
212}
213
214impl From<&[u64]> for RowIdSequence {
215 fn from(row_ids: &[u64]) -> Self {
216 Self(vec![U64Segment::from_slice(row_ids)])
217 }
218}
219
220fn find_duplicate(row_ids: &[u64]) -> Option<u64> {
225 if row_ids.windows(2).all(|pair| pair[0] < pair[1]) {
226 return None;
227 }
228 let mut sorted = row_ids.to_vec();
229 sorted.sort_unstable();
230 sorted
231 .windows(2)
232 .find(|pair| pair[0] == pair[1])
233 .map(|pair| pair[0])
234}
235
236impl RowIdSequence {
237 pub fn new() -> Self {
238 Self::default()
239 }
240
241 pub fn try_from_iter(row_ids: impl IntoIterator<Item = u64>) -> Result<Self> {
252 let row_ids: Vec<u64> = row_ids.into_iter().collect();
253 if row_ids.is_empty() {
254 return Ok(Self::new());
255 }
256 if let Some(duplicate) = find_duplicate(&row_ids) {
257 return Err(Error::invalid_input(format!(
258 "Row ids must be unique, but row id {} appears more than once in the sequence of {} row ids",
259 duplicate,
260 row_ids.len()
261 )));
262 }
263 Ok(Self(vec![U64Segment::from_iter(row_ids)]))
264 }
265
266 pub fn iter(&self) -> impl DoubleEndedIterator<Item = u64> + '_ {
267 self.0.iter().flat_map(|segment| segment.iter())
268 }
269
270 pub fn len(&self) -> u64 {
271 self.0.iter().map(|segment| segment.len() as u64).sum()
272 }
273
274 pub fn is_empty(&self) -> bool {
275 self.0.is_empty()
276 }
277
278 pub fn row_id_range(&self) -> Option<RangeInclusive<u64>> {
286 let min = self
287 .0
288 .iter()
289 .filter_map(|s| s.range())
290 .map(|r| *r.start())
291 .min()?;
292 let max = self
293 .0
294 .iter()
295 .filter_map(|s| s.range())
296 .map(|r| *r.end())
297 .max()?;
298 Some(min..=max)
299 }
300
301 pub fn extend(&mut self, other: Self) {
303 if let (Some(U64Segment::Range(range1)), Some(U64Segment::Range(range2))) =
307 (self.0.last(), other.0.first())
308 && range1.end == range2.start
309 {
310 let new_range = U64Segment::Range(range1.start..range2.end);
311 self.0.pop();
312 self.0.push(new_range);
313 self.0.extend(other.0.into_iter().skip(1));
314 return;
315 }
316 self.0.extend(other.0);
318 }
319
320 pub fn delete(&mut self, row_ids: impl IntoIterator<Item = u64>) {
322 let (row_ids, offsets) = self.find_ids(row_ids);
324
325 let capacity = self.0.capacity();
326 let old_segments = std::mem::replace(&mut self.0, Vec::with_capacity(capacity));
327 let mut remaining_segments = old_segments.as_slice();
328
329 for (segment_idx, range) in offsets {
330 let segments_handled = old_segments.len() - remaining_segments.len();
331 let segments_to_add = segment_idx - segments_handled;
332 self.0
333 .extend_from_slice(&remaining_segments[..segments_to_add]);
334 remaining_segments = &remaining_segments[segments_to_add..];
335
336 let segment;
337 (segment, remaining_segments) = remaining_segments.split_first().unwrap();
338
339 let segment_ids = &row_ids[range];
340 self.0.push(segment.delete(segment_ids));
341 }
342
343 self.0.extend_from_slice(remaining_segments);
345 }
346
347 pub fn mask(&mut self, positions: impl IntoIterator<Item = u32>) -> Result<()> {
349 let mut local_positions = Vec::new();
350 let mut positions_iter = positions.into_iter();
351 let mut curr_position = positions_iter.next();
352 let mut offset = 0;
353 let mut cutoff = 0;
354
355 for segment in &mut self.0 {
356 cutoff += segment.len() as u32;
358 while let Some(position) = curr_position {
359 if position >= cutoff {
360 break;
361 }
362 local_positions.push(position - offset);
363 curr_position = positions_iter.next();
364 }
365
366 if !local_positions.is_empty() {
367 segment.mask(&local_positions);
368 local_positions.clear();
369 }
370 offset = cutoff;
371 }
372
373 self.0.retain(|segment| !segment.is_empty());
374
375 Ok(())
376 }
377
378 fn find_ids(
384 &self,
385 row_ids: impl IntoIterator<Item = u64>,
386 ) -> (Vec<u64>, Vec<(usize, Range<usize>)>) {
387 let mut segment_iter = self.0.iter().enumerate().cycle();
391
392 let mut segment_matches = vec![Vec::new(); self.0.len()];
393
394 row_ids.into_iter().for_each(|row_id| {
395 let mut i = 0;
396 while i < self.0.len() {
398 let (segment_idx, segment) = segment_iter.next().unwrap();
399 if segment.range().is_some_and(|range| range.contains(&row_id))
400 && let Some(offset) = segment.position(row_id)
401 {
402 segment_matches.get_mut(segment_idx).unwrap().push(offset);
403 }
405 i += 1;
406 }
407 });
408 for matches in &mut segment_matches {
409 matches.sort_unstable();
410 }
411
412 let mut offset = 0;
413 let segment_ranges = segment_matches
414 .iter()
415 .enumerate()
416 .filter(|(_, matches)| !matches.is_empty())
417 .map(|(segment_idx, matches)| {
418 let range = offset..offset + matches.len();
419 offset += matches.len();
420 (segment_idx, range)
421 })
422 .collect();
423 let row_ids = segment_matches
424 .into_iter()
425 .enumerate()
426 .flat_map(|(segment_idx, offset)| {
427 offset
428 .into_iter()
429 .map(move |offset| self.0[segment_idx].get(offset).unwrap())
430 })
431 .collect();
432
433 (row_ids, segment_ranges)
434 }
435
436 pub fn slice(&self, offset: usize, len: usize) -> RowIdSeqSlice<'_> {
437 if len == 0 {
438 return RowIdSeqSlice {
439 segments: &[],
440 offset_start: 0,
441 offset_last: 0,
442 };
443 }
444
445 let mut offset_start = offset;
447 let mut segment_offset = 0;
448 for segment in &self.0 {
449 let segment_len = segment.len();
450 if offset_start < segment_len {
451 break;
452 }
453 offset_start -= segment_len;
454 segment_offset += 1;
455 }
456
457 let mut offset_last = offset_start + len;
459 let mut segment_offset_last = segment_offset;
460 for segment in &self.0[segment_offset..] {
461 let segment_len = segment.len();
462 if offset_last <= segment_len {
463 break;
464 }
465 offset_last -= segment_len;
466 segment_offset_last += 1;
467 }
468
469 RowIdSeqSlice {
470 segments: &self.0[segment_offset..=segment_offset_last],
471 offset_start,
472 offset_last,
473 }
474 }
475
476 pub fn segments(&self) -> &[U64Segment] {
481 &self.0
482 }
483
484 pub fn get(&self, index: usize) -> Option<u64> {
485 let mut offset = 0;
486 for segment in &self.0 {
487 let segment_len = segment.len();
488 if index < offset + segment_len {
489 return segment.get(index - offset);
490 }
491 offset += segment_len;
492 }
493 None
494 }
495
496 pub fn select<'a>(
504 &'a self,
505 selection: impl Iterator<Item = usize> + 'a,
506 ) -> impl Iterator<Item = u64> + 'a {
507 let mut cursor = RowIdSequenceCursor::default();
508 let mut last_index = None;
509 selection.filter_map(move |index| {
510 if last_index.is_some_and(|last| index < last) {
511 panic!("Selection is not sorted");
512 }
513 last_index = Some(index);
514 cursor.get(self, index)
515 })
516 }
517
518 pub(crate) fn cursor(&self) -> RowIdSequenceCursor {
519 RowIdSequenceCursor::default()
520 }
521
522 pub(crate) fn cursor_with_dense_range_expansion(&self) -> (RowIdSequenceCursor, bool) {
529 let mut cursor = self.cursor();
530 let [segment @ U64Segment::RangeWithBitmap { .. }] = self.0.as_slice() else {
531 return (cursor, false);
532 };
533 let segment_len = segment.len();
534 cursor.segment_len = Some(segment_len);
535 let use_dense_range_expansion = segment.use_dense_range_expansion(segment_len);
536 (cursor, use_dense_range_expansion)
537 }
538
539 pub(crate) fn select_range_with_cursor(
542 &self,
543 cursor: &mut RowIdSequenceCursor,
544 selection: Range<usize>,
545 ) -> Vec<u64> {
546 let mut row_ids = Vec::with_capacity(selection.len());
547 cursor.extend_range(self, selection, &mut row_ids);
548 row_ids
549 }
550
551 pub(crate) fn select_dense_range_with_cursor(
553 &self,
554 cursor: &mut RowIdSequenceCursor,
555 selection: Range<usize>,
556 ) -> Vec<u64> {
557 let mut row_ids = Vec::with_capacity(selection.len());
558 cursor.extend_dense_range(self, selection, &mut row_ids);
559 row_ids
560 }
561
562 pub(crate) fn select_with_cursor<'a>(
567 &'a self,
568 cursor: &'a mut RowIdSequenceCursor,
569 selection: impl Iterator<Item = usize> + 'a,
570 ) -> impl Iterator<Item = u64> + 'a {
571 selection.filter_map(move |index| cursor.get(self, index))
572 }
573
574 #[instrument(level = "debug", skip_all)]
589 pub fn mask_to_offset_ranges(&self, mask: &RowAddrMask) -> Vec<Range<u64>> {
590 let mut offset = 0;
591 let mut ranges = Vec::new();
592 for segment in &self.0 {
593 match segment {
594 U64Segment::Range(range) => {
595 let mut ids = RowAddrTreeMap::from(range.clone());
596 ids.mask(mask);
597 let mut cur: Option<Range<u64>> = None;
600 for (fragment, run) in ids.iter_runs() {
601 let frag = u64::from(fragment);
602 let run_start = (frag << 32) | u64::from(*run.start());
603 let run_end_excl = (frag << 32) | (u64::from(*run.end()) + 1);
604 let start = run_start - range.start + offset;
605 let end = run_end_excl - range.start + offset;
606 match cur.as_mut() {
607 Some(c) if c.end == start => c.end = end,
608 Some(c) => {
609 ranges.push(std::mem::replace(c, start..end));
610 }
611 None => cur = Some(start..end),
612 }
613 }
614 if let Some(c) = cur {
615 ranges.push(c);
616 }
617 offset += range.end - range.start;
618 }
619 U64Segment::RangeWithHoles { range, holes } => {
620 let offset_start = offset;
621 let mut ids = RowAddrTreeMap::from(range.clone());
622 offset += range.end - range.start;
623 for hole in holes.iter() {
624 if ids.remove(hole) {
625 offset -= 1;
626 }
627 }
628 ids.mask(mask);
629
630 let mut sorted_holes = holes.clone().into_iter().collect::<Vec<_>>();
632 sorted_holes.sort_unstable();
633 let mut next_holes_iter = sorted_holes.into_iter().peekable();
634 let mut holes_passed = 0;
635 ranges.extend(GroupingIterator::new(ids.into_addr_iter().map(|addr| {
636 while let Some(next_hole) = next_holes_iter.peek() {
637 if *next_hole < addr {
638 next_holes_iter.next();
639 holes_passed += 1;
640 } else {
641 break;
642 }
643 }
644 addr - range.start + offset_start - holes_passed
645 })));
646 }
647 U64Segment::RangeWithBitmap { range, bitmap } => {
648 let mut ids = RowAddrTreeMap::from(range.clone());
649 let offset_start = offset;
650 offset += range.end - range.start;
651 for (i, val) in range.clone().enumerate() {
652 if !bitmap.get(i) && ids.remove(val) {
653 offset -= 1;
654 }
655 }
656 ids.mask(mask);
657 let mut bitmap_iter = bitmap.iter();
658 let mut bitmap_iter_pos = 0;
659 let mut holes_passed = 0;
660 ranges.extend(GroupingIterator::new(ids.into_addr_iter().map(|addr| {
661 let position_in_range = addr - range.start;
662 while bitmap_iter_pos < position_in_range {
663 if !bitmap_iter.next().unwrap() {
664 holes_passed += 1;
665 }
666 bitmap_iter_pos += 1;
667 }
668 offset_start + position_in_range - holes_passed
669 })));
670 }
671 U64Segment::SortedArray(array) | U64Segment::Array(array) => {
672 ranges.extend(GroupingIterator::new(array.iter().enumerate().filter_map(
674 |(off, id)| {
675 if mask.selected(id) {
676 Some(off as u64 + offset)
677 } else {
678 None
679 }
680 },
681 )));
682 offset += array.len() as u64;
683 }
684 }
685 }
686 ranges
687 }
688}
689
690struct GroupingIterator<I: Iterator<Item = u64>> {
695 iter: I,
696 cur_range: Option<Range<u64>>,
697}
698
699impl<I: Iterator<Item = u64>> GroupingIterator<I> {
700 fn new(iter: I) -> Self {
701 Self {
702 iter,
703 cur_range: None,
704 }
705 }
706}
707
708impl<I: Iterator<Item = u64>> Iterator for GroupingIterator<I> {
709 type Item = Range<u64>;
710
711 fn next(&mut self) -> Option<Self::Item> {
712 for id in self.iter.by_ref() {
713 if let Some(range) = self.cur_range.as_mut() {
714 if range.end == id {
715 range.end = id + 1;
716 } else {
717 let ret = Some(range.clone());
718 self.cur_range = Some(id..id + 1);
719 return ret;
720 }
721 } else {
722 self.cur_range = Some(id..id + 1);
723 }
724 }
725 self.cur_range.take()
726 }
727}
728
729impl From<&RowIdSequence> for RowAddrTreeMap {
730 fn from(row_ids: &RowIdSequence) -> Self {
731 let mut tree_map = Self::new();
732 for segment in &row_ids.0 {
733 let mut seg = Self::new();
734 match segment {
735 U64Segment::Range(range) => {
736 seg.insert_range(range.clone());
737 }
738 U64Segment::RangeWithBitmap { range, bitmap } => {
739 seg.insert_range(range.clone());
740 for (i, val) in range.clone().enumerate() {
741 if !bitmap.get(i) {
742 seg.remove(val);
743 }
744 }
745 }
746 U64Segment::RangeWithHoles { range, holes } => {
747 seg.insert_range(range.clone());
748 for hole in holes.iter() {
749 seg.remove(hole);
750 }
751 }
752 U64Segment::SortedArray(array) | U64Segment::Array(array) => {
753 for val in array.iter() {
754 seg.insert(val);
755 }
756 }
757 }
758 tree_map |= seg;
759 }
760 tree_map
761 }
762}
763
764#[derive(Debug)]
765pub struct RowIdSeqSlice<'a> {
766 segments: &'a [U64Segment],
768 offset_start: usize,
770 offset_last: usize,
772}
773
774impl RowIdSeqSlice<'_> {
775 pub fn iter(&self) -> impl Iterator<Item = u64> + '_ {
776 let mut known_size = self.segments.iter().map(|segment| segment.len()).sum();
777 known_size -= self.offset_start;
778 known_size -= self.segments.last().map(|s| s.len()).unwrap_or_default() - self.offset_last;
779
780 let end = self.segments.len().saturating_sub(1);
781 self.segments
782 .iter()
783 .enumerate()
784 .flat_map(move |(i, segment)| {
785 match i {
786 0 if self.segments.len() == 1 => {
787 let len = self.offset_last - self.offset_start;
788 Box::new(segment.iter().skip(self.offset_start).take(len))
791 as Box<dyn Iterator<Item = u64>>
792 }
793 0 => Box::new(segment.iter().skip(self.offset_start)),
794 i if i == end => Box::new(segment.iter().take(self.offset_last)),
795 _ => Box::new(segment.iter()),
796 }
797 })
798 .exact_size(known_size)
799 }
800}
801
802pub fn rechunk_sequences(
816 sequences: impl IntoIterator<Item = RowIdSequence>,
817 chunk_sizes: impl IntoIterator<Item = u64>,
818 allow_incomplete: bool,
819) -> Result<Vec<RowIdSequence>> {
820 let chunk_sizes_vec: Vec<u64> = chunk_sizes.into_iter().collect();
822 let total_chunks = chunk_sizes_vec.len();
823 let mut chunked_sequences = Vec::with_capacity(total_chunks);
824 let mut segment_iter = sequences
825 .into_iter()
826 .flat_map(|sequence| sequence.0.into_iter())
827 .peekable();
828
829 let too_few_segments_error = |chunk_index: usize, expected_chunk_size: u64, remaining: u64| {
830 Error::invalid_input(format!(
831 "Got too few segments for chunk {}. Expected chunk size: {}, remaining needed: {}",
832 chunk_index, expected_chunk_size, remaining
833 ))
834 };
835
836 let too_many_segments_error = |processed_chunks: usize, total_chunk_sizes: usize| {
837 Error::invalid_input(format!(
838 "Got too many segments for the provided chunk lengths. Processed {} chunks out of {} expected",
839 processed_chunks, total_chunk_sizes
840 ))
841 };
842
843 let mut segment_offset = 0_u64;
844
845 for (chunk_index, chunk_size) in chunk_sizes_vec.iter().enumerate() {
846 let chunk_size = *chunk_size;
847 let mut sequence = RowIdSequence(Vec::new());
848 let mut remaining = chunk_size;
849
850 while remaining > 0 {
851 let remaining_in_segment = segment_iter
852 .peek()
853 .map_or(0, |segment| segment.len() as u64 - segment_offset);
854
855 if remaining_in_segment == 0 {
857 if segment_iter.next().is_some() {
858 segment_offset = 0;
859 continue;
860 } else {
861 if allow_incomplete {
863 break;
864 } else {
865 return Err(too_few_segments_error(chunk_index, chunk_size, remaining));
866 }
867 }
868 }
869
870 match remaining_in_segment.cmp(&remaining) {
872 std::cmp::Ordering::Greater => {
873 let segment = segment_iter
875 .peek()
876 .ok_or_else(|| too_few_segments_error(chunk_index, chunk_size, remaining))?
877 .slice(segment_offset as usize, remaining as usize);
878 sequence.extend(RowIdSequence(vec![segment]));
879 segment_offset += remaining;
880 remaining = 0;
881 }
882 std::cmp::Ordering::Equal | std::cmp::Ordering::Less => {
883 let segment = segment_iter
887 .next()
888 .ok_or_else(|| too_few_segments_error(chunk_index, chunk_size, remaining))?
889 .slice(segment_offset as usize, remaining_in_segment as usize);
890 sequence.extend(RowIdSequence(vec![segment]));
891 segment_offset = 0;
892 remaining -= remaining_in_segment;
893 }
894 }
895 }
896
897 chunked_sequences.push(sequence);
898 }
899
900 if segment_iter.peek().is_some() {
901 return Err(too_many_segments_error(
902 chunked_sequences.len(),
903 total_chunks,
904 ));
905 }
906
907 Ok(chunked_sequences)
908}
909
910pub fn select_row_ids<'a>(
912 sequence: &'a RowIdSequence,
913 offsets: &'a ReadBatchParams,
914) -> Result<Vec<u64>> {
915 let out_of_bounds_err = |offset: u32| {
916 Error::invalid_input(format!(
917 "Index out of bounds: {} for sequence of length {}",
918 offset,
919 sequence.len()
920 ))
921 };
922
923 match offsets {
924 ReadBatchParams::Indices(indices) => {
925 let indices = indices.values();
926 if indices.windows(2).all(|pair| pair[0] <= pair[1]) {
927 if let Some(&last) = indices.last()
929 && last as u64 >= sequence.len()
930 {
931 return Err(out_of_bounds_err(last));
932 }
933 return Ok(sequence
934 .select(indices.iter().map(|&index| index as usize))
935 .collect());
936 }
937 indices
938 .iter()
939 .map(|index| {
940 sequence
941 .get(*index as usize)
942 .ok_or_else(|| out_of_bounds_err(*index))
943 })
944 .collect()
945 }
946 ReadBatchParams::Range(range) => {
947 if range.end > sequence.len() as usize {
948 return Err(out_of_bounds_err(range.end as u32));
949 }
950 let sequence = sequence.slice(range.start, range.end - range.start);
951 Ok(sequence.iter().collect())
952 }
953 ReadBatchParams::Ranges(ranges) => {
954 let num_rows = ranges
955 .iter()
956 .map(|r| (r.end - r.start) as usize)
957 .sum::<usize>();
958 let mut result = Vec::with_capacity(num_rows);
959 for range in ranges.as_ref() {
960 if range.end > sequence.len() {
961 return Err(out_of_bounds_err(range.end as u32));
962 }
963 let sequence =
964 sequence.slice(range.start as usize, (range.end - range.start) as usize);
965 result.extend(sequence.iter());
966 }
967 Ok(result)
968 }
969
970 ReadBatchParams::RangeFull => Ok(sequence.iter().collect()),
971 ReadBatchParams::RangeTo(to) => {
972 if to.end > sequence.len() as usize {
973 return Err(out_of_bounds_err(to.end as u32));
974 }
975 let len = to.end;
976 let sequence = sequence.slice(0, len);
977 Ok(sequence.iter().collect())
978 }
979 ReadBatchParams::RangeFrom(from) => {
980 let sequence = sequence.slice(from.start, sequence.len() as usize - from.start);
981 Ok(sequence.iter().collect())
982 }
983 }
984}
985
986#[cfg(test)]
987mod test {
988 use super::*;
989
990 use pretty_assertions::assert_eq;
991 use test::bitmap::Bitmap;
992
993 #[test]
994 fn test_row_id_sequence_from_range() {
995 let sequence = RowIdSequence::from(0..10);
996 assert_eq!(sequence.len(), 10);
997 assert_eq!(sequence.is_empty(), false);
998
999 let iter = sequence.iter();
1000 assert_eq!(iter.collect::<Vec<_>>(), (0..10).collect::<Vec<_>>());
1001 }
1002
1003 #[rstest::rstest]
1004 #[case::sorted_contiguous(vec![0, 1, 2, 3])]
1005 #[case::sorted_with_gaps(vec![0, 2, 4])]
1006 #[case::sparse(vec![0, 1_000_000])]
1007 #[case::unsorted(vec![12, 11, 10])]
1008 fn test_row_id_sequence_try_from_iter(#[case] row_ids: Vec<u64>) {
1009 let sequence = RowIdSequence::try_from_iter(row_ids.clone()).unwrap();
1010 assert_eq!(sequence.len(), row_ids.len() as u64);
1011 assert_eq!(sequence.iter().collect::<Vec<_>>(), row_ids);
1012 }
1013
1014 #[test]
1015 fn test_row_id_sequence_try_from_iter_contiguous_is_a_range() {
1016 let sequence = RowIdSequence::try_from_iter(0..10).unwrap();
1017 assert_eq!(sequence.0, vec![U64Segment::Range(0..10)]);
1018 }
1019
1020 #[test]
1021 fn test_row_id_sequence_try_from_iter_empty() {
1022 let sequence = RowIdSequence::try_from_iter(std::iter::empty()).unwrap();
1023 assert_eq!(sequence.len(), 0);
1024 assert!(sequence.is_empty());
1025 }
1026
1027 #[rstest::rstest]
1028 #[case::adjacent(vec![1, 1, 2])]
1029 #[case::separated(vec![1, 2, 3, 1])]
1030 #[case::unsorted(vec![5, 3, 5])]
1031 fn test_row_id_sequence_try_from_iter_rejects_duplicates(#[case] row_ids: Vec<u64>) {
1032 let error = RowIdSequence::try_from_iter(row_ids).unwrap_err();
1035 assert!(
1036 matches!(error, Error::InvalidInput { .. }),
1037 "expected InvalidInput, got {:?}",
1038 error
1039 );
1040 assert!(
1041 error.to_string().contains("must be unique"),
1042 "unexpected message: {}",
1043 error
1044 );
1045 }
1046
1047 #[test]
1048 fn test_row_id_sequence_extend() {
1049 let mut sequence = RowIdSequence::from(0..10);
1050 sequence.extend(RowIdSequence::from(10..20));
1051 assert_eq!(sequence.0, vec![U64Segment::Range(0..20)]);
1052
1053 let mut sequence = RowIdSequence::from(0..10);
1054 sequence.extend(RowIdSequence::from(20..30));
1055 assert_eq!(
1056 sequence.0,
1057 vec![U64Segment::Range(0..10), U64Segment::Range(20..30)]
1058 );
1059 }
1060
1061 #[test]
1062 fn test_row_id_sequence_delete() {
1063 let mut sequence = RowIdSequence::from(0..10);
1064 sequence.delete(vec![1, 3, 5, 7, 9]);
1065 let mut expected_bitmap = Bitmap::new_empty(9);
1066 for i in [0, 2, 4, 6, 8] {
1067 expected_bitmap.set(i as usize);
1068 }
1069 assert_eq!(
1070 sequence.0,
1071 vec![U64Segment::RangeWithBitmap {
1072 range: 0..9,
1073 bitmap: expected_bitmap
1074 },]
1075 );
1076
1077 let mut sequence = RowIdSequence::from(0..10);
1078 sequence.extend(RowIdSequence::from(12..20));
1079 sequence.delete(vec![0, 9, 10, 11, 12, 13]);
1080 assert_eq!(
1081 sequence.0,
1082 vec![U64Segment::Range(1..9), U64Segment::Range(14..20),]
1083 );
1084
1085 let mut sequence = RowIdSequence::from(0..10);
1086 sequence.delete(vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
1087 assert_eq!(sequence.0, vec![U64Segment::Range(0..0)]);
1088 }
1089
1090 #[test]
1091 fn test_row_id_slice() {
1092 let sequence = RowIdSequence(vec![
1095 U64Segment::Range(30..35), U64Segment::RangeWithHoles {
1097 range: 50..60,
1099 holes: vec![53, 54].into(),
1100 },
1101 U64Segment::SortedArray(vec![7, 9].into()), U64Segment::RangeWithBitmap {
1103 range: 0..5,
1104 bitmap: [true, false, true, false, true].as_slice().into(),
1105 },
1106 U64Segment::Array(vec![35, 39].into()),
1107 U64Segment::Range(40..50),
1108 ]);
1109
1110 for offset in 0..sequence.len() as usize {
1112 for len in 0..sequence.len() as usize {
1113 if offset + len > sequence.len() as usize {
1114 continue;
1115 }
1116 let slice = sequence.slice(offset, len);
1117
1118 let actual = slice.iter().collect::<Vec<_>>();
1119 let expected = sequence.iter().skip(offset).take(len).collect::<Vec<_>>();
1120 assert_eq!(
1121 actual, expected,
1122 "Failed for offset {} and len {}",
1123 offset, len
1124 );
1125
1126 let (claimed_size, claimed_max) = slice.iter().size_hint();
1127 assert_eq!(claimed_max, Some(claimed_size)); assert_eq!(claimed_size, actual.len()); }
1130 }
1131 }
1132
1133 #[test]
1134 fn test_row_id_slice_empty() {
1135 let sequence = RowIdSequence::from(0..10);
1136 let slice = sequence.slice(10, 0);
1137 assert_eq!(slice.iter().collect::<Vec<_>>(), Vec::<u64>::new());
1138 }
1139
1140 #[test]
1141 fn test_row_id_sequence_rechunk() {
1142 fn assert_rechunked(
1143 input: Vec<RowIdSequence>,
1144 chunk_sizes: Vec<u64>,
1145 expected: Vec<RowIdSequence>,
1146 ) {
1147 let chunked = rechunk_sequences(input, chunk_sizes, false).unwrap();
1148 assert_eq!(chunked, expected);
1149 }
1150
1151 let many_segments = vec![
1153 RowIdSequence(vec![U64Segment::Range(0..5), U64Segment::Range(35..40)]),
1154 RowIdSequence::from(10..18),
1155 RowIdSequence::from(18..28),
1156 RowIdSequence::from(28..30),
1157 ];
1158 let fewer_segments = vec![
1159 RowIdSequence(vec![U64Segment::Range(0..5), U64Segment::Range(35..40)]),
1160 RowIdSequence::from(10..30),
1161 ];
1162 assert_rechunked(
1163 many_segments.clone(),
1164 fewer_segments.iter().map(|seq| seq.len()).collect(),
1165 fewer_segments.clone(),
1166 );
1167
1168 assert_rechunked(
1170 fewer_segments,
1171 many_segments.iter().map(|seq| seq.len()).collect(),
1172 many_segments.clone(),
1173 );
1174
1175 assert_rechunked(
1177 many_segments.clone(),
1178 many_segments.iter().map(|seq| seq.len()).collect(),
1179 many_segments.clone(),
1180 );
1181
1182 let result = rechunk_sequences(many_segments.clone(), vec![100], false);
1184 assert!(result.is_err());
1185
1186 let result = rechunk_sequences(many_segments, vec![5], false);
1188 assert!(result.is_err());
1189 }
1190
1191 #[test]
1192 fn test_select_row_ids() {
1193 let offsets = [
1195 ReadBatchParams::Indices(vec![1, 3, 9, 5, 7, 6].into()),
1196 ReadBatchParams::Indices(vec![1, 3, 5, 6, 7, 9].into()),
1197 ReadBatchParams::Range(2..8),
1198 ReadBatchParams::RangeFull,
1199 ReadBatchParams::RangeTo(..5),
1200 ReadBatchParams::RangeFrom(5..),
1201 ReadBatchParams::Ranges(vec![2..3, 5..10].into()),
1202 ];
1203
1204 let sequences = [
1207 RowIdSequence(vec![
1208 U64Segment::Range(0..5),
1209 U64Segment::RangeWithHoles {
1210 range: 50..60,
1211 holes: vec![53, 54].into(),
1212 },
1213 U64Segment::SortedArray(vec![7, 9].into()),
1214 ]),
1215 RowIdSequence(vec![
1216 U64Segment::RangeWithBitmap {
1217 range: 0..5,
1218 bitmap: [true, false, true, false, true].as_slice().into(),
1219 },
1220 U64Segment::Array(vec![30, 20, 10].into()),
1221 U64Segment::Range(40..50),
1222 ]),
1223 ];
1224
1225 for params in offsets {
1226 for sequence in &sequences {
1227 let row_ids = select_row_ids(sequence, ¶ms).unwrap();
1228 let flat_sequence = sequence.iter().collect::<Vec<_>>();
1229
1230 let selection: Vec<usize> = match ¶ms {
1232 ReadBatchParams::RangeFull => (0..flat_sequence.len()).collect(),
1233 ReadBatchParams::RangeTo(to) => (0..to.end).collect(),
1234 ReadBatchParams::RangeFrom(from) => (from.start..flat_sequence.len()).collect(),
1235 ReadBatchParams::Range(range) => range.clone().collect(),
1236 ReadBatchParams::Ranges(ranges) => ranges
1237 .iter()
1238 .flat_map(|r| r.start as usize..r.end as usize)
1239 .collect(),
1240 ReadBatchParams::Indices(indices) => {
1241 indices.values().iter().map(|i| *i as usize).collect()
1242 }
1243 };
1244
1245 let expected = selection
1246 .into_iter()
1247 .map(|i| flat_sequence[i])
1248 .collect::<Vec<_>>();
1249 assert_eq!(
1250 row_ids, expected,
1251 "Failed for params {:?} on the sequence {:?}",
1252 ¶ms, sequence
1253 );
1254 }
1255 }
1256 }
1257
1258 #[test]
1259 fn test_select_row_ids_out_of_bounds() {
1260 let offsets = [
1261 ReadBatchParams::Indices(vec![1, 1000, 4].into()),
1262 ReadBatchParams::Indices(vec![1, 4, 1000].into()),
1263 ReadBatchParams::Range(2..1000),
1264 ReadBatchParams::RangeTo(..1000),
1265 ];
1266
1267 let sequence = RowIdSequence::from(0..10);
1268
1269 for params in offsets {
1270 let result = select_row_ids(&sequence, ¶ms);
1271 assert!(result.is_err());
1272 assert!(matches!(result.unwrap_err(), Error::InvalidInput { .. }));
1273 }
1274 }
1275
1276 #[test]
1277 fn test_row_id_sequence_to_treemap() {
1278 let sequence = RowIdSequence(vec![
1279 U64Segment::Range(0..5),
1280 U64Segment::RangeWithHoles {
1281 range: 50..60,
1282 holes: vec![53, 54].into(),
1283 },
1284 U64Segment::SortedArray(vec![7, 9].into()),
1285 U64Segment::RangeWithBitmap {
1286 range: 10..15,
1287 bitmap: [true, false, true, false, true].as_slice().into(),
1288 },
1289 U64Segment::Array(vec![35, 39].into()),
1290 U64Segment::Range(40..50),
1291 ]);
1292
1293 let tree_map = RowAddrTreeMap::from(&sequence);
1294 let expected = vec![
1295 0, 1, 2, 3, 4, 7, 9, 10, 12, 14, 35, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
1296 51, 52, 55, 56, 57, 58, 59,
1297 ]
1298 .into_iter()
1299 .collect::<RowAddrTreeMap>();
1300 assert_eq!(tree_map, expected);
1301 }
1302
1303 #[test]
1304 fn test_row_id_sequence_to_treemap_overlapping_segments() {
1305 let sequence = RowIdSequence(vec![
1309 U64Segment::RangeWithBitmap {
1310 range: 0..6,
1311 bitmap: [true, false, true, false, true, false].as_slice().into(),
1312 },
1313 U64Segment::RangeWithBitmap {
1314 range: 0..6,
1315 bitmap: [false, true, false, true, false, true].as_slice().into(),
1316 },
1317 ]);
1318
1319 let expected = sequence.iter().collect::<RowAddrTreeMap>();
1320 assert_eq!(expected, (0..6).collect::<RowAddrTreeMap>());
1321 assert_eq!(RowAddrTreeMap::from(&sequence), expected);
1322 }
1323
1324 #[test]
1325 fn test_row_addr_mask() {
1326 let sequence = RowIdSequence(vec![
1332 U64Segment::Range(0..5),
1333 U64Segment::RangeWithHoles {
1334 range: 50..60,
1335 holes: vec![53, 54].into(),
1336 },
1337 U64Segment::SortedArray(vec![7, 9].into()),
1338 U64Segment::RangeWithBitmap {
1339 range: 10..15,
1340 bitmap: [true, false, true, false, true].as_slice().into(),
1341 },
1342 U64Segment::Array(vec![35, 39].into()),
1343 ]);
1344
1345 let values_to_remove = [4, 55, 7, 12, 39];
1347 let positions_to_remove = sequence
1348 .iter()
1349 .enumerate()
1350 .filter_map(|(i, val)| {
1351 if values_to_remove.contains(&val) {
1352 Some(i as u32)
1353 } else {
1354 None
1355 }
1356 })
1357 .collect::<Vec<_>>();
1358 let mut sequence = sequence;
1359 sequence.mask(positions_to_remove).unwrap();
1360 let expected = RowIdSequence(vec![
1361 U64Segment::Range(0..4),
1362 U64Segment::RangeWithBitmap {
1363 range: 50..60,
1364 bitmap: [
1365 true, true, true, false, false, false, true, true, true, true,
1366 ]
1367 .as_slice()
1368 .into(),
1369 },
1370 U64Segment::Range(9..10),
1371 U64Segment::RangeWithBitmap {
1372 range: 10..15,
1373 bitmap: [true, false, false, false, true].as_slice().into(),
1374 },
1375 U64Segment::Array(vec![35].into()),
1376 ]);
1377 assert_eq!(sequence, expected);
1378 }
1379
1380 #[test]
1381 fn test_row_addr_mask_everything() {
1382 let mut sequence = RowIdSequence(vec![
1383 U64Segment::Range(0..5),
1384 U64Segment::SortedArray(vec![7, 9].into()),
1385 ]);
1386 sequence.mask(0..sequence.len() as u32).unwrap();
1387 let expected = RowIdSequence(vec![]);
1388 assert_eq!(sequence, expected);
1389 }
1390
1391 #[test]
1392 fn test_selection() {
1393 let sequence = RowIdSequence(vec![
1394 U64Segment::Range(0..5),
1395 U64Segment::RangeWithHoles {
1396 range: 10..16,
1397 holes: vec![12].into(),
1398 },
1399 U64Segment::RangeWithBitmap {
1400 range: 20..28,
1401 bitmap: [true, false, true, true, false, true, false, true]
1402 .as_slice()
1403 .into(),
1404 },
1405 U64Segment::SortedArray(vec![40, 42, 45].into()),
1406 U64Segment::Array(vec![60, 50, 70].into()),
1407 ]);
1408 let live = sequence.iter().collect::<Vec<_>>();
1409 let selection = sequence.select(vec![2, 4, 13, 14, 57].into_iter());
1410 assert_eq!(
1411 selection.collect::<Vec<_>>(),
1412 vec![live[2], live[4], live[13], live[14]]
1413 );
1414
1415 for chunk_size in [1, 3, 7, 16] {
1416 let mut cursor = sequence.cursor();
1417 let mut chunked = Vec::new();
1418 for start in (0..live.len()).step_by(chunk_size) {
1419 let end = (start + chunk_size).min(live.len());
1420 chunked.extend(sequence.select_range_with_cursor(&mut cursor, start..end));
1421 }
1422 assert_eq!(chunked, live);
1423 }
1424
1425 let mut cursor = sequence.cursor();
1426 assert_eq!(
1427 sequence.select_range_with_cursor(&mut cursor, 6..19),
1428 live[6..19]
1429 );
1430 assert_eq!(
1431 sequence.select_range_with_cursor(&mut cursor, 1..8),
1432 live[1..8]
1433 );
1434 assert_eq!(
1435 sequence.select_range_with_cursor(&mut cursor, live.len() - 2..live.len() + 5),
1436 live[live.len() - 2..]
1437 );
1438 }
1439
1440 #[test]
1441 fn test_selection_over_bitmap_segments() {
1442 let mut bitmap = Bitmap::new_full(40);
1443 for hole in [3, 4, 17, 39] {
1444 bitmap.clear(hole);
1445 }
1446 let sequence = RowIdSequence(vec![
1447 U64Segment::RangeWithBitmap {
1448 range: 100..140,
1449 bitmap,
1450 },
1451 U64Segment::Range(200..205),
1452 ]);
1453 let live: Vec<u64> = sequence.iter().collect();
1454 assert_eq!(live.len(), 41);
1455
1456 let all = sequence.select(0..live.len()).collect::<Vec<_>>();
1458 assert_eq!(all, live);
1459 let picks = vec![0, 2, 3, 3, 15, 16, 35, 36, 40, 99];
1461 let got = sequence.select(picks.iter().copied()).collect::<Vec<_>>();
1462 let want: Vec<u64> = picks.iter().filter_map(|&i| live.get(i).copied()).collect();
1463 assert_eq!(got, want);
1464
1465 let mut cursor = sequence.cursor();
1466 let mut chunked = Vec::new();
1467 for range in [0..7, 7..30, 30..live.len()] {
1468 chunked.extend(sequence.select_range_with_cursor(&mut cursor, range));
1469 }
1470 assert_eq!(chunked, live);
1471 assert_eq!(
1472 sequence.select_range_with_cursor(&mut cursor, 2..6),
1473 live[2..6]
1474 );
1475 }
1476
1477 #[test]
1478 fn test_dense_range_cursor_selection() {
1479 let mut bitmap = Bitmap::new_full(40);
1480 for hole in [3, 4, 17, 39] {
1481 bitmap.clear(hole);
1482 }
1483 let sequence = RowIdSequence(vec![U64Segment::RangeWithBitmap {
1484 range: 100..140,
1485 bitmap,
1486 }]);
1487 let expected = sequence.iter().collect::<Vec<_>>();
1488 let (mut cursor, use_dense_range_expansion) = sequence.cursor_with_dense_range_expansion();
1489 assert!(use_dense_range_expansion);
1490 assert_eq!(cursor.segment_len, Some(expected.len()));
1491
1492 let mut actual = Vec::new();
1493 for selection in [0..7, 7..8, 8..31, 31..expected.len() + 5] {
1494 actual.extend(sequence.select_dense_range_with_cursor(&mut cursor, selection));
1495 }
1496 assert_eq!(actual, expected);
1497 assert_eq!(
1498 sequence.select_dense_range_with_cursor(&mut cursor, 2..9),
1499 expected[2..9]
1500 );
1501
1502 let mut sparse_bitmap = Bitmap::new_empty(40);
1503 for value in (0..40).step_by(2) {
1504 sparse_bitmap.set(value);
1505 }
1506 let sparse = RowIdSequence(vec![U64Segment::RangeWithBitmap {
1507 range: 0..40,
1508 bitmap: sparse_bitmap,
1509 }]);
1510 let (sparse_cursor, use_dense_range_expansion) = sparse.cursor_with_dense_range_expansion();
1511 assert!(!use_dense_range_expansion);
1512 assert_eq!(sparse_cursor.segment_len, Some(20));
1513
1514 let mut multiple_segments = sequence.clone();
1515 multiple_segments.extend(RowIdSequence::from(200..205));
1516 let (multiple_cursor, use_dense_range_expansion) =
1517 multiple_segments.cursor_with_dense_range_expansion();
1518 assert!(!use_dense_range_expansion);
1519 assert_eq!(multiple_cursor.segment_len, None);
1520 }
1521
1522 #[test]
1523 fn test_selection_over_a_large_bitmap_segment() {
1524 const ROWS: usize = 1_000_000;
1527 let mut bitmap = Bitmap::new_full(ROWS);
1528 for hole in (0..ROWS).step_by(17) {
1529 bitmap.clear(hole);
1530 }
1531 let sequence = RowIdSequence(vec![
1532 U64Segment::Range(0..8),
1533 U64Segment::RangeWithBitmap {
1534 range: 1_000..(1_000 + ROWS as u64),
1535 bitmap,
1536 },
1537 ]);
1538 let live: Vec<u64> = sequence.iter().collect();
1539
1540 let all = sequence.select(0..live.len()).collect::<Vec<_>>();
1541 assert_eq!(all, live);
1542
1543 let mut picks: Vec<usize> = [0, 7, 8, 9, 15, 16, 63, 64, 65]
1545 .into_iter()
1546 .chain((0..live.len()).step_by(9973))
1547 .chain([live.len() - 1, live.len()])
1548 .collect();
1549 picks.sort_unstable();
1550 let got = sequence.select(picks.iter().copied()).collect::<Vec<_>>();
1551 let want: Vec<u64> = picks.iter().filter_map(|&i| live.get(i).copied()).collect();
1552 assert_eq!(got, want);
1553
1554 let tail_start = live.len() - 100_000;
1555 let mut cursor = sequence.cursor();
1556 assert_eq!(
1557 sequence.select_range_with_cursor(&mut cursor, tail_start..live.len()),
1558 live[tail_start..]
1559 );
1560
1561 for chunk_size in [1, 7, 8, 9, 1_024, 4_097] {
1562 let mut cursor = sequence.cursor();
1563 let mut chunked = Vec::with_capacity(live.len() - tail_start);
1564 let mut start = tail_start;
1565 while start < live.len() {
1566 let end = (start + chunk_size).min(live.len());
1567 chunked.extend(sequence.select_range_with_cursor(&mut cursor, start..end));
1568 start = end;
1569 }
1570 assert_eq!(chunked, live[tail_start..]);
1571 }
1572 }
1573
1574 #[test]
1575 #[should_panic(expected = "Selection is not sorted")]
1576 fn test_selection_unsorted() {
1577 let sequence = RowIdSequence(vec![
1578 U64Segment::Range(0..5),
1579 U64Segment::Range(10..15),
1580 U64Segment::Range(20..25),
1581 ]);
1582 let _ = sequence
1583 .select(vec![2, 4, 3].into_iter())
1584 .collect::<Vec<_>>();
1585 }
1586
1587 #[test]
1588 fn test_mask_to_offset_ranges() {
1589 let sequence = RowIdSequence(vec![U64Segment::Range(0..10)]);
1591 let mask = RowAddrMask::from_allowed(RowAddrTreeMap::from_iter(&[0, 2, 4, 6, 8]));
1592 let ranges = sequence.mask_to_offset_ranges(&mask);
1593 assert_eq!(ranges, vec![0..1, 2..3, 4..5, 6..7, 8..9]);
1594
1595 let sequence = RowIdSequence(vec![U64Segment::Range(40..60)]);
1596 let mask = RowAddrMask::from_allowed(RowAddrTreeMap::from_iter(&[54]));
1597 let ranges = sequence.mask_to_offset_ranges(&mask);
1598 assert_eq!(ranges, vec![14..15]);
1599
1600 let sequence = RowIdSequence(vec![U64Segment::Range(40..60)]);
1601 let mask = RowAddrMask::from_block(RowAddrTreeMap::from_iter(&[54]));
1602 let ranges = sequence.mask_to_offset_ranges(&mask);
1603 assert_eq!(ranges, vec![0..14, 15..20]);
1604
1605 let sequence = RowIdSequence(vec![U64Segment::RangeWithHoles {
1608 range: 0..10,
1609 holes: vec![2, 6].into(),
1610 }]);
1611 let mask = RowAddrMask::from_allowed(RowAddrTreeMap::from_iter(&[0, 2, 4, 6, 8]));
1612 let ranges = sequence.mask_to_offset_ranges(&mask);
1613 assert_eq!(ranges, vec![0..1, 3..4, 6..7]);
1614
1615 let sequence = RowIdSequence(vec![U64Segment::RangeWithHoles {
1616 range: 40..60,
1617 holes: vec![47, 43].into(),
1618 }]);
1619 let mask = RowAddrMask::from_allowed(RowAddrTreeMap::from_iter(&[44]));
1620 let ranges = sequence.mask_to_offset_ranges(&mask);
1621 assert_eq!(ranges, vec![3..4]);
1622
1623 let sequence = RowIdSequence(vec![U64Segment::RangeWithHoles {
1624 range: 40..60,
1625 holes: vec![47, 43].into(),
1626 }]);
1627 let mask = RowAddrMask::from_block(RowAddrTreeMap::from_iter(&[44]));
1628 let ranges = sequence.mask_to_offset_ranges(&mask);
1629 assert_eq!(ranges, vec![0..3, 4..18]);
1630
1631 let sequence = RowIdSequence(vec![U64Segment::RangeWithBitmap {
1634 range: 0..10,
1635 bitmap: [
1636 true, true, false, false, true, true, true, true, false, false,
1637 ]
1638 .as_slice()
1639 .into(),
1640 }]);
1641 let mask = RowAddrMask::from_allowed(RowAddrTreeMap::from_iter(&[0, 2, 4, 6, 8]));
1642 let ranges = sequence.mask_to_offset_ranges(&mask);
1643 assert_eq!(ranges, vec![0..1, 2..3, 4..5]);
1644
1645 let sequence = RowIdSequence(vec![U64Segment::RangeWithBitmap {
1646 range: 40..45,
1647 bitmap: [true, true, false, false, true].as_slice().into(),
1648 }]);
1649 let mask = RowAddrMask::from_allowed(RowAddrTreeMap::from_iter(&[44]));
1650 let ranges = sequence.mask_to_offset_ranges(&mask);
1651 assert_eq!(ranges, vec![2..3]);
1652
1653 let sequence = RowIdSequence(vec![U64Segment::RangeWithBitmap {
1654 range: 40..45,
1655 bitmap: [true, true, false, false, true].as_slice().into(),
1656 }]);
1657 let mask = RowAddrMask::from_block(RowAddrTreeMap::from_iter(&[44]));
1658 let ranges = sequence.mask_to_offset_ranges(&mask);
1659 assert_eq!(ranges, vec![0..2]);
1660
1661 let sequence = RowIdSequence(vec![U64Segment::SortedArray(vec![0, 2, 4, 6, 8].into())]);
1663 let mask = RowAddrMask::from_allowed(RowAddrTreeMap::from_iter(&[0, 6, 8]));
1664 let ranges = sequence.mask_to_offset_ranges(&mask);
1665 assert_eq!(ranges, vec![0..1, 3..5]);
1666
1667 let sequence = RowIdSequence(vec![U64Segment::Array(vec![8, 2, 6, 0, 4].into())]);
1668 let mask = RowAddrMask::from_allowed(RowAddrTreeMap::from_iter(&[0, 6, 8]));
1669 let ranges = sequence.mask_to_offset_ranges(&mask);
1670 assert_eq!(ranges, vec![0..1, 2..4]);
1671
1672 let sequence = RowIdSequence(vec![
1677 U64Segment::Range(0..5),
1678 U64Segment::RangeWithHoles {
1679 range: 100..105,
1680 holes: vec![103].into(),
1681 },
1682 U64Segment::SortedArray(vec![44, 46, 78].into()),
1683 ]);
1684 let mask = RowAddrMask::from_allowed(RowAddrTreeMap::from_iter(&[0, 2, 46, 100, 104]));
1685 let ranges = sequence.mask_to_offset_ranges(&mask);
1686 assert_eq!(ranges, vec![0..1, 2..3, 5..6, 8..9, 10..11]);
1687
1688 let sequence = RowIdSequence(vec![U64Segment::Range(0..10)]);
1690 let mask = RowAddrMask::default();
1691 let ranges = sequence.mask_to_offset_ranges(&mask);
1692 assert_eq!(ranges, vec![0..10]);
1693
1694 let sequence = RowIdSequence(vec![U64Segment::Range(0..10)]);
1696 let mask = RowAddrMask::allow_nothing();
1697 let ranges = sequence.mask_to_offset_ranges(&mask);
1698 assert_eq!(ranges, vec![]);
1699 }
1700
1701 #[test]
1702 fn test_row_id_sequence_rechunk_with_empty_segments() {
1703 let input_sequences = vec![
1705 RowIdSequence::from(0..2), RowIdSequence::from(20..23), ];
1708 let chunk_sizes = vec![2, 3]; let result = rechunk_sequences(input_sequences, chunk_sizes, false).unwrap();
1711 assert_eq!(result.len(), 2);
1712 assert_eq!(result[0].len(), 2);
1713 assert_eq!(result[1].len(), 3);
1714
1715 let first_chunk: Vec<u64> = result[0].iter().collect();
1716 let second_chunk: Vec<u64> = result[1].iter().collect();
1717 assert_eq!(first_chunk, vec![0, 1]);
1718 assert_eq!(second_chunk, vec![20, 21, 22]);
1719
1720 let input_sequences = vec![
1722 RowIdSequence::from(0..2), RowIdSequence::from(20..21), RowIdSequence::from(30..32), ];
1726 let chunk_sizes = vec![5]; let result = rechunk_sequences(input_sequences, chunk_sizes, false).unwrap();
1729 assert_eq!(result.len(), 1);
1730 assert_eq!(result[0].len(), 5);
1731
1732 let elements: Vec<u64> = result[0].iter().collect();
1733 assert_eq!(elements, vec![0, 1, 20, 30, 31]);
1734
1735 let input_sequences = vec![
1737 RowIdSequence::from(0..2), RowIdSequence::from(10..10), RowIdSequence::from(20..22), ];
1741 let chunk_sizes = vec![3, 1];
1742 let result = rechunk_sequences(input_sequences, chunk_sizes, false).unwrap();
1743
1744 assert_eq!(result.len(), 2);
1745 assert_eq!(result[0].len(), 3);
1746 assert_eq!(result[1].len(), 1);
1747
1748 let first_chunk_elements: Vec<u64> = result[0].iter().collect();
1749 let second_chunk_elements: Vec<u64> = result[1].iter().collect();
1750 assert_eq!(first_chunk_elements, vec![0, 1, 20]);
1751 assert_eq!(second_chunk_elements, vec![21]);
1752
1753 let input_sequences = vec![
1755 RowIdSequence::from(0..1), RowIdSequence::from(10..10), RowIdSequence::from(20..20), RowIdSequence::from(30..32), ];
1760 let chunk_sizes = vec![3];
1761 let result = rechunk_sequences(input_sequences, chunk_sizes, false).unwrap();
1762
1763 assert_eq!(result.len(), 1);
1764 assert_eq!(result[0].len(), 3);
1765
1766 let elements: Vec<u64> = result[0].iter().collect();
1767 assert_eq!(elements, vec![0, 30, 31]);
1768
1769 let input_sequences = vec![
1771 RowIdSequence::from(0..3), RowIdSequence::from(10..10), RowIdSequence::from(20..22), ];
1775 let chunk_sizes = vec![3, 2];
1776 let result = rechunk_sequences(input_sequences, chunk_sizes, false).unwrap();
1777
1778 assert_eq!(result.len(), 2);
1779 assert_eq!(result[0].len(), 3);
1780 assert_eq!(result[1].len(), 2);
1781
1782 let first_chunk_elements: Vec<u64> = result[0].iter().collect();
1783 let second_chunk_elements: Vec<u64> = result[1].iter().collect();
1784 assert_eq!(first_chunk_elements, vec![0, 1, 2]);
1785 assert_eq!(second_chunk_elements, vec![20, 21]);
1786
1787 let input_sequences = vec![
1789 RowIdSequence::from(0..2), RowIdSequence::from(10..10), ];
1792 let chunk_sizes = vec![5]; let result = rechunk_sequences(input_sequences, chunk_sizes, true).unwrap();
1794
1795 assert_eq!(result.len(), 1);
1796 assert_eq!(result[0].len(), 2);
1797
1798 let elements: Vec<u64> = result[0].iter().collect();
1799 assert_eq!(elements, vec![0, 1]);
1800 }
1801
1802 #[test]
1803 fn test_row_id_range_empty() {
1804 let seq = RowIdSequence::from(0u64..0);
1805 assert_eq!(seq.row_id_range(), None);
1806 }
1807
1808 #[test]
1809 fn test_row_id_range_single_contiguous() {
1810 let seq = RowIdSequence::from(10u64..20);
1811 assert_eq!(seq.row_id_range(), Some(10..=19));
1812 }
1813
1814 #[test]
1815 fn test_row_id_range_unsorted_array() {
1816 let seq = RowIdSequence::from([50u64, 10, 30].as_slice());
1818 let r = seq.row_id_range().unwrap();
1819 assert!(*r.start() <= 10);
1820 assert!(*r.end() >= 50);
1821 }
1822
1823 #[test]
1824 fn test_row_id_range_multi_segment() {
1825 let mut seq = RowIdSequence::from(0u64..5);
1827 seq.extend(RowIdSequence::from(100u64..105));
1828 let r = seq.row_id_range().unwrap();
1829 assert_eq!(*r.start(), 0);
1830 assert_eq!(*r.end(), 104);
1831 }
1832}