Skip to content

Commit e608b80

Browse files
Merge pull request #57 from frankmcsherry/reserve_for
Add `Container::reserve_for`
2 parents d5928fb + 5aa831d commit e608b80

File tree

2 files changed

+106
-13
lines changed

2 files changed

+106
-13
lines changed

columnar_derive/src/lib.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,10 @@ fn derive_struct(name: &syn::Ident, generics: &syn::Generics, data_struct: syn::
388388
fn extend_from_self(&mut self, other: Self::Borrowed<'_>, range: std::ops::Range<usize>) {
389389
#( self.#names.extend_from_self(other.#names, range.clone()); )*
390390
}
391+
392+
fn reserve_for<'a, I>(&mut self, selves: I) where Self: 'a, I: Iterator<Item = Self::Borrowed<'a>> + Clone {
393+
#( self.#names.reserve_for(selves.clone().map(|x| x.#names)); )*
394+
}
391395
}
392396
}
393397
};
@@ -527,6 +531,8 @@ fn derive_unit_struct(name: &syn::Ident, _generics: &syn::Generics, vis: syn::Vi
527531
fn extend_from_self(&mut self, _other: Self::Borrowed<'_>, range: std::ops::Range<usize>) {
528532
self.count += range.len() as u64;
529533
}
534+
535+
fn reserve_for<'a, I>(&mut self, selves: I) where Self: 'a, I: Iterator<Item = Self::Borrowed<'a>> + Clone { }
530536
}
531537

532538
}.into()
@@ -1014,6 +1020,12 @@ fn derive_enum(name: &syn::Ident, generics: &syn:: Generics, data_enum: syn::Dat
10141020
}
10151021

10161022
// TODO: implement `extend_from_self`.
1023+
1024+
fn reserve_for<'a, I>(&mut self, selves: I) where Self: 'a, I: Iterator<Item = Self::Borrowed<'a>> + Clone {
1025+
#( self.#names.reserve_for(selves.clone().map(|x| x.#names)); )*
1026+
self.variant.reserve_for(selves.clone().map(|x| x.variant));
1027+
self.offset.reserve_for(selves.map(|x| x.offset));
1028+
}
10171029
}
10181030
}
10191031
};
@@ -1168,6 +1180,10 @@ fn derive_tags(name: &syn::Ident, _generics: &syn:: Generics, data_enum: syn::Da
11681180
fn reborrow_ref<'b, 'a: 'b>(thing: Self::Ref<'a>) -> Self::Ref<'b> { thing }
11691181

11701182
// TODO: implement `extend_from_self`.
1183+
1184+
fn reserve_for<'a, I>(&mut self, selves: I) where Self: 'a, I: Iterator<Item = Self::Borrowed<'a>> + Clone {
1185+
self.variant.reserve_for(selves.map(|x| x.variant));
1186+
}
11711187
}
11721188
}.into()
11731189
}

src/lib.rs

Lines changed: 90 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,29 @@ pub trait Container : Len + Clear + for<'a> Push<Self::Ref<'a>> + Clone + Defaul
9393
/// Reborrows the borrowed type to a shorter lifetime. See [`Columnar::reborrow`] for details.
9494
fn reborrow_ref<'b, 'a: 'b>(item: Self::Ref<'a>) -> Self::Ref<'b> where Self: 'a;
9595

