Skip to content

Commit

Permalink
Introduce CapacityContainer
Browse files Browse the repository at this point in the history
Signed-off-by: Moritz Hoffmann <[email protected]>
  • Loading branch information
antiguru committed Jul 9, 2024
1 parent 3f9d387 commit 63103bd
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 1 deletion.
21 changes: 20 additions & 1 deletion container/src/flatcontainer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<R, S> Container for FlatStack<R, S>
where
Expand Down Expand Up @@ -48,6 +48,25 @@ impl<R: Region + Clone + 'static> SizableContainer for FlatStack<R> {
}
}

impl<R, S> CapacityContainer for FlatStack<R, S>
{
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<R, S, T> PushInto<T> for FlatStack<R, S>
where
R: Region + Push<T>,
Expand Down
26 changes: 26 additions & 0 deletions container/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<T> {
/// Push item into self.
Expand Down Expand Up @@ -245,6 +257,20 @@ impl<T: Clone + 'static> SizableContainer for Vec<T> {
}
}

impl<T> CapacityContainer for Vec<T> {
fn preferred_capacity() -> usize {
buffer::default_capacity::<T>()
}

#[inline]
fn ensure_preferred_capacity(&mut self) {
if self.capacity() < <Self as CapacityContainer>::preferred_capacity() {
self.reserve(<Self as CapacityContainer>::preferred_capacity() - self.capacity());
}
}
}


impl<T> PushInto<T> for Vec<T> {
#[inline]
fn push_into(&mut self, item: T) {
Expand Down

0 comments on commit 63103bd

Please sign in to comment.