#![forbid(missing_docs)]
pub mod columnation;
pub trait Container: Default + Clone + 'static {
type Item;
fn len(&self) -> usize;
fn is_empty(&self) -> bool {
self.len() == 0
}
fn capacity(&self) -> usize;
fn clear(&mut self);
}
impl<T: Clone + 'static> Container for Vec<T> {
type Item = T;
fn len(&self) -> usize {
Vec::len(self)
}
fn is_empty(&self) -> bool {
Vec::is_empty(self)
}
fn capacity(&self) -> usize {
Vec::capacity(self)
}
fn clear(&mut self) { Vec::clear(self) }
}
mod rc {
use std::rc::Rc;
use crate::Container;
impl<T: Container> Container for Rc<T> {
type Item = T::Item;
fn len(&self) -> usize {
std::ops::Deref::deref(self).len()
}
fn is_empty(&self) -> bool {
std::ops::Deref::deref(self).is_empty()
}
fn capacity(&self) -> usize {
std::ops::Deref::deref(self).capacity()
}
fn clear(&mut self) {
if let Some(inner) = Rc::get_mut(self) {
inner.clear();
} else {
*self = Self::default();
}
}
}
}
mod arc {
use std::sync::Arc;
use crate::Container;
impl<T: Container> Container for Arc<T> {
type Item = T::Item;
fn len(&self) -> usize {
std::ops::Deref::deref(self).len()
}
fn is_empty(&self) -> bool {
std::ops::Deref::deref(self).is_empty()
}
fn capacity(&self) -> usize {
std::ops::Deref::deref(self).capacity()
}
fn clear(&mut self) {
if let Some(inner) = Arc::get_mut(self) {
inner.clear();
} else {
*self = Self::default();
}
}
}
}
pub trait PushPartitioned: Container {
fn push_partitioned<I, F>(&mut self, buffers: &mut [Self], index: I, flush: F)
where
I: FnMut(&Self::Item) -> usize,
F: FnMut(usize, &mut Self);
}
impl<T: Clone + 'static> PushPartitioned for Vec<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>(this: &mut Vec<E>) {
let capacity = this.capacity();
let desired_capacity = buffer::default_capacity::<E>();
if capacity < desired_capacity {
this.reserve(desired_capacity - capacity);
}
}
for datum in self.drain(..) {
let index = index(&datum);
ensure_capacity(&mut buffers[index]);
buffers[index].push(datum);
if buffers[index].len() == buffers[index].capacity() {
flush(index, &mut buffers[index]);
}
}
}
}
pub mod buffer {
pub const BUFFER_SIZE_BYTES: usize = 1 << 13;
pub const fn default_capacity<T>() -> usize {
let size = ::std::mem::size_of::<T>();
if size == 0 {
BUFFER_SIZE_BYTES
} else if size <= BUFFER_SIZE_BYTES {
BUFFER_SIZE_BYTES / size
} else {
1
}
}
}