96+
97+
/// Allocates an empty container that can be extended by `selves` without reallocation.
98+
///
99+
/// This goal is optimistic, and some containers may struggle to size correctly, especially
100+
/// if they employ compression or other variable-sizing techniques that respond to the data
101+
/// and the order in which is it presented. Best effort, but still useful!
102+
fn with_capacity_for<'a, I>(selves: I) -> Self
103+
where
104+
Self: 'a,
105+
I: Iterator<Item = Self::Borrowed<'a>> + Clone
106+
{
107+
let mut output = Self::default();
108+
output.reserve_for(selves);
109+
output
110+
}
111+
112+
// Ensure that `self` can extend from `selves` without reallocation.
113+
fn reserve_for<'a, I>(&mut self, selves: I)
114+
where
115+
Self: 'a,
116+
I: Iterator<Item = Self::Borrowed<'a>> + Clone;
117+
118+
96119
/// Extends `self` by a range in `other`.
97120
///
98121
/// This method has a default implementation, but can and should be specialized when ranges can be copied.
@@ -113,7 +136,9 @@ impl<T: Clone + Send + 'static> Container for Vec<T> {
113136
fn extend_from_self(&mut self, other: Self::Borrowed<'_>, range: std::ops::Range<usize>) {
114137
self.extend_from_slice(&other[range])
115138
}
116-
139+
fn reserve_for<'a, I>(&mut self, selves: I) where Self: 'a, I: Iterator<Item = Self::Borrowed<'a>> + Clone {
140+
self.reserve(selves.map(|x| x.len()).sum::<usize>())
141+
}
117142
}
118143

119144
/// A container that can also be viewed as and reconstituted from bytes.
@@ -983,6 +1008,10 @@ pub mod primitive {
9831008
fn extend_from_self(&mut self, other: Self::Borrowed<'_>, range: std::ops::Range<usize>) {
9841009
self.values.extend_from_self(other.values, range)
9851010
}
1011+
1012+
fn reserve_for<'a, I>(&mut self, selves: I) where Self: 'a, I: Iterator<Item = Self::Borrowed<'a>> + Clone {
1013+
self.values.reserve_for(selves.map(|x| x.values))
1014+
}
9861015
}
9871016

9881017
impl<CV: Len> Len for Usizes<CV> { fn len(&self) -> usize { self.values.len() }}
@@ -1054,6 +1083,10 @@ pub mod primitive {
10541083
fn extend_from_self(&mut self, other: Self::Borrowed<'_>, range: std::ops::Range<usize>) {
10551084
self.values.extend_from_self(other.values, range)
10561085
}
1086+
1087+
fn reserve_for<'a, I>(&mut self, selves: I) where Self: 'a, I: Iterator<Item = Self::Borrowed<'a>> + Clone {
1088+
self.values.reserve_for(selves.map(|x| x.values))
1089+
}
10571090
}
10581091

10591092
impl<CV: Len> Len for Isizes<CV> { fn len(&self) -> usize { self.values.len() }}
@@ -1141,6 +1174,8 @@ pub mod primitive {
11411174
fn extend_from_self(&mut self, _other: Self::Borrowed<'_>, range: std::ops::Range<usize>) {
11421175
self.count += range.len() as u64;
11431176
}
1177+
1178+
fn reserve_for<'a, I>(&mut self, _selves: I) where Self: 'a, I: Iterator<Item = Self::Borrowed<'a>> + Clone { }
11441179
}
11451180

11461181
impl<const K: u64, CC: CopyAs<u64>> Len for Fixeds<K, CC> {
@@ -1237,6 +1272,10 @@ pub mod primitive {
12371272
}
12381273
/// Reborrows the borrowed type to a shorter lifetime. See [`Columnar::reborrow`] for details.
12391274
#[inline(always)]fn reborrow_ref<'b, 'a: 'b>(item: Self::Ref<'a>) -> Self::Ref<'b> where Self: 'a { item }
1275+
1276+
fn reserve_for<'a, I>(&mut self, selves: I) where Self: 'a, I: Iterator<Item = Self::Borrowed<'a>> + Clone {
1277+
self.bounds.reserve_for(selves.map(|x| x.bounds))
1278+
}
12401279
}
12411280

