Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Separate data storage #19

Merged
merged 15 commits into from
Jul 2, 2024
1 change: 1 addition & 0 deletions src/impls/mod.rs → src/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ pub mod option;
pub mod result;
pub mod slice;
pub mod slice_copy;
pub mod storage;
pub mod string;
pub mod tuple;
mod vec;
96 changes: 61 additions & 35 deletions src/impls/columns.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
//! A region to contain a variable number of columns.

use std::fmt::Debug;
use std::iter::Zip;
use std::slice::Iter;

#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};

use crate::impls::deduplicate::ConsecutiveOffsetPairs;
use crate::impls::offsets::OffsetOptimized;
use crate::impls::offsets::{OffsetContainer, OffsetOptimized};
use crate::{CopyIter, IntoOwned};
use crate::{OwnedRegion, Push, Region};

Expand Down Expand Up @@ -52,24 +54,27 @@ use crate::{OwnedRegion, Push, Region};
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(
feature = "serde",
serde(
bound = "R: Serialize + for<'a> Deserialize<'a>, R::Index: Serialize + for<'a> Deserialize<'a>"
)
serde(bound = "
R: Serialize + for<'a> Deserialize<'a>,
R::Index: Serialize + for<'a> Deserialize<'a>,
O: Serialize + for<'a> Deserialize<'a>,
")
)]
pub struct ColumnsRegion<R>
pub struct ColumnsRegion<R, O = OffsetOptimized>
where
R: Region,
{
/// Indices to address rows in `inner`. For each row, we remember
/// an index for each column.
indices: ConsecutiveOffsetPairs<OwnedRegion<R::Index>, OffsetOptimized>,
indices: ConsecutiveOffsetPairs<OwnedRegion<R::Index>, O>,
/// Storage for columns.
inner: Vec<R>,
}

impl<R> Clone for ColumnsRegion<R>
impl<R, O> Clone for ColumnsRegion<R, O>
where
R: Region + Clone,
O: Clone,
{
fn clone(&self) -> Self {
Self {
Expand All @@ -84,13 +89,14 @@ where
}
}

impl<R> Region for ColumnsRegion<R>
impl<R, O> Region for ColumnsRegion<R, O>
where
R: Region,
O: OffsetContainer<usize>,
{
type Owned = Vec<R::Owned>;
type ReadItem<'a> = ReadColumns<'a, R> where Self: 'a;
type Index = usize;
type Index = <ConsecutiveOffsetPairs<OwnedRegion<R::Index>, OffsetOptimized> as Region>::Index;

fn merge_regions<'a>(regions: impl Iterator<Item = &'a Self> + Clone) -> Self
where
Expand Down Expand Up @@ -160,9 +166,10 @@ where
}
}

impl<R> Default for ColumnsRegion<R>
impl<R, O> Default for ColumnsRegion<R, O>
where
R: Region,
O: OffsetContainer<usize>,
{
fn default() -> Self {
Self {
Expand Down Expand Up @@ -321,13 +328,11 @@ where
}

/// An iterator over the elements of a row.
pub struct ReadColumnsIter<'a, R: Region>(
Result<ReadColumnsIterInner<'a, R>, std::slice::Iter<'a, R::Owned>>,
);
pub struct ReadColumnsIter<'a, R: Region>(Result<ReadColumnsIterInner<'a, R>, Iter<'a, R::Owned>>);

/// An iterator over the elements of a row.
pub struct ReadColumnsIterInner<'a, R: Region> {
iter: std::iter::Zip<std::slice::Iter<'a, R::Index>, std::slice::Iter<'a, R>>,
iter: Zip<Iter<'a, R::Index>, Iter<'a, R>>,
}

impl<'a, R> Iterator for ReadColumnsIter<'a, R>
Expand All @@ -342,8 +347,17 @@ where
Err(slice) => slice.next().map(IntoOwned::borrow_as),
}
}

fn size_hint(&self) -> (usize, Option<usize>) {
match &self.0 {
Ok(inner) => inner.size_hint(),
Err(slice) => slice.size_hint(),
}
}
}

impl<'a, R> ExactSizeIterator for ReadColumnsIter<'a, R> where R: Region {}

impl<'a, R> Iterator for ReadColumnsIterInner<'a, R>
where
R: Region,
Expand All @@ -353,13 +367,18 @@ where
fn next(&mut self) -> Option<Self::Item> {
self.iter.next().map(|(&i, r)| r.index(i))
}

fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
}

