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

Thinking about relating owned types and read items #31

Merged
merged 12 commits into from
May 28, 2024
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