12421281
impl<'a> Push<&'a u64> for Strides { #[inline(always)] fn push(&mut self, item: &'a u64) { self.push(*item) } }
@@ -1394,6 +1433,8 @@ pub mod primitive {
13941433
fn extend_from_self(&mut self, _other: Self::Borrowed<'_>, range: std::ops::Range<usize>) {
13951434
self.count += range.len() as u64;
13961435
}
1436+
1437+
fn reserve_for<'a, I>(&mut self, _selves: I) where Self: 'a, I: Iterator<Item = Self::Borrowed<'a>> + Clone { }
13971438
}
13981439

13991440
impl<CC: CopyAs<u64>> Len for Empties<CC> {
@@ -1504,6 +1545,10 @@ pub mod primitive {
15041545
fn reborrow_ref<'b, 'a: 'b>(thing: Self::Ref<'a>) -> Self::Ref<'b> where Self: 'a { thing }
15051546

15061547
// TODO: There is probably a smart way to implement `extend_from_slice`, but it isn't trivial due to alignment.
1548+
1549+
fn reserve_for<'a, I>(&mut self, selves: I) where Self: 'a, I: Iterator<Item = Self::Borrowed<'a>> + Clone {
1550+
self.values.reserve_for(selves.map(|x| x.values))
1551+
}
15071552
}
15081553

15091554
impl<'a, VC: crate::AsBytes<'a>> crate::AsBytes<'a> for crate::primitive::Bools<VC, &'a u64> {
@@ -1634,6 +1679,11 @@ pub mod primitive {
16341679
self.seconds.extend_from_self(other.seconds, range.clone());
16351680
self.nanoseconds.extend_from_self(other.nanoseconds, range);
16361681
}
1682+
1683+
fn reserve_for<'a, I>(&mut self, selves: I) where Self: 'a, I: Iterator<Item = Self::Borrowed<'a>> + Clone {
1684+
self.seconds.reserve_for(selves.clone().map(|x| x.seconds));
1685+
self.nanoseconds.reserve_for(selves.map(|x| x.nanoseconds));
1686+
}
16371687
}
16381688

16391689
impl<'a, SC: crate::AsBytes<'a>, NC: crate::AsBytes<'a>> crate::AsBytes<'a> for crate::primitive::Durations<SC, NC> {
@@ -1772,6 +1822,12 @@ pub mod string {
17721822
}
17731823
}
17741824
}
1825+
1826+
fn reserve_for<'a, I>(&mut self, selves: I) where Self: 'a, I: Iterator<Item = Self::Borrowed<'a>> + Clone {
1827+
self.bounds.reserve_for(selves.clone().map(|x| x.bounds));
1828+
self.values.reserve_for(selves.map(|x| x.values));
1829+
}
1830+
17751831
}
17761832

17771833
impl<'a, BC: crate::AsBytes<'a>, VC: crate::AsBytes<'a>> crate::AsBytes<'a> for Strings<BC, VC> {
@@ -1987,6 +2043,11 @@ pub mod vector {
19872043
}
19882044
}
19892045
}
2046+
2047+
fn reserve_for<'a, I>(&mut self, selves: I) where Self: 'a, I: Iterator<Item = Self::Borrowed<'a>> + Clone {
2048+
self.bounds.reserve_for(selves.clone().map(|x| x.bounds));
2049+
self.values.reserve_for(selves.map(|x| x.values));
2050+
}
19902051
}
19912052

