Skip to content

Commit

Permalink
Thinking about relating owned types and read items (#31)
Browse files Browse the repository at this point in the history
Add IntoOwned trait, add Owned type to region, add a constraint that read items must be IntoOwned.

---------

Signed-off-by: Moritz Hoffmann <[email protected]>
  • Loading branch information
antiguru authored May 28, 2024
1 parent 7676982 commit 2ed1204
Show file tree
Hide file tree
Showing 11 changed files with 738 additions and 49 deletions.
9 changes: 5 additions & 4 deletions src/impls/codec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ impl<C: Codec, R> Region for CodecRegion<C, R>
where
for<'a> R: Region<ReadItem<'a> = &'a [u8]> + 'a,
{
type Owned = Vec<u8>;
type ReadItem<'a> = &'a [u8]
where
Self: 'a;
Expand Down Expand Up @@ -421,8 +422,8 @@ mod tests {
}
for _ in 0..1000 {
for r in &mut regions {
r.push("abcdef".as_bytes());
r.push("defghi".as_bytes());
let _ = r.push("abcdef".as_bytes());
let _ = r.push("defghi".as_bytes());
}
}

Expand All @@ -447,8 +448,8 @@ mod tests {
}
for _ in 0..1000 {
for r in &mut regions {
r.push("abcdef".as_bytes());
r.push("defghi".as_bytes());
let _ = r.push("abcdef".as_bytes());
let _ = r.push("defghi".as_bytes());
}
}

Expand Down
113 changes: 103 additions & 10 deletions src/impls/columns.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use serde::{Deserialize, Serialize};

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

/// A region that can store a variable number of elements per row.
Expand Down Expand Up @@ -71,6 +71,7 @@ impl<R> Region for ColumnsRegion<R>
where
R: Region,
{
type Owned = Vec<R::Owned>;
type ReadItem<'a> = ReadColumns<'a, R> where Self: 'a;
type Index = usize;

Expand All @@ -94,10 +95,10 @@ where
}

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

fn reserve_regions<'a, I>(&mut self, regions: I)
Expand Down Expand Up @@ -155,7 +156,11 @@ where
}

/// Read the values of a row.
pub struct ReadColumns<'a, R>
pub struct ReadColumns<'a, R>(Result<ReadColumnsInner<'a, R>, &'a [R::Owned]>)
where
R: Region;

struct ReadColumnsInner<'a, R>
where
R: Region,
{
Expand All @@ -174,7 +179,17 @@ where
}
}

impl<'a, R> Clone for ReadColumnsInner<'a, R>
where
R: Region,
{
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> Debug for ReadColumns<'a, R>
where
Expand All @@ -196,6 +211,37 @@ where
self.into_iter()
}

/// Get the element at `offset`.
#[must_use]
pub fn get(&self, offset: usize) -> R::ReadItem<'a> {
match &self.0 {
Ok(inner) => inner.get(offset),
Err(slice) => IntoOwned::borrow_as(&slice[offset]),
}
}

/// Returns the length of this row.
#[must_use]
pub fn len(&self) -> usize {
match &self.0 {
Ok(inner) => inner.len(),
Err(slice) => slice.len(),
}
}

/// Returns `true` if this row is empty.
#[must_use]
pub fn is_empty(&self) -> bool {
match &self.0 {
Ok(inner) => inner.is_empty(),
Err(slice) => slice.is_empty(),
}
}
}
impl<'a, R> ReadColumnsInner<'a, R>
where
R: Region,
{
/// Get the element at `offset`.
#[must_use]
pub fn get(&self, offset: usize) -> R::ReadItem<'a> {
Expand All @@ -215,6 +261,31 @@ where
}
}

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

#[inline]
fn into_owned(self) -> Self::Owned {
self.iter().map(IntoOwned::into_owned).collect()
}

fn clone_onto(self, other: &mut Self::Owned) {
let r = std::cmp::min(self.len(), other.len());
for (item, target) in self.iter().zip(other.iter_mut()) {
item.clone_onto(target);
}
other.extend(self.iter().skip(r).map(IntoOwned::into_owned));
other.truncate(self.len());
}

fn borrow_as(owned: &'a Self::Owned) -> Self {
Self(Err(owned.as_slice()))
}
}