impl<R> Push<ReadColumns<'_, R>> for ColumnsRegion<R>
impl<R, O> Push<ReadColumns<'_, R>> for ColumnsRegion<R, O>
where
for<'a> R: Region + Push<<R as Region>::ReadItem<'a>>,
O: OffsetContainer<usize>,
{
fn push(&mut self, item: ReadColumns<'_, R>) -> <ColumnsRegion<R> as Region>::Index {
fn push(&mut self, item: ReadColumns<'_, R>) -> <ColumnsRegion<R, O> as Region>::Index {
// Ensure all required regions exist.
while self.inner.len() < item.len() {
self.inner.push(R::default());
Expand All @@ -373,11 +392,12 @@ where
}
}

impl<'a, R, T> Push<&'a [T]> for ColumnsRegion<R>
impl<'a, R, O, T> Push<&'a [T]> for ColumnsRegion<R, O>
where
R: Region + Push<&'a T>,
O: OffsetContainer<usize>,
{
fn push(&mut self, item: &'a [T]) -> <ColumnsRegion<R> as Region>::Index {
fn push(&mut self, item: &'a [T]) -> <ColumnsRegion<R, O> as Region>::Index {
// Ensure all required regions exist.
while self.inner.len() < item.len() {
self.inner.push(R::default());
Expand All @@ -391,11 +411,12 @@ where
}
}

impl<R, T, const N: usize> Push<[T; N]> for ColumnsRegion<R>
impl<R, O, T, const N: usize> Push<[T; N]> for ColumnsRegion<R, O>
where
R: Region + Push<T>,
O: OffsetContainer<usize>,
{
fn push(&mut self, item: [T; N]) -> <ColumnsRegion<R> as Region>::Index {
fn push(&mut self, item: [T; N]) -> <ColumnsRegion<R, O> as Region>::Index {
// Ensure all required regions exist.
while self.inner.len() < item.len() {
self.inner.push(R::default());
Expand All @@ -409,11 +430,12 @@ where
}
}

impl<'a, R, T, const N: usize> Push<&'a [T; N]> for ColumnsRegion<R>
impl<'a, R, O, T, const N: usize> Push<&'a [T; N]> for ColumnsRegion<R, O>
where
R: Region + Push<&'a T>,
O: OffsetContainer<usize>,
{
fn push(&mut self, item: &'a [T; N]) -> <ColumnsRegion<R> as Region>::Index {
fn push(&mut self, item: &'a [T; N]) -> <ColumnsRegion<R, O> as Region>::Index {
// Ensure all required regions exist.
while self.inner.len() < item.len() {
self.inner.push(R::default());
Expand All @@ -427,11 +449,12 @@ where
}
}

impl<R, T> Push<Vec<T>> for ColumnsRegion<R>
impl<R, O, T> Push<Vec<T>> for ColumnsRegion<R, O>
where
R: Region + Push<T>,
O: OffsetContainer<usize>,
{
fn push(&mut self, item: Vec<T>) -> <ColumnsRegion<R> as Region>::Index {
fn push(&mut self, item: Vec<T>) -> <ColumnsRegion<R, O> as Region>::Index {
// Ensure all required regions exist.
while self.inner.len() < item.len() {
self.inner.push(R::default());
Expand All @@ -445,11 +468,12 @@ where
}
}

impl<'a, R, T> Push<&'a Vec<T>> for ColumnsRegion<R>
impl<'a, R, O, T> Push<&'a Vec<T>> for ColumnsRegion<R, O>
where
R: Region + Push<&'a T>,
O: OffsetContainer<usize>,
{
fn push(&mut self, item: &'a Vec<T>) -> <ColumnsRegion<R> as Region>::Index {
fn push(&mut self, item: &'a Vec<T>) -> <ColumnsRegion<R, O> as Region>::Index {
// Ensure all required regions exist.
while self.inner.len() < item.len() {
self.inner.push(R::default());
Expand All @@ -463,13 +487,15 @@ where
}
}

impl<R, T, I> Push<CopyIter<I>> for ColumnsRegion<R>
impl<R, O, T, I> Push<CopyIter<I>> for ColumnsRegion<R, O>
where
R: Region + Push<T>,
O: OffsetContainer<usize>,
I: IntoIterator<Item = T>,
I::IntoIter: ExactSizeIterator,
{
#[inline]
fn push(&mut self, item: CopyIter<I>) -> <ColumnsRegion<R> as Region>::Index {
fn push(&mut self, item: CopyIter<I>) -> <ColumnsRegion<R, O> as Region>::Index {
let iter = item.0.into_iter().enumerate().map(|(index, value)| {
// Ensure all required regions exist.
if self.inner.len() <= index {
Expand Down Expand Up @@ -501,7 +527,7 @@ mod tests {
indices.push(index);
}

for (&index, row) in indices.iter().zip(&data) {
for (index, row) in indices.iter().zip(&data) {
assert!(row.iter().copied().eq(r.index(index).iter()));
}
}
Expand All @@ -527,7 +553,7 @@ mod tests {
indices.push(index);
}

for (&index, row) in indices.iter().zip(&data) {
for (index, row) in indices.iter().zip(&data) {
assert!(row.iter().copied().eq(r.index(index).iter()));
}

Expand Down Expand Up @@ -556,7 +582,7 @@ mod tests {
indices.push(index);
}

for (&index, row) in indices.iter().zip(&data) {
for (index, row) in indices.iter().zip(&data) {
assert!(row.iter().eq(r.index(index).iter()));
}

Expand Down Expand Up @@ -584,8 +610,8 @@ mod tests {
indices.push(index);
}

for (&index, row) in indices.iter().zip(&data) {
assert!(row.iter().copied().eq(r.index(index).iter()));
for (index, row) in indices.iter().zip(&data) {
assert!(row.iter().eq(r.index(index).iter()));
}

println!("{r:?}");
Expand All @@ -612,8 +638,8 @@ mod tests {
indices.push(index);
}

for (&index, row) in indices.iter().zip(&data) {
assert!(row.iter().copied().eq(r.index(index).iter()));
for (index, row) in indices.iter().zip(&data) {
assert!(row.iter().eq(r.index(index).iter()));
}

assert_eq!("1", r.index(indices[1]).get(0));
Expand Down
2 changes: 1 addition & 1 deletion src/impls/deduplicate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ where
/// use flatcontainer::{Push, OwnedRegion, Region, StringRegion};
/// let mut r = <ConsecutiveOffsetPairs<OwnedRegion<u8>>>::default();
///
/// let index: usize = r.push(&b"abc");
/// let index = r.push(&b"abc");
/// assert_eq!(b"abc", r.index(index));
/// ```
#[derive(Debug)]
Expand Down
Loading