From 3f9d3874c6c5d75e2a9e67af9e78d6c40234be6a Mon Sep 17 00:00:00 2001 From: Moritz Hoffmann Date: Mon, 1 Jul 2024 22:15:55 -0400 Subject: [PATCH 1/3] Flat container storage abstraction Signed-off-by: Moritz Hoffmann --- container/Cargo.toml | 3 ++- container/src/flatcontainer.rs | 14 ++++++++++++-- timely/src/order.rs | 12 ++++++++++++ 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/container/Cargo.toml b/container/Cargo.toml index 88d2ef563..baed97e41 100644 --- a/container/Cargo.toml +++ b/container/Cargo.toml @@ -7,5 +7,6 @@ license = "MIT" [dependencies] columnation = { git = "https://github.com/frankmcsherry/columnation" } -flatcontainer = "0.5" +# flatcontainer = "0.5" +flatcontainer = { git = "https://github.com/antiguru/flatcontainer" } serde = { version = "1.0"} diff --git a/container/src/flatcontainer.rs b/container/src/flatcontainer.rs index 62600a77e..27bd31c31 100644 --- a/container/src/flatcontainer.rs +++ b/container/src/flatcontainer.rs @@ -1,9 +1,14 @@ //! Present a [`FlatStack`] as a timely container. pub use flatcontainer::*; +use flatcontainer::impls::index::IndexContainer; use crate::{buffer, Container, SizableContainer, PushInto}; -impl Container for FlatStack { +impl Container for FlatStack +where + R: Region + Clone + 'static, + S: IndexContainer<::Index> + Clone + 'static, +{ type ItemRef<'a> = R::ReadItem<'a> where Self: 'a; type Item<'a> = R::ReadItem<'a> where Self: 'a; @@ -28,6 +33,7 @@ impl Container for FlatStack { } } +// Only implemented for `FlatStack` with `Vec` offsets. impl SizableContainer for FlatStack { fn capacity(&self) -> usize { self.capacity() @@ -42,7 +48,11 @@ impl SizableContainer for FlatStack { } } -impl, T> PushInto for FlatStack { +impl PushInto for FlatStack +where + R: Region + Push, + S: IndexContainer + Clone + 'static, +{ #[inline] fn push_into(&mut self, item: T) { self.copy(item); diff --git a/timely/src/order.rs b/timely/src/order.rs index 982724255..a9f362d97 100644 --- a/timely/src/order.rs +++ b/timely/src/order.rs @@ -280,6 +280,18 @@ mod product { } } + impl<'a, 'b, RO, RI> ReserveItems<&'b Product, RI::ReadItem<'a>>> for ProductRegion + where + RO: Region + ReserveItems<&'b ::ReadItem<'a>> + 'a, + RI: Region + ReserveItems<&'b ::ReadItem<'a>> + 'a, + { + #[inline] + fn reserve_items(&mut self, items: I) where I: Iterator, RI::ReadItem<'a>>> + Clone { + self.outer_region.reserve_items(items.clone().map(|i| &i.outer)); + self.inner_region.reserve_items(items.clone().map(|i| &i.inner)); + } + } + impl Push> for ProductRegion where RO: Region + Push, From 63103bd5f7584fd77b3256580df229189cbcd314 Mon Sep 17 00:00:00 2001 From: Moritz Hoffmann Date: Tue, 9 Jul 2024 10:36:29 -0400 Subject: [PATCH 2/3] Introduce CapacityContainer Signed-off-by: Moritz Hoffmann --- container/src/flatcontainer.rs | 21 ++++++++++++++++++++- container/src/lib.rs | 26 ++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/container/src/flatcontainer.rs b/container/src/flatcontainer.rs index 27bd31c31..c7d5dcd11 100644 --- a/container/src/flatcontainer.rs +++ b/container/src/flatcontainer.rs @@ -2,7 +2,7 @@ pub use flatcontainer::*; use flatcontainer::impls::index::IndexContainer; -use crate::{buffer, Container, SizableContainer, PushInto}; +use crate::{buffer, Container, SizableContainer, PushInto, CapacityContainer}; impl Container for FlatStack where @@ -48,6 +48,25 @@ impl SizableContainer for FlatStack { } } +impl CapacityContainer for FlatStack +{ + fn preferred_capacity() -> usize { + // We don't have a good way to present any pre-defined capacity here, since it's a + // concept foreign to flat containers. Each region might have a capacity, but overall + // the concept of capacity does not exist. For this reason, we just hardcode a number, + // which seems to work reasonably well. + // + // We should revisit this if/once we have an abstraction that can express a capacity + // for `FlatStack`, but we aren't there yet. + 1024 + } + + fn ensure_preferred_capacity(&mut self) { + // Nop, same reasoning as for `preferred_capacity`. We don't know how to ensure capacity + // for a certain number of elements. + } +} + impl PushInto for FlatStack where R: Region + Push, diff --git a/container/src/lib.rs b/container/src/lib.rs index a86c09b5a..21e1c7881 100644 --- a/container/src/lib.rs +++ b/container/src/lib.rs @@ -73,6 +73,18 @@ pub trait SizableContainer: Container { fn reserve(&mut self, additional: usize); } +/// A container that has a preferred capacity and can ensure it has said capacity. +/// +// TODO: This trait shouldn't exist, but @antiguru cannot come up with a better way to encode that +// we might want to preallocate a buffer :( +pub trait CapacityContainer { + /// The preferred capacity + fn preferred_capacity() -> usize; + + /// Ensure that the container has sufficient capacity to absorb `preferred_capacity` elements. + fn ensure_preferred_capacity(&mut self); +} + /// A container that can absorb items of a specific type. pub trait PushInto { /// Push item into self. @@ -245,6 +257,20 @@ impl SizableContainer for Vec { } } +impl CapacityContainer for Vec { + fn preferred_capacity() -> usize { + buffer::default_capacity::() + } + + #[inline] + fn ensure_preferred_capacity(&mut self) { + if self.capacity() < ::preferred_capacity() { + self.reserve(::preferred_capacity() - self.capacity()); + } + } +} + + impl PushInto for Vec { #[inline] fn push_into(&mut self, item: T) { From 122b0dad6e79e8d8d1070710107f0fc9705f169d Mon Sep 17 00:00:00 2001 From: Moritz Hoffmann Date: Tue, 23 Jul 2024 15:42:14 -0400 Subject: [PATCH 3/3] Only implement CapacityContainer for FlatStack with Vec storage Signed-off-by: Moritz Hoffmann --- container/src/flatcontainer.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/container/src/flatcontainer.rs b/container/src/flatcontainer.rs index c7d5dcd11..41dcf0fb2 100644 --- a/container/src/flatcontainer.rs +++ b/container/src/flatcontainer.rs @@ -48,7 +48,7 @@ impl SizableContainer for FlatStack { } } -impl CapacityContainer for FlatStack +impl CapacityContainer for FlatStack { fn preferred_capacity() -> usize { // We don't have a good way to present any pre-defined capacity here, since it's a @@ -62,8 +62,9 @@ impl CapacityContainer for FlatStack } fn ensure_preferred_capacity(&mut self) { - // Nop, same reasoning as for `preferred_capacity`. We don't know how to ensure capacity - // for a certain number of elements. + if self.capacity() < Self::preferred_capacity() { + self.reserve(Self::preferred_capacity() - self.capacity()); + } } }