impl<'a, R> IntoIterator for &ReadColumns<'a, R>
where
R: Region,
Expand All @@ -223,14 +294,22 @@ where
type IntoIter = ReadColumnsIter<'a, R>;

fn into_iter(self) -> Self::IntoIter {
ReadColumnsIter {
iter: self.index.iter().zip(self.columns.iter()),
match self.0 {
Ok(inner) => ReadColumnsIter(Ok(ReadColumnsIterInner {
iter: inner.index.iter().zip(inner.columns.iter()),
})),
Err(slice) => ReadColumnsIter(Err(slice.iter())),
}
}
}

/// An iterator over the elements of a row.
pub struct ReadColumnsIter<'a, R: Region> {
pub struct ReadColumnsIter<'a, R: Region>(
Result<ReadColumnsIterInner<'a, R>, std::slice::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>>,
}

Expand All @@ -240,6 +319,20 @@ where
{
type Item = R::ReadItem<'a>;

fn next(&mut self) -> Option<Self::Item> {
match &mut self.0 {
Ok(inner) => inner.next(),
Err(slice) => slice.next().map(IntoOwned::borrow_as),
}
}
}

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

fn next(&mut self) -> Option<Self::Item> {
self.iter.next().map(|(&i, r)| r.index(i))
}
Expand Down Expand Up @@ -541,7 +634,7 @@ mod tests {
}

r.clear();
r.index(idx.unwrap());
let _ = r.index(idx.unwrap());
}

#[test]
Expand All @@ -551,10 +644,10 @@ mod tests {
let mut r = <ColumnsRegion<OwnedRegion<u8>>>::default();

for row in &data {
r.push(row);
let _ = r.push(row);
}
for row in data {
r.push(row);
let _ = r.push(row);
}

let mut r2 = <ColumnsRegion<OwnedRegion<u8>>>::default();
Expand Down
11 changes: 10 additions & 1 deletion src/impls/deduplicate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ impl<R: Region> Default for CollapseSequence<R> {
}

impl<R: Region> Region for CollapseSequence<R> {
type Owned = R::Owned;
type ReadItem<'a> = R::ReadItem<'a> where Self: 'a;
type Index = R::Index;

Expand Down Expand Up @@ -131,6 +132,7 @@ where
impl<R: Region<Index = (usize, usize)>, O: OffsetContainer<usize>> Default
for ConsecutiveOffsetPairs<R, O>
{
#[inline]
fn default() -> Self {
let mut d = Self {
inner: Default::default(),
Expand All @@ -147,12 +149,14 @@ where
R: Region<Index = (usize, usize)>,
O: OffsetContainer<usize>,
{
type Owned = R::Owned;
type ReadItem<'a> = R::ReadItem<'a>
where
Self: 'a;

type Index = usize;

#[inline]
fn merge_regions<'a>(regions: impl Iterator<Item = &'a Self> + Clone) -> Self
where
Self: 'a,
Expand All @@ -166,11 +170,13 @@ where
}
}

#[inline]
fn index(&self, index: Self::Index) -> Self::ReadItem<'_> {
self.inner
.index((self.offsets.index(index), self.offsets.index(index + 1)))
}

#[inline]
fn reserve_regions<'a, I>(&mut self, regions: I)
where
Self: 'a,
Expand All @@ -179,18 +185,21 @@ where
self.inner.reserve_regions(regions.map(|r| &r.inner));
}

#[inline]
fn clear(&mut self) {
self.last_index = 0;
self.inner.clear();
self.offsets.clear();
self.offsets.push(0);
}

#[inline]
fn heap_size<F: FnMut(usize, usize)>(&self, mut callback: F) {
self.offsets.heap_size(&mut callback);
self.inner.heap_size(callback);
}

#[inline]
fn reborrow<'b, 'a: 'b>(item: Self::ReadItem<'a>) -> Self::ReadItem<'b>
where
Self: 'a,
Expand Down Expand Up @@ -247,7 +256,7 @@ mod tests {
CollapseSequence::<ConsecutiveOffsetPairs<StringRegion, OffsetOptimized>>::default();

for _ in 0..1000 {
r.push("abc");
let _ = r.push("abc");
}

println!("{r:?}");
Expand Down
Loading

0 comments on commit 2ed1204

Please sign in to comment.