Skip to content

Commit

Permalink
Split Region into ReadRegion and Region
Browse files Browse the repository at this point in the history
A ReadRegion encodes how to read data out of a region, and Region
describes how to create and copy data into regions. This split allows
to create regions that are immutably created.

Signed-off-by: Moritz Hoffmann <[email protected]>
  • Loading branch information
antiguru committed Jun 25, 2024
1 parent 84f6123 commit ab83123
Show file tree
Hide file tree
Showing 17 changed files with 379 additions and 296 deletions.
25 changes: 15 additions & 10 deletions src/impls/codec.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! A region that encodes its contents.
use crate::{OwnedRegion, Push, Region};
use crate::{OwnedRegion, Push, ReadRegion, Region};

pub use self::misra_gries::MisraGries;
pub use dictionary::DictionaryCodec;
Expand Down Expand Up @@ -81,17 +81,26 @@ impl<C: Clone, R: Clone> Clone for CodecRegion<C, R> {
}
}

impl<C: Codec, R> Region for CodecRegion<C, R>
impl<C: Codec, R> ReadRegion for CodecRegion<C, R>
where
for<'a> R: Region<ReadItem<'a> = &'a [u8]> + 'a,
for<'a> R: ReadRegion<ReadItem<'a> = &'a [u8]> + 'a,
{
type Owned = Vec<u8>;
type ReadItem<'a> = &'a [u8]
where
Self: 'a;
where
Self: 'a;

type Index = R::Index;

fn index(&self, index: Self::Index) -> Self::ReadItem<'_> {
self.codec.decode(self.inner.index(index))
}
}

impl<C: Codec, R> Region for CodecRegion<C, R>
where
for<'a> R: Region<ReadItem<'a> = &'a [u8]> + 'a,
{
/// Construct a region that can absorb the contents of `regions` in the future.
fn merge_regions<'a>(regions: impl Iterator<Item = &'a Self> + Clone) -> Self
where
Expand All @@ -104,10 +113,6 @@ where
}
}

fn index(&self, index: Self::Index) -> Self::ReadItem<'_> {
self.codec.decode(self.inner.index(index))
}

fn reserve_regions<'a, I>(&mut self, regions: I)
where
Self: 'a,
Expand Down Expand Up @@ -138,7 +143,7 @@ impl<C: Codec, R> Push<&[u8]> for CodecRegion<C, R>
where
for<'a> R: Region<ReadItem<'a> = &'a [u8]> + Push<&'a [u8]> + 'a,
{
fn push(&mut self, item: &[u8]) -> <CodecRegion<C, R> as Region>::Index {
fn push(&mut self, item: &[u8]) -> <CodecRegion<C, R> as ReadRegion>::Index {
self.codec.encode(item, &mut self.inner)
}
}
Expand Down
88 changes: 47 additions & 41 deletions src/impls/columns.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use serde::{Deserialize, Serialize};
use crate::impls::deduplicate::ConsecutiveOffsetPairs;
use crate::impls::offsets::OffsetOptimized;
use crate::{CopyIter, IntoOwned};
use crate::{OwnedRegion, Push, Region};
use crate::{OwnedRegion, Push, ReadRegion, Region};

/// A region that can store a variable number of elements per row.
///
Expand All @@ -24,7 +24,7 @@ use crate::{OwnedRegion, Push, Region};
/// Copy a table-like structure:
/// ```
/// # use flatcontainer::impls::deduplicate::ConsecutiveOffsetPairs;
/// # use flatcontainer::{ColumnsRegion, Push, Region, StringRegion};
/// # use flatcontainer::{ColumnsRegion, Push, ReadRegion, Region, StringRegion};
/// let data = [
/// vec![],
/// vec!["1"],
Expand Down Expand Up @@ -58,7 +58,7 @@ use crate::{OwnedRegion, Push, Region};
)]
pub struct ColumnsRegion<R>
where
R: Region,
R: ReadRegion,
{
/// Indices to address rows in `inner`. For each row, we remember
/// an index for each column.
Expand All @@ -84,14 +84,26 @@ where
}
}

impl<R> Region for ColumnsRegion<R>
impl<R> ReadRegion for ColumnsRegion<R>
where
R: Region,
R: ReadRegion,
{
type Owned = Vec<R::Owned>;
type ReadItem<'a> = ReadColumns<'a, R> where Self: 'a;
type Index = usize;

fn index(&self, index: Self::Index) -> Self::ReadItem<'_> {
ReadColumns(Ok(ReadColumnsInner {
columns: &self.inner,
index: self.indices.index(index),
}))
}
}

impl<R> Region for ColumnsRegion<R>
where
R: Region,
{
fn merge_regions<'a>(regions: impl Iterator<Item = &'a Self> + Clone) -> Self
where
Self: 'a,
Expand All @@ -111,13 +123,6 @@ where
}
}

fn index(&self, index: Self::Index) -> Self::ReadItem<'_> {
ReadColumns(Ok(ReadColumnsInner {
columns: &self.inner,
index: self.indices.index(index),
}))
}

fn reserve_regions<'a, I>(&mut self, regions: I)
where
Self: 'a,
Expand Down Expand Up @@ -175,11 +180,11 @@ where
/// Read the values of a row.
pub struct ReadColumns<'a, R>(Result<ReadColumnsInner<'a, R>, &'a [R::Owned]>)
where
R: Region;
R: ReadRegion;