19922053
impl<'a, TC: crate::AsBytes<'a>, BC: crate::AsBytes<'a>> crate::AsBytes<'a> for Vecs<TC, BC> {
@@ -2088,7 +2149,7 @@ pub mod tuple {
20882149
// These are all macro based, because the implementations are very similar.
20892150
// The macro requires two names, one for the store and one for pushable types.
20902151
macro_rules! tuple_impl {
2091-
( $($name:ident,$name2:ident)+) => (
2152+
( $($name:ident,$name2:ident,$idx:tt)+) => (
20922153

20932154
impl<$($name: Columnar),*> Columnar for ($($name,)*) {
20942155
#[inline(always)]
@@ -2129,6 +2190,11 @@ pub mod tuple {
21292190
let ($($name2,)*) = other;
21302191
$( $name.extend_from_self($name2, range.clone()); )*
21312192
}
2193+
2194+
fn reserve_for<'a, I>(&mut self, selves: I) where Self: 'a, I: Iterator<Item = Self::Borrowed<'a>> + Clone {
2195+
let ($($name,)*) = self;
2196+
$( $name.reserve_for(selves.clone().map(|x| x.$idx)); )*
2197+
}
21322198
}
21332199

21342200
#[allow(non_snake_case)]
@@ -2217,16 +2283,16 @@ pub mod tuple {
22172283
)
22182284
}
22192285

2220-
tuple_impl!(A,AA);
2221-
tuple_impl!(A,AA B,BB);
2222-
tuple_impl!(A,AA B,BB C,CC);
2223-
tuple_impl!(A,AA B,BB C,CC D,DD);
2224-
tuple_impl!(A,AA B,BB C,CC D,DD E,EE);
2225-
tuple_impl!(A,AA B,BB C,CC D,DD E,EE F,FF);
2226-
tuple_impl!(A,AA B,BB C,CC D,DD E,EE F,FF G,GG);
2227-
tuple_impl!(A,AA B,BB C,CC D,DD E,EE F,FF G,GG H,HH);
2228-
tuple_impl!(A,AA B,BB C,CC D,DD E,EE F,FF G,GG H,HH I,II);
2229-
tuple_impl!(A,AA B,BB C,CC D,DD E,EE F,FF G,GG H,HH I,II J,JJ);
2286+
tuple_impl!(A,AA,0);
2287+
tuple_impl!(A,AA,0 B,BB,1);
2288+
tuple_impl!(A,AA,0 B,BB,1 C,CC,2);
2289+
tuple_impl!(A,AA,0 B,BB,1 C,CC,2 D,DD,3);
2290+
tuple_impl!(A,AA,0 B,BB,1 C,CC,2 D,DD,3 E,EE,4);
2291+
tuple_impl!(A,AA,0 B,BB,1 C,CC,2 D,DD,3 E,EE,4 F,FF,5);
2292+
tuple_impl!(A,AA,0 B,BB,1 C,CC,2 D,DD,3 E,EE,4 F,FF,5 G,GG,6);
2293+
tuple_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);
2294+
tuple_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);
2295+
tuple_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);
22302296

22312297
#[cfg(test)]
22322298
mod test {
@@ -2427,7 +2493,7 @@ pub mod sums {
24272493
use crate::{Clear, Columnar, Container, Len, IndexMut, Index, IndexAs, Push, HeapSize};
24282494
use crate::RankSelect;
24292495

2430-
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
2496+
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
24312497
#[derive(Copy, Clone, Debug, Default, PartialEq)]
24322498
pub struct Results<SC, TC, CC=Vec<u64>, VC=Vec<u64>, WC=u64> {
24332499
/// Bits set to `true` correspond to `Ok` variants.
@@ -2500,6 +2566,12 @@ pub mod sums {
25002566
self.errs.extend_from_self(other.errs, errs_start .. errs_start + errs);
25012567
}
25022568
}
2569+
2570+
fn reserve_for<'a, I>(&mut self, selves: I) where Self: 'a, I: Iterator<Item = Self::Borrowed<'a>> + Clone {
2571+
// TODO: reserve room in `self.indexes`.
2572+
self.oks.reserve_for(selves.clone().map(|x| x.oks));
2573+
self.errs.reserve_for(selves.map(|x| x.errs));
2574+
}
25032575
}
25042576

25052577
impl<'a, SC: crate::AsBytes<'a>, TC: crate::AsBytes<'a>, CC: crate::AsBytes<'a>, VC: crate::AsBytes<'a>> crate::AsBytes<'a> for Results<SC, TC, CC, VC, &'a u64> {
@@ -2740,6 +2812,11 @@ pub mod sums {
27402812
self.somes.extend_from_self(other.somes, somes_start .. somes_start + somes);
27412813
}
27422814
}
2815+
2816+
fn reserve_for<'a, I>(&mut self, selves: I) where Self: 'a, I: Iterator<Item = Self::Borrowed<'a>> + Clone {
2817+
// TODO: reserve room in `self.indexes`.
2818+
self.somes.reserve_for(selves.map(|x| x.somes));
2819+
}
27432820
}
27442821

27452822
impl<'a, TC: crate::AsBytes<'a>, CC: crate::AsBytes<'a>, VC: crate::AsBytes<'a>> crate::AsBytes<'a> for Options<TC, CC, VC, &'a u64> {

0 commit comments

Comments
 (0)