Skip to content

Commit

Permalink
Further cleanup
Browse files Browse the repository at this point in the history
Signed-off-by: Moritz Hoffmann <[email protected]>
  • Loading branch information
antiguru committed May 24, 2024
1 parent 4d9464a commit d3ffc2e
Show file tree
Hide file tree
Showing 8 changed files with 92 additions and 131 deletions.
62 changes: 26 additions & 36 deletions src/impls/codec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,46 +28,37 @@ fn consolidate_from<T: Ord>(vec: &mut Vec<(T, usize)>, offset: usize) {

/// Sorts and consolidates a slice, returning the valid prefix length.
fn consolidate_slice<T: Ord>(slice: &mut [(T, usize)]) -> usize {
// We could do an insertion-sort like initial scan which builds up sorted, consolidated runs.
// In a world where there are not many results, we may never even need to call in to merge sort.
slice.sort_by(|x, y| x.0.cmp(&y.0));

let slice_ptr = slice.as_mut_ptr();

// Counts the number of distinct known-non-zero accumulations. Indexes the write location.
let mut offset = 0;
for index in 1..slice.len() {
// The following unsafe block elides various bounds checks, using the reasoning that `offset`
// is always strictly less than `index` at the beginning of each iteration. This is initially
// true, and in each iteration `offset` can increase by at most one (whereas `index` always
// increases by one). As `index` is always in bounds, and `offset` starts at zero, it too is
// always in bounds.
//
// LLVM appears to struggle to optimize out Rust's split_at_mut, which would prove disjointness
// using run-time tests.
unsafe {
assert!(offset < index);

// LOOP INVARIANT: offset < index
let ptr1 = slice_ptr.add(offset);
let ptr2 = slice_ptr.add(index);

if (*ptr1).0 == (*ptr2).0 {
(*ptr1).1 += (*ptr2).1;
if slice.len() > 1 {
// We could do an insertion-sort like initial scan which builds up sorted, consolidated runs.
// In a world where there are not many results, we may never even need to call in to merge sort.
slice.sort_by(|x, y| x.0.cmp(&y.0));

// Counts the number of distinct known-non-zero accumulations. Indexes the write location.
let mut offset = 0;
let mut accum = slice[offset].1;

for index in 1..slice.len() {
if slice[index].0 == slice[index - 1].0 {
accum += slice[index].1;
} else {
if (*ptr1).1 != 0 {
if accum != 0 {
slice.swap(offset, index - 1);
slice[offset].1.clone_from(&accum);
offset += 1;
}
let ptr1 = slice_ptr.add(offset);
std::ptr::swap(ptr1, ptr2);
accum.clone_from(&slice[index].1);
}
}
}
if offset < slice.len() && slice[offset].1 != 0 {
offset += 1;
}
if accum != 0 {
slice.swap(offset, slice.len() - 1);
slice[offset].1 = accum;
offset += 1;
}

offset
offset
} else {
slice.iter().filter(|x| x.1 != 0).count()
}
}

/// A region that encodes its data in a codec `C`.
Expand Down Expand Up @@ -123,8 +114,7 @@ where

impl<C: Codec, R> Push<&[u8]> for CodecRegion<C, R>
where
for<'a> R: Region<ReadItem<'a> = &'a [u8]> + 'a,
for<'a> R: Push<&'a [u8]>,
for<'a> R: Region<ReadItem<'a> = &'a [u8]> + Push<&'a [u8]> + 'a,
{
fn push(&mut self, item: &[u8]) -> <CodecRegion<C, R> as Region>::Index {
self.codec.encode(item, &mut self.inner)
Expand Down
8 changes: 3 additions & 5 deletions src/impls/columns.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ where
{
fn default() -> Self {
Self {
indices: Default::default(),
indices: ConsecutiveOffsetPairs::default(),
inner: Vec::default(),
}
}
Expand Down Expand Up @@ -240,8 +240,7 @@ where

impl<R> Push<ReadColumns<'_, R>> for ColumnsRegion<R>
where
R: Region,
for<'a> R: Push<<R as Region>::ReadItem<'a>>,
for<'a> R: Region + Push<<R as Region>::ReadItem<'a>>,
{
fn push(&mut self, item: ReadColumns<'_, R>) -> <ColumnsRegion<R> as Region>::Index {
// Ensure all required regions exist.
Expand All @@ -259,8 +258,7 @@ where

impl<'a, R, T> Push<&'a [T]> for ColumnsRegion<R>
where
R: Region,
R: Push<&'a T>,
R: Region + Push<&'a T>,
{
fn push(&mut self, item: &'a [T]) -> <ColumnsRegion<R> as Region>::Index {
// Ensure all required regions exist.
Expand Down
9 changes: 6 additions & 3 deletions src/impls/deduplicate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,9 @@ impl<R: Region> Region for CollapseSequence<R> {
}
}

impl<T, R: Region + Push<T>> Push<T> for CollapseSequence<R>
impl<R, T> Push<T> for CollapseSequence<R>
where
R: Region + Push<T>,
for<'a> T: PartialEq<R::ReadItem<'a>>,
{
fn push(&mut self, item: T) -> <CollapseSequence<R> as Region>::Index {
Expand Down Expand Up @@ -182,8 +183,10 @@ impl<R: Region<Index = (usize, usize)>, O: OffsetContainer<usize>> Region
}
}

impl<R: Region<Index = (usize, usize)> + Push<T>, O: OffsetContainer<usize>, T> Push<T>
for ConsecutiveOffsetPairs<R, O>
impl<R, O, T> Push<T> for ConsecutiveOffsetPairs<R, O>
where
R: Region<Index = (usize, usize)> + Push<T>,
O: OffsetContainer<usize>,
{
#[inline]
fn push(&mut self, item: T) -> <ConsecutiveOffsetPairs<R, O> as Region>::Index {
Expand Down
18 changes: 6 additions & 12 deletions src/impls/result.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,10 +82,8 @@ where

impl<T, TC, E, EC> Push<Result<T, E>> for ResultRegion<TC, EC>
where
TC: Region,
EC: Region,
TC: Push<T>,
EC: Push<E>,
TC: Region + Push<T>,
EC: Region + Push<E>,
{
#[inline]
fn push(&mut self, item: Result<T, E>) -> <ResultRegion<TC, EC> as Region>::Index {
Expand All @@ -98,10 +96,8 @@ where

impl<'a, T: 'a, TC, E: 'a, EC> Push<&'a Result<T, E>> for ResultRegion<TC, EC>
where
TC: Region,
EC: Region,
TC: Push<&'a T>,
EC: Push<&'a E>,
TC: Region + Push<&'a T>,
EC: Region + Push<&'a E>,
{
#[inline]
fn push(&mut self, item: &'a Result<T, E>) -> <ResultRegion<TC, EC> as Region>::Index {
Expand All @@ -114,10 +110,8 @@ where

impl<'a, T: 'a, TC, E: 'a, EC> ReserveItems<&'a Result<T, E>> for ResultRegion<TC, EC>
where
TC: Region,
EC: Region,
TC: ReserveItems<&'a T>,
EC: ReserveItems<&'a E>,
TC: Region + ReserveItems<&'a T>,
EC: Region + ReserveItems<&'a E>,
{
fn reserve_items<I>(&mut self, items: I)
where
Expand Down
56 changes: 22 additions & 34 deletions src/impls/slice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -213,14 +213,13 @@ impl<'a, C: Region, O: OffsetContainer<C::Index>> Iterator for ReadSliceIter<'a,
}
}

impl<C, T, O> Push<&[T]> for SliceRegion<C, O>
impl<'a, C, T, O> Push<&'a [T]> for SliceRegion<C, O>
where
C: Region,
for<'a> C: Push<&'a T>,
C: Region + Push<&'a T>,
O: OffsetContainer<C::Index>,
{
#[inline]
fn push(&mut self, item: &[T]) -> <SliceRegion<C, O> as Region>::Index {
fn push(&mut self, item: &'a [T]) -> <SliceRegion<C, O> as Region>::Index {
let start = self.slices.len();
self.slices.extend(item.iter().map(|t| self.inner.push(t)));
(start, self.slices.len())
Expand All @@ -229,8 +228,7 @@ where

impl<'a, T, R, O> ReserveItems<&'a [T]> for SliceRegion<R, O>
where
R: ReserveItems<&'a T>,
R: Region,
R: Region + ReserveItems<&'a T>,
O: OffsetContainer<R::Index>,
{
fn reserve_items<I>(&mut self, items: I)
Expand All @@ -244,8 +242,7 @@ where

impl<C, T, O> Push<Vec<T>> for SliceRegion<C, O>
where
C: Region,
C: Push<T>,
C: Region + Push<T>,
O: OffsetContainer<C::Index>,
{
#[inline]
Expand All @@ -259,8 +256,7 @@ where

impl<C, T, O> Push<&Vec<T>> for SliceRegion<C, O>
where
C: Region,
for<'a> SliceRegion<C, O>: Push<&'a [T]>,
for<'a> C: Region + Push<&'a T>,
O: OffsetContainer<C::Index>,
{
#[inline]
Expand All @@ -269,40 +265,37 @@ where
}
}

impl<C, T, O> Push<&&Vec<T>> for SliceRegion<C, O>
impl<'a, C, T, O> Push<&&'a Vec<T>> for SliceRegion<C, O>
where
C: Region,
for<'a> SliceRegion<C, O>: Push<&'a [T]>,
C: Region + Push<&'a T>,
O: OffsetContainer<C::Index>,
{
#[inline]
fn push(&mut self, item: &&Vec<T>) -> <SliceRegion<C, O> as Region>::Index {
fn push(&mut self, item: &&'a Vec<T>) -> <SliceRegion<C, O> as Region>::Index {
self.push(item.as_slice())
}
}

impl<'b, T, R, O> ReserveItems<&'b Vec<T>> for SliceRegion<R, O>
impl<'a, T, R, O> ReserveItems<&'a Vec<T>> for SliceRegion<R, O>
where
for<'a> R: ReserveItems<&'a T>,
R: Region,
R: Region + ReserveItems<&'a T>,
O: OffsetContainer<R::Index>,
{
fn reserve_items<I>(&mut self, items: I)
where
I: Iterator<Item = &'b Vec<T>> + Clone,
I: Iterator<Item = &'a Vec<T>> + Clone,
{
self.reserve_items(items.map(Deref::deref));
}
}

impl<C, O> Push<ReadSlice<'_, C, O>> for SliceRegion<C, O>
impl<'a, C, O> Push<ReadSlice<'a, C, O>> for SliceRegion<C, O>
where
for<'a> C: Region,
for<'a> C: Push<<C as Region>::ReadItem<'a>>,
C: Region + Push<<C as Region>::ReadItem<'a>>,
O: OffsetContainer<C::Index>,
{
#[inline]
fn push(&mut self, item: ReadSlice<'_, C, O>) -> <SliceRegion<C, O> as Region>::Index {
fn push(&mut self, item: ReadSlice<'a, C, O>) -> <SliceRegion<C, O> as Region>::Index {
let ReadSlice { region, start, end } = item;
let start_len = self.slices.len();
for index in start..end {
Expand All @@ -316,8 +309,7 @@ where

impl<T, R, O, const N: usize> Push<[T; N]> for SliceRegion<R, O>
where
for<'a> R: Region,
for<'a> Self: Push<&'a [T]>,
for<'a> R: Region + Push<&'a T>,
O: OffsetContainer<R::Index>,
{
#[inline]
Expand All @@ -328,8 +320,7 @@ where

impl<'a, T, R, O, const N: usize> Push<&'a [T; N]> for SliceRegion<R, O>
where
SliceRegion<R, O>: Push<&'a [T]>,
R: Region,
R: Region + Push<&'a T>,
O: OffsetContainer<R::Index>,
{
#[inline]
Expand All @@ -338,22 +329,20 @@ where
}
}

impl<T, R, O, const N: usize> Push<&&[T; N]> for SliceRegion<R, O>
impl<'a, T, R, O, const N: usize> Push<&&'a [T; N]> for SliceRegion<R, O>
where
for<'b> SliceRegion<R, O>: Push<&'b [T]>,
R: Region,
R: Region + Push<&'a T>,
O: OffsetContainer<R::Index>,
{
#[inline]
fn push(&mut self, item: &&[T; N]) -> <SliceRegion<R, O> as Region>::Index {
fn push(&mut self, item: &&'a [T; N]) -> <SliceRegion<R, O> as Region>::Index {
self.push(item.as_slice())
}
}

impl<'a, T, R, O, const N: usize> ReserveItems<&'a [T; N]> for SliceRegion<R, O>
where
R: ReserveItems<&'a T>,
R: Region,
R: Region + ReserveItems<&'a T>,
O: OffsetContainer<R::Index>,
{
fn reserve_items<I>(&mut self, items: I)
Expand All @@ -366,8 +355,7 @@ where

impl<'a, R, O> ReserveItems<ReadSlice<'a, R, O>> for SliceRegion<R, O>
where
R: ReserveItems<<R as Region>::ReadItem<'a>> + 'a,
R: Region,
R: Region + ReserveItems<<R as Region>::ReadItem<'a>> + 'a,
O: OffsetContainer<R::Index>,
{
fn reserve_items<I>(&mut self, items: I)
Expand Down
2 changes: 1 addition & 1 deletion src/impls/slice_copy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ impl<T: Clone> Push<&[T]> for OwnedRegion<T> {

impl<T: Clone> Push<&&[T]> for OwnedRegion<T>
where
for<'a> OwnedRegion<T>: Push<&'a [T]>,
for<'a> Self: Push<&'a [T]>,
{
#[inline]
fn push(&mut self, item: &&[T]) -> <OwnedRegion<T> as Region>::Index {
Expand Down
Loading

0 comments on commit d3ffc2e

Please sign in to comment.