struct ReadColumnsInner<'a, R>
where
R: Region,
R: ReadRegion,
{
/// Storage for columns.
columns: &'a [R],
Expand All @@ -189,7 +194,7 @@ where

impl<'a, R> Clone for ReadColumns<'a, R>
where
R: Region,
R: ReadRegion,
{
fn clone(&self) -> Self {
*self
Expand All @@ -198,19 +203,19 @@ where

impl<'a, R> Clone for ReadColumnsInner<'a, R>
where
R: Region,
R: ReadRegion,
{
fn clone(&self) -> Self {
*self
}
}

impl<'a, R> Copy for ReadColumns<'a, R> where R: Region {}
impl<'a, R> Copy for ReadColumnsInner<'a, R> where R: Region {}
impl<'a, R> Copy for ReadColumns<'a, R> where R: ReadRegion {}
impl<'a, R> Copy for ReadColumnsInner<'a, R> where R: ReadRegion {}

impl<'a, R> Debug for ReadColumns<'a, R>
where
R: Region,
R: ReadRegion,
R::ReadItem<'a>: Debug,
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
Expand All @@ -220,7 +225,7 @@ where

impl<'a, R> ReadColumns<'a, R>
where
R: Region,
R: ReadRegion,
{
/// Iterate the individual values of a row.
#[must_use]
Expand Down Expand Up @@ -255,9 +260,10 @@ where
}
}
}

impl<'a, R> ReadColumnsInner<'a, R>
where
R: Region,
R: ReadRegion,
{
/// Get the element at `offset`.
#[must_use]
Expand All @@ -280,7 +286,7 @@ where

impl<'a, R> IntoOwned<'a> for ReadColumns<'a, R>
where
R: Region,
R: ReadRegion,
{
type Owned = Vec<R::Owned>;

Expand All @@ -305,7 +311,7 @@ where

impl<'a, R> IntoIterator for &ReadColumns<'a, R>
where
R: Region,
R: ReadRegion,
{
type Item = R::ReadItem<'a>;
type IntoIter = ReadColumnsIter<'a, R>;
Expand All @@ -321,18 +327,18 @@ where
}

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

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

impl<'a, R> Iterator for ReadColumnsIter<'a, R>
where
R: Region,
R: ReadRegion,
{
type Item = R::ReadItem<'a>;

Expand All @@ -346,7 +352,7 @@ where

impl<'a, R> Iterator for ReadColumnsIterInner<'a, R>
where
R: Region,
R: ReadRegion,
{
type Item = R::ReadItem<'a>;

Expand All @@ -357,9 +363,9 @@ where

impl<R> Push<ReadColumns<'_, R>> for ColumnsRegion<R>
where
for<'a> R: Region + Push<<R as Region>::ReadItem<'a>>,
for<'a> R: ReadRegion + Push<<R as ReadRegion>::ReadItem<'a>>,
{
fn push(&mut self, item: ReadColumns<'_, R>) -> <ColumnsRegion<R> as Region>::Index {
fn push(&mut self, item: ReadColumns<'_, R>) -> <ColumnsRegion<R> as ReadRegion>::Index {
// Ensure all required regions exist.
while self.inner.len() < item.len() {
self.inner.push(R::default());
Expand All @@ -375,9 +381,9 @@ where

impl<'a, R, T> Push<&'a [T]> for ColumnsRegion<R>
where
R: Region + Push<&'a T>,
R: ReadRegion + Push<&'a T>,
{
fn push(&mut self, item: &'a [T]) -> <ColumnsRegion<R> as Region>::Index {
fn push(&mut self, item: &'a [T]) -> <ColumnsRegion<R> as ReadRegion>::Index {
// Ensure all required regions exist.
while self.inner.len() < item.len() {
self.inner.push(R::default());
Expand All @@ -393,9 +399,9 @@ where

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

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

impl<R, T> Push<Vec<T>> for ColumnsRegion<R>
where
R: Region + Push<T>,
R: ReadRegion + Push<T>,
{
fn push(&mut self, item: Vec<T>) -> <ColumnsRegion<R> as Region>::Index {
fn push(&mut self, item: Vec<T>) -> <ColumnsRegion<R> as ReadRegion>::Index {
// Ensure all required regions exist.
while self.inner.len() < item.len() {
self.inner.push(R::default());
Expand All @@ -447,9 +453,9 @@ where

impl<'a, R, T> Push<&'a Vec<T>> for ColumnsRegion<R>
where
R: Region + Push<&'a T>,
R: ReadRegion + Push<&'a T>,
{
fn push(&mut self, item: &'a Vec<T>) -> <ColumnsRegion<R> as Region>::Index {
fn push(&mut self, item: &'a Vec<T>) -> <ColumnsRegion<R> as ReadRegion>::Index {
// Ensure all required regions exist.
while self.inner.len() < item.len() {
self.inner.push(R::default());
Expand All @@ -465,11 +471,11 @@ where

impl<R, T, I> Push<CopyIter<I>> for ColumnsRegion<R>
where
R: Region + Push<T>,
R: ReadRegion + Push<T>,
I: IntoIterator<Item = T>,
{
#[inline]
fn push(&mut self, item: CopyIter<I>) -> <ColumnsRegion<R> as Region>::Index {
fn push(&mut self, item: CopyIter<I>) -> <ColumnsRegion<R> as ReadRegion>::Index {
let iter = item.0.into_iter().enumerate().map(|(index, value)| {
// Ensure all required regions exist.
if self.inner.len() <= index {
Expand Down
Loading

0 comments on commit ab83123

Please sign in to comment.