1use std::ops::{Range, RangeInclusive};
5
6use super::{bitmap::Bitmap, encoded_array::EncodedU64Array};
7use lance_core::deepsize::DeepSizeOf;
8
9#[inline]
12fn u128_byte_cost_to_usize(v: u128) -> usize {
13 usize::try_from(v).unwrap_or(usize::MAX)
14}
15
16#[derive(Debug, PartialEq, Eq, Clone)]
41pub enum U64Segment {
42 Range(Range<u64>),
46 RangeWithHoles {
51 range: Range<u64>,
52 holes: EncodedU64Array,
56 },
57 RangeWithBitmap { range: Range<u64>, bitmap: Bitmap },
64 SortedArray(EncodedU64Array),
68 Array(EncodedU64Array),
70}
71
72impl DeepSizeOf for U64Segment {
73 fn deep_size_of_children(&self, context: &mut lance_core::deepsize::Context) -> usize {
74 match self {
75 Self::Range(_) => 0,
76 Self::RangeWithHoles { holes, .. } => holes.deep_size_of_children(context),
77 Self::RangeWithBitmap { bitmap, .. } => bitmap.deep_size_of_children(context),
78 Self::SortedArray(array) => array.deep_size_of_children(context),
79 Self::Array(array) => array.deep_size_of_children(context),
80 }
81 }
82}
83
84#[derive(Debug)]
86struct SegmentStats {
87 min: u64,
89 max: u64,
91 count: u64,
93 sorted: bool,
95}
96
97impl SegmentStats {
98 fn n_holes(&self) -> u128 {
103 debug_assert!(self.sorted);
104 if self.count == 0 {
105 0
106 } else {
107 let total_slots = self.max as u128 - self.min as u128 + 1;
108 total_slots - self.count as u128
109 }
110 }
111}
112
113impl U64Segment {
114 fn holes_in_slice<'a>(
116 range: RangeInclusive<u64>,
117 existing: impl IntoIterator<Item = u64> + 'a,
118 ) -> impl Iterator<Item = u64> + 'a {
119 let mut existing = existing.into_iter().peekable();
120 range.filter(move |val| {
121 if let Some(&existing_val) = existing.peek()
122 && existing_val == *val
123 {
124 existing.next();
125 return false;
126 }
127 true
128 })
129 }
130
131 fn compute_stats(values: impl IntoIterator<Item = u64>) -> SegmentStats {
132 let mut sorted = true;
133 let mut min = u64::MAX;
134 let mut max = 0;
135 let mut count = 0;
136
137 for val in values {
138 count += 1;
139 if val < min {
140 min = val;
141 }
142 if val > max {
143 max = val;
144 }
145 if sorted && count > 1 && val < max {
146 sorted = false;
147 }
148 }
149
150 if count == 0 {
151 min = 0;
152 max = 0;
153 }
154
155 SegmentStats {
156 min,
157 max,
158 count,
159 sorted,
160 }
161 }
162
163 fn sorted_sequence_sizes(stats: &SegmentStats) -> [usize; 3] {
169 let n_holes = stats.n_holes();
170 let total_slots = stats.max as u128 - stats.min as u128 + 1;
171
172 let range_with_holes = 24u128.saturating_add(4u128.saturating_mul(n_holes));
173 let range_with_bitmap = 24u128.saturating_add(total_slots.div_ceil(8));
174 let sorted_array = 24u128.saturating_add(2u128.saturating_mul(stats.count as u128));
175
176 [
177 u128_byte_cost_to_usize(range_with_holes),
178 u128_byte_cost_to_usize(range_with_bitmap),
179 u128_byte_cost_to_usize(sorted_array),
180 ]
181 }
182
183 fn from_stats_and_sequence(
184 stats: SegmentStats,
185 sequence: impl IntoIterator<Item = u64>,
186 ) -> Self {
187 if stats.sorted {
188 let n_holes = stats.n_holes();
189 let exclusive_end = stats.max.checked_add(1);
193 if stats.count == 0 {
194 Self::Range(0..0)
195 } else if n_holes == 0 && exclusive_end.is_some() {
196 Self::Range(stats.min..exclusive_end.unwrap())
197 } else if let Some(end) = exclusive_end {
198 let sizes = Self::sorted_sequence_sizes(&stats);
199 let min_size = sizes.iter().min().unwrap();
200 if min_size == &sizes[0] {
201 let range = stats.min..end;
202 let mut holes =
203 Self::holes_in_slice(stats.min..=stats.max, sequence).collect::<Vec<_>>();
204 holes.sort_unstable();
205 let holes = EncodedU64Array::from(holes);
206 Self::RangeWithHoles { range, holes }
207 } else if min_size == &sizes[1] {
208 let range = stats.min..end;
209 let mut bitmap = Bitmap::new_full((stats.max - stats.min) as usize + 1);
210 for hole in Self::holes_in_slice(stats.min..=stats.max, sequence) {
211 let offset = (hole - stats.min) as usize;
212 bitmap.clear(offset);
213 }
214 Self::RangeWithBitmap { range, bitmap }
215 } else {
216 Self::SortedArray(EncodedU64Array::from_iter(sequence))
217 }
218 } else {
219 Self::SortedArray(EncodedU64Array::from_iter(sequence))
222 }
223 } else {
224 Self::Array(EncodedU64Array::from_iter(sequence))
225 }
226 }
227
228 pub fn from_slice(slice: &[u64]) -> Self {
229 Self::from_iter(slice.iter().copied())
230 }
231}
232
233impl FromIterator<u64> for U64Segment {
234 fn from_iter<T: IntoIterator<Item = u64>>(iter: T) -> Self {
235 let values: Vec<u64> = iter.into_iter().collect();
236 let stats = Self::compute_stats(values.iter().copied());
237 Self::from_stats_and_sequence(stats, values)
238 }
239}
240
241impl U64Segment {
242 pub fn iter(&self) -> Box<dyn DoubleEndedIterator<Item = u64> + '_> {
243 match self {
244 Self::Range(range) => Box::new(range.clone()),
245 Self::RangeWithHoles { range, holes } => {
246 Box::new((range.start..range.end).filter(move |&val| {
247 holes.binary_search(val).is_err()
251 }))
252 }
253 Self::RangeWithBitmap { range, bitmap } => {
254 Box::new((range.start..range.end).filter(|val| {
255 let offset = (val - range.start) as usize;
256 bitmap.get(offset)
257 }))
258 }
259 Self::SortedArray(array) => Box::new(array.iter()),
260 Self::Array(array) => Box::new(array.iter()),
261 }
262 }
263
264 pub fn len(&self) -> usize {
265 match self {
266 Self::Range(range) => (range.end - range.start) as usize,
267 Self::RangeWithHoles { range, holes } => {
268 let holes = holes.iter().count();
269 (range.end - range.start) as usize - holes
270 }
271 Self::RangeWithBitmap { range, bitmap } => {
272 let holes = bitmap.count_zeros();
273 (range.end - range.start) as usize - holes
274 }
275 Self::SortedArray(array) => array.len(),
276 Self::Array(array) => array.len(),
277 }
278 }
279
280 pub(crate) fn use_dense_range_expansion(&self, segment_len: usize) -> bool {
281 let Self::RangeWithBitmap { bitmap, .. } = self else {
282 return false;
283 };
284 let dense_threshold = bitmap.len().saturating_sub(bitmap.len() / 4);
287 segment_len >= dense_threshold
288 }
289
290 pub fn is_empty(&self) -> bool {
291 self.len() == 0
292 }
293
294 pub fn range(&self) -> Option<RangeInclusive<u64>> {
299 match self {
300 Self::Range(range)
301 | Self::RangeWithBitmap { range, .. }
302 | Self::RangeWithHoles { range, .. } => {
303 (!range.is_empty()).then(|| range.start..=(range.end - 1))
304 }
305 Self::SortedArray(array) => Some(array.first()?..=array.last()?),
307 Self::Array(array) => Some(array.min()?..=array.max()?),
308 }
309 }
310
311 pub fn slice(&self, offset: usize, len: usize) -> Self {
312 if len == 0 {
313 return Self::Range(0..0);
314 }
315
316 let values: Vec<u64> = self.iter().skip(offset).take(len).collect();
317
318 Self::from_slice(&values)
320 }
321
322 pub fn position(&self, val: u64) -> Option<usize> {
323 match self {
324 Self::Range(range) => {
325 if range.contains(&val) {
326 Some((val - range.start) as usize)
327 } else {
328 None
329 }
330 }
331 Self::RangeWithHoles { range, holes } => {
332 if !range.contains(&val) {
333 return None;
334 }
335 match holes.binary_search(val) {
338 Ok(_) => None,
339 Err(num_holes_before) => {
340 let offset = (val - range.start) as usize;
341 Some(offset - num_holes_before)
342 }
343 }
344 }
345 Self::RangeWithBitmap { range, bitmap } => {
346 if range.contains(&val) && bitmap.get((val - range.start) as usize) {
347 let offset = (val - range.start) as usize;
348 let num_zeros = bitmap.slice(0, offset).count_zeros();
349 Some(offset - num_zeros)
350 } else {
351 None
352 }
353 }
354 Self::SortedArray(array) => array.binary_search(val).ok(),
355 Self::Array(array) => array.iter().position(|v| v == val),
356 }
357 }
358
359 pub fn get(&self, i: usize) -> Option<u64> {
360 match self {
361 Self::Range(range) => match range.start.checked_add(i as u64) {
362 Some(val) if val < range.end => Some(val),
363 _ => None,
364 },
365 Self::RangeWithHoles { range, holes } => {
366 let len = (range.end - range.start) as usize - holes.len();
367 if i >= len {
368 return None;
369 }
370 let target = range.start + i as u64;
375 let mut lo = 0usize;
376 let mut hi = holes.len();
377 while lo < hi {
378 let mid = (lo + hi) / 2;
379 let h = holes.get(mid).unwrap();
380 if h.saturating_sub(mid as u64) > target {
381 hi = mid;
382 } else {
383 lo = mid + 1;
384 }
385 }
386 Some(range.start + i as u64 + lo as u64)
387 }
388 Self::RangeWithBitmap { .. } => self.cursor().get(i),
389 Self::SortedArray(array) => array.get(i),
390 Self::Array(array) => array.get(i),
391 }
392 }
393
394 pub fn cursor(&self) -> SegmentCursor<'_> {
396 SegmentCursor {
397 segment: self,
398 state: SegmentCursorState::default(),
399 }
400 }
401
402 pub fn contains(&self, val: u64) -> bool {
404 match self {
405 Self::Range(range) => range.contains(&val),
406 Self::RangeWithHoles { range, holes } => {
407 if !range.contains(&val) {
408 return false;
409 }
410 !holes.iter().any(|hole| hole == val)
412 }
413 Self::RangeWithBitmap { range, bitmap } => {
414 if !range.contains(&val) {
415 return false;
416 }
417 let idx = (val - range.start) as usize;
419 bitmap.get(idx)
420 }
421 Self::SortedArray(array) => array.binary_search(val).is_ok(),
422 Self::Array(array) => array.iter().any(|v| v == val),
423 }
424 }
425
426 pub fn with_new_high(self, val: u64) -> lance_core::Result<Self> {
428 if let Some(range) = self.range()
430 && val <= *range.end()
431 {
432 return Err(lance_core::Error::invalid_input(format!(
433 "New value {} must be higher than current maximum {}",
434 val,
435 range.end()
436 )));
437 }
438
439 Ok(match self {
440 Self::Range(range) => {
441 if range.start == range.end {
443 Self::Range(Range {
444 start: val,
445 end: val + 1,
446 })
447 } else if val == range.end {
448 Self::Range(Range {
449 start: range.start,
450 end: val + 1,
451 })
452 } else {
453 Self::RangeWithHoles {
454 range: Range {
455 start: range.start,
456 end: val + 1,
457 },
458 holes: EncodedU64Array::U64((range.end..val).collect()),
459 }
460 }
461 }
462 Self::RangeWithHoles { range, holes } => {
463 if val == range.end {
464 Self::RangeWithHoles {
465 range: Range {
466 start: range.start,
467 end: val + 1,
468 },
469 holes,
470 }
471 } else {
472 let mut new_holes: Vec<u64> = holes.iter().collect();
473 new_holes.extend(range.end..val);
474 Self::RangeWithHoles {
475 range: Range {
476 start: range.start,
477 end: val + 1,
478 },
479 holes: EncodedU64Array::U64(new_holes),
480 }
481 }
482 }
483 Self::RangeWithBitmap { range, bitmap } => {
484 let new_range = Range {
485 start: range.start,
486 end: val + 1,
487 };
488 let gap_size = (val - range.end) as usize;
489 let new_bitmap = bitmap
490 .iter()
491 .chain(std::iter::repeat_n(false, gap_size))
492 .chain(std::iter::once(true))
493 .collect::<Vec<bool>>();
494
495 Self::RangeWithBitmap {
496 range: new_range,
497 bitmap: Bitmap::from(new_bitmap.as_slice()),
498 }
499 }
500 Self::SortedArray(array) => match array {
501 EncodedU64Array::U64(mut vec) => {
502 vec.push(val);
503 Self::SortedArray(EncodedU64Array::U64(vec))
504 }
505 EncodedU64Array::U16 { base, offsets } => {
506 if let Some(offset) = val.checked_sub(base) {
507 if offset <= u16::MAX as u64 {
508 let mut offsets = offsets;
509 offsets.push(offset as u16);
510 return Ok(Self::SortedArray(EncodedU64Array::U16 { base, offsets }));
511 } else if offset <= u32::MAX as u64 {
512 let mut u32_offsets: Vec<u32> =
513 offsets.into_iter().map(|o| o as u32).collect();
514 u32_offsets.push(offset as u32);
515 return Ok(Self::SortedArray(EncodedU64Array::U32 {
516 base,
517 offsets: u32_offsets,
518 }));
519 }
520 }
521 let mut new_array: Vec<u64> =
522 offsets.into_iter().map(|o| base + o as u64).collect();
523 new_array.push(val);
524 Self::SortedArray(EncodedU64Array::from(new_array))
525 }
526 EncodedU64Array::U32 { base, mut offsets } => {
527 if let Some(offset) = val.checked_sub(base)
528 && offset <= u32::MAX as u64
529 {
530 offsets.push(offset as u32);
531 return Ok(Self::SortedArray(EncodedU64Array::U32 { base, offsets }));
532 }
533 let mut new_array: Vec<u64> =
534 offsets.into_iter().map(|o| base + o as u64).collect();
535 new_array.push(val);
536 Self::SortedArray(EncodedU64Array::from(new_array))
537 }
538 },
539 Self::Array(array) => match array {
540 EncodedU64Array::U64(mut vec) => {
541 vec.push(val);
542 Self::Array(EncodedU64Array::U64(vec))
543 }
544 EncodedU64Array::U16 { base, offsets } => {
545 if let Some(offset) = val.checked_sub(base) {
546 if offset <= u16::MAX as u64 {
547 let mut offsets = offsets;
548 offsets.push(offset as u16);
549 return Ok(Self::Array(EncodedU64Array::U16 { base, offsets }));
550 } else if offset <= u32::MAX as u64 {
551 let mut u32_offsets: Vec<u32> =
552 offsets.into_iter().map(|o| o as u32).collect();
553 u32_offsets.push(offset as u32);
554 return Ok(Self::Array(EncodedU64Array::U32 {
555 base,
556 offsets: u32_offsets,
557 }));
558 }
559 }
560 let mut new_array: Vec<u64> =
561 offsets.into_iter().map(|o| base + o as u64).collect();
562 new_array.push(val);
563 Self::Array(EncodedU64Array::from(new_array))
564 }
565 EncodedU64Array::U32 { base, mut offsets } => {
566 if let Some(offset) = val.checked_sub(base)
567 && offset <= u32::MAX as u64
568 {
569 offsets.push(offset as u32);
570 return Ok(Self::Array(EncodedU64Array::U32 { base, offsets }));
571 }
572 let mut new_array: Vec<u64> =
573 offsets.into_iter().map(|o| base + o as u64).collect();
574 new_array.push(val);
575 Self::Array(EncodedU64Array::from(new_array))
576 }
577 },
578 })
579 }
580
581 pub fn delete(&self, vals: &[u64]) -> Self {
586 debug_assert!(vals.iter().all(|&val| self.range().unwrap().contains(&val)));
588
589 let make_new_iter = || {
590 let mut vals_iter = vals.iter().copied().peekable();
591 self.iter().filter(move |val| {
592 if let Some(&next_val) = vals_iter.peek()
593 && next_val == *val
594 {
595 vals_iter.next();
596 return false;
597 }
598 true
599 })
600 };
601 let stats = Self::compute_stats(make_new_iter());
602 Self::from_stats_and_sequence(stats, make_new_iter())
603 }
604
605 pub fn mask(&mut self, positions: &[u32]) {
606 if positions.is_empty() {
607 return;
608 }
609 if positions.len() == self.len() {
610 *self = Self::Range(0..0);
611 return;
612 }
613 let count = (self.len() - positions.len()) as u64;
614 let sorted = match self {
615 Self::Range(_) => true,
616 Self::RangeWithHoles { .. } => true,
617 Self::RangeWithBitmap { .. } => true,
618 Self::SortedArray(_) => true,
619 Self::Array(_) => false,
620 };
621 let first_unmasked = (0..self.len())
623 .zip(positions.iter().cycle())
624 .find(|(sequential_i, i)| **i != *sequential_i as u32)
625 .map(|(sequential_i, _)| sequential_i)
626 .unwrap();
627 let min = self.get(first_unmasked).unwrap();
628
629 let last_unmasked = (0..self.len())
630 .rev()
631 .zip(positions.iter().rev().cycle())
632 .filter(|(sequential_i, i)| **i != *sequential_i as u32)
633 .map(|(sequential_i, _)| sequential_i)
634 .next()
635 .unwrap();
636 let max = self.get(last_unmasked).unwrap();
637
638 let stats = SegmentStats {
639 min,
640 max,
641 count,
642 sorted,
643 };
644
645 let mut positions = positions.iter().copied().peekable();
646 let sequence = self.iter().enumerate().filter_map(move |(i, val)| {
647 if let Some(next_pos) = positions.peek()
648 && *next_pos == i as u32
649 {
650 positions.next();
651 return None;
652 }
653 Some(val)
654 });
655 *self = Self::from_stats_and_sequence(stats, sequence)
656 }
657}
658
659pub struct SegmentCursor<'a> {
661 segment: &'a U64Segment,
662 state: SegmentCursorState,
663}
664
665#[derive(Debug, Default)]
666pub(crate) struct SegmentCursorState {
667 byte_idx: usize,
669 ones_before: usize,
671}
672
673impl SegmentCursor<'_> {
674 pub fn get(&mut self, i: usize) -> Option<u64> {
676 self.state.get(self.segment, i)
677 }
678}
679
680impl SegmentCursorState {
681 pub(crate) fn extend_range(
684 &mut self,
685 segment: &U64Segment,
686 selection: Range<usize>,
687 values: &mut Vec<u64>,
688 ) {
689 let U64Segment::RangeWithBitmap { range, bitmap } = segment else {
690 match segment {
691 U64Segment::Range(range) => {
692 let segment_len = (range.end - range.start) as usize;
693 let end = selection.end.min(segment_len);
694 if selection.start < end {
695 values.extend(
696 (range.start + selection.start as u64)..(range.start + end as u64),
697 );
698 }
699 }
700 _ => values.extend(selection.filter_map(|index| segment.get(index))),
701 }
702 return;
703 };
704
705 if selection.start < self.ones_before {
706 self.byte_idx = 0;
707 self.ones_before = 0;
708 }
709
710 while let Some(&byte) = bitmap.data.get(self.byte_idx) {
711 let ones = byte.count_ones() as usize;
712 let ones_after_byte = self.ones_before + ones;
713 if selection.start >= ones_after_byte {
714 self.ones_before = ones_after_byte;
715 self.byte_idx += 1;
716 continue;
717 }
718
719 let mut remaining_bits = byte;
720 let mut rank = self.ones_before;
721 while remaining_bits != 0 {
722 if rank >= selection.end {
723 return;
724 }
725 let bit = remaining_bits.trailing_zeros() as usize;
726 if rank >= selection.start {
727 values.push(range.start + (self.byte_idx * 8 + bit) as u64);
728 }
729 remaining_bits &= remaining_bits - 1;
730 rank += 1;
731 }
732
733 self.ones_before = ones_after_byte;
734 self.byte_idx += 1;
735 if self.ones_before >= selection.end {
736 return;
737 }
738 }
739 }
740
741 pub(crate) fn extend_dense_range(
742 &mut self,
743 segment: &U64Segment,
744 selection: Range<usize>,
745 values: &mut Vec<u64>,
746 ) {
747 let U64Segment::RangeWithBitmap { range, bitmap } = segment else {
748 self.extend_range(segment, selection, values);
749 return;
750 };
751 if selection.start < self.ones_before {
752 self.byte_idx = 0;
753 self.ones_before = 0;
754 }
755 self.extend_dense_bitmap_range(range.start, bitmap.bytes(), selection, values);
756 }
757
758 #[inline]
759 fn extend_dense_bitmap_range(
760 &mut self,
761 range_start: u64,
762 bitmap_bytes: &[u8],
763 selection: Range<usize>,
764 values: &mut Vec<u64>,
765 ) {
766 while let Some(&byte) = bitmap_bytes.get(self.byte_idx) {
767 let ones = byte.count_ones() as usize;
768 let ones_after_byte = self.ones_before + ones;
769 if selection.start >= ones_after_byte {
770 self.ones_before = ones_after_byte;
771 self.byte_idx += 1;
772 continue;
773 }
774
775 let includes_entire_byte =
776 selection.start <= self.ones_before && selection.end >= ones_after_byte;
777 if includes_entire_byte && ones >= 6 {
778 let byte_start = range_start + (self.byte_idx * 8) as u64;
779 if byte == u8::MAX {
780 values.extend(byte_start..byte_start + 8);
781 } else {
782 let mut remaining_bits = byte;
783 let mut bit_offset = 0_u64;
784 while remaining_bits != 0 {
785 let zeros = remaining_bits.trailing_zeros();
786 remaining_bits >>= zeros;
787 bit_offset += u64::from(zeros);
788 let run = remaining_bits.trailing_ones();
789 values.extend(
790 (byte_start + bit_offset)..(byte_start + bit_offset + u64::from(run)),
791 );
792 remaining_bits >>= run;
793 bit_offset += u64::from(run);
794 }
795 }
796 self.ones_before = ones_after_byte;
797 self.byte_idx += 1;
798 if self.ones_before >= selection.end {
799 return;
800 }
801 continue;
802 }
803
804 let mut remaining_bits = byte;
805 let mut rank = self.ones_before;
806 while remaining_bits != 0 {
807 if rank >= selection.end {
808 return;
809 }
810 let bit = remaining_bits.trailing_zeros() as usize;
811 if rank >= selection.start {
812 values.push(range_start + (self.byte_idx * 8 + bit) as u64);
813 }
814 remaining_bits &= remaining_bits - 1;
815 rank += 1;
816 }
817
818 self.ones_before = ones_after_byte;
819 self.byte_idx += 1;
820 if self.ones_before >= selection.end {
821 return;
822 }
823 }
824 }
825
826 pub(crate) fn get(&mut self, segment: &U64Segment, i: usize) -> Option<u64> {
828 let U64Segment::RangeWithBitmap { range, bitmap } = segment else {
829 return segment.get(i);
830 };
831 if i < self.ones_before {
832 self.byte_idx = 0;
833 self.ones_before = 0;
834 }
835 let mut remaining = i - self.ones_before;
838 let range_start = range.start;
839 let bitmap_bytes = bitmap.bytes();
840 while let Some(&byte) = bitmap_bytes.get(self.byte_idx) {
841 let ones = byte.count_ones() as usize;
842 if remaining < ones {
843 let mut b = byte;
844 for _ in 0..remaining {
845 b &= b - 1; }
847 let bit = b.trailing_zeros() as usize;
848 return Some(range_start + (self.byte_idx * 8 + bit) as u64);
849 }
850 remaining -= ones;
851 self.ones_before += ones;
852 self.byte_idx += 1;
853 }
854 None
855 }
856}
857
858#[cfg(test)]
859mod test {
860 use super::*;
861
862 #[test]
863 fn test_range_with_bitmap_data_remains_publicly_mutable() {
864 let mut segment = U64Segment::RangeWithBitmap {
865 range: 0..8,
866 bitmap: Bitmap::new_empty(8),
867 };
868 let U64Segment::RangeWithBitmap { bitmap, .. } = &mut segment else {
869 unreachable!();
870 };
871
872 bitmap.data[0] = 0b1010_0101;
873 assert_eq!(bitmap.len, 8);
874 assert_eq!(bitmap.count_ones(), 4);
875 }
876
877 #[test]
878 fn test_extend_range_over_full_and_near_dense_bitmap_bytes() {
879 let mut bitmap = Bitmap::new_full(24);
880 bitmap.clear(10);
881 bitmap.clear(17);
882 bitmap.clear(22);
883 let segment = U64Segment::RangeWithBitmap {
884 range: 100..124,
885 bitmap,
886 };
887 assert!(segment.use_dense_range_expansion(segment.len()));
888
889 let mut sparse_bitmap = Bitmap::new_empty(24);
890 for i in [0, 8, 16] {
891 sparse_bitmap.set(i);
892 }
893 let sparse_segment = U64Segment::RangeWithBitmap {
894 range: 0..24,
895 bitmap: sparse_bitmap,
896 };
897 assert!(!sparse_segment.use_dense_range_expansion(sparse_segment.len()));
898 let expected = segment.iter().collect::<Vec<_>>();
899
900 let mut state = SegmentCursorState::default();
901 let mut actual = Vec::new();
902 for selection in [0..8, 8..15, 15..21] {
903 state.extend_dense_range(&segment, selection, &mut actual);
904 }
905 assert_eq!(actual, expected);
906
907 let mut state = SegmentCursorState::default();
908 let mut partial = Vec::new();
909 state.extend_dense_range(&segment, 9..20, &mut partial);
910 assert_eq!(partial, expected[9..20]);
911 }
912
913 #[test]
914 fn test_segments() {
915 fn check_segment(values: &[u64], expected: &U64Segment) {
916 let segment = U64Segment::from_slice(values);
917 assert_eq!(segment, *expected);
918 assert_eq!(values.len(), segment.len());
919
920 let roundtripped = segment.iter().collect::<Vec<_>>();
921 assert_eq!(roundtripped, values);
922
923 let expected_min = values.iter().copied().min();
924 let expected_max = values.iter().copied().max();
925 match segment.range() {
926 Some(range) => {
927 assert_eq!(range.start(), &expected_min.unwrap());
928 assert_eq!(range.end(), &expected_max.unwrap());
929 }
930 None => {
931 assert_eq!(expected_min, None);
932 assert_eq!(expected_max, None);
933 }
934 }
935
936 for (i, value) in values.iter().enumerate() {
937 assert_eq!(segment.get(i), Some(*value), "i = {}", i);
938 assert_eq!(segment.position(*value), Some(i), "i = {}", i);
939 }
940
941 check_segment_iter(&segment);
942 }
943
944 fn check_segment_iter(segment: &U64Segment) {
945 let forwards = segment.iter().collect::<Vec<_>>();
947 let mut backwards = segment.iter().rev().collect::<Vec<_>>();
948 backwards.reverse();
949 assert_eq!(forwards, backwards);
950
951 let mut expected = Vec::with_capacity(segment.len());
953 let mut actual = Vec::with_capacity(segment.len());
954 let mut iter = segment.iter();
955 for i in 0..segment.len() {
957 if i % 2 == 0 {
958 actual.push(iter.next().unwrap());
959 expected.push(segment.get(i / 2).unwrap());
960 } else {
961 let i = segment.len() - 1 - i / 2;
962 actual.push(iter.next_back().unwrap());
963 expected.push(segment.get(i).unwrap());
964 };
965 }
966 assert_eq!(expected, actual);
967 }
968
969 check_segment(&[], &U64Segment::Range(0..0));
971
972 check_segment(&[42], &U64Segment::Range(42..43));
974
975 check_segment(
977 &(100..200).collect::<Vec<_>>(),
978 &U64Segment::Range(100..200),
979 );
980
981 let values = (0..1000).filter(|&x| x != 100).collect::<Vec<_>>();
983 check_segment(
984 &values,
985 &U64Segment::RangeWithHoles {
986 range: 0..1000,
987 holes: vec![100].into(),
988 },
989 );
990
991 let values = (0..1000).filter(|&x| x % 2 == 0).collect::<Vec<_>>();
993 check_segment(
994 &values,
995 &U64Segment::RangeWithBitmap {
996 range: 0..999,
997 bitmap: Bitmap::from((0..999).map(|x| x % 2 == 0).collect::<Vec<_>>().as_slice()),
998 },
999 );
1000
1001 check_segment(
1003 &[1, 7000, 24000],
1004 &U64Segment::SortedArray(vec![1, 7000, 24000].into()),
1005 );
1006
1007 check_segment(
1009 &[7000, 1, 24000],
1010 &U64Segment::Array(vec![7000, 1, 24000].into()),
1011 );
1012 }
1013
1014 #[test]
1018 fn test_empty_segments_have_no_range() {
1019 let empty: Vec<u64> = Vec::new();
1020 let segments = [
1021 U64Segment::Range(5..5),
1022 U64Segment::RangeWithHoles {
1023 range: 0..0,
1024 holes: empty.clone().into(),
1025 },
1026 U64Segment::RangeWithBitmap {
1027 range: 0..0,
1028 bitmap: Bitmap::new_empty(0),
1029 },
1030 U64Segment::SortedArray(empty.clone().into()),
1031 U64Segment::Array(empty.into()),
1032 ];
1033 for segment in segments {
1034 assert_eq!(segment.range(), None, "{segment:?} should have no range");
1035 }
1036 }
1037
1038 #[test]
1039 fn test_segment_overflow_boundary() {
1040 let values: Vec<u64> = vec![0, 1, 2, 100, i64::MAX as u64];
1043 let segment = U64Segment::from_slice(&values);
1044 assert!(
1045 matches!(segment, U64Segment::SortedArray(_)),
1046 "sparse range spanning i64::MAX should be SortedArray, got {:?}",
1047 std::mem::discriminant(&segment)
1048 );
1049 assert_eq!(segment.len(), 5);
1050 assert_eq!(segment.iter().collect::<Vec<_>>(), values);
1051
1052 let values: Vec<u64> = vec![0, u64::MAX];
1055 let segment = U64Segment::from_slice(&values);
1056 assert!(
1057 matches!(segment, U64Segment::SortedArray(_)),
1058 "full u64 span should be SortedArray, got {:?}",
1059 std::mem::discriminant(&segment)
1060 );
1061 assert_eq!(segment.len(), 2);
1062 assert_eq!(segment.iter().collect::<Vec<_>>(), values);
1063
1064 let values: Vec<u64> = vec![u64::MAX - 3, u64::MAX - 1, u64::MAX];
1068 let segment = U64Segment::from_slice(&values);
1069 assert!(
1070 matches!(segment, U64Segment::SortedArray(_)),
1071 "dense set near u64::MAX should be SortedArray (exclusive end unrepresentable), got {:?}",
1072 std::mem::discriminant(&segment)
1073 );
1074 assert_eq!(segment.len(), 3);
1075 assert_eq!(segment.iter().collect::<Vec<_>>(), values);
1076
1077 let values: Vec<u64> = vec![u64::MAX];
1080 let segment = U64Segment::from_slice(&values);
1081 assert!(
1082 matches!(segment, U64Segment::SortedArray(_)),
1083 "single u64::MAX should be SortedArray, got {:?}",
1084 std::mem::discriminant(&segment)
1085 );
1086 assert_eq!(segment.len(), 1);
1087 assert_eq!(segment.iter().collect::<Vec<_>>(), values);
1088
1089 let values: Vec<u64> = vec![u64::MAX - 3, u64::MAX - 2, u64::MAX - 1];
1092 let segment = U64Segment::from_slice(&values);
1093 assert_eq!(segment, U64Segment::Range((u64::MAX - 3)..u64::MAX));
1094 assert_eq!(segment.len(), 3);
1095 assert_eq!(segment.iter().collect::<Vec<_>>(), values);
1096
1097 let values: Vec<u64> = (100..1100).filter(|&x| x != 500).collect();
1100 let segment = U64Segment::from_slice(&values);
1101 assert_eq!(
1102 segment,
1103 U64Segment::RangeWithHoles {
1104 range: 100..1100,
1105 holes: vec![500].into(),
1106 }
1107 );
1108 assert_eq!(segment.len(), 999);
1109 assert_eq!(segment.iter().collect::<Vec<_>>(), values);
1110
1111 let values: Vec<u64> = vec![100, 101, 102, 103, 105];
1113 let segment = U64Segment::from_slice(&values);
1114 assert!(
1115 matches!(segment, U64Segment::RangeWithBitmap { .. }),
1116 "small dense range with hole should be RangeWithBitmap, got {:?}",
1117 std::mem::discriminant(&segment)
1118 );
1119 assert_eq!(segment.len(), 5);
1120 assert_eq!(segment.iter().collect::<Vec<_>>(), values);
1121 }
1122
1123 #[test]
1124 fn test_u128_byte_cost_to_usize() {
1125 assert_eq!(super::u128_byte_cost_to_usize(0), 0);
1126 assert_eq!(super::u128_byte_cost_to_usize(42), 42);
1127 assert_eq!(
1128 super::u128_byte_cost_to_usize(usize::MAX as u128),
1129 usize::MAX
1130 );
1131 assert_eq!(super::u128_byte_cost_to_usize(u128::MAX), usize::MAX);
1132 }
1133
1134 #[test]
1135 fn test_sorted_sequence_sizes_sparse_span_saturates_range_with_holes_cost() {
1136 let stats = super::SegmentStats {
1137 min: 0,
1138 max: i64::MAX as u64,
1139 count: 5,
1140 sorted: true,
1141 };
1142 let sizes = U64Segment::sorted_sequence_sizes(&stats);
1143 assert_eq!(sizes[0], usize::MAX);
1144 assert!(sizes[2] < sizes[0]);
1145 }
1146
1147 #[test]
1148 fn test_sorted_sequence_sizes_sorted_array_cost_saturates() {
1149 let stats = super::SegmentStats {
1152 min: 0,
1153 max: u64::MAX,
1154 count: u64::MAX,
1155 sorted: true,
1156 };
1157 let sizes = U64Segment::sorted_sequence_sizes(&stats);
1158 assert_eq!(sizes[2], usize::MAX);
1159 }
1160
1161 #[test]
1162 fn test_sorted_sequence_sizes_full_span_bitmap_cost() {
1163 let stats = super::SegmentStats {
1166 min: 0,
1167 max: u64::MAX,
1168 count: 1,
1169 sorted: true,
1170 };
1171 let sizes = U64Segment::sorted_sequence_sizes(&stats);
1172 assert!(sizes[1] < sizes[0]);
1173 assert!(sizes[1] < usize::MAX);
1174 }
1175
1176 #[test]
1177 fn test_with_new_high() {
1178 let segment = U64Segment::Range(10..20);
1180
1181 let result = segment.clone().with_new_high(20).unwrap();
1183 assert_eq!(result, U64Segment::Range(10..21));
1184
1185 let result = segment.with_new_high(25).unwrap();
1187 assert_eq!(
1188 result,
1189 U64Segment::RangeWithHoles {
1190 range: 10..26,
1191 holes: EncodedU64Array::U64(vec![20, 21, 22, 23, 24]),
1192 }
1193 );
1194
1195 let segment = U64Segment::RangeWithHoles {
1197 range: 10..20,
1198 holes: EncodedU64Array::U64(vec![15, 17]),
1199 };
1200
1201 let result = segment.clone().with_new_high(20).unwrap();
1203 assert_eq!(
1204 result,
1205 U64Segment::RangeWithHoles {
1206 range: 10..21,
1207 holes: EncodedU64Array::U64(vec![15, 17]),
1208 }
1209 );
1210
1211 let result = segment.with_new_high(25).unwrap();
1213 assert_eq!(
1214 result,
1215 U64Segment::RangeWithHoles {
1216 range: 10..26,
1217 holes: EncodedU64Array::U64(vec![15, 17, 20, 21, 22, 23, 24]),
1218 }
1219 );
1220
1221 let mut bitmap = Bitmap::new_full(10);
1223 bitmap.clear(3); bitmap.clear(7); let segment = U64Segment::RangeWithBitmap {
1226 range: 10..20,
1227 bitmap,
1228 };
1229
1230 let result = segment.clone().with_new_high(20).unwrap();
1232 let expected_bitmap = {
1233 let mut b = Bitmap::new_full(11);
1234 b.clear(3); b.clear(7); b
1237 };
1238 assert_eq!(
1239 result,
1240 U64Segment::RangeWithBitmap {
1241 range: 10..21,
1242 bitmap: expected_bitmap,
1243 }
1244 );
1245
1246 let result = segment.with_new_high(25).unwrap();
1248 let expected_bitmap = {
1249 let mut b = Bitmap::new_full(16);
1250 b.clear(3); b.clear(7); for i in 10..15 {
1254 b.clear(i);
1255 }
1256 b
1257 };
1258 assert_eq!(
1259 result,
1260 U64Segment::RangeWithBitmap {
1261 range: 10..26,
1262 bitmap: expected_bitmap,
1263 }
1264 );
1265
1266 let segment = U64Segment::SortedArray(EncodedU64Array::U64(vec![1, 5, 10]));
1268
1269 let result = segment.with_new_high(15).unwrap();
1270 assert_eq!(
1271 result,
1272 U64Segment::SortedArray(EncodedU64Array::U64(vec![1, 5, 10, 15]))
1273 );
1274
1275 let segment = U64Segment::Array(EncodedU64Array::U64(vec![10, 5, 1]));
1277
1278 let result = segment.with_new_high(15).unwrap();
1279 assert_eq!(
1280 result,
1281 U64Segment::Array(EncodedU64Array::U64(vec![10, 5, 1, 15]))
1282 );
1283
1284 let segment = U64Segment::Range(0..0);
1287 let result = segment.with_new_high(5).unwrap();
1288 assert_eq!(result, U64Segment::Range(5..6));
1289
1290 let segment = U64Segment::Range(42..43);
1292 let result = segment.with_new_high(50).unwrap();
1293 assert_eq!(
1294 result,
1295 U64Segment::RangeWithHoles {
1296 range: 42..51,
1297 holes: EncodedU64Array::U64(vec![43, 44, 45, 46, 47, 48, 49]),
1298 }
1299 );
1300 }
1301
1302 #[test]
1303 fn test_with_new_high_assertion() {
1304 let segment = U64Segment::Range(10..20);
1305 let result = segment.with_new_high(15);
1307 assert!(result.is_err());
1308 let error = result.unwrap_err();
1309 assert!(
1310 error
1311 .to_string()
1312 .contains("New value 15 must be higher than current maximum 19")
1313 );
1314 }
1315
1316 #[test]
1317 fn test_with_new_high_assertion_equal() {
1318 let segment = U64Segment::Range(1..6);
1319 let result = segment.with_new_high(5);
1321 assert!(result.is_err());
1322 let error = result.unwrap_err();
1323 assert!(
1324 error
1325 .to_string()
1326 .contains("New value 5 must be higher than current maximum 5")
1327 );
1328 }
1329
1330 #[test]
1331 fn test_contains() {
1332 let segment = U64Segment::Range(10..20);
1334 assert!(segment.contains(10), "Should contain 10");
1335 assert!(segment.contains(15), "Should contain 15");
1336 assert!(segment.contains(19), "Should contain 19");
1337 assert!(!segment.contains(9), "Should not contain 9");
1338 assert!(!segment.contains(20), "Should not contain 20");
1339 assert!(!segment.contains(25), "Should not contain 25");
1340
1341 let segment = U64Segment::RangeWithHoles {
1343 range: 10..20,
1344 holes: EncodedU64Array::U64(vec![15, 17]),
1345 };
1346 assert!(segment.contains(10), "Should contain 10");
1347 assert!(segment.contains(14), "Should contain 14");
1348 assert!(!segment.contains(15), "Should not contain 15 (hole)");
1349 assert!(segment.contains(16), "Should contain 16");
1350 assert!(!segment.contains(17), "Should not contain 17 (hole)");
1351 assert!(segment.contains(18), "Should contain 18");
1352 assert!(
1353 !segment.contains(20),
1354 "Should not contain 20 (out of range)"
1355 );
1356
1357 let mut bitmap = Bitmap::new_full(10);
1359 bitmap.clear(3); bitmap.clear(7); let segment = U64Segment::RangeWithBitmap {
1362 range: 10..20,
1363 bitmap,
1364 };
1365 assert!(segment.contains(10), "Should contain 10");
1366 assert!(segment.contains(12), "Should contain 12");
1367 assert!(
1368 !segment.contains(13),
1369 "Should not contain 13 (cleared in bitmap)"
1370 );
1371 assert!(segment.contains(16), "Should contain 16");
1372 assert!(
1373 !segment.contains(17),
1374 "Should not contain 17 (cleared in bitmap)"
1375 );
1376 assert!(segment.contains(19), "Should contain 19");
1377 assert!(
1378 !segment.contains(20),
1379 "Should not contain 20 (out of range)"
1380 );
1381
1382 let segment = U64Segment::SortedArray(EncodedU64Array::U64(vec![1, 5, 10]));
1384 assert!(segment.contains(1), "Should contain 1");
1385 assert!(segment.contains(5), "Should contain 5");
1386 assert!(segment.contains(10), "Should contain 10");
1387 assert!(!segment.contains(0), "Should not contain 0");
1388 assert!(!segment.contains(3), "Should not contain 3");
1389 assert!(!segment.contains(15), "Should not contain 15");
1390
1391 let segment = U64Segment::Array(EncodedU64Array::U64(vec![10, 5, 1]));
1393 assert!(segment.contains(1), "Should contain 1");
1394 assert!(segment.contains(5), "Should contain 5");
1395 assert!(segment.contains(10), "Should contain 10");
1396 assert!(!segment.contains(0), "Should not contain 0");
1397 assert!(!segment.contains(3), "Should not contain 3");
1398 assert!(!segment.contains(15), "Should not contain 15");
1399
1400 let segment = U64Segment::Range(0..0);
1402 assert!(
1403 !segment.contains(0),
1404 "Empty segment should not contain anything"
1405 );
1406 assert!(
1407 !segment.contains(5),
1408 "Empty segment should not contain anything"
1409 );
1410 }
1411}