Skip to main content

columnar/
tuple.rs

1#![allow(non_snake_case)]
2
3use crate::{Columnar, Container, Borrow, Len, Clear, HeapSize, Index, IndexMut, Push};
4
5// Implementations for tuple types.
6// These are all macro based, because the implementations are very similar.
7// The macro requires two names, one for the store and one for pushable types.
8macro_rules! tuple_impl {
9    ( $($name:ident,$name2:ident,$idx:tt)+) => (
10
11        impl<$($name: Columnar),*> Columnar for ($($name,)*) {
12            #[inline(always)]
13            fn copy_from<'a>(&mut self, other: crate::Ref<'a, Self>) {
14                let ($($name,)*) = self;
15                let ($($name2,)*) = other;
16                $(crate::Columnar::copy_from($name, $name2);)*
17            }
18            #[inline(always)]
19            fn into_owned<'a>(other: crate::Ref<'a, Self>) -> Self {
20                let ($($name2,)*) = other;
21                ($($name::into_owned($name2),)*)
22            }
23            type Container = ($($name::Container,)*);
24        }
25        impl<$($name2: Borrow,)*> Borrow for ($($name2,)*) {
26            type Ref<'a> = ($($name2::Ref<'a>,)*) where $($name2: 'a,)*;
27            type Borrowed<'a> = ($($name2::Borrowed<'a>,)*) where $($name2: 'a,)*;
28            #[inline(always)]
29            fn borrow<'a>(&'a self) -> Self::Borrowed<'a> {
30                let ($($name,)*) = self;
31                ($($name.borrow(),)*)
32            }
33            #[inline(always)]
34            fn reborrow<'b, 'a: 'b>(thing: Self::Borrowed<'a>) -> Self::Borrowed<'b> where $($name2: 'a,)* {
35                let ($($name,)*) = thing;
36                ($($name2::reborrow($name),)*)
37            }
38            #[inline(always)]
39            fn reborrow_ref<'b, 'a: 'b>(thing: Self::Ref<'a>) -> Self::Ref<'b> where Self: 'a {
40                let ($($name2,)*) = thing;
41                ($($name2::reborrow_ref($name2),)*)
42            }
43        }
44        impl<$($name2: Container,)*> Container for ($($name2,)*) {
45            #[inline(always)]
46            fn extend_from_self(&mut self, other: Self::Borrowed<'_>, range: std::ops::Range<usize>) {
47                let ($($name,)*) = self;
48                let ($($name2,)*) = other;
49                $( $name.extend_from_self($name2, range.clone()); )*
50            }
51
52            fn reserve_for<'a, I>(&mut self, selves: I) where Self: 'a, I: Iterator<Item = Self::Borrowed<'a>> + Clone {
53                let ($($name,)*) = self;
54                $( $name.reserve_for(selves.clone().map(|x| x.$idx)); )*
55            }
56        }
57
58        #[allow(non_snake_case)]
59        impl<'a, $($name: crate::AsBytes<'a>),*> crate::AsBytes<'a> for ($($name,)*) {
60            #[inline(always)]
61            fn as_bytes(&self) -> impl Iterator<Item=(u64, &'a [u8])> {
62                let ($($name,)*) = self;
63                let iter = None.into_iter();
64                $( let iter = crate::chain(iter, $name.as_bytes()); )*
65                iter
66            }
67        }
68        impl<'a, $($name: crate::FromBytes<'a>),*> crate::FromBytes<'a> for ($($name,)*) {
69            #[inline(always)]
70            #[allow(non_snake_case)]
71            fn from_bytes(bytes: &mut impl Iterator<Item=&'a [u8]>) -> Self {
72                $(let $name = crate::FromBytes::from_bytes(bytes);)*
73                ($($name,)*)
74            }
75        }
76
77        impl<$($name: Len),*> Len for ($($name,)*) {
78            #[inline(always)]
79            fn len(&self) -> usize {
80                self.0.len()
81            }
82        }
83        impl<$($name: Clear),*> Clear for ($($name,)*) {
84            #[inline(always)]
85            fn clear(&mut self) {
86                let ($($name,)*) = self;
87                $($name.clear();)*
88            }
89        }
90        impl<$($name: HeapSize),*> HeapSize for ($($name,)*) {
91            #[inline(always)]
92            fn heap_size(&self) -> (usize, usize) {
93                let ($($name,)*) = self;
94                let mut l = 0;
95                let mut c = 0;
96                $(let (l0, c0) = $name.heap_size(); l += l0; c += c0;)*
97                (l, c)
98            }
99        }
100        impl<$($name: Index),*> Index for ($($name,)*) {
101            type Ref = ($($name::Ref,)*);
102            #[inline(always)]
103            fn get(&self, index: usize) -> Self::Ref {
104                let ($($name,)*) = self;
105                ($($name.get(index),)*)
106            }
107        }
108        impl<'a, $($name),*> Index for &'a ($($name,)*) where $( &'a $name: Index),* {
109            type Ref = ($(<&'a $name as Index>::Ref,)*);
110            #[inline(always)]
111            fn get(&self, index: usize) -> Self::Ref {
112                let ($($name,)*) = self;
113                ($($name.get(index),)*)
114            }
115        }
116
117        impl<$($name: IndexMut),*> IndexMut for ($($name,)*) {
118            type IndexMut<'a> = ($($name::IndexMut<'a>,)*) where $($name: 'a),*;
119            #[inline(always)]
120            fn get_mut(&mut self, index: usize) -> Self::IndexMut<'_> {
121                let ($($name,)*) = self;
122                ($($name.get_mut(index),)*)
123            }
124        }
125        impl<$($name2, $name: Push<$name2>),*> Push<($($name2,)*)> for ($($name,)*) {
126            #[inline]
127            fn push(&mut self, item: ($($name2,)*)) {
128                let ($($name,)*) = self;
129                let ($($name2,)*) = item;
130                $($name.push($name2);)*
131            }
132        }
133        impl<'a, $($name2, $name: Push<&'a $name2>),*> Push<&'a ($($name2,)*)> for ($($name,)*) {
134            #[inline]
135            fn push(&mut self, item: &'a ($($name2,)*)) {
136                let ($($name,)*) = self;
137                let ($($name2,)*) = item;
138                $($name.push($name2);)*
139            }
140        }
141    )
142}
143
144tuple_impl!(A,AA,0);
145tuple_impl!(A,AA,0 B,BB,1);
146tuple_impl!(A,AA,0 B,BB,1 C,CC,2);
147tuple_impl!(A,AA,0 B,BB,1 C,CC,2 D,DD,3);
148tuple_impl!(A,AA,0 B,BB,1 C,CC,2 D,DD,3 E,EE,4);
149tuple_impl!(A,AA,0 B,BB,1 C,CC,2 D,DD,3 E,EE,4 F,FF,5);
150tuple_impl!(A,AA,0 B,BB,1 C,CC,2 D,DD,3 E,EE,4 F,FF,5 G,GG,6);
151tuple_impl!(A,AA,0 B,BB,1 C,CC,2 D,DD,3 E,EE,4 F,FF,5 G,GG,6 H,HH,7);
152tuple_impl!(A,AA,0 B,BB,1 C,CC,2 D,DD,3 E,EE,4 F,FF,5 G,GG,6 H,HH,7 I,II,8);
153tuple_impl!(A,AA,0 B,BB,1 C,CC,2 D,DD,3 E,EE,4 F,FF,5 G,GG,6 H,HH,7 I,II,8 J,JJ,9);
154
155#[cfg(test)]
156mod test {
157    #[test]
158    fn round_trip() {
159
160        use crate::common::{Index, Push, HeapSize, Len};
161
162        let mut column: crate::ContainerOf<(u64, u8, String)> = Default::default();
163        for i in 0..100 {
164            column.push((i, i as u8, &i.to_string()));
165            column.push((i, i as u8, &"".to_string()));
166        }
167
168        assert_eq!(column.len(), 200);
169        assert_eq!(column.heap_size(), (3590, 4608));
170
171        for i in 0..100u64 {
172            assert_eq!((&column).get((2*i+0) as usize), (&i, &(i as u8), i.to_string().as_str()));
173            assert_eq!((&column).get((2*i+1) as usize), (&i, &(i as u8), ""));
174        }
175
176        // Compare to the heap size of a `Vec<Option<usize>>`.
177        let mut column: Vec<(u64, u8, String)> = Default::default();
178        for i in 0..100 {
179            column.push((i, i as u8, i.to_string()));
180            column.push((i, i as u8, "".to_string()));
181        }
182        // NB: Rust seems to change the capacities across versions (1.88 != 1.89),
183        // so we just compare the allocated regions to avoid updating the MSRV.
184        assert_eq!(column.heap_size().0, 8190);
185
186    }
187}