Skip to content

Commit

Permalink
Introduce GATs for containers
Browse files Browse the repository at this point in the history
Containers are generic over their contents, and over reading and draining.

Signed-off-by: Moritz Hoffmann <[email protected]>
  • Loading branch information
antiguru committed Mar 1, 2024
1 parent 0369222 commit a840ef4
Show file tree
Hide file tree
Showing 12 changed files with 298 additions and 112 deletions.
1 change: 1 addition & 0 deletions container/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ license = "MIT"

[dependencies]
columnation = { git = "https://github.com/frankmcsherry/columnation" }
flatcontainer = "0.1"
serde = { version = "1.0"}
72 changes: 44 additions & 28 deletions container/src/columnation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,24 @@ impl<T: Columnation> TimelyStack<T> {
});
(length, capacity)
}

/// The length in items.
#[inline]
pub fn len(&self) -> usize {
self.local.len()
}

/// The capacity of the local vector.
#[inline]
pub fn capacity(&self) -> usize {
self.local.capacity()
}

/// Reserve space for `additional` elements.
#[inline]
pub fn reserve(&mut self, additional: usize) {
self.local.reserve(additional)
}
}

impl<A: Columnation, B: Columnation> TimelyStack<(A, B)> {
Expand Down Expand Up @@ -291,12 +309,14 @@ mod serde {
}

mod container {
use crate::{Container, PushPartitioned};
use std::ops::Deref;
use crate::{Container, PushContainer};

use crate::columnation::{Columnation, TimelyStack};

impl<T: Columnation + 'static> Container for TimelyStack<T> {
type Item = T;
type ItemRef<'a> = &'a T where Self: 'a;
type Item<'a> = &'a T where Self: 'a;

fn len(&self) -> usize {
self.local.len()
Expand All @@ -306,38 +326,34 @@ mod container {
self.local.is_empty()
}

fn capacity(&self) -> usize {
self.local.capacity()
}

fn clear(&mut self) {
TimelyStack::clear(self)
}

type Iter<'a> = std::slice::Iter<'a, T>;

fn iter<'a>(&'a self) -> Self::Iter<'a> {
self.deref().iter()
}

type DrainIter<'a> = std::slice::Iter<'a, T>;

fn drain<'a>(&'a mut self) -> Self::DrainIter<'a> {
(&*self).iter()
}
}

impl<T: Columnation + 'static> PushPartitioned for TimelyStack<T> {
fn push_partitioned<I, F>(&mut self, buffers: &mut [Self], mut index: I, mut flush: F)
where
I: FnMut(&Self::Item) -> usize,
F: FnMut(usize, &mut Self),
{
fn ensure_capacity<E: Columnation>(this: &mut TimelyStack<E>) {
let capacity = this.local.capacity();
let desired_capacity = crate::buffer::default_capacity::<E>();
if capacity < desired_capacity {
this.local.reserve(desired_capacity - capacity);
}
}
impl<T: Columnation + 'static> PushContainer for TimelyStack<T> {
fn capacity(&self) -> usize {
self.capacity()
}

for datum in &self[..] {
let index = index(&datum);
ensure_capacity(&mut buffers[index]);
buffers[index].copy(datum);
if buffers[index].len() == buffers[index].local.capacity() {
flush(index, &mut buffers[index]);
}
}
self.clear();
fn preferred_capacity() -> usize {
crate::buffer::default_capacity::<T>()
}

fn reserve(&mut self, additional: usize) {
self.reserve(additional)
}
}
}
50 changes: 50 additions & 0 deletions container/src/flatcontainer.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
//! Present a [`FlatStack`] as a timely container.

pub use flatcontainer::*;
use crate::{buffer, Container, PushContainer, PushInto};

impl<R: Region + Clone + 'static> Container for FlatStack<R> {
type ItemRef<'a> = R::ReadItem<'a> where Self: 'a;
type Item<'a> = R::ReadItem<'a> where Self: 'a;

fn len(&self) -> usize {
self.len()
}

fn clear(&mut self) {
self.clear()
}

type Iter<'a> = <&'a Self as IntoIterator>::IntoIter;

fn iter<'a>(&'a self) -> Self::Iter<'a> {
IntoIterator::into_iter(self)
}

type DrainIter<'a> = Self::Iter<'a>;

fn drain<'a>(&'a mut self) -> Self::DrainIter<'a> {
IntoIterator::into_iter(&*self)
}
}

impl<R: Region + Clone + 'static> PushContainer for FlatStack<R> {
fn capacity(&self) -> usize {
self.capacity()
}

fn preferred_capacity() -> usize {
buffer::default_capacity::<R::Index>()
}

fn reserve(&mut self, additional: usize) {
self.reserve(additional);
}
}

impl<R: Region + Clone + 'static, T: CopyOnto<R>> PushInto<FlatStack<R>> for T {
#[inline]
fn push_into(self, target: &mut FlatStack<R>) {
target.copy(self);
}
}
Loading

0 comments on commit a840ef4

Please sign in to comment.