flatk/chunked/
offsets.rs

1use super::*;
2use std::convert::{AsMut, AsRef};
3use std::ops::Range;
4
5#[cfg(feature = "rayon")]
6pub(crate) mod par_iter;
7
8/// A collection of offsets into another collection.
9/// This newtype is intended to verify basic invariants about offsets into
10/// another collection, namely that the collection is monotonically increasing
11/// and non-empty.
12#[derive(Copy, Clone, Debug, PartialEq)]
13pub struct Offsets<O = Vec<usize>>(O);
14
15impl<O: Set<Elem = usize, Atom = usize>> Set for Offsets<O> {
16    type Elem = usize;
17    type Atom = usize;
18
19    #[inline]
20    fn len(&self) -> usize {
21        self.0.len()
22    }
23}
24
25impl<O: AsRef<[usize]> + Set> Offsets<O> {
26    #[inline]
27    fn offset_value_ranges(&self) -> OffsetValueRanges {
28        self.view().into_offset_value_ranges()
29    }
30}
31
32impl<'a> Offsets<&'a [usize]> {
33    #[inline]
34    fn into_offset_value_ranges(self) -> OffsetValueRanges<'a> {
35        OffsetValueRanges { offsets: self }
36    }
37
38    /// Separate the offsets into two groups overlapping by one chunk at the given index.
39    #[inline]
40    pub fn separate_offsets_with_overlap(
41        self,
42        index: usize,
43    ) -> (Offsets<&'a [usize]>, Offsets<&'a [usize]>) {
44        // Check bounds, and ensure that self has at least two elements.
45        assert!(index + 1 < self.0.len());
46        let l = &self.0[..index + 2];
47        let r = &self.0[index..];
48        (Offsets(l), Offsets(r))
49    }
50}
51
52impl<O: RemovePrefix + Set> Offsets<O> {
53    /// Unchecked version of `RemovePrefix::remove_prefix`.
54    ///
55    /// # Safety
56    ///
57    /// This function may cause undefined behaviour in safe APIs if calling this function produces
58    /// an empty `offsets` collection.
59    #[inline]
60    pub unsafe fn remove_prefix_unchecked(&mut self, n: usize) {
61        self.0.remove_prefix(n);
62    }
63}
64
65impl Offsets<&[usize]> {
66    /// Remove `n` offsets from the end.
67    ///
68    /// # Safety
69    ///
70    /// This function may cause undefined behaviour in safe APIs if calling this function produces
71    /// an empty `offsets` collection.
72    #[inline]
73    pub unsafe fn remove_suffix_unchecked(&mut self, n: usize) {
74        self.0 = self.0.get_unchecked(..self.0.len() - n);
75    }
76}
77
78impl<O: Viewed> Viewed for Offsets<O> {}
79
80// SAFETY: Offsets should always be non-empty.
81unsafe impl<O: AsRef<[usize]>> GetOffset for Offsets<O> {
82    /// A version of `offset_value` without bounds checking.
83    ///
84    /// # Safety
85    ///
86    /// It is assumed that `index` is strictly less than `self.num_offsets()`.
87    #[inline]
88    unsafe fn offset_value_unchecked(&self, index: usize) -> usize {
89        *self.0.as_ref().get_unchecked(index)
90    }
91
92    /// Get the total number of offsets.
93    ///
94    /// This is one more than the number of chunks represented.
95    fn num_offsets(&self) -> usize {
96        self.0.as_ref().len()
97    }
98}
99
100impl<O: AsRef<[usize]>> BinarySearch<usize> for Offsets<O> {
101    /// Binary search the offsets for a given offset `off`.
102    ///
103    /// `off` is expected to be with respect to the beginning of the range represented by the
104    /// current offsets. In other words, we are searching for offsets, not raw offset values
105    /// stored in `Offsets`.
106    ///
107    /// The semantics of this function are identical to Rust's `std::slice::binary_search`.
108    #[inline]
109    fn binary_search(&self, off: &usize) -> Result<usize, usize> {
110        self.as_ref()
111            .binary_search(&(*off + self.first_offset_value()))
112    }
113}
114
115/// An iterator over offset values.
116#[derive(Copy, Clone, Debug, PartialEq)]
117pub struct OffsetValues<'a> {
118    offset_values: &'a [usize],
119}
120
121impl<'a> Iterator for OffsetValues<'a> {
122    type Item = usize;
123
124    /// Get the next available offset.
125    #[inline]
126    fn next(&mut self) -> Option<usize> {
127        self.offset_values.split_first().map(|(first, rest)| {
128            self.offset_values = rest;
129            *first
130        })
131    }
132
133    #[inline]
134    fn size_hint(&self) -> (usize, Option<usize>) {
135        let n = self.offset_values.len();
136        (n, Some(n))
137    }
138
139    #[inline]
140    fn count(self) -> usize {
141        ExactSizeIterator::len(&self)
142    }
143
144    #[inline]
145    fn nth(&mut self, n: usize) -> Option<Self::Item> {
146        self.offset_values.get(n).copied()
147    }
148
149    #[inline]
150    fn last(mut self) -> Option<Self::Item> {
151        self.next_back()
152    }
153}
154
155impl DoubleEndedIterator for OffsetValues<'_> {
156    #[inline]
157    fn next_back(&mut self) -> Option<usize> {
158        self.offset_values.split_last().map(|(last, rest)| {
159            self.offset_values = rest;
160            *last
161        })
162    }
163
164    #[inline]
165    fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
166        self.offset_values
167            .get(ExactSizeIterator::len(self) - 1 - n)
168            .copied()
169    }
170}
171
172impl ExactSizeIterator for OffsetValues<'_> {}
173impl std::iter::FusedIterator for OffsetValues<'_> {}
174
175unsafe impl TrustedRandomAccess for OffsetValues<'_> {
176    unsafe fn get_unchecked(&mut self, i: usize) -> Self::Item {
177        *self.offset_values.get_unchecked(i)
178    }
179}
180
181/// Iterator over ranges of offset values.
182#[derive(Copy, Clone, Debug, PartialEq)]
183pub struct OffsetValueRanges<'a> {
184    /// Offsets used to keep track of which range we are at.
185    offsets: Offsets<&'a [usize]>,
186}
187
188// SAFETY: since sizes are one less than offsets, the last offset will never be consumed.
189unsafe impl GetOffset for OffsetValueRanges<'_> {
190    /// Get the offset value without bounds checking.
191    ///
192    /// # Safety
193    ///
194    /// This function assumes that `i` is strictly less than `self.num_offsets()`.
195    #[inline]
196    unsafe fn offset_value_unchecked(&self, i: usize) -> usize {
197        self.offsets.offset_value_unchecked(i)
198    }
199    #[inline]
200    fn num_offsets(&self) -> usize {
201        self.offsets.num_offsets()
202    }
203}
204
205impl<'a> Iterator for OffsetValueRanges<'a> {
206    type Item = std::ops::Range<usize>;
207
208    #[inline]
209    fn next(&mut self) -> Option<Self::Item> {
210        if self.offsets.num_offsets() < 2 {
211            return None;
212        }
213        let begin = self.offsets.first_offset_value();
214
215        // SAFETY: there are at least two offsets as checked above.
216        unsafe {
217            self.offsets.remove_prefix_unchecked(1);
218        }
219
220        let end = self.offsets.first_offset_value();
221        Some(begin..end)
222    }
223
224    #[inline]
225    fn size_hint(&self) -> (usize, Option<usize>) {
226        let n = self.offsets.num_offsets() - 1;
227        (n, Some(n))
228    }
229
230    #[inline]
231    fn count(self) -> usize {
232        self.len()
233    }
234
235    #[inline]
236    fn nth(&mut self, n: usize) -> Option<Self::Item> {
237        if n + 1 < self.offsets.num_offsets() {
238            // SAFETY: bounds are checked above to ensure at least one more element after n
239            // elements are removed.
240            unsafe {
241                let begin = self.offsets.offset_value_unchecked(n);
242                self.offsets.remove_prefix_unchecked(n + 1);
243                let end = self.offsets.first_offset_value();
244                Some(begin..end)
245            }
246        } else {
247            None
248        }
249    }
250
251    #[inline]
252    fn last(mut self) -> Option<Self::Item> {
253        self.next_back()
254    }
255}
256
257impl<'a> DoubleEndedIterator for OffsetValueRanges<'a> {
258    #[inline]
259    fn next_back(&mut self) -> Option<Self::Item> {
260        if self.offsets.num_offsets() < 2 {
261            return None;
262        }
263        let end = self.offsets.last_offset_value();
264        // SAFETY: there are at least two offsets as checked above.
265        unsafe {
266            self.offsets.remove_suffix_unchecked(1);
267        }
268        let begin = self.offsets.last_offset_value();
269        Some(begin..end)
270    }
271
272    #[inline]
273    fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
274        let num_offsets = self.offsets.num_offsets();
275        if n + 1 < num_offsets {
276            // SAFETY: bounds are checked above to ensure at least one more element after n
277            // elements are removed.
278            unsafe {
279                let end = self.offsets.offset_value_unchecked(num_offsets - 1 - n);
280                self.offsets.remove_suffix_unchecked(n + 1);
281                let begin = self.offsets.last_offset_value();
282                Some(begin..end)
283            }
284        } else {
285            None
286        }
287    }
288}
289
290impl ExactSizeIterator for OffsetValueRanges<'_> {}
291impl std::iter::FusedIterator for OffsetValueRanges<'_> {}
292
293unsafe impl TrustedRandomAccess for OffsetValueRanges<'_> {
294    #[inline]
295    unsafe fn get_unchecked(&mut self, i: usize) -> Self::Item {
296        let begin = self.offsets.offset_value_unchecked(i - 1);
297        let end = self.offsets.offset_value_unchecked(i);
298        begin..end
299    }
300}
301
302/// Iterator over ranges of offsets.
303///
304/// This is basically an adapter for `OffsetValueRanges` that subtracts the first offset value from
305/// each reange to generate a useful offset range.
306#[derive(Copy, Clone, Debug, PartialEq)]
307pub struct Ranges<'a> {
308    /// Offset value ranges iterator.
309    offset_value_ranges: OffsetValueRanges<'a>,
310    /// The very first offset value used to normalize the generated ranges.
311    first_offset_value: usize,
312}
313
314impl<'a> Ranges<'a> {
315    /// Produces a function that converts an offset *value* range into a bona-fide offset range by
316    /// subtracting the first offset from both endpoints.
317    #[inline]
318    fn offset_range_converter(&self) -> impl Fn(Range<usize>) -> Range<usize> + '_ {
319        move |Range { start, end }| start - self.first_offset_value..end - self.first_offset_value
320    }
321}
322
323// SAFETY: since ranges are one less than offsets, the last offset will never be consumed.
324unsafe impl GetOffset for Ranges<'_> {
325    #[inline]
326    unsafe fn offset_value_unchecked(&self, i: usize) -> usize {
327        self.offset_value_ranges.offset_value_unchecked(i)
328    }
329    #[inline]
330    fn num_offsets(&self) -> usize {
331        self.offset_value_ranges.num_offsets()
332    }
333}
334
335impl<'a> Iterator for Ranges<'a> {
336    type Item = Range<usize>;
337
338    #[inline]
339    fn next(&mut self) -> Option<Self::Item> {
340        self.offset_value_ranges
341            .next()
342            .map(self.offset_range_converter())
343    }
344
345    #[inline]
346    fn size_hint(&self) -> (usize, Option<usize>) {
347        self.offset_value_ranges.size_hint()
348    }
349
350    #[inline]
351    fn count(self) -> usize {
352        self.offset_value_ranges.count()
353    }
354
355    #[inline]
356    fn nth(&mut self, n: usize) -> Option<Self::Item> {
357        self.offset_value_ranges
358            .nth(n)
359            .map(self.offset_range_converter())
360    }
361
362    #[inline]
363    fn last(self) -> Option<Self::Item> {
364        self.offset_value_ranges
365            .last()
366            .map(self.offset_range_converter())
367    }
368}
369
370impl<'a> DoubleEndedIterator for Ranges<'a> {
371    #[inline]
372    fn next_back(&mut self) -> Option<Self::Item> {
373        self.offset_value_ranges
374            .next_back()
375            .map(self.offset_range_converter())
376    }
377
378    #[inline]
379    fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
380        self.offset_value_ranges
381            .nth_back(n)
382            .map(self.offset_range_converter())
383    }
384}
385
386impl ExactSizeIterator for Ranges<'_> {}
387impl std::iter::FusedIterator for Ranges<'_> {}
388
389unsafe impl TrustedRandomAccess for Ranges<'_> {
390    #[inline]
391    unsafe fn get_unchecked(&mut self, i: usize) -> Self::Item {
392        let rng = self.offset_value_ranges.get_unchecked(i);
393        (self.offset_range_converter())(rng)
394    }
395}
396
397#[derive(Copy, Clone, Debug, PartialEq)]
398pub struct Sizes<'a> {
399    offset_value_ranges: OffsetValueRanges<'a>,
400}
401
402impl<'a> Sizes<'a> {
403    /// Produces a function that converts an offset value range into a range size by
404    /// subtracting the last and first end points.
405    #[inline]
406    fn range_to_size_mapper(&self) -> impl Fn(Range<usize>) -> usize + '_ {
407        move |Range { start, end }| end - start
408    }
409}
410
411// SAFETY: since sizes are one less than offsets, the last offset will never be consumed.
412unsafe impl GetOffset for Sizes<'_> {
413    #[inline]
414    unsafe fn offset_value_unchecked(&self, i: usize) -> usize {
415        self.offset_value_ranges.offset_value_unchecked(i)
416    }
417    #[inline]
418    fn num_offsets(&self) -> usize {
419        self.offset_value_ranges.num_offsets()
420    }
421}
422
423impl<'a> Iterator for Sizes<'a> {
424    type Item = usize;
425
426    #[inline]
427    fn next(&mut self) -> Option<usize> {
428        self.offset_value_ranges
429            .next()
430            .map(self.range_to_size_mapper())
431    }
432
433    #[inline]
434    fn size_hint(&self) -> (usize, Option<usize>) {
435        self.offset_value_ranges.size_hint()
436    }
437
438    #[inline]
439    fn count(self) -> usize {
440        self.offset_value_ranges.count()
441    }
442
443    #[inline]
444    fn nth(&mut self, n: usize) -> Option<Self::Item> {
445        self.offset_value_ranges
446            .nth(n)
447            .map(self.range_to_size_mapper())
448    }
449
450    #[inline]
451    fn last(self) -> Option<Self::Item> {
452        self.offset_value_ranges
453            .last()
454            .map(self.range_to_size_mapper())
455    }
456}
457
458impl<'a> DoubleEndedIterator for Sizes<'a> {
459    #[inline]
460    fn next_back(&mut self) -> Option<Self::Item> {
461        self.offset_value_ranges
462            .next_back()
463            .map(self.range_to_size_mapper())
464    }
465
466    #[inline]
467    fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
468        self.offset_value_ranges
469            .nth_back(n)
470            .map(self.range_to_size_mapper())
471    }
472}
473
474impl ExactSizeIterator for Sizes<'_> {}
475impl std::iter::FusedIterator for Sizes<'_> {}
476
477unsafe impl TrustedRandomAccess for Sizes<'_> {
478    #[inline]
479    unsafe fn get_unchecked(&mut self, i: usize) -> Self::Item {
480        let rng = self.offset_value_ranges.get_unchecked(i);
481        (self.range_to_size_mapper())(rng)
482    }
483}
484
485#[derive(Copy, Clone, Debug, PartialEq)]
486pub struct OffsetValuesAndSizes<'a> {
487    offset_value_ranges: OffsetValueRanges<'a>,
488}
489
490impl<'a> OffsetValuesAndSizes<'a> {
491    /// Produces a function that converts an offset value range into a starting offset value and
492    /// range size by subtracting the last and first end points.
493    #[inline]
494    fn range_mapper(&self) -> impl Fn(Range<usize>) -> (usize, usize) + '_ {
495        move |Range { start, end }| (start, end - start)
496    }
497}
498
499// SAFETY: since sizes are one less than offsets, the last offset will never be consumed.
500unsafe impl GetOffset for OffsetValuesAndSizes<'_> {
501    #[inline]
502    unsafe fn offset_value_unchecked(&self, i: usize) -> usize {
503        self.offset_value_ranges.offset_value_unchecked(i)
504    }
505    #[inline]
506    fn num_offsets(&self) -> usize {
507        self.offset_value_ranges.num_offsets()
508    }
509}
510
511impl<'a> Iterator for OffsetValuesAndSizes<'a> {
512    type Item = (usize, usize);
513
514    #[inline]
515    fn next(&mut self) -> Option<Self::Item> {
516        self.offset_value_ranges.next().map(self.range_mapper())
517    }
518
519    #[inline]
520    fn size_hint(&self) -> (usize, Option<usize>) {
521        self.offset_value_ranges.size_hint()
522    }
523
524    #[inline]
525    fn count(self) -> usize {
526        self.offset_value_ranges.count()
527    }
528
529    #[inline]
530    fn nth(&mut self, n: usize) -> Option<Self::Item> {
531        self.offset_value_ranges.nth(n).map(self.range_mapper())
532    }
533
534    #[inline]
535    fn last(self) -> Option<Self::Item> {
536        self.offset_value_ranges.last().map(self.range_mapper())
537    }
538}
539
540impl<'a> DoubleEndedIterator for OffsetValuesAndSizes<'a> {
541    #[inline]
542    fn next_back(&mut self) -> Option<Self::Item> {
543        self.offset_value_ranges
544            .next_back()
545            .map(self.range_mapper())
546    }
547
548    #[inline]
549    fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
550        self.offset_value_ranges
551            .nth_back(n)
552            .map(self.range_mapper())
553    }
554}
555
556impl ExactSizeIterator for OffsetValuesAndSizes<'_> {}
557impl std::iter::FusedIterator for OffsetValuesAndSizes<'_> {}
558
559unsafe impl TrustedRandomAccess for OffsetValuesAndSizes<'_> {
560    #[inline]
561    unsafe fn get_unchecked(&mut self, i: usize) -> Self::Item {
562        let rng = self.offset_value_ranges.get_unchecked(i);
563        (self.range_mapper())(rng)
564    }
565}
566
567#[derive(Copy, Clone, Debug, PartialEq)]
568pub struct OffsetsAndSizes<'a> {
569    offset_value_ranges: OffsetValueRanges<'a>,
570    first_offset_value: usize,
571}
572
573impl<'a> OffsetsAndSizes<'a> {
574    /// Produces a function that converts an offset value range into a range size by
575    /// subtracting the last and first end points.
576    #[inline]
577    fn range_mapper(&self) -> impl Fn(Range<usize>) -> (usize, usize) + '_ {
578        move |Range { start, end }| (start - self.first_offset_value, end - start)
579    }
580}
581
582// SAFETY: since sizes are one less than offsets, the last offset will never be consumed.
583unsafe impl GetOffset for OffsetsAndSizes<'_> {
584    #[inline]
585    unsafe fn offset_value_unchecked(&self, i: usize) -> usize {
586        self.offset_value_ranges.offset_value_unchecked(i)
587    }
588    #[inline]
589    fn num_offsets(&self) -> usize {
590        self.offset_value_ranges.num_offsets()
591    }
592}
593
594impl<'a> Iterator for OffsetsAndSizes<'a> {
595    type Item = (usize, usize);
596
597    #[inline]
598    fn next(&mut self) -> Option<Self::Item> {
599        self.offset_value_ranges.next().map(self.range_mapper())
600    }
601
602    #[inline]
603    fn size_hint(&self) -> (usize, Option<usize>) {
604        self.offset_value_ranges.size_hint()
605    }
606
607    #[inline]
608    fn count(self) -> usize {
609        self.offset_value_ranges.count()
610    }
611
612    #[inline]
613    fn nth(&mut self, n: usize) -> Option<Self::Item> {
614        self.offset_value_ranges.nth(n).map(self.range_mapper())
615    }
616
617    #[inline]
618    fn last(self) -> Option<Self::Item> {
619        self.offset_value_ranges.last().map(self.range_mapper())
620    }
621}
622
623impl<'a> DoubleEndedIterator for OffsetsAndSizes<'a> {
624    #[inline]
625    fn next_back(&mut self) -> Option<Self::Item> {
626        self.offset_value_ranges
627            .next_back()
628            .map(self.range_mapper())
629    }
630
631    #[inline]
632    fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
633        self.offset_value_ranges
634            .nth_back(n)
635            .map(self.range_mapper())
636    }
637}
638
639impl ExactSizeIterator for OffsetsAndSizes<'_> {}
640impl std::iter::FusedIterator for OffsetsAndSizes<'_> {}
641
642unsafe impl TrustedRandomAccess for OffsetsAndSizes<'_> {
643    #[inline]
644    unsafe fn get_unchecked(&mut self, i: usize) -> Self::Item {
645        let rng = self.offset_value_ranges.get_unchecked(i);
646        (self.range_mapper())(rng)
647    }
648}
649
650impl<'a> IntoValues for Offsets<&'a [usize]> {
651    type Iter = OffsetValues<'a>;
652    /// Returns an iterator over offset values represented by the stored `Offsets`.
653    #[inline]
654    fn into_values(self) -> OffsetValues<'a> {
655        OffsetValues {
656            offset_values: self.0,
657        }
658    }
659}
660
661impl<'a> IntoSizes for Offsets<&'a [usize]> {
662    type Iter = Sizes<'a>;
663    /// Returns an iterator over chunk sizes represented by the stored `Offsets`.
664    #[inline]
665    fn into_sizes(self) -> Sizes<'a> {
666        Sizes {
667            offset_value_ranges: self.into_offset_value_ranges(),
668        }
669    }
670}
671
672impl<'a> IntoOffsetValuesAndSizes for Offsets<&'a [usize]> {
673    type Iter = OffsetValuesAndSizes<'a>;
674    /// Returns an iterator over offset value and chunk size pairs.
675    #[inline]
676    fn into_offset_values_and_sizes(self) -> OffsetValuesAndSizes<'a> {
677        OffsetValuesAndSizes {
678            offset_value_ranges: self.into_offset_value_ranges(),
679        }
680    }
681}
682
683impl<'a> IntoRanges for Offsets<&'a [usize]> {
684    type Iter = Ranges<'a>;
685    /// Returns an iterator over offset ranges represented by the stored `Offsets`.
686    #[inline]
687    fn into_ranges(self) -> Ranges<'a> {
688        Ranges {
689            offset_value_ranges: self.into_offset_value_ranges(),
690            first_offset_value: self.first_offset_value(),
691        }
692    }
693}
694
695impl<O: AsRef<[usize]> + Set> Offsets<O> {
696    /// Returns an iterator over chunk sizes represented by the stored `Offsets`.
697    #[inline]
698    pub fn sizes(&self) -> Sizes {
699        Sizes {
700            offset_value_ranges: self.offset_value_ranges(),
701        }
702    }
703
704    /// Returns an iterator over offsets.
705    #[inline]
706    pub fn iter(&self) -> impl Iterator<Item = usize> + '_ {
707        let first = self.first_offset_value();
708        self.0.as_ref().iter().map(move |&x| x - first)
709    }
710
711    /// Returns an iterator over offset values.
712    #[inline]
713    pub fn values(&self) -> OffsetValues {
714        OffsetValues {
715            offset_values: self.0.as_ref(),
716        }
717    }
718
719    /// Returns an iterator over offset ranges.
720    #[inline]
721    pub fn ranges(&self) -> Ranges {
722        Ranges {
723            offset_value_ranges: self.offset_value_ranges(),
724            first_offset_value: self.first_offset_value(),
725        }
726    }
727}
728
729impl<'a, O: AsRef<[usize]>> View<'a> for Offsets<O> {
730    type Type = Offsets<&'a [usize]>;
731    #[inline]
732    fn view(&'a self) -> Self::Type {
733        Offsets(self.0.as_ref())
734    }
735}
736
737impl<'a, O: AsMut<[usize]>> ViewMut<'a> for Offsets<O> {
738    type Type = Offsets<&'a mut [usize]>;
739    #[inline]
740    fn view_mut(&'a mut self) -> Self::Type {
741        Offsets(self.0.as_mut())
742    }
743}
744
745//impl<'a, O: AsRef<[usize]>> Viewable for &'a Offsets<O> {
746//    type View = Offsets<&'a [usize]>;
747//    fn into_view(self) -> Self::View {
748//        Offsets(self.0.as_ref())
749//    }
750//}
751
752impl<O: AsRef<[usize]>> From<O> for Offsets<O> {
753    #[inline]
754    fn from(offsets: O) -> Self {
755        // Note that new checks that offsets has at least one element.
756        Offsets::new(offsets)
757    }
758}
759
760impl<O: AsRef<[usize]>> AsRef<[usize]> for Offsets<O> {
761    #[inline]
762    fn as_ref(&self) -> &[usize] {
763        self.0.as_ref()
764    }
765}
766
767impl<O: AsMut<[usize]>> AsMut<[usize]> for Offsets<O> {
768    #[inline]
769    fn as_mut(&mut self) -> &mut [usize] {
770        self.0.as_mut()
771    }
772}
773
774/// A default set of offsets must allocate.
775impl Default for Offsets<Vec<usize>> {
776    #[inline]
777    fn default() -> Self {
778        Offsets(vec![0])
779    }
780}
781
782impl<O: Dummy> Dummy for Offsets<O> {
783    #[inline]
784    unsafe fn dummy() -> Self {
785        Offsets(Dummy::dummy())
786    }
787}
788
789impl<O: AsRef<[usize]>> Offsets<O> {
790    /// Construct a set `Offsets` from a given set of offsets.
791    ///
792    /// # Panics
793    ///
794    /// The given `offsets` must be a non-empty collection, otherwise this function will panic.
795    #[inline]
796    pub fn new(offsets: O) -> Self {
797        assert!(!offsets.as_ref().is_empty());
798        Offsets(offsets)
799    }
800
801    /// An unchecked version of the `new` constructor.
802    ///
803    /// # Safety
804    ///
805    /// Calling this function with empty `offsets` may cause undefined behaviour in safe APIs.
806    #[inline]
807    pub unsafe fn from_raw(offsets: O) -> Self {
808        Offsets(offsets)
809    }
810}
811
812impl<O> Offsets<O> {
813    #[inline]
814    pub fn into_inner(self) -> O {
815        self.0
816    }
817}
818
819impl<O: AsMut<[usize]>> Offsets<O> {
820    /// Moves an offset back by a specified amount.
821    ///
822    /// This effectively transfers `by` elements to the specified `at` chunk from the preceeding chunk.
823    ///
824    /// # Panics
825    ///
826    /// This function panics if `at` is out of bounds.
827    ///
828    /// If `at` it zero, the beginning of the indexed range is simply extended, but an overflow
829    /// panic will be caused if the first offset is moved below zero since offsets are represented
830    /// by unsigned integers.
831    ///
832    /// It is a logic error to move an offset past its preceeding offset because this will break
833    /// the monotonicity of the offset sequence, which can cause panics from other function on the
834    /// Offsets.
835    ///
836    /// # Example
837    ///
838    /// ```
839    /// use flatk::Offsets;
840    /// let mut o = Offsets::new(vec![0, 4, 9]);
841    /// o.move_back(1, 2);
842    /// assert_eq!(o, vec![0, 2, 9].into());
843    /// ```
844    #[inline]
845    pub fn move_back(&mut self, at: usize, by: usize) {
846        let offsets = self.as_mut();
847        offsets[at] -= by;
848        debug_assert!(at == 0 || offsets[at] >= offsets[at - 1]);
849    }
850    /// Moves an offset forward by a specified amount.
851    ///
852    /// This effectively transfers `by` elements to the specified `at` chunk from the succeeding chunk.
853    ///
854    /// If `at` indexes the last offset, then the indexed range is simply increased.
855    ///
856    /// # Panics
857    ///
858    /// This function panics if `at` is out of bounds.
859    ///
860    /// It is a logic error to move an offset past its succeeding offset because this will break
861    /// the monotonicity of the offset sequence, which can cause panics from other function on the
862    /// Offsets.
863    ///
864    /// # Example
865    ///
866    /// ```
867    /// use flatk::Offsets;
868    /// let mut o = Offsets::new(vec![0, 4, 9]);
869    /// o.move_forward(1, 2);
870    /// assert_eq!(o, vec![0, 6, 9].into());
871    /// ```
872    #[inline]
873    pub fn move_forward(&mut self, at: usize, by: usize) {
874        let offsets = self.as_mut();
875        offsets[at] += by;
876        debug_assert!(at == offsets.len() - 1 || offsets[at] <= offsets[at + 1]);
877    }
878
879    /// Extend the last offset.
880    ///
881    /// This effectively increases the last chunk size.
882    /// This function is the same as `self.move_forward(self.len() - 1, by)`.
883    ///
884    /// # Example
885    ///
886    /// ```
887    /// use flatk::Offsets;
888    /// let mut o = Offsets::new(vec![0, 4, 9]);
889    /// o.extend_last(2);
890    /// assert_eq!(o, vec![0, 4, 11].into());
891    /// ```
892    #[inline]
893    pub fn extend_last(&mut self, by: usize) {
894        let offsets = self.as_mut();
895        offsets[offsets.len() - 1] += by;
896    }
897
898    /// Shrink the last offset.
899    ///
900    /// This effectively decreases the last chunk size.
901    /// This function is the same as `self.move_back(self.len() - 1, by)`.
902    ///
903    /// # Panics
904    ///
905    /// It is a logic error to move an offset past its preceeding offset because this will break
906    /// the monotonicity of the offset sequence, which can cause panics from other function on the
907    /// Offsets.
908    ///
909    /// # Example
910    ///
911    /// ```
912    /// use flatk::Offsets;
913    /// let mut o = Offsets::new(vec![0, 4, 9]);
914    /// o.shrink_last(2);
915    /// assert_eq!(o, vec![0, 4, 7].into());
916    /// ```
917    #[inline]
918    pub fn shrink_last(&mut self, by: usize) {
919        let offsets = self.as_mut();
920        offsets[offsets.len() - 1] -= by;
921        debug_assert!(
922            offsets.len() == 1 || offsets[offsets.len() - 1] >= offsets[offsets.len() - 2]
923        );
924    }
925}
926
927impl<O: Push<usize>> Push<usize> for Offsets<O> {
928    #[inline]
929    fn push(&mut self, item: usize) {
930        self.0.push(item);
931    }
932}
933
934impl<I: std::slice::SliceIndex<[usize]>, O: AsRef<[usize]>> std::ops::Index<I> for Offsets<O> {
935    type Output = I::Output;
936    #[inline]
937    fn index(&self, index: I) -> &Self::Output {
938        self.0.as_ref().index(index)
939    }
940}
941
942impl<I: std::slice::SliceIndex<[usize]>, O: AsRef<[usize]> + AsMut<[usize]>> std::ops::IndexMut<I>
943    for Offsets<O>
944{
945    #[inline]
946    fn index_mut(&mut self, index: I) -> &mut Self::Output {
947        self.0.as_mut().index_mut(index)
948    }
949}
950
951impl Clear for Offsets {
952    #[inline]
953    fn clear(&mut self) {
954        self.0.truncate(1);
955    }
956}
957
958impl<O: std::iter::FromIterator<usize> + AsRef<[usize]>> std::iter::FromIterator<usize>
959    for Offsets<O>
960{
961    #[inline]
962    fn from_iter<T>(iter: T) -> Self
963    where
964        T: IntoIterator<Item = usize>,
965    {
966        Offsets::new(O::from_iter(iter))
967    }
968}
969
970impl<'a> SplitOffsetsAt for Offsets<&'a [usize]> {
971    /// Same as `split_offsets_at`, but in addition, return the offset of the middle element
972    /// (intersection): this is the value `offsets[mid] - offsets[0]`.
973    ///
974    /// # Panics
975    ///
976    /// Calling this function with an empty slice or with `mid` greater than or equal to its length
977    /// will cause a panic.
978    #[inline]
979    fn split_offsets_with_intersection_at(
980        self,
981        mid: usize,
982    ) -> (Offsets<&'a [usize]>, Offsets<&'a [usize]>, usize) {
983        let (l, r) = self.split_offsets_at(mid);
984        // This is safe since self.0 is not empty, both l and r have at least one element.
985        let off = unsafe { *r.0.get_unchecked(0) - *l.0.get_unchecked(0) };
986        (l, r, off)
987    }
988
989    /// Splits a slice of offsets at the given index into two slices such that each
990    /// slice is a valid slice of offsets. This means that the element at index
991    /// `mid` is shared between the two output slices.
992    ///
993    /// # Panics
994    ///
995    /// Calling this function with an empty slice or with `mid` greater than or equal to its length
996    /// will cause a panic.
997    #[inline]
998    fn split_offsets_at(self, mid: usize) -> (Offsets<&'a [usize]>, Offsets<&'a [usize]>) {
999        // Check bounds, and ensure that self is not empty.
1000        assert!(mid < self.0.len());
1001        let l = &self.0[..=mid];
1002        let r = &self.0[mid..];
1003        (Offsets(l), Offsets(r))
1004    }
1005}
1006
1007impl<O: AsRef<[usize]> + Set> IndexRange for Offsets<O> {
1008    #[inline]
1009    unsafe fn index_range_unchecked(&self, range: Range<usize>) -> Range<usize> {
1010        self.offset_unchecked(range.start)..self.offset_unchecked(range.end)
1011    }
1012    /// Return the `[begin..end)` bound of the chunk at the given index.
1013    #[inline]
1014    fn index_range(&self, range: Range<usize>) -> Option<Range<usize>> {
1015        if range.end < self.num_offsets() {
1016            unsafe { Some(self.index_range_unchecked(range)) }
1017        } else {
1018            None
1019        }
1020    }
1021}
1022
1023impl<'a, O: Get<'a, usize>> GetIndex<'a, Offsets<O>> for usize {
1024    type Output = O::Output;
1025    #[inline]
1026    fn get(self, offsets: &Offsets<O>) -> Option<Self::Output> {
1027        offsets.0.get(self)
1028    }
1029}
1030
1031impl<'a, O: Get<'a, usize>> GetIndex<'a, Offsets<O>> for &usize {
1032    type Output = O::Output;
1033    #[inline]
1034    fn get(self, offsets: &Offsets<O>) -> Option<Self::Output> {
1035        offsets.0.get(*self)
1036    }
1037}
1038
1039impl<'a, O: Get<'a, Range<usize>>> GetIndex<'a, Offsets<O>> for Range<usize> {
1040    type Output = Offsets<O::Output>;
1041    #[inline]
1042    fn get(mut self, offsets: &Offsets<O>) -> Option<Self::Output> {
1043        self.end += 1;
1044        offsets.0.get(self).map(Offsets)
1045    }
1046}
1047
1048impl<O: Isolate<usize>> IsolateIndex<Offsets<O>> for usize {
1049    type Output = O::Output;
1050    #[inline]
1051    unsafe fn isolate_unchecked(self, offsets: Offsets<O>) -> Self::Output {
1052        offsets.0.isolate_unchecked(self)
1053    }
1054    #[inline]
1055    fn try_isolate(self, offsets: Offsets<O>) -> Option<Self::Output> {
1056        offsets.0.try_isolate(self)
1057    }
1058}
1059
1060impl<O: Isolate<Range<usize>>> IsolateIndex<Offsets<O>> for Range<usize> {
1061    type Output = Offsets<O::Output>;
1062    #[inline]
1063    unsafe fn isolate_unchecked(mut self, offsets: Offsets<O>) -> Self::Output {
1064        self.end += 1;
1065        Offsets(offsets.0.isolate_unchecked(self))
1066    }
1067    #[inline]
1068    fn try_isolate(mut self, offsets: Offsets<O>) -> Option<Self::Output> {
1069        self.end += 1;
1070        offsets.0.try_isolate(self).map(Offsets)
1071    }
1072}
1073
1074impl<O: Truncate> Truncate for Offsets<O> {
1075    #[inline]
1076    fn truncate(&mut self, new_len: usize) {
1077        self.0.truncate(new_len);
1078    }
1079}
1080
1081impl<O: RemovePrefix + Set> RemovePrefix for Offsets<O> {
1082    /// Remove the first `n` offsets.
1083    ///
1084    /// # Panics
1085    ///
1086    /// This function will panic if all offsets are removed, which violates the `Offsets` invariant
1087    /// that there must always be at least one offset.
1088    #[inline]
1089    fn remove_prefix(&mut self, n: usize) {
1090        self.0.remove_prefix(n);
1091        assert!(!self.0.is_empty());
1092    }
1093}
1094
1095impl<O: IntoOwned> IntoOwned for Offsets<O> {
1096    type Owned = Offsets<O::Owned>;
1097    #[inline]
1098    fn into_owned(self) -> Self::Owned {
1099        Offsets(self.0.into_owned())
1100    }
1101}
1102
1103impl<O: Reserve> Reserve for Offsets<O> {
1104    #[inline]
1105    fn reserve_with_storage(&mut self, n: usize, storage_n: usize) {
1106        self.0.reserve_with_storage(n, storage_n);
1107    }
1108}
1109
1110impl std::iter::Extend<usize> for Offsets {
1111    /// Extend this set of offsets with a given iterator of offsets.
1112    ///
1113    /// This operation automatically shifts the merged offsets in the iterator
1114    /// to start from the last offset in `self`.
1115    ///
1116    /// Note that there will be 1 less offset added to `self` than produced by
1117    /// `iter` since the first offset is only used to determine the relative
1118    /// magnitude of the rest and corresponds to the last offset in `self`.
1119    fn extend<T: IntoIterator<Item = usize>>(&mut self, iter: T) {
1120        let mut iter = iter.into_iter();
1121        if let Some(first) = iter.next() {
1122            let last = self.last_offset_value();
1123            self.0.extend(iter.map(|off| off + last - first));
1124        }
1125    }
1126}
1127
1128#[cfg(test)]
1129mod tests {
1130    use super::*;
1131    /// Test for the `split_offset_at` helper function.
1132    #[test]
1133    fn split_offset_at_test() {
1134        // Split in the middle
1135        let offsets = Offsets(vec![0, 1, 2, 3, 4, 5]);
1136        let (l, r, off) = offsets.view().split_offsets_with_intersection_at(3);
1137        assert_eq!(l.0, &[0, 1, 2, 3]);
1138        assert_eq!(r.0, &[3, 4, 5]);
1139        assert_eq!(off, 3);
1140
1141        // Split at the beginning
1142        let (l, r, off) = offsets.view().split_offsets_with_intersection_at(0);
1143        assert_eq!(l.0, &[0]);
1144        assert_eq!(r.0, &[0, 1, 2, 3, 4, 5]);
1145        assert_eq!(off, 0);
1146
1147        // Split at the end
1148        let (l, r, off) = offsets.view().split_offsets_with_intersection_at(5);
1149        assert_eq!(l.0, &[0, 1, 2, 3, 4, 5]);
1150        assert_eq!(r.0, &[5]);
1151        assert_eq!(off, 5);
1152    }
1153
1154    /// Check that clearing the offsets keeps exactly one element.
1155    #[test]
1156    fn clear() {
1157        let mut offsets = Offsets(vec![0, 1, 2, 3, 4, 5]);
1158        offsets.clear();
1159        assert_eq!(offsets.into_inner(), vec![0]);
1160    }
1161
1162    /// Check indexing offsets.
1163    #[test]
1164    fn get_offset() {
1165        let s = Offsets::new(vec![2, 5, 6, 8]);
1166        assert_eq!(0, s.offset(0));
1167        assert_eq!(3, s.offset(1));
1168        assert_eq!(4, s.offset(2));
1169        assert_eq!(6, s.offset(3));
1170    }
1171
1172    #[test]
1173    fn sizes_iter() {
1174        let offsets = Offsets(vec![0, 3, 5, 6, 10]);
1175        assert_eq!(3, offsets.sizes().nth(0).unwrap());
1176        assert_eq!(2, offsets.sizes().nth(1).unwrap());
1177        assert_eq!(1, offsets.sizes().nth(2).unwrap());
1178        assert_eq!(4, offsets.sizes().nth(3).unwrap());
1179        assert_eq!(None, offsets.sizes().nth(4));
1180    }
1181
1182    #[test]
1183    fn double_ended_sizes_iter() {
1184        use ExactSizeIterator;
1185        let offsets = Offsets::new(vec![0, 3, 6, 9, 12, 16, 20, 24, 27, 30, 33, 36]);
1186        let mut iter = offsets.sizes();
1187        let iter_len = iter.len();
1188        assert_eq!(iter_len, offsets.num_offsets() - 1);
1189        assert_eq!(iter_len, iter.count());
1190
1191        assert_eq!(iter.next().unwrap(), 3);
1192        assert_eq!(iter.nth(2).unwrap(), 3);
1193        assert_eq!(iter.next().unwrap(), 4);
1194
1195        assert_eq!(iter.next_back().unwrap(), 3);
1196        assert_eq!(iter.nth_back(2).unwrap(), 3);
1197        assert_eq!(iter.next_back().unwrap(), 4);
1198        assert_eq!(iter.next().unwrap(), 4);
1199        assert_eq!(iter.next(), None);
1200
1201        // The following checks that count is correctly implemented for the sizes iterator.
1202        let mut count = 0;
1203        for _ in offsets.sizes() {
1204            count += 1;
1205        }
1206        assert_eq!(iter_len, count);
1207    }
1208
1209    #[test]
1210    fn ranges_iter() {
1211        let offsets = Offsets(vec![0, 3, 5, 6, 10]);
1212        assert_eq!(0..3, offsets.ranges().nth(0).unwrap());
1213        assert_eq!(3..5, offsets.ranges().nth(1).unwrap());
1214        assert_eq!(5..6, offsets.ranges().nth(2).unwrap());
1215        assert_eq!(6..10, offsets.ranges().nth(3).unwrap());
1216        assert_eq!(None, offsets.ranges().nth(4));
1217    }
1218
1219    #[test]
1220    fn double_ended_ranges_iter() {
1221        use ExactSizeIterator;
1222        let offsets = Offsets::new(vec![0, 3, 6, 9, 12, 16, 20, 24, 27, 30, 33, 36]);
1223        let mut iter = offsets.ranges();
1224        let iter_len = iter.len();
1225        assert_eq!(iter_len, offsets.num_offsets() - 1);
1226        assert_eq!(iter_len, iter.count());
1227
1228        assert_eq!(iter.next().unwrap(), 0..3);
1229        assert_eq!(iter.nth(2).unwrap(), 9..12);
1230        assert_eq!(iter.next().unwrap(), 12..16);
1231
1232        assert_eq!(iter.next_back().unwrap(), 33..36);
1233        assert_eq!(iter.nth_back(2).unwrap(), 24..27);
1234        assert_eq!(iter.next_back().unwrap(), 20..24);
1235        assert_eq!(iter.next().unwrap(), 16..20);
1236        assert_eq!(iter.next(), None);
1237
1238        // The following checks that count is correctly implemented for the sizes iterator.
1239        let mut count = 0;
1240        for _ in offsets.sizes() {
1241            count += 1;
1242        }
1243        assert_eq!(iter_len, count);
1244    }
1245
1246    #[test]
1247    fn extend_offsets() {
1248        let mut offsets = Offsets::new(vec![0, 3, 7]);
1249        let orig_offsets = offsets.clone();
1250        offsets.extend([]); // Safe and and no panics, nothing happens.
1251        assert_eq!(offsets, orig_offsets);
1252        offsets.extend([0]); // Nothing new added.
1253        assert_eq!(offsets, orig_offsets);
1254        offsets.extend([0, 1, 10]);
1255        assert_eq!(offsets, Offsets::new(vec![0, 3, 7, 8, 17]));
1256    }
1257}