Skip to main content

columnar/
primitive.rs

1//! Types that prefer to be represented by `Vec<T>`.
2use alloc::{vec::Vec, string::String};
3
4use core::num::Wrapping;
5
6/// An implementation of opinions for types that want to use `Vec<T>`.
7macro_rules! implement_columnable {
8    ($($index_type:ty),*) => { $(
9        impl crate::Columnar for $index_type {
10            #[inline(always)]
11            fn into_owned<'a>(other: crate::Ref<'a, Self>) -> Self { *other }
12
13            type Container = Vec<$index_type>;
14        }
15
16        impl<'a> crate::AsBytes<'a> for &'a [$index_type] {
17            #[inline(always)]
18            fn as_bytes(&self) -> impl Iterator<Item=(u64, &'a [u8])> {
19                core::iter::once((core::mem::align_of::<$index_type>() as u64, bytemuck::cast_slice(&self[..])))
20            }
21        }
22        impl<'a> crate::FromBytes<'a> for &'a [$index_type] {
23            const SLICE_COUNT: usize = 1;
24            #[inline(always)]
25            fn from_bytes(bytes: &mut impl Iterator<Item=&'a [u8]>) -> Self {
26                // We use `unwrap()` here in order to panic with the `bytemuck` error, which may be informative.
27                bytemuck::try_cast_slice(bytes.next().expect("Iterator exhausted prematurely")).unwrap()
28            }
29            #[inline(always)]
30            fn from_store(store: &crate::bytes::indexed::DecodedStore<'a>, offset: &mut usize) -> Self {
31                let (w, tail) = store.get(*offset);
32                *offset += 1;
33                let all: &[$index_type] = bytemuck::cast_slice(w);
34                let trim = ((8 - tail as usize) % 8) / core::mem::size_of::<$index_type>();
35                debug_assert!(trim <= all.len(), "from_store: trim {trim} exceeds slice length {}", all.len());
36                all.get(..all.len().wrapping_sub(trim)).unwrap_or(&[])
37            }
38            fn element_sizes(sizes: &mut Vec<usize>) -> Result<(), String> {
39                sizes.push(core::mem::size_of::<$index_type>());
40                Ok(())
41            }
42        }
43        impl<'a, const N: usize> crate::AsBytes<'a> for &'a [[$index_type; N]] {
44            #[inline(always)]
45            fn as_bytes(&self) -> impl Iterator<Item=(u64, &'a [u8])> {
46                core::iter::once((core::mem::align_of::<$index_type>() as u64, bytemuck::cast_slice(&self[..])))
47            }
48        }
49        impl<'a, const N: usize> crate::FromBytes<'a> for &'a [[$index_type; N]] {
50            const SLICE_COUNT: usize = 1;
51            #[inline(always)]
52            fn from_bytes(bytes: &mut impl Iterator<Item=&'a [u8]>) -> Self {
53                // We use `unwrap()` here in order to panic with the `bytemuck` error, which may be informative.
54                bytemuck::try_cast_slice(bytes.next().expect("Iterator exhausted prematurely")).unwrap()
55            }
56            #[inline(always)]
57            fn from_store(store: &crate::bytes::indexed::DecodedStore<'a>, offset: &mut usize) -> Self {
58                let (w, tail) = store.get(*offset);
59                *offset += 1;
60                let all: &[[$index_type; N]] = bytemuck::cast_slice(w);
61                let trim = ((8 - tail as usize) % 8) / (core::mem::size_of::<$index_type>() * N);
62                debug_assert!(trim <= all.len(), "from_store: trim {trim} exceeds slice length {}", all.len());
63                all.get(..all.len().wrapping_sub(trim)).unwrap_or(&[])
64            }
65            fn element_sizes(sizes: &mut Vec<usize>) -> Result<(), String> {
66                sizes.push(core::mem::size_of::<$index_type>() * N);
67                Ok(())
68            }
69        }
70    )* }
71}
72
73implement_columnable!(u8, u16, u32, u64);
74implement_columnable!(i8, i16, i32, i64);
75implement_columnable!(f32, f64);
76implement_columnable!(Wrapping<u8>, Wrapping<u16>, Wrapping<u32>, Wrapping<u64>);
77implement_columnable!(Wrapping<i8>, Wrapping<i16>, Wrapping<i32>, Wrapping<i64>);
78
79pub use sizes::{Usizes, Isizes};
80/// Columnar stores for `usize` and `isize`, stored as 64 bits.
81mod sizes {
82
83    use crate::*;
84    use crate::common::{BorrowIndexAs, PushIndexAs};
85
86    #[derive(Copy, Clone, Default)]
87    pub struct Usizes<CV = Vec<u64>> { pub values: CV }
88
89    impl Columnar for usize {
90        fn into_owned<'a>(other: crate::Ref<'a, Self>) -> Self { other }
91        type Container = Usizes;
92    }
93
94    impl<CV: BorrowIndexAs<u64> + Len> Borrow for Usizes<CV> {
95        type Ref<'a> = usize;
96        type Borrowed<'a> = Usizes<CV::Borrowed<'a>> where CV: 'a;
97        fn borrow<'a>(&'a self) -> Self::Borrowed<'a> {
98            Usizes { values: self.values.borrow() }
99        }
100        #[inline(always)]
101        fn reborrow<'b, 'a: 'b>(thing: Self::Borrowed<'a>) -> Self::Borrowed<'b> where CV: 'a {
102            Usizes { values: CV::reborrow(thing.values) }
103        }
104        #[inline(always)]
105        fn reborrow_ref<'b, 'a: 'b>(thing: Self::Ref<'a>) -> Self::Ref<'b> where Self: 'a { thing }
106    }
107
108    impl<CV: PushIndexAs<u64>> Container for Usizes<CV> {
109        #[inline(always)]
110        fn extend_from_self(&mut self, other: Self::Borrowed<'_>, range: core::ops::Range<usize>) {
111            self.values.extend_from_self(other.values, range)
112        }
113
114        fn reserve_for<'a, I>(&mut self, selves: I) where Self: 'a, I: Iterator<Item = Self::Borrowed<'a>> + Clone {
115            self.values.reserve_for(selves.map(|x| x.values))
116        }
117    }
118
119    impl<CV: Len> Len for Usizes<CV> { fn len(&self) -> usize { self.values.len() }}
120    impl IndexMut for Usizes {
121        type IndexMut<'a> = &'a mut u64;
122        #[inline(always)] fn get_mut(&mut self, index: usize) -> Self::IndexMut<'_> { &mut self.values[index] }
123    }
124    impl<CV: IndexAs<u64>> Index for Usizes<CV> {
125        type Ref = usize;
126        #[inline(always)] fn get(&self, index: usize) -> Self::Ref { self.values.index_as(index).try_into().expect("Usizes values should fit in `usize`") }
127    }
128    impl<CV: IndexAs<u64>> Index for &Usizes<CV> {
129        type Ref = usize;
130        #[inline(always)] fn get(&self, index: usize) -> Self::Ref { self.values.index_as(index).try_into().expect("Usizes values should fit in `usize`") }
131    }
132    impl<CV: for<'a> Push<&'a u64>> Push<usize> for Usizes<CV> {
133        #[inline]
134        fn push(&mut self, item: usize) { self.values.push(&item.try_into().expect("usize must fit in a u64")) }
135    }
136    impl Push<&usize> for Usizes {
137        #[inline]
138        fn push(&mut self, item: &usize) { self.values.push((*item).try_into().expect("usize must fit in a u64")) }
139    }
140    impl<CV: Clear> Clear for Usizes<CV> { fn clear(&mut self) { self.values.clear() }}
141
142    impl<'a, CV: crate::AsBytes<'a>> crate::AsBytes<'a> for crate::primitive::Usizes<CV> {
143        #[inline(always)]
144        fn as_bytes(&self) -> impl Iterator<Item=(u64, &'a [u8])> {
145            self.values.as_bytes()
146        }
147    }
148
149    impl<'a, CV: crate::FromBytes<'a>> crate::FromBytes<'a> for crate::primitive::Usizes<CV> {
150        const SLICE_COUNT: usize = CV::SLICE_COUNT;
151        #[inline(always)]
152        fn from_bytes(bytes: &mut impl Iterator<Item=&'a [u8]>) -> Self {
153            Self { values: CV::from_bytes(bytes) }
154        }
155        #[inline(always)]
156        fn from_store(store: &crate::bytes::indexed::DecodedStore<'a>, offset: &mut usize) -> Self {
157            Self { values: CV::from_store(store, offset) }
158        }
159    }
160
161
162    #[derive(Copy, Clone, Default)]
163    pub struct Isizes<CV = Vec<i64>> { pub values: CV }
164
165    impl Columnar for isize {
166        fn into_owned<'a>(other: crate::Ref<'a, Self>) -> Self { other }
167        type Container = Isizes;
168    }
169
170    impl<CV: BorrowIndexAs<i64>> Borrow for Isizes<CV> {
171        type Ref<'a> = isize;
172        type Borrowed<'a> = Isizes<CV::Borrowed<'a>> where CV: 'a;
173        fn borrow<'a>(&'a self) -> Self::Borrowed<'a> {
174            Isizes { values: self.values.borrow() }
175        }
176        #[inline(always)]
177        fn reborrow<'b, 'a: 'b>(thing: Self::Borrowed<'a>) -> Self::Borrowed<'b> where CV: 'a {
178            Isizes { values: CV::reborrow(thing.values) }
179        }
180        #[inline(always)]
181        fn reborrow_ref<'b, 'a: 'b>(thing: Self::Ref<'a>) -> Self::Ref<'b> where Self: 'a { thing }
182    }
183
184    impl<CV: PushIndexAs<i64>> Container for Isizes<CV> {
185        #[inline(always)]
186        fn extend_from_self(&mut self, other: Self::Borrowed<'_>, range: core::ops::Range<usize>) {
187            self.values.extend_from_self(other.values, range)
188        }
189
190        fn reserve_for<'a, I>(&mut self, selves: I) where Self: 'a, I: Iterator<Item = Self::Borrowed<'a>> + Clone {
191            self.values.reserve_for(selves.map(|x| x.values))
192        }
193    }
194
195    impl<CV: Len> Len for Isizes<CV> { fn len(&self) -> usize { self.values.len() }}
196    impl IndexMut for Isizes {
197        type IndexMut<'a> = &'a mut i64;
198        #[inline(always)] fn get_mut(&mut self, index: usize) -> Self::IndexMut<'_> { &mut self.values[index] }
199    }
200    impl<CV: IndexAs<i64>> Index for Isizes<CV> {
201        type Ref = isize;
202        #[inline(always)] fn get(&self, index: usize) -> Self::Ref { self.values.index_as(index).try_into().expect("Isizes values should fit in `isize`") }
203    }
204    impl<CV: IndexAs<i64>> Index for &Isizes<CV> {
205        type Ref = isize;
206        #[inline(always)] fn get(&self, index: usize) -> Self::Ref { self.values.index_as(index).try_into().expect("Isizes values should fit in `isize`") }
207    }
208    impl<CV: for<'a> Push<&'a i64>> Push<isize> for Isizes<CV> {
209        #[inline]
210        fn push(&mut self, item: isize) { self.values.push(&item.try_into().expect("isize must fit in a i64")) }
211    }
212    impl Push<&isize> for Isizes {
213        #[inline]
214        fn push(&mut self, item: &isize) { self.values.push((*item).try_into().expect("isize must fit in a i64")) }
215    }
216    impl<CV: Clear> Clear for Isizes<CV> { fn clear(&mut self) { self.values.clear() }}
217
218    impl<'a, CV: crate::AsBytes<'a>> crate::AsBytes<'a> for crate::primitive::Isizes<CV> {
219        #[inline(always)]
220        fn as_bytes(&self) -> impl Iterator<Item=(u64, &'a [u8])> {
221            self.values.as_bytes()
222        }
223    }
224
225    impl<'a, CV: crate::FromBytes<'a>> crate::FromBytes<'a> for crate::primitive::Isizes<CV> {
226        const SLICE_COUNT: usize = CV::SLICE_COUNT;
227        #[inline(always)]
228        fn from_bytes(bytes: &mut impl Iterator<Item=&'a [u8]>) -> Self {
229            Self { values: CV::from_bytes(bytes) }
230        }
231        #[inline(always)]
232        fn from_store(store: &crate::bytes::indexed::DecodedStore<'a>, offset: &mut usize) -> Self {
233            Self { values: CV::from_store(store, offset) }
234        }
235    }
236}
237
238pub use chars::{Chars};
239/// Columnar store for `char`, stored as a `u32`.
240mod chars {
241
242    use crate::*;
243    use crate::common::{BorrowIndexAs, PushIndexAs};
244
245    type Encoded = u32;
246
247    #[derive(Copy, Clone, Default)]
248    pub struct Chars<CV = Vec<Encoded>> { pub values: CV }
249
250    impl Columnar for char {
251        fn into_owned<'a>(other: crate::Ref<'a, Self>) -> Self { other }
252        type Container = Chars;
253    }
254
255    impl<CV: BorrowIndexAs<Encoded>> Borrow for Chars<CV> {
256        type Ref<'a> = char;
257        type Borrowed<'a> = Chars<CV::Borrowed<'a>> where CV: 'a;
258        fn borrow<'a>(&'a self) -> Self::Borrowed<'a> {
259            Chars { values: self.values.borrow() }
260        }
261        #[inline(always)]
262        fn reborrow<'b, 'a: 'b>(thing: Self::Borrowed<'a>) -> Self::Borrowed<'b> where CV: 'a {
263            Chars { values: CV::reborrow(thing.values) }
264        }
265        #[inline(always)]
266        fn reborrow_ref<'b, 'a: 'b>(thing: Self::Ref<'a>) -> Self::Ref<'b> where Self: 'a { thing }
267    }
268
269    impl<CV: PushIndexAs<Encoded>> Container for Chars<CV> {
270        #[inline(always)]
271        fn extend_from_self(&mut self, other: Self::Borrowed<'_>, range: core::ops::Range<usize>) {
272            self.values.extend_from_self(other.values, range)
273        }
274
275        fn reserve_for<'a, I>(&mut self, selves: I) where Self: 'a, I: Iterator<Item = Self::Borrowed<'a>> + Clone {
276            self.values.reserve_for(selves.map(|x| x.values))
277        }
278    }
279
280    impl<CV: Len> Len for Chars<CV> { fn len(&self) -> usize { self.values.len() }}
281    impl<CV: IndexAs<Encoded>> Index for Chars<CV> {
282        type Ref = char;
283        #[inline(always)] fn get(&self, index: usize) -> Self::Ref { char::from_u32(self.values.index_as(index)).unwrap() }
284    }
285    impl<CV: IndexAs<Encoded>> Index for &Chars<CV> {
286        type Ref = char;
287        #[inline(always)] fn get(&self, index: usize) -> Self::Ref { char::from_u32(self.values.index_as(index)).unwrap() }
288    }
289    impl<CV: for<'a> Push<&'a Encoded>> Push<char> for Chars<CV> {
290        #[inline]
291        fn push(&mut self, item: char) { self.values.push(&u32::from(item)) }
292    }
293    impl Push<&char> for Chars {
294        #[inline]
295        fn push(&mut self, item: &char) { self.values.push(u32::from(*item)) }
296    }
297    impl<CV: Clear> Clear for Chars<CV> { fn clear(&mut self) { self.values.clear() }}
298
299    impl<'a, CV: crate::AsBytes<'a>> crate::AsBytes<'a> for Chars<CV> {
300        #[inline(always)]
301        fn as_bytes(&self) -> impl Iterator<Item=(u64, &'a [u8])> {
302            self.values.as_bytes()
303        }
304    }
305
306    impl<'a, CV: crate::FromBytes<'a>> crate::FromBytes<'a> for Chars<CV> {
307        const SLICE_COUNT: usize = CV::SLICE_COUNT;
308        #[inline(always)]
309        fn from_bytes(bytes: &mut impl Iterator<Item=&'a [u8]>) -> Self {
310            Self { values: CV::from_bytes(bytes) }
311        }
312        #[inline(always)]
313        fn from_store(store: &crate::bytes::indexed::DecodedStore<'a>, offset: &mut usize) -> Self {
314            Self { values: CV::from_store(store, offset) }
315        }
316    }
317}
318
319pub use larges::{U128s, I128s};
320/// Columnar stores for `u128` and `i128`, stored as [u8; 16] bits.
321mod larges {
322
323    use crate::*;
324    use crate::common::{BorrowIndexAs, PushIndexAs};
325
326    type Encoded = [u8; 16];
327
328    #[derive(Copy, Clone, Default)]
329    pub struct U128s<CV = Vec<Encoded>> { pub values: CV }
330
331    impl Columnar for u128 {
332        fn into_owned<'a>(other: crate::Ref<'a, Self>) -> Self { other }
333        type Container = U128s;
334    }
335
336    impl<CV: BorrowIndexAs<Encoded>> Borrow for U128s<CV> {
337        type Ref<'a> = u128;
338        type Borrowed<'a> = U128s<CV::Borrowed<'a>> where CV: 'a;
339        fn borrow<'a>(&'a self) -> Self::Borrowed<'a> {
340            U128s { values: self.values.borrow() }
341        }
342        #[inline(always)]
343        fn reborrow<'b, 'a: 'b>(thing: Self::Borrowed<'a>) -> Self::Borrowed<'b> where CV: 'a {
344            U128s { values: CV::reborrow(thing.values) }
345        }
346        #[inline(always)]
347        fn reborrow_ref<'b, 'a: 'b>(thing: Self::Ref<'a>) -> Self::Ref<'b> where Self: 'a { thing }
348    }
349
350    impl<CV: PushIndexAs<Encoded>> Container for U128s<CV> {
351        #[inline(always)]
352        fn extend_from_self(&mut self, other: Self::Borrowed<'_>, range: core::ops::Range<usize>) {
353            self.values.extend_from_self(other.values, range)
354        }
355
356        fn reserve_for<'a, I>(&mut self, selves: I) where Self: 'a, I: Iterator<Item = Self::Borrowed<'a>> + Clone {
357            self.values.reserve_for(selves.map(|x| x.values))
358        }
359    }
360
361    impl<CV: Len> Len for U128s<CV> { fn len(&self) -> usize { self.values.len() }}
362    impl<CV: IndexAs<Encoded>> Index for U128s<CV> {
363        type Ref = u128;
364        #[inline(always)] fn get(&self, index: usize) -> Self::Ref { u128::from_le_bytes(self.values.index_as(index)) }
365    }
366    impl<CV: IndexAs<Encoded>> Index for &U128s<CV> {
367        type Ref = u128;
368        #[inline(always)] fn get(&self, index: usize) -> Self::Ref { u128::from_le_bytes(self.values.index_as(index)) }
369    }
370    impl<CV: for<'a> Push<&'a Encoded>> Push<u128> for U128s<CV> {
371        #[inline]
372        fn push(&mut self, item: u128) { self.values.push(&item.to_le_bytes()) }
373    }
374    impl Push<&u128> for U128s {
375        #[inline]
376        fn push(&mut self, item: &u128) { self.values.push(item.to_le_bytes()) }
377    }
378    impl<CV: Clear> Clear for U128s<CV> { fn clear(&mut self) { self.values.clear() }}
379
380    impl<'a, CV: crate::AsBytes<'a>> crate::AsBytes<'a> for U128s<CV> {
381        #[inline(always)]
382        fn as_bytes(&self) -> impl Iterator<Item=(u64, &'a [u8])> {
383            self.values.as_bytes()
384        }
385    }
386
387    impl<'a, CV: crate::FromBytes<'a>> crate::FromBytes<'a> for U128s<CV> {
388        const SLICE_COUNT: usize = CV::SLICE_COUNT;
389        #[inline(always)]
390        fn from_bytes(bytes: &mut impl Iterator<Item=&'a [u8]>) -> Self {
391            Self { values: CV::from_bytes(bytes) }
392        }
393        #[inline(always)]
394        fn from_store(store: &crate::bytes::indexed::DecodedStore<'a>, offset: &mut usize) -> Self {
395            Self { values: CV::from_store(store, offset) }
396        }
397    }
398
399    #[derive(Copy, Clone, Default)]
400    pub struct I128s<CV = Vec<Encoded>> { pub values: CV }
401
402    impl Columnar for i128 {
403        fn into_owned<'a>(other: crate::Ref<'a, Self>) -> Self { other }
404        type Container = I128s;
405    }
406
407    impl<CV: BorrowIndexAs<Encoded>> Borrow for I128s<CV> {
408        type Ref<'a> = i128;
409        type Borrowed<'a> = I128s<CV::Borrowed<'a>> where CV: 'a;
410        fn borrow<'a>(&'a self) -> Self::Borrowed<'a> {
411            I128s { values: self.values.borrow() }
412        }
413        #[inline(always)]
414        fn reborrow<'b, 'a: 'b>(thing: Self::Borrowed<'a>) -> Self::Borrowed<'b> where CV: 'a {
415            I128s { values: CV::reborrow(thing.values) }
416        }
417        #[inline(always)]
418        fn reborrow_ref<'b, 'a: 'b>(thing: Self::Ref<'a>) -> Self::Ref<'b> where Self: 'a { thing }
419    }
420
421    impl<CV: PushIndexAs<Encoded>> Container for I128s<CV> {
422        #[inline(always)]
423        fn extend_from_self(&mut self, other: Self::Borrowed<'_>, range: core::ops::Range<usize>) {
424            self.values.extend_from_self(other.values, range)
425        }
426
427        fn reserve_for<'a, I>(&mut self, selves: I) where Self: 'a, I: Iterator<Item = Self::Borrowed<'a>> + Clone {
428            self.values.reserve_for(selves.map(|x| x.values))
429        }
430    }
431
432    impl<CV: Len> Len for I128s<CV> { fn len(&self) -> usize { self.values.len() }}
433    impl<CV: IndexAs<Encoded>> Index for I128s<CV> {
434        type Ref = i128;
435        #[inline(always)] fn get(&self, index: usize) -> Self::Ref { i128::from_le_bytes(self.values.index_as(index)) }
436    }
437    impl<CV: IndexAs<Encoded>> Index for &I128s<CV> {
438        type Ref = i128;
439        #[inline(always)] fn get(&self, index: usize) -> Self::Ref { i128::from_le_bytes(self.values.index_as(index)) }
440    }
441    impl<CV: for<'a> Push<&'a Encoded>> Push<i128> for I128s<CV> {
442        #[inline]
443        fn push(&mut self, item: i128) { self.values.push(&item.to_le_bytes()) }
444    }
445    impl Push<&i128> for I128s {
446        #[inline]
447        fn push(&mut self, item: &i128) { self.values.push(item.to_le_bytes()) }
448    }
449    impl<CV: Clear> Clear for I128s<CV> { fn clear(&mut self) { self.values.clear() }}
450
451    impl<'a, CV: crate::AsBytes<'a>> crate::AsBytes<'a> for I128s<CV> {
452        #[inline(always)]
453        fn as_bytes(&self) -> impl Iterator<Item=(u64, &'a [u8])> {
454            self.values.as_bytes()
455        }
456    }
457
458    impl<'a, CV: crate::FromBytes<'a>> crate::FromBytes<'a> for I128s<CV> {
459        const SLICE_COUNT: usize = CV::SLICE_COUNT;
460        #[inline(always)]
461        fn from_bytes(bytes: &mut impl Iterator<Item=&'a [u8]>) -> Self {
462            Self { values: CV::from_bytes(bytes) }
463        }
464        #[inline(always)]
465        fn from_store(store: &crate::bytes::indexed::DecodedStore<'a>, offset: &mut usize) -> Self {
466            Self { values: CV::from_store(store, offset) }
467        }
468    }
469}
470
471/// Columnar stores for non-decreasing `u64`, stored in various ways.
472///
473/// The venerable `Vec<u64>` works as a general container for arbitrary offests,
474/// but it can be non-optimal for various patterns of offset, including constant
475/// inter-offset spacing, and relatively short runs (compared to a `RankSelect`).
476pub mod offsets {
477
478
479    pub use array::Fixeds;
480    pub use stride::Strides;
481
482    /// An offset container that encodes a constant spacing in its type.
483    ///
484    /// Any attempt to push any value will result in pushing the next value
485    /// at the specified spacing. This type is only appropriate in certain
486    /// contexts, for example when storing `[T; K]` array types, or having
487    /// introspected a `Strides` and found it to be only one constant stride.
488    mod array {
489
490        use alloc::{vec::Vec, string::String};
491        use crate::{Container, Borrow, Index, Len, Push};
492        use crate::common::index::CopyAs;
493
494        /// An offset container that encodes a constant `K` spacing.
495        #[derive(Copy, Clone, Debug, Default)]
496        pub struct Fixeds<const K: u64, CC = u64> { pub count: CC }
497
498        impl<const K: u64> Borrow for Fixeds<K> {
499            type Ref<'a> = u64;
500            type Borrowed<'a> = Fixeds<K, &'a u64>;
501            #[inline(always)]
502            fn borrow<'a>(&'a self) -> Self::Borrowed<'a> { Fixeds { count: &self.count } }
503            #[inline(always)]
504            fn reborrow<'b, 'a: 'b>(thing: Self::Borrowed<'a>) -> Self::Borrowed<'b> where Self: 'a {
505                Fixeds { count: thing.count }
506            }
507            #[inline(always)]
508            fn reborrow_ref<'b, 'a: 'b>(thing: Self::Ref<'a>) -> Self::Ref<'b> where Self: 'a { thing }
509        }
510
511        impl<const K: u64> Container for Fixeds<K> {
512            #[inline(always)]
513            fn extend_from_self(&mut self, _other: Self::Borrowed<'_>, range: core::ops::Range<usize>) {
514                self.count += range.len() as u64;
515            }
516
517            fn reserve_for<'a, I>(&mut self, _selves: I) where Self: 'a, I: Iterator<Item = Self::Borrowed<'a>> + Clone { }
518        }
519
520        impl<const K: u64, CC: CopyAs<u64>> Len for Fixeds<K, CC> {
521            #[inline(always)] fn len(&self) -> usize { self.count.copy_as() as usize }
522        }
523
524        impl<const K: u64, CC> Index for Fixeds<K, CC> {
525            type Ref = u64;
526            #[inline(always)]
527            fn get(&self, index: usize) -> Self::Ref { (index as u64 + 1) * K }
528        }
529        impl<'a, const K: u64, CC> Index for &'a Fixeds<K, CC> {
530            type Ref = u64;
531            #[inline(always)]
532            fn get(&self, index: usize) -> Self::Ref { (index as u64 + 1) * K }
533        }
534
535        impl<'a, const K: u64, T> Push<T> for Fixeds<K> {
536            // TODO: check for overflow?
537            #[inline(always)]
538            fn push(&mut self, _item: T) { self.count += 1; }
539            #[inline(always)]
540            fn extend(&mut self, iter: impl IntoIterator<Item=T>) {
541                self.count += iter.into_iter().count() as u64;
542            }
543        }
544
545        impl<const K: u64> crate::Clear for Fixeds<K> {
546            #[inline(always)]
547            fn clear(&mut self) { self.count = 0; }
548        }
549
550        impl<'a, const K: u64> crate::AsBytes<'a> for Fixeds<K, &'a u64> {
551            #[inline(always)]
552            fn as_bytes(&self) -> impl Iterator<Item=(u64, &'a [u8])> {
553                core::iter::once((8, bytemuck::cast_slice(core::slice::from_ref(self.count))))
554            }
555        }
556        impl<'a, const K: u64> crate::FromBytes<'a> for Fixeds<K, &'a u64> {
557            const SLICE_COUNT: usize = 1;
558            #[inline(always)]
559            fn from_bytes(bytes: &mut impl Iterator<Item=&'a [u8]>) -> Self {
560                Self { count: &bytemuck::try_cast_slice(bytes.next().expect("Iterator exhausted prematurely")).unwrap()[0] }
561            }
562            #[inline(always)]
563            fn from_store(store: &crate::bytes::indexed::DecodedStore<'a>, offset: &mut usize) -> Self {
564                let (w, _) = store.get(*offset); *offset += 1;
565                debug_assert!(!w.is_empty(), "Fixeds::from_store: empty count slice");
566                Self { count: w.first().unwrap_or(&0) }
567            }
568            fn element_sizes(sizes: &mut Vec<usize>) -> Result<(), String> {
569                sizes.push(8);
570                Ok(())
571            }
572            fn validate(slices: &[(&[u64], u8)]) -> Result<(), String> {
573                if slices.is_empty() || slices[0].0.is_empty() {
574                    return Err("Fixeds: count slice must be non-empty".into());
575                }
576                Ok(())
577            }
578        }
579
580        use super::Strides;
581        impl<const K: u64> core::convert::TryFrom<Strides> for Fixeds<K> {
582            type Error = Strides;
583            fn try_from(item: Strides) -> Result<Self, Self::Error> {
584                if item.strided() == Some(K) { Ok( Self { count: item.head[1] } ) } else { Err(item) }
585            }
586        }
587        impl<'a, const K: u64> core::convert::TryFrom<Strides<&'a [u64], &'a [u64]>> for Fixeds<K, &'a u64> {
588            type Error = Strides<&'a [u64], &'a [u64]>;
589            fn try_from(item: Strides<&'a [u64], &'a [u64]>) -> Result<Self, Self::Error> {
590                if item.strided() == Some(K) { Ok( Self { count: &item.head[1] } ) } else { Err(item) }
591            }
592        }
593    }
594
595    /// An general offset container optimized for fixed inter-offset sizes.
596    ///
597    /// Although it can handle general offsets, it starts with the optimistic
598    /// assumption that the offsets will be evenly spaced from zero, and while
599    /// that holds it will maintain the stride and length. Should it stop being
600    /// true, when a non-confirming offset is pushed, it will start to store
601    /// the offsets in a general container.
602    mod stride {
603
604        use alloc::{vec::Vec, string::String};
605        use core::ops::Deref;
606        use crate::{Container, Borrow, Index, IndexAs, Len, Push, Clear, AsBytes, FromBytes};
607
608        /// Columnar store for non-decreasing `u64` offsets with stride optimization.
609        ///
610        /// `head` holds `[stride, length]`: when the first `length` offsets follow a
611        /// regular stride pattern (`(i+1) * stride`), they are stored implicitly.
612        /// Remaining offsets go into `bounds`. In the owned form `head` is `[u64; 2]`;
613        /// in the borrowed form it is `&[u64]` of length 2.
614        #[derive(Copy, Clone, Debug, Default)]
615        pub struct Strides<BC = Vec<u64>, HC = [u64; 2]> {
616            pub head: HC,
617            pub bounds: BC,
618        }
619
620        impl Borrow for Strides {
621            type Ref<'a> = u64;
622            type Borrowed<'a> = Strides<&'a [u64], &'a [u64]>;
623
624            #[inline(always)] fn borrow<'a>(&'a self) -> Self::Borrowed<'a> { Strides { head: &self.head, bounds: &self.bounds[..] } }
625            #[inline(always)] fn reborrow<'b, 'a: 'b>(item: Self::Borrowed<'a>) -> Self::Borrowed<'b> where Self: 'a {
626                Strides { head: item.head, bounds: item.bounds }
627            }
628            #[inline(always)] fn reborrow_ref<'b, 'a: 'b>(item: Self::Ref<'a>) -> Self::Ref<'b> where Self: 'a { item }
629        }
630
631        impl Container for Strides {
632            fn reserve_for<'a, I>(&mut self, selves: I) where Self: 'a, I: Iterator<Item = Self::Borrowed<'a>> + Clone {
633                self.bounds.reserve_for(selves.map(|x| x.bounds))
634            }
635        }
636
637        impl<'a> Push<&'a u64> for Strides { #[inline(always)] fn push(&mut self, item: &'a u64) { self.push(*item) } }
638        impl Push<u64> for Strides { #[inline(always)] fn push(&mut self, item: u64) { self.push(item) } }
639        impl Clear for Strides { #[inline(always)] fn clear(&mut self) { self.clear() } }
640
641        impl<BC: Len, HC: IndexAs<u64>> Len for Strides<BC, HC> {
642            #[inline(always)]
643            fn len(&self) -> usize { self.head.index_as(1) as usize + self.bounds.len() }
644        }
645        impl<BC: IndexAs<u64>, HC: IndexAs<u64>> Index for Strides<BC, HC> {
646            type Ref = u64;
647            #[inline(always)]
648            fn get(&self, index: usize) -> Self::Ref {
649                let index = index as u64;
650                let length = self.head.index_as(1);
651                let stride = self.head.index_as(0);
652                if index < length { (index+1) * stride } else { self.bounds.index_as((index - length) as usize) }
653            }
654        }
655
656        impl<'a, BC: AsBytes<'a>> AsBytes<'a> for Strides<BC, &'a [u64]> {
657            #[inline(always)]
658            fn as_bytes(&self) -> impl Iterator<Item=(u64, &'a [u8])> {
659                let head = core::iter::once((8u64, bytemuck::cast_slice(self.head)));
660                let bounds = self.bounds.as_bytes();
661                crate::chain(head, bounds)
662            }
663        }
664        impl<'a, BC: FromBytes<'a>> FromBytes<'a> for Strides<BC, &'a [u64]> {
665            const SLICE_COUNT: usize = 1 + BC::SLICE_COUNT;
666            #[inline(always)]
667            fn from_bytes(bytes: &mut impl Iterator<Item=&'a [u8]>) -> Self {
668                let head: &[u64] = bytemuck::try_cast_slice(bytes.next().expect("Iterator exhausted prematurely")).unwrap();
669                let bounds = BC::from_bytes(bytes);
670                Self { head, bounds }
671            }
672            #[inline(always)]
673            fn from_store(store: &crate::bytes::indexed::DecodedStore<'a>, offset: &mut usize) -> Self {
674                let (head, _) = store.get(*offset); *offset += 1;
675                debug_assert!(head.len() >= 2, "Strides::from_store: head slice too short (len {})", head.len());
676                let bounds = BC::from_store(store, offset);
677                Self { head, bounds }
678            }
679            fn element_sizes(sizes: &mut Vec<usize>) -> Result<(), String> {
680                sizes.push(8); // head: [stride, length]
681                BC::element_sizes(sizes)
682            }
683            fn validate(slices: &[(&[u64], u8)]) -> Result<(), String> {
684                if slices.is_empty() || slices[0].0.len() < 2 {
685                    return Err("Strides: head slice must have at least 2 elements (stride, length)".into());
686                }
687                BC::validate(&slices[1..])
688            }
689        }
690
691        impl Strides {
692            pub fn new(stride: u64, length: u64) -> Self {
693                Self { head: [stride, length], bounds: Vec::default() }
694            }
695            #[inline(always)]
696            pub fn push(&mut self, item: u64) {
697                if self.head[1] == 0 {
698                    self.head[0] = item;
699                    self.head[1] = 1;
700                }
701                else if !self.bounds.is_empty() {
702                    self.bounds.push(item);
703                }
704                else if item == self.head[0] * (self.head[1] + 1) {
705                    self.head[1] += 1;
706                }
707                else {
708                    self.bounds.push(item);
709                }
710            }
711            /// Removes the last element, if non-empty.
712            ///
713            /// If empty, will trip a debug assert, but wrap in release.
714            #[inline(always)]
715            pub fn pop(&mut self) {
716                debug_assert!(self.len() > 0);
717                if self.bounds.is_empty() { self.head[1] -= 1; }
718                else { self.bounds.pop(); }
719            }
720            #[inline(always)]
721            pub fn clear(&mut self) {
722                self.head = [0, 0];
723                self.bounds.clear();
724            }
725        }
726
727        impl<BC: Deref<Target=[u64]>, HC: IndexAs<u64>> Strides<BC, HC> {
728            #[inline(always)]
729            pub fn bounds(&self, index: usize) -> (usize, usize) {
730                let stride = self.head.index_as(0);
731                let length = self.head.index_as(1);
732                let index = index as u64;
733                let lower = if index == 0 { 0 } else {
734                    let index = index - 1;
735                    if index < length { (index+1) * stride } else { self.bounds[(index - length) as usize] }
736                } as usize;
737                let upper = if index < length { (index+1) * stride } else { self.bounds[(index - length) as usize] } as usize;
738                (lower, upper)
739            }
740        }
741        impl<BC: Len, HC: IndexAs<u64>> Strides<BC, HC> {
742            #[inline(always)] pub fn strided(&self) -> Option<u64> {
743                if self.bounds.is_empty() {
744                    Some(self.head.index_as(0))
745                }
746                else { None }
747            }
748        }
749    }
750
751    #[cfg(test)]
752    mod test {
753        use alloc::vec::Vec;
754        #[test]
755        fn round_trip() {
756
757            use crate::common::{Index, Push, Len};
758            use crate::{Borrow, Vecs};
759            use crate::primitive::offsets::{Strides, Fixeds};
760
761            let mut cols = Vecs::<Vec::<i32>, Strides>::default();
762            for i in 0 .. 100 {
763                cols.push(&[1i32, 2, i]);
764            }
765
766            let cols = Vecs {
767                bounds: TryInto::<Fixeds<3>>::try_into(cols.bounds).unwrap(),
768                values: cols.values,
769            };
770
771            assert_eq!(cols.borrow().len(), 100);
772            for i in 0 .. 100 {
773                assert_eq!(cols.borrow().get(i).len(), 3);
774            }
775
776            let mut cols = Vecs {
777                bounds: Strides::new(3, cols.bounds.count),
778                values: cols.values
779            };
780
781            cols.push(&[0, 0]);
782            assert!(TryInto::<Fixeds<3>>::try_into(cols.bounds).is_err());
783        }
784    }
785}
786
787pub use empty::Empties;
788/// A columnar store for `()`.
789mod empty {
790
791    use alloc::{vec::Vec, string::String};
792    use crate::common::index::CopyAs;
793    use crate::{Clear, Columnar, Container, Len, IndexMut, Index, Push, Borrow};
794
795    #[derive(Copy, Clone, Debug, Default)]
796    pub struct Empties<CC = u64> { pub count: CC, pub empty: () }
797
798    impl Columnar for () {
799        #[inline(always)]
800        fn into_owned<'a>(_other: crate::Ref<'a, Self>) -> Self { }
801        type Container = Empties;
802    }
803
804    impl Borrow for Empties {
805        type Ref<'a> = ();
806        type Borrowed<'a> = Empties<&'a u64>;
807        #[inline(always)]
808        fn borrow<'a>(&'a self) -> Self::Borrowed<'a> { Empties { count: &self.count, empty: () } }
809        #[inline(always)]
810        fn reborrow<'b, 'a: 'b>(thing: Self::Borrowed<'a>) -> Self::Borrowed<'b> where Self: 'a {
811            Empties { count: thing.count, empty: () }
812        }
813        #[inline(always)]
814        fn reborrow_ref<'b, 'a: 'b>(thing: Self::Ref<'a>) -> Self::Ref<'b> where Self: 'a { thing }
815    }
816
817    impl Container for Empties {
818        #[inline(always)]
819        fn extend_from_self(&mut self, _other: Self::Borrowed<'_>, range: core::ops::Range<usize>) {
820            self.count += range.len() as u64;
821        }
822
823        fn reserve_for<'a, I>(&mut self, _selves: I) where Self: 'a, I: Iterator<Item = Self::Borrowed<'a>> + Clone { }
824    }
825
826    impl<CC: CopyAs<u64>> Len for Empties<CC> {
827        #[inline(always)] fn len(&self) -> usize { self.count.copy_as() as usize }
828    }
829    impl<CC> IndexMut for Empties<CC> {
830        type IndexMut<'a> = &'a mut () where CC: 'a;
831        // TODO: panic if out of bounds?
832        #[inline(always)] fn get_mut(&mut self, _index: usize) -> Self::IndexMut<'_> { &mut self.empty }
833    }
834    impl<CC> Index for Empties<CC> {
835        type Ref = ();
836        #[inline(always)]
837        fn get(&self, _index: usize) -> Self::Ref { }
838    }
839    impl<'a, CC> Index for &'a Empties<CC> {
840        type Ref = &'a ();
841        #[inline(always)]
842        fn get(&self, _index: usize) -> Self::Ref { &() }
843    }
844    impl Push<()> for Empties {
845        // TODO: check for overflow?
846        #[inline(always)]
847        fn push(&mut self, _item: ()) { self.count += 1; }
848        #[inline(always)]
849        fn extend(&mut self, iter: impl IntoIterator<Item=()>) {
850            self.count += iter.into_iter().count() as u64;
851        }
852    }
853    impl<'a> Push<&'a ()> for Empties {
854        // TODO: check for overflow?
855        #[inline(always)]
856        fn push(&mut self, _item: &()) { self.count += 1; }
857        #[inline(always)]
858        fn extend(&mut self, iter: impl IntoIterator<Item=&'a ()>) {
859            self.count += iter.into_iter().count() as u64;
860        }
861    }
862
863    impl Clear for Empties {
864        #[inline(always)]
865        fn clear(&mut self) { self.count = 0; }
866    }
867
868    impl<'a> crate::AsBytes<'a> for crate::primitive::Empties<&'a u64> {
869        #[inline(always)]
870        fn as_bytes(&self) -> impl Iterator<Item=(u64, &'a [u8])> {
871            core::iter::once((8, bytemuck::cast_slice(core::slice::from_ref(self.count))))
872        }
873    }
874    impl<'a> crate::FromBytes<'a> for crate::primitive::Empties<&'a u64> {
875        const SLICE_COUNT: usize = 1;
876        #[inline(always)]
877        fn from_bytes(bytes: &mut impl Iterator<Item=&'a [u8]>) -> Self {
878            Self { count: &bytemuck::try_cast_slice(bytes.next().expect("Iterator exhausted prematurely")).unwrap()[0], empty: () }
879        }
880        #[inline(always)]
881        fn from_store(store: &crate::bytes::indexed::DecodedStore<'a>, offset: &mut usize) -> Self {
882            let (w, _) = store.get(*offset); *offset += 1;
883            debug_assert!(!w.is_empty(), "Empties::from_store: empty count slice");
884            Self { count: w.first().unwrap_or(&0), empty: () }
885        }
886        fn element_sizes(sizes: &mut Vec<usize>) -> Result<(), String> {
887            sizes.push(8);
888            Ok(())
889        }
890        fn validate(slices: &[(&[u64], u8)]) -> Result<(), String> {
891            if slices.is_empty() || slices[0].0.is_empty() {
892                return Err("Empties: count slice must be non-empty".into());
893            }
894            Ok(())
895        }
896    }
897}
898
899pub use boolean::Bools;
900/// A columnar store for `bool`.
901mod boolean {
902
903    use alloc::{vec::Vec, string::String};
904    use crate::{Container, Clear, Len, Index, IndexAs, Push, Borrow};
905
906    /// A store for maintaining `Vec<bool>`.
907    ///
908    /// Packed bits are stored in `values` as complete `u64` words. The `tail`
909    /// holds `[last_word, last_bits]`: the partial word being filled and the
910    /// count of valid bits in it. In the owned form `tail` is `[u64; 2]`;
911    /// in the borrowed form it is `&[u64]` of length 2.
912    #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
913    #[derive(Copy, Clone, Debug, Default, PartialEq)]
914    pub struct Bools<VC = Vec<u64>, TC = [u64; 2]> {
915        /// The bundles of bits that form complete `u64` values.
916        pub values: VC,
917        /// `[last_word, last_bits]`: the partial word and the number of valid bits in it.
918        pub tail: TC,
919    }
920
921    impl crate::Columnar for bool {
922        #[inline(always)]
923        fn into_owned<'a>(other: crate::Ref<'a, Self>) -> Self { other }
924        type Container = Bools;
925    }
926
927    impl<VC: crate::common::BorrowIndexAs<u64>> Borrow for Bools<VC> {
928        type Ref<'a> = bool;
929        type Borrowed<'a> = Bools<VC::Borrowed<'a>, &'a [u64]> where VC: 'a;
930        #[inline(always)]
931        fn borrow<'a>(&'a self) -> Self::Borrowed<'a> {
932            Bools {
933                values: self.values.borrow(),
934                tail: &self.tail,
935            }
936        }
937        #[inline(always)]
938        fn reborrow<'b, 'a: 'b>(thing: Self::Borrowed<'a>) -> Self::Borrowed<'b> where VC: 'a {
939            Bools {
940                values: VC::reborrow(thing.values),
941                tail: thing.tail,
942            }
943        }
944        #[inline(always)]
945        fn reborrow_ref<'b, 'a: 'b>(thing: Self::Ref<'a>) -> Self::Ref<'b> where Self: 'a { thing }
946    }
947
948    impl<VC: crate::common::PushIndexAs<u64>> Container for Bools<VC> {
949        // TODO: There is probably a smart way to implement `extend_from_slice`, but it isn't trivial due to alignment.
950
951        fn reserve_for<'a, I>(&mut self, selves: I) where Self: 'a, I: Iterator<Item = Self::Borrowed<'a>> + Clone {
952            self.values.reserve_for(selves.map(|x| x.values))
953        }
954    }
955
956    impl<'a, VC: crate::AsBytes<'a>> crate::AsBytes<'a> for crate::primitive::Bools<VC, &'a [u64]> {
957        #[inline(always)]
958        fn as_bytes(&self) -> impl Iterator<Item=(u64, &'a [u8])> {
959            let iter = self.values.as_bytes();
960            crate::chain_one(iter, (core::mem::align_of::<u64>() as u64, bytemuck::cast_slice(self.tail)))
961        }
962    }
963
964    impl<'a, VC: crate::FromBytes<'a>> crate::FromBytes<'a> for crate::primitive::Bools<VC, &'a [u64]> {
965        const SLICE_COUNT: usize = VC::SLICE_COUNT + 1;
966        #[inline(always)]
967        fn from_bytes(bytes: &mut impl Iterator<Item=&'a [u8]>) -> Self {
968            let values = crate::FromBytes::from_bytes(bytes);
969            let tail: &[u64] = bytemuck::try_cast_slice(bytes.next().expect("Iterator exhausted prematurely")).unwrap();
970            Self { values, tail }
971        }
972        #[inline(always)]
973        fn from_store(store: &crate::bytes::indexed::DecodedStore<'a>, offset: &mut usize) -> Self {
974            let values = VC::from_store(store, offset);
975            let (tail, _) = store.get(*offset); *offset += 1;
976            debug_assert!(tail.len() >= 2, "Bools::from_store: tail slice too short (len {})", tail.len());
977            Self { values, tail }
978        }
979        fn element_sizes(sizes: &mut Vec<usize>) -> Result<(), String> {
980            VC::element_sizes(sizes)?;
981            sizes.push(8); // tail: [last_word, last_bits]
982            Ok(())
983        }
984        fn validate(slices: &[(&[u64], u8)]) -> Result<(), String> {
985            if slices.len() < Self::SLICE_COUNT {
986                return Err(format!("Bools: expected {} slices but got {}", Self::SLICE_COUNT, slices.len()));
987            }
988            VC::validate(slices)?;
989            let vc = VC::SLICE_COUNT;
990            if slices[vc].0.len() < 2 {
991                return Err("Bools: tail slice must have at least 2 elements (last_word, last_bits)".into());
992            }
993            Ok(())
994        }
995    }
996
997    impl<VC: Len, TC: IndexAs<u64>> Len for Bools<VC, TC> {
998        #[inline(always)] fn len(&self) -> usize { self.values.len() * 64 + (self.tail.index_as(1) as usize) }
999    }
1000
1001    impl<VC: Len + IndexAs<u64>, TC: IndexAs<u64>> Index for Bools<VC, TC> {
1002        type Ref = bool;
1003        #[inline(always)] fn get(&self, index: usize) -> Self::Ref {
1004            let block = index / 64;
1005            let word = if block == self.values.len() {
1006                self.tail.index_as(0)
1007            } else {
1008                self.values.index_as(block)
1009            };
1010            let bit = index % 64;
1011            (word >> bit) & 1 == 1
1012        }
1013    }
1014
1015    impl<VC: Len + IndexAs<u64>, TC: IndexAs<u64>> Index for &Bools<VC, TC> {
1016        type Ref = bool;
1017        #[inline(always)] fn get(&self, index: usize) -> Self::Ref {
1018            (*self).get(index)
1019        }
1020    }
1021
1022    impl<VC: for<'a> Push<&'a u64>> Push<bool> for Bools<VC> {
1023        #[inline]
1024        fn push(&mut self, bit: bool) {
1025            self.tail[0] |= (bit as u64) << self.tail[1];
1026            self.tail[1] += 1;
1027            // If we have a fully formed word, commit it to `self.values`.
1028            if self.tail[1] == 64 {
1029                self.values.push(&self.tail[0]);
1030                self.tail = [0, 0];
1031            }
1032        }
1033    }
1034    impl<'a, VC: for<'b> Push<&'b u64>> Push<&'a bool> for Bools<VC> {
1035        #[inline(always)]
1036        fn push(&mut self, bit: &'a bool) {
1037            self.push(*bit)
1038        }
1039    }
1040
1041
1042    impl<VC: Clear> Clear for Bools<VC> {
1043        #[inline(always)]
1044        fn clear(&mut self) {
1045            self.values.clear();
1046            self.tail = [0, 0];
1047        }
1048    }
1049
1050}
1051
1052pub use duration::Durations;
1053/// A columnar store for `core::time::Duration`.
1054mod duration {
1055
1056    use alloc::vec::Vec;
1057    use core::time::Duration;
1058    use crate::{Container, Len, Index, IndexAs, Push, Clear, Borrow};
1059
1060    // `core::time::Duration` is equivalent to `(u64, u32)`, corresponding to seconds and nanoseconds.
1061    #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1062    #[derive(Copy, Clone, Debug, Default, PartialEq)]
1063    pub struct Durations<SC = Vec<u64>, NC = Vec<u32>> {
1064        pub seconds: SC,
1065        pub nanoseconds: NC,
1066    }
1067
1068    impl crate::Columnar for Duration {
1069        #[inline(always)]
1070        fn into_owned<'a>(other: crate::Ref<'a, Self>) -> Self { other }
1071        type Container = Durations;
1072    }
1073
1074    impl<SC: crate::common::BorrowIndexAs<u64>, NC: crate::common::BorrowIndexAs<u32>> Borrow for Durations<SC, NC> {
1075        type Ref<'a> = Duration;
1076        type Borrowed<'a> = Durations<SC::Borrowed<'a>, NC::Borrowed<'a>> where SC: 'a, NC: 'a;
1077        #[inline(always)]
1078        fn borrow<'a>(&'a self) -> Self::Borrowed<'a> {
1079            Durations {
1080                seconds: self.seconds.borrow(),
1081                nanoseconds: self.nanoseconds.borrow(),
1082            }
1083        }
1084        #[inline(always)]
1085        fn reborrow<'b, 'a: 'b>(thing: Self::Borrowed<'a>) -> Self::Borrowed<'b> where SC: 'a, NC: 'a {
1086            Durations {
1087                seconds: SC::reborrow(thing.seconds),
1088                nanoseconds: NC::reborrow(thing.nanoseconds),
1089            }
1090        }
1091        #[inline(always)]
1092        fn reborrow_ref<'b, 'a: 'b>(thing: Self::Ref<'a>) -> Self::Ref<'b> where Self: 'a { thing }
1093    }
1094
1095    impl<SC: crate::common::PushIndexAs<u64>, NC: crate::common::PushIndexAs<u32>> Container for Durations<SC, NC> {
1096        #[inline(always)]
1097        fn extend_from_self(&mut self, other: Self::Borrowed<'_>, range: core::ops::Range<usize>) {
1098            self.seconds.extend_from_self(other.seconds, range.clone());
1099            self.nanoseconds.extend_from_self(other.nanoseconds, range);
1100        }
1101
1102        fn reserve_for<'a, I>(&mut self, selves: I) where Self: 'a, I: Iterator<Item = Self::Borrowed<'a>> + Clone {
1103            self.seconds.reserve_for(selves.clone().map(|x| x.seconds));
1104            self.nanoseconds.reserve_for(selves.map(|x| x.nanoseconds));
1105        }
1106    }
1107
1108    impl<'a, SC: crate::AsBytes<'a>, NC: crate::AsBytes<'a>> crate::AsBytes<'a> for crate::primitive::Durations<SC, NC> {
1109        #[inline(always)]
1110        fn as_bytes(&self) -> impl Iterator<Item=(u64, &'a [u8])> {
1111            crate::chain(self.seconds.as_bytes(), self.nanoseconds.as_bytes())
1112        }
1113    }
1114    impl<'a, SC: crate::FromBytes<'a>, NC: crate::FromBytes<'a>> crate::FromBytes<'a> for crate::primitive::Durations<SC, NC> {
1115        const SLICE_COUNT: usize = SC::SLICE_COUNT + NC::SLICE_COUNT;
1116        #[inline(always)]
1117        fn from_bytes(bytes: &mut impl Iterator<Item=&'a [u8]>) -> Self {
1118            Self {
1119                seconds: crate::FromBytes::from_bytes(bytes),
1120                nanoseconds: crate::FromBytes::from_bytes(bytes),
1121            }
1122        }
1123        #[inline(always)]
1124        fn from_store(store: &crate::bytes::indexed::DecodedStore<'a>, offset: &mut usize) -> Self {
1125            Self {
1126                seconds: SC::from_store(store, offset),
1127                nanoseconds: NC::from_store(store, offset),
1128            }
1129        }
1130    }
1131
1132    impl<SC: Len, NC> Len for Durations<SC, NC> {
1133        #[inline(always)] fn len(&self) -> usize { self.seconds.len() }
1134    }
1135
1136    impl<SC: IndexAs<u64>, NC: IndexAs<u32>> Index for Durations<SC, NC> {
1137        type Ref = Duration;
1138        #[inline(always)] fn get(&self, index: usize) -> Self::Ref {
1139            Duration::new(self.seconds.index_as(index), self.nanoseconds.index_as(index))
1140        }
1141    }
1142    impl<SC: IndexAs<u64>, NC: IndexAs<u32>> Index for &Durations<SC, NC> {
1143        type Ref = Duration;
1144        #[inline(always)] fn get(&self, index: usize) -> Self::Ref {
1145            Duration::new(self.seconds.index_as(index), self.nanoseconds.index_as(index))
1146        }
1147    }
1148
1149    impl<SC: for<'a> Push<&'a u64>, NC: for<'a> Push<&'a u32>> Push<core::time::Duration> for Durations<SC, NC> {
1150        #[inline]
1151        fn push(&mut self, item: core::time::Duration) {
1152            self.seconds.push(&item.as_secs());
1153            self.nanoseconds.push(&item.subsec_nanos());
1154        }
1155    }
1156    impl<'a, SC: for<'b> Push<&'b u64>, NC: for<'b> Push<&'b u32>> Push<&'a core::time::Duration> for Durations<SC, NC> {
1157        #[inline]
1158        fn push(&mut self, item: &'a core::time::Duration) {
1159            self.push(*item)
1160        }
1161    }
1162    impl<'a, SC: Push<&'a u64>, NC: Push<&'a u32>> Push<(&'a u64, &'a u32)> for Durations<SC, NC> {
1163        #[inline]
1164        fn push(&mut self, item: (&'a u64, &'a u32)) {
1165            self.seconds.push(item.0);
1166            self.nanoseconds.push(item.1);
1167        }
1168    }
1169
1170    impl<SC: Clear, NC: Clear> Clear for Durations<SC, NC> {
1171        #[inline(always)]
1172        fn clear(&mut self) {
1173            self.seconds.clear();
1174            self.nanoseconds.clear();
1175        }
1176    }
1177
1178}
1179