diff --git a/README.md b/README.md index 5b987aa..c49ca46 100644 --- a/README.md +++ b/README.md @@ -47,9 +47,9 @@ to look up a value. A region for slices has storage to remember slices of indexe where the index can be used to look up the datum's representation in an inner region. -`flatcontainer` provides [`FlatStack`], an exemplary implementation of how to +`flatcontainer` provides the [`FlatStack`] type, an exemplary implementation of how to implement a collection of items that supports pushing additional elements, -and retrieval by offset of previously pushed elements. It can be used in many +and retrieval by an index to previously pushed elements. It can be used in many places that simply want to use a flat data representation, but it leaves potential for optimization behind. Specifically, indexes, although opaque, follow a simple structure where a more efficient storage can save memory instead of blindly @@ -101,10 +101,10 @@ we know more about the data, and can use a better approach to storing indexes. e.g., 0, 2, 4, 8, ..., which we can represent using constant memory by remembering the stride and length. We can extend this to storing a tail of elements equals to the last stride by adding another count. Such an index container uses 0 bits in the limit! -* Consult the [offsets] module for types specialized to storing indexes using less bits. +* Consult the [index] module for types specialized to storing indexes using less bits. Flatcontainer provides some implementations of these concepts. To merge adjacent start-end -pairs, wrap a region in a [`ConsecutiveOffsetPairs`] region. It stores indexes and presents +pairs, wrap a region in a [`ConsecutiveIndexPairs`] region. It stores indexes and presents outwards as a dense sequence of 0, 1, 2, ... A [`CollapseSequence`] region remembers the index of the last element, and if a new element @@ -112,8 +112,8 @@ equals the last, it'll return the previous index again instead of storing the sa multiple times. This is limited to the direct predecessor, because otherwise storing indexes and scanning through previous elements would be too expensive. -[offsets]: impls::offsets -[`ConsecutiveOffsetPairs`]: impls::deduplicate::ConsecutiveOffsetPairs +[index]: impls::index +[`ConsecutiveIndexPairs`]: impls::deduplicate::ConsecutiveIndexPairs [`CollapseSequence`]: impls::deduplicate::CollapseSequence ## Comparison to columnation diff --git a/benches/bench.rs b/benches/bench.rs index 9903bab..da6c9b1 100644 --- a/benches/bench.rs +++ b/benches/bench.rs @@ -4,8 +4,8 @@ extern crate test; -use flatcontainer::impls::deduplicate::{CollapseSequence, ConsecutiveOffsetPairs}; -use flatcontainer::impls::offsets::OffsetOptimized; +use flatcontainer::impls::deduplicate::{CollapseSequence, ConsecutiveIndexPairs}; +use flatcontainer::impls::index::IndexOptimized; use flatcontainer::impls::tuple::{TupleABCRegion, TupleABRegion}; use flatcontainer::{ ColumnsRegion, FlatStack, MirrorRegion, OwnedRegion, Push, Region, RegionPreference, @@ -87,7 +87,7 @@ fn string10_copy_region(bencher: &mut Bencher) { #[bench] fn string10_copy_region_collapse(bencher: &mut Bencher) { _bench_copy_region::< - SliceRegion>, OffsetOptimized>, + SliceRegion>, IndexOptimized>, _, >(bencher, vec![format!("grawwwwrr!"); 1024]); } diff --git a/src/impls.rs b/src/impls.rs index 519873c..3dbf004 100644 --- a/src/impls.rs +++ b/src/impls.rs @@ -4,8 +4,8 @@ pub mod codec; pub mod columns; pub mod deduplicate; pub mod huffman_container; +pub mod index; pub mod mirror; -pub mod offsets; pub mod option; pub mod result; pub mod slice; diff --git a/src/impls/columns.rs b/src/impls/columns.rs index 43366c7..5ccb772 100644 --- a/src/impls/columns.rs +++ b/src/impls/columns.rs @@ -7,8 +7,8 @@ use std::slice::Iter; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; -use crate::impls::deduplicate::ConsecutiveOffsetPairs; -use crate::impls::offsets::{OffsetContainer, OffsetOptimized}; +use crate::impls::deduplicate::ConsecutiveIndexPairs; +use crate::impls::index::{IndexContainer, IndexOptimized}; use crate::{IntoOwned, PushIter}; use crate::{OwnedRegion, Push, Region}; @@ -25,7 +25,7 @@ use crate::{OwnedRegion, Push, Region}; /// /// Copy a table-like structure: /// ``` -/// # use flatcontainer::impls::deduplicate::ConsecutiveOffsetPairs; +/// # use flatcontainer::impls::deduplicate::ConsecutiveIndexPairs; /// # use flatcontainer::{ColumnsRegion, Push, Region, StringRegion}; /// let data = [ /// vec![], @@ -37,7 +37,7 @@ use crate::{OwnedRegion, Push, Region}; /// vec![], /// ]; /// -/// let mut r = >>::default(); +/// let mut r = >>::default(); /// /// let mut indices = Vec::with_capacity(data.len()); /// @@ -60,13 +60,13 @@ use crate::{OwnedRegion, Push, Region}; O: Serialize + for<'a> Deserialize<'a>, ") )] -pub struct ColumnsRegion +pub struct ColumnsRegion where R: Region, { /// Indices to address rows in `inner`. For each row, we remember /// an index for each column. - indices: ConsecutiveOffsetPairs, O>, + indices: ConsecutiveIndexPairs, O>, /// Storage for columns. inner: Vec, } @@ -92,11 +92,11 @@ where impl Region for ColumnsRegion where R: Region, - O: OffsetContainer, + O: IndexContainer, { type Owned = Vec; type ReadItem<'a> = ReadColumns<'a, R> where Self: 'a; - type Index = , OffsetOptimized> as Region>::Index; + type Index = , IndexOptimized> as Region>::Index; fn merge_regions<'a>(regions: impl Iterator + Clone) -> Self where @@ -112,7 +112,7 @@ where } Self { - indices: ConsecutiveOffsetPairs::merge_regions(regions.map(|r| &r.indices)), + indices: ConsecutiveIndexPairs::merge_regions(regions.map(|r| &r.indices)), inner, } } @@ -169,11 +169,11 @@ where impl Default for ColumnsRegion where R: Region, - O: OffsetContainer, + O: IndexContainer, { fn default() -> Self { Self { - indices: ConsecutiveOffsetPairs::default(), + indices: ConsecutiveIndexPairs::default(), inner: Vec::default(), } } @@ -376,7 +376,7 @@ where impl Push> for ColumnsRegion where for<'a> R: Region + Push<::ReadItem<'a>>, - O: OffsetContainer, + O: IndexContainer, { fn push(&mut self, item: ReadColumns<'_, R>) -> as Region>::Index { // Ensure all required regions exist. @@ -395,7 +395,7 @@ where impl<'a, R, O, T> Push<&'a [T]> for ColumnsRegion where R: Region + Push<&'a T>, - O: OffsetContainer, + O: IndexContainer, { fn push(&mut self, item: &'a [T]) -> as Region>::Index { // Ensure all required regions exist. @@ -414,7 +414,7 @@ where impl Push<[T; N]> for ColumnsRegion where R: Region + Push, - O: OffsetContainer, + O: IndexContainer, { fn push(&mut self, item: [T; N]) -> as Region>::Index { // Ensure all required regions exist. @@ -433,7 +433,7 @@ where impl<'a, R, O, T, const N: usize> Push<&'a [T; N]> for ColumnsRegion where R: Region + Push<&'a T>, - O: OffsetContainer, + O: IndexContainer, { fn push(&mut self, item: &'a [T; N]) -> as Region>::Index { // Ensure all required regions exist. @@ -452,7 +452,7 @@ where impl Push> for ColumnsRegion where R: Region + Push, - O: OffsetContainer, + O: IndexContainer, { fn push(&mut self, item: Vec) -> as Region>::Index { // Ensure all required regions exist. @@ -471,7 +471,7 @@ where impl<'a, R, O, T> Push<&'a Vec> for ColumnsRegion where R: Region + Push<&'a T>, - O: OffsetContainer, + O: IndexContainer, { fn push(&mut self, item: &'a Vec) -> as Region>::Index { // Ensure all required regions exist. @@ -490,7 +490,7 @@ where impl Push> for ColumnsRegion where R: Region + Push, - O: OffsetContainer, + O: IndexContainer, I: IntoIterator, I::IntoIter: ExactSizeIterator, { @@ -509,7 +509,7 @@ where #[cfg(test)] mod tests { - use crate::impls::deduplicate::{CollapseSequence, ConsecutiveOffsetPairs}; + use crate::impls::deduplicate::{CollapseSequence, ConsecutiveIndexPairs}; use crate::{MirrorRegion, OwnedRegion, Push, PushIter, Region, StringRegion}; use super::*; @@ -573,7 +573,7 @@ mod tests { ]; let mut r = - ColumnsRegion::>>::default(); + ColumnsRegion::>>::default(); let mut indices = Vec::with_capacity(data.len()); @@ -601,7 +601,7 @@ mod tests { vec![], ]; - let mut r = ColumnsRegion::>::default(); + let mut r = ColumnsRegion::>::default(); let mut indices = Vec::with_capacity(data.len()); @@ -629,7 +629,7 @@ mod tests { vec![], ]; - let mut r = ColumnsRegion::>::default(); + let mut r = ColumnsRegion::>::default(); let mut indices = Vec::with_capacity(data.len()); @@ -713,7 +713,7 @@ mod tests { vec![], ]; - let mut r = ColumnsRegion::>::default(); + let mut r = ColumnsRegion::>::default(); for row in &data { let _ = r.push(PushIter(row.iter())); diff --git a/src/impls/deduplicate.rs b/src/impls/deduplicate.rs index 7c19bc6..c28bf5f 100644 --- a/src/impls/deduplicate.rs +++ b/src/impls/deduplicate.rs @@ -3,7 +3,7 @@ #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; -use crate::impls::offsets::{OffsetContainer, OffsetOptimized}; +use crate::impls::index::{IndexContainer, IndexOptimized}; use crate::{Push, Region, ReserveItems}; /// A region to deduplicate consecutive equal items. @@ -114,68 +114,68 @@ where /// Transform an index of `(usize, usize)` to a sequence of `0..`. Requires the pairs to /// be dense, i.e., `(i, j)` is followed by `(j, k)`. /// -/// Defers to region `R` for storing items, and uses offset container `O` to +/// Defers to region `R` for storing items, and uses index container `O` to /// remeber indices. By default, `O` is `Vec`. /// /// # Examples /// /// The following example shows that two inserts into a copy region have a collapsible index: /// ``` -/// use flatcontainer::impls::deduplicate::{CollapseSequence, ConsecutiveOffsetPairs}; +/// use flatcontainer::impls::deduplicate::{CollapseSequence, ConsecutiveIndexPairs}; /// use flatcontainer::{Push, OwnedRegion, Region, StringRegion}; -/// let mut r = >>::default(); +/// let mut r = >>::default(); /// /// let index = r.push(&b"abc"); /// assert_eq!(b"abc", r.index(index)); /// ``` #[derive(Debug)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -pub struct ConsecutiveOffsetPairs { +pub struct ConsecutiveIndexPairs { /// Wrapped region inner: R, - /// Storage for offsets. Always stores element 0. - offsets: O, + /// Storage for indices. Always stores element 0. + indices: O, /// The most recent end of the index pair of region `R`. last_index: usize, } -impl Clone for ConsecutiveOffsetPairs { +impl Clone for ConsecutiveIndexPairs { fn clone(&self) -> Self { Self { inner: self.inner.clone(), - offsets: self.offsets.clone(), + indices: self.indices.clone(), last_index: self.last_index, } } fn clone_from(&mut self, source: &Self) { self.inner.clone_from(&source.inner); - self.offsets.clone_from(&source.offsets); + self.indices.clone_from(&source.indices); self.last_index = source.last_index; } } -impl Default for ConsecutiveOffsetPairs +impl Default for ConsecutiveIndexPairs where R: Default, - O: OffsetContainer, + O: IndexContainer, { #[inline] fn default() -> Self { let mut d = Self { inner: Default::default(), - offsets: Default::default(), + indices: Default::default(), last_index: 0, }; - d.offsets.push(0); + d.indices.push(0); d } } -impl Region for ConsecutiveOffsetPairs +impl Region for ConsecutiveIndexPairs where R: Region, - O: OffsetContainer, + O: IndexContainer, { type Owned = R::Owned; type ReadItem<'a> = R::ReadItem<'a> @@ -189,11 +189,11 @@ where where Self: 'a, { - let mut offsets = O::default(); - offsets.push(0); + let mut indices = O::default(); + indices.push(0); Self { inner: R::merge_regions(regions.map(|r| &r.inner)), - offsets, + indices, last_index: 0, } } @@ -201,7 +201,7 @@ where #[inline] fn index(&self, index: Self::Index) -> Self::ReadItem<'_> { self.inner - .index((self.offsets.index(index), self.offsets.index(index + 1))) + .index((self.indices.index(index), self.indices.index(index + 1))) } #[inline] @@ -217,13 +217,13 @@ where fn clear(&mut self) { self.last_index = 0; self.inner.clear(); - self.offsets.clear(); - self.offsets.push(0); + self.indices.clear(); + self.indices.push(0); } #[inline] fn heap_size(&self, mut callback: F) { - self.offsets.heap_size(&mut callback); + self.indices.heap_size(&mut callback); self.inner.heap_size(callback); } @@ -236,25 +236,25 @@ where } } -impl Push for ConsecutiveOffsetPairs +impl Push for ConsecutiveIndexPairs where R: Region + Push, - O: OffsetContainer, + O: IndexContainer, { #[inline] - fn push(&mut self, item: T) -> as Region>::Index { + fn push(&mut self, item: T) -> as Region>::Index { let index = self.inner.push(item); debug_assert_eq!(index.0, self.last_index); self.last_index = index.1; - self.offsets.push(index.1); - self.offsets.len() - 2 + self.indices.push(index.1); + self.indices.len() - 2 } } -impl ReserveItems for ConsecutiveOffsetPairs +impl ReserveItems for ConsecutiveIndexPairs where R: Region + ReserveItems, - O: OffsetContainer, + O: IndexContainer, { fn reserve_items(&mut self, items: I) where @@ -266,8 +266,8 @@ where #[cfg(test)] mod tests { - use crate::impls::deduplicate::{CollapseSequence, ConsecutiveOffsetPairs}; - use crate::impls::offsets::OffsetOptimized; + use crate::impls::deduplicate::{CollapseSequence, ConsecutiveIndexPairs}; + use crate::impls::index::IndexOptimized; use crate::{FlatStack, Push, StringRegion}; #[test] @@ -292,9 +292,9 @@ mod tests { } #[test] - fn test_offset_optimized() { + fn test_index_optimized() { let mut r = - CollapseSequence::>::default(); + CollapseSequence::>::default(); for _ in 0..1000 { let _ = r.push("abc"); diff --git a/src/impls/offsets.rs b/src/impls/index.rs similarity index 75% rename from src/impls/offsets.rs rename to src/impls/index.rs index c968c24..229e889 100644 --- a/src/impls/offsets.rs +++ b/src/impls/index.rs @@ -1,12 +1,12 @@ -//! Types to represent offsets. +//! Types to store indexes. #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; use crate::impls::storage::Storage; -/// A container to store offsets. -pub trait OffsetContainer: Storage { +/// A container to store indices. +pub trait IndexContainer: Storage { /// Iterator over the elements. type Iter<'a>: Iterator + Clone where @@ -30,14 +30,14 @@ pub trait OffsetContainer: Storage { /// A container for offsets that can represent strides of offsets. /// -/// Does not implement `OffsetContainer` because it cannot accept arbitrary pushes. Instead, +/// Does not implement [`IndexContainer`] because it cannot accept arbitrary pushes. Instead, /// its `push` method returns a boolean to indicate whether the push was successful or not. /// /// This type can absorb sequences of the form `0, stride, 2 * stride, 3 * stride, ...` and /// saturates in a repeated last element. #[derive(Eq, PartialEq, Debug, Default, Clone, Copy)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -pub enum OffsetStride { +pub enum Stride { /// No push has occurred. #[default] Empty, @@ -50,36 +50,36 @@ pub enum OffsetStride { Saturated(usize, usize, usize), } -impl OffsetStride { +impl Stride { /// Accepts or rejects a newly pushed element. #[must_use] #[inline] pub fn push(&mut self, item: usize) -> bool { match self { - OffsetStride::Empty => { + Stride::Empty => { if item == 0 { - *self = OffsetStride::Zero; + *self = Stride::Zero; true } else { false } } - OffsetStride::Zero => { - *self = OffsetStride::Striding(item, 2); + Stride::Zero => { + *self = Stride::Striding(item, 2); true } - OffsetStride::Striding(stride, count) => { + Stride::Striding(stride, count) => { if item == *stride * *count { *count += 1; true } else if item == *stride * (*count - 1) { - *self = OffsetStride::Saturated(*stride, *count, 1); + *self = Stride::Saturated(*stride, *count, 1); true } else { false } } - OffsetStride::Saturated(stride, count, reps) => { + Stride::Saturated(stride, count, reps) => { if item == *stride * (*count - 1) { *reps += 1; true @@ -95,17 +95,17 @@ impl OffsetStride { /// # Panics /// /// Panics for out-of-bounds accesses, i.e., if `index` greater or equal to - /// [`len`][OffsetStride::len]. + /// [`len`](Stride::len). #[must_use] #[inline] pub fn index(&self, index: usize) -> usize { match self { - OffsetStride::Empty => { - panic!("Empty OffsetStride") + Stride::Empty => { + panic!("Empty Stride") } - OffsetStride::Zero => 0, - OffsetStride::Striding(stride, _steps) => *stride * index, - OffsetStride::Saturated(stride, steps, _reps) => { + Stride::Zero => 0, + Stride::Striding(stride, _steps) => *stride * index, + Stride::Saturated(stride, steps, _reps) => { if index < *steps { *stride * index } else { @@ -120,10 +120,10 @@ impl OffsetStride { #[inline] pub fn len(&self) -> usize { match self { - OffsetStride::Empty => 0, - OffsetStride::Zero => 1, - OffsetStride::Striding(_stride, steps) => *steps, - OffsetStride::Saturated(_stride, steps, reps) => *steps + *reps, + Stride::Empty => 0, + Stride::Zero => 1, + Stride::Striding(_stride, steps) => *steps, + Stride::Saturated(_stride, steps, reps) => *steps + *reps, } } @@ -131,7 +131,7 @@ impl OffsetStride { #[must_use] #[inline] pub fn is_empty(&self) -> bool { - matches!(self, OffsetStride::Empty) + matches!(self, Stride::Empty) } /// Removes all elements. @@ -143,22 +143,22 @@ impl OffsetStride { /// Return an iterator over the elements. #[must_use] #[inline] - pub fn iter(&self) -> OffsetStrideIter { - OffsetStrideIter { + pub fn iter(&self) -> StrideIter { + StrideIter { strided: *self, index: 0, } } } -/// An iterator over the elements of an [`OffsetStride`]. +/// An iterator over the elements of an [`Stride`]. #[derive(Clone, Copy)] -pub struct OffsetStrideIter { - strided: OffsetStride, +pub struct StrideIter { + strided: Stride, index: usize, } -impl Iterator for OffsetStrideIter { +impl Iterator for StrideIter { type Item = usize; #[inline] @@ -176,17 +176,17 @@ impl Iterator for OffsetStrideIter { /// A list of unsigned integers that uses `u32` elements as long as they are small enough, and switches to `u64` once they are not. #[derive(Eq, PartialEq, Clone, Debug, Default)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -pub struct OffsetList { - /// Offsets that fit within a `u32`. +pub struct IndexList { + /// Indexes that fit within a `u32`. pub smol: S, - /// Offsets that either do not fit in a `u32`, or are inserted after some offset that did not fit. + /// Indexes that either do not fit in a `u32`, or are inserted after some offset that did not fit. pub chonk: L, } -impl OffsetList +impl IndexList where - S: OffsetContainer, - L: OffsetContainer, + S: IndexContainer, + L: IndexContainer, { /// Allocate a new list with a specified capacity. #[must_use] @@ -198,21 +198,21 @@ where } } - /// Inserts the offset, as a `u32` if that is still on the table. + /// Inserts the index, as a `u32` if that is still on the table. /// /// # Panics /// /// Panics if `usize` does not fit in `u64`. #[inline] - pub fn push(&mut self, offset: usize) { + pub fn push(&mut self, index: usize) { if self.chonk.is_empty() { - if let Ok(smol) = offset.try_into() { + if let Ok(smol) = index.try_into() { self.smol.push(smol); } else { - self.chonk.push(offset.try_into().unwrap()); + self.chonk.push(index.try_into().unwrap()); } } else { - self.chonk.push(offset.try_into().unwrap()); + self.chonk.push(index.try_into().unwrap()); } } @@ -265,10 +265,10 @@ where } } -impl Storage for OffsetList +impl Storage for IndexList where - S: OffsetContainer, - L: OffsetContainer, + S: IndexContainer, + L: IndexContainer, { #[inline] fn with_capacity(capacity: usize) -> Self { @@ -301,12 +301,12 @@ where } } -impl OffsetContainer for OffsetList +impl IndexContainer for IndexList where - S: OffsetContainer, - L: OffsetContainer, + S: IndexContainer, + L: IndexContainer, { - type Iter<'a> = OffsetListIter, L::Iter<'a>> where Self: 'a; + type Iter<'a> = IndexListIter, L::Iter<'a>> where Self: 'a; #[inline] fn index(&self, index: usize) -> usize { @@ -330,21 +330,21 @@ where #[inline] fn iter(&self) -> Self::Iter<'_> { - OffsetListIter { + IndexListIter { smol: self.smol.iter(), chonk: self.chonk.iter(), } } } -/// An iterator over the elements of an [`OffsetList`]. +/// An iterator over the elements of an [`IndexList`]. #[derive(Clone, Copy)] -pub struct OffsetListIter { +pub struct IndexListIter { smol: S, chonk: L, } -impl Iterator for OffsetListIter +impl Iterator for IndexListIter where S: Iterator, L: Iterator, @@ -364,15 +364,15 @@ where /// a regular offset list. #[derive(Eq, PartialEq, Default, Debug, Clone)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -pub struct OffsetOptimized, L = Vec> { - strided: OffsetStride, - spilled: OffsetList, +pub struct IndexOptimized, L = Vec> { + strided: Stride, + spilled: IndexList, } -impl Storage for OffsetOptimized +impl Storage for IndexOptimized where - S: OffsetContainer, - L: OffsetContainer, + S: IndexContainer, + L: IndexContainer, { #[inline] fn with_capacity(_capacity: usize) -> Self { @@ -383,7 +383,7 @@ where #[inline] fn clear(&mut self) { self.spilled.clear(); - self.strided = OffsetStride::default(); + self.strided = Stride::default(); } #[inline] @@ -409,12 +409,12 @@ where } } -impl OffsetContainer for OffsetOptimized +impl IndexContainer for IndexOptimized where - S: OffsetContainer, - L: OffsetContainer, + S: IndexContainer, + L: IndexContainer, { - type Iter<'a> = OffsetOptimizedIter, L::Iter<'a>> where Self: 'a; + type Iter<'a> = IndexOptimizedIter, L::Iter<'a>> where Self: 'a; fn index(&self, index: usize) -> usize { if index < self.strided.len() { @@ -445,21 +445,21 @@ where } fn iter(&self) -> Self::Iter<'_> { - OffsetOptimizedIter { + IndexOptimizedIter { strided: self.strided.iter(), spilled: self.spilled.iter(), } } } -/// An iterator over the elements of an [`OffsetOptimized`]. +/// An iterator over the elements of an [`IndexOptimized`]. #[derive(Clone, Copy)] -pub struct OffsetOptimizedIter { - strided: OffsetStrideIter, - spilled: OffsetListIter, +pub struct IndexOptimizedIter { + strided: StrideIter, + spilled: IndexListIter, } -impl Iterator for OffsetOptimizedIter +impl Iterator for IndexOptimizedIter where S: Iterator, L: Iterator, @@ -471,7 +471,7 @@ where } } -impl OffsetContainer for Vec { +impl IndexContainer for Vec { type Iter<'a> = std::iter::Copied> where Self: 'a; fn index(&self, index: usize) -> T { @@ -497,28 +497,28 @@ impl OffsetContainer for Vec { #[cfg(test)] mod tests { - use crate::impls::deduplicate::ConsecutiveOffsetPairs; + use crate::impls::deduplicate::ConsecutiveIndexPairs; use crate::{Push, Region, SliceRegion, StringRegion}; use super::*; #[test] - fn test_offset_optimized() { + fn test_index_optimized() { fn copy, T>(r: &mut R, item: T) -> R::Index { r.push(item) } let mut r = SliceRegion::< - ConsecutiveOffsetPairs, - OffsetOptimized, + ConsecutiveIndexPairs, + IndexOptimized, >::default(); let idx = copy(&mut r, ["abc"]); assert_eq!("abc", r.index(idx).get(0)) } #[test] - fn test_offset_optimized_clear() { - let mut oo = ::default(); + fn test_index_optimized_clear() { + let mut oo = ::default(); oo.push(0); assert_eq!(oo.len(), 1); oo.clear(); @@ -531,16 +531,16 @@ mod tests { } #[test] - fn test_offset_optimized_reserve() { - let mut oo = ::default(); + fn test_index_optimized_reserve() { + let mut oo = ::default(); oo.push(9999999999); assert_eq!(oo.len(), 1); oo.reserve(1); } #[test] - fn test_offset_optimized_heap_size() { - let mut oo = ::default(); + fn test_index_optimized_heap_size() { + let mut oo = ::default(); oo.push(9999999999); let mut cap = 0; oo.heap_size(|_, ca| { @@ -550,8 +550,8 @@ mod tests { } #[test] - fn test_offset_stride_push() { - let mut os = OffsetStride::default(); + fn test_index_stride_push() { + let mut os = Stride::default(); assert_eq!(os.len(), 0); assert!(os.is_empty()); assert!(os.push(0)); @@ -578,15 +578,15 @@ mod tests { #[test] fn test_chonk() { - let mut ol = , Vec<_>>>::default(); + let mut ol = , Vec<_>>>::default(); ol.push(usize::MAX); assert_eq!(usize::MAX, ol.index(0)); } #[test] #[should_panic] - fn test_offset_stride_index() { - let os = OffsetStride::default(); + fn test_index_stride_index() { + let os = Stride::default(); let _ = os.index(0); } } diff --git a/src/impls/slice.rs b/src/impls/slice.rs index 9fe04ad..34dda42 100644 --- a/src/impls/slice.rs +++ b/src/impls/slice.rs @@ -7,7 +7,7 @@ use std::ops::{Deref, Range}; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; -use crate::impls::offsets::OffsetContainer; +use crate::impls::index::IndexContainer; use crate::{IntoOwned, Push, Region, RegionPreference, ReserveItems}; impl RegionPreference for Vec { @@ -81,7 +81,7 @@ where } } -impl> Region for SliceRegion { +impl> Region for SliceRegion { type Owned = Vec; type ReadItem<'a> = ReadSlice<'a, R, O> where Self: 'a; type Index = (usize, usize); @@ -138,7 +138,7 @@ impl> Region for SliceRegion { } } -impl> Default for SliceRegion { +impl> Default for SliceRegion { #[inline] fn default() -> Self { Self { @@ -149,11 +149,11 @@ impl> Default for SliceRegion { } /// A helper to read data out of a slice region. -pub struct ReadSlice<'a, R: Region, O: OffsetContainer = Vec<::Index>>( +pub struct ReadSlice<'a, R: Region, O: IndexContainer = Vec<::Index>>( Result, &'a [R::Owned]>, ); -impl> ReadSlice<'_, R, O> { +impl> ReadSlice<'_, R, O> { /// Read the n-th item from the underlying region. /// /// # Panics @@ -194,7 +194,7 @@ impl> ReadSlice<'_, R, O> { } } -impl> PartialEq for ReadSlice<'_, R, O> +impl> PartialEq for ReadSlice<'_, R, O> where for<'a> R::ReadItem<'a>: PartialEq, { @@ -203,12 +203,12 @@ where } } -impl> Eq for ReadSlice<'_, R, O> where +impl> Eq for ReadSlice<'_, R, O> where for<'a> R::ReadItem<'a>: Eq { } -impl> PartialOrd for ReadSlice<'_, R, O> +impl> PartialOrd for ReadSlice<'_, R, O> where for<'a> R::ReadItem<'a>: PartialOrd, { @@ -217,7 +217,7 @@ where } } -impl> Ord for ReadSlice<'_, R, O> +impl> Ord for ReadSlice<'_, R, O> where for<'a> R::ReadItem<'a>: Ord, { @@ -226,13 +226,13 @@ where } } -struct ReadSliceInner<'a, R: Region, O: OffsetContainer = Vec<::Index>> { +struct ReadSliceInner<'a, R: Region, O: IndexContainer = Vec<::Index>> { region: &'a SliceRegion, start: usize, end: usize, } -impl> ReadSliceInner<'_, R, O> { +impl> ReadSliceInner<'_, R, O> { /// Read the n-th item from the underlying region. /// /// # Panics @@ -267,7 +267,7 @@ impl> ReadSliceInner<'_, R, O> { } } -impl> Debug for ReadSlice<'_, R, O> +impl> Debug for ReadSlice<'_, R, O> where for<'a> R::ReadItem<'a>: Debug, { @@ -276,27 +276,27 @@ where } } -impl> Clone for ReadSlice<'_, R, O> { +impl> Clone for ReadSlice<'_, R, O> { #[inline] fn clone(&self) -> Self { *self } } -impl> Clone for ReadSliceInner<'_, R, O> { +impl> Clone for ReadSliceInner<'_, R, O> { #[inline] fn clone(&self) -> Self { *self } } -impl> Copy for ReadSlice<'_, R, O> {} -impl> Copy for ReadSliceInner<'_, R, O> {} +impl> Copy for ReadSlice<'_, R, O> {} +impl> Copy for ReadSliceInner<'_, R, O> {} impl<'a, R, O> IntoOwned<'a> for ReadSlice<'a, R, O> where R: Region, - O: OffsetContainer, + O: IndexContainer, { type Owned = Vec; @@ -321,7 +321,7 @@ where } } -impl<'a, R: Region, O: OffsetContainer> IntoIterator for ReadSlice<'a, R, O> { +impl<'a, R: Region, O: IndexContainer> IntoIterator for ReadSlice<'a, R, O> { type Item = R::ReadItem<'a>; type IntoIter = ReadSliceIter<'a, R, O>; @@ -338,11 +338,11 @@ impl<'a, R: Region, O: OffsetContainer> IntoIterator for ReadSlice<'a, /// An iterator over the items read from a slice region. #[derive(Debug)] -pub struct ReadSliceIter<'a, C: Region, O: OffsetContainer>( +pub struct ReadSliceIter<'a, C: Region, O: IndexContainer>( Result, std::slice::Iter<'a, C::Owned>>, ); -impl<'a, C: Region, O: OffsetContainer> Clone for ReadSliceIter<'a, C, O> { +impl<'a, C: Region, O: IndexContainer> Clone for ReadSliceIter<'a, C, O> { #[inline] fn clone(&self) -> Self { Self(self.0.clone()) @@ -351,19 +351,19 @@ impl<'a, C: Region, O: OffsetContainer> Clone for ReadSliceIter<'a, C, /// An iterator over the items read from a slice region. #[derive(Debug)] -pub struct ReadSliceIterInner<'a, C: Region, O: OffsetContainer>( +pub struct ReadSliceIterInner<'a, C: Region, O: IndexContainer>( &'a SliceRegion, Range, ); -impl<'a, C: Region, O: OffsetContainer> Clone for ReadSliceIterInner<'a, C, O> { +impl<'a, C: Region, O: IndexContainer> Clone for ReadSliceIterInner<'a, C, O> { #[inline] fn clone(&self) -> Self { Self(self.0, self.1.clone()) } } -impl<'a, C: Region, O: OffsetContainer> Iterator for ReadSliceIter<'a, C, O> { +impl<'a, C: Region, O: IndexContainer> Iterator for ReadSliceIter<'a, C, O> { type Item = C::ReadItem<'a>; #[inline] @@ -378,13 +378,13 @@ impl<'a, C: Region, O: OffsetContainer> Iterator for ReadSliceIter<'a, impl<'a, R, O> ExactSizeIterator for ReadSliceIter<'a, R, O> where R: Region, - O: OffsetContainer, + O: IndexContainer, std::slice::Iter<'a, R::Owned>: ExactSizeIterator, ReadSliceIterInner<'a, R, O>: ExactSizeIterator, { } -impl<'a, C: Region, O: OffsetContainer> Iterator for ReadSliceIterInner<'a, C, O> { +impl<'a, C: Region, O: IndexContainer> Iterator for ReadSliceIterInner<'a, C, O> { type Item = C::ReadItem<'a>; #[inline] @@ -398,7 +398,7 @@ impl<'a, C: Region, O: OffsetContainer> Iterator for ReadSliceIterInne impl<'a, R, O> ExactSizeIterator for ReadSliceIterInner<'a, R, O> where R: Region, - O: OffsetContainer, + O: IndexContainer, Range: ExactSizeIterator, { } @@ -406,7 +406,7 @@ where impl<'a, C, T, O> Push<&'a [T]> for SliceRegion where C: Region + Push<&'a T>, - O: OffsetContainer, + O: IndexContainer, { #[inline] fn push(&mut self, item: &'a [T]) -> as Region>::Index { @@ -419,7 +419,7 @@ where impl<'a, T, R, O> ReserveItems<&'a [T]> for SliceRegion where R: Region + ReserveItems<&'a T>, - O: OffsetContainer, + O: IndexContainer, { #[inline] fn reserve_items(&mut self, items: I) @@ -434,7 +434,7 @@ where impl Push> for SliceRegion where C: Region + Push, - O: OffsetContainer, + O: IndexContainer, { #[inline] fn push(&mut self, item: Vec) -> as Region>::Index { @@ -448,7 +448,7 @@ where impl Push<&Vec> for SliceRegion where for<'a> C: Region + Push<&'a T>, - O: OffsetContainer, + O: IndexContainer, { #[inline] fn push(&mut self, item: &Vec) -> as Region>::Index { @@ -459,7 +459,7 @@ where impl<'a, C, T, O> Push<&&'a Vec> for SliceRegion where C: Region + Push<&'a T>, - O: OffsetContainer, + O: IndexContainer, { #[inline] fn push(&mut self, item: &&'a Vec) -> as Region>::Index { @@ -470,7 +470,7 @@ where impl<'a, T, R, O> ReserveItems<&'a Vec> for SliceRegion where for<'b> R: Region + ReserveItems<&'b T>, - O: OffsetContainer, + O: IndexContainer, { #[inline] fn reserve_items(&mut self, items: I) @@ -484,7 +484,7 @@ where impl<'a, C, O> Push> for SliceRegion where C: Region + Push<::ReadItem<'a>>, - O: OffsetContainer, + O: IndexContainer, { #[inline] fn push(&mut self, item: ReadSlice<'a, C, O>) -> as Region>::Index { @@ -505,7 +505,7 @@ where impl<'a, C, O> Push> for SliceRegion where C: Region + Push<::ReadItem<'a>>, - O: OffsetContainer, + O: IndexContainer, { #[inline] fn push(&mut self, item: ReadSliceInner<'a, C, O>) -> as Region>::Index { @@ -523,7 +523,7 @@ where impl Push<[T; N]> for SliceRegion where for<'a> R: Region + Push<&'a T>, - O: OffsetContainer, + O: IndexContainer, { #[inline] fn push(&mut self, item: [T; N]) -> as Region>::Index { @@ -534,7 +534,7 @@ where impl<'a, T, R, O, const N: usize> Push<&'a [T; N]> for SliceRegion where R: Region + Push<&'a T>, - O: OffsetContainer, + O: IndexContainer, { #[inline] fn push(&mut self, item: &'a [T; N]) -> as Region>::Index { @@ -545,7 +545,7 @@ where impl<'a, T, R, O, const N: usize> Push<&&'a [T; N]> for SliceRegion where R: Region + Push<&'a T>, - O: OffsetContainer, + O: IndexContainer, { #[inline] fn push(&mut self, item: &&'a [T; N]) -> as Region>::Index { @@ -556,7 +556,7 @@ where impl<'a, T, R, O, const N: usize> ReserveItems<&'a [T; N]> for SliceRegion where R: Region + ReserveItems<&'a T>, - O: OffsetContainer, + O: IndexContainer, { fn reserve_items(&mut self, items: I) where @@ -569,7 +569,7 @@ where impl<'a, R, O> ReserveItems> for SliceRegion where R: Region + ReserveItems<::ReadItem<'a>> + 'a, - O: OffsetContainer, + O: IndexContainer, { fn reserve_items(&mut self, items: I) where @@ -616,7 +616,7 @@ mod tests { let mut r = >>::default(); let index = r.push([1; 4]); - // Offset 4 is out of bounds and expected to panic. + // Index 4 is out of bounds and expected to panic. let _ = r.index(index).get(4); } diff --git a/src/lib.rs b/src/lib.rs index 23af4ae..759a508 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -9,7 +9,7 @@ use serde::{Deserialize, Serialize}; pub mod impls; -use crate::impls::offsets::OffsetContainer; +use crate::impls::index::IndexContainer; pub use impls::columns::ColumnsRegion; pub use impls::mirror::MirrorRegion; pub use impls::option::OptionRegion; @@ -183,7 +183,7 @@ impl Default for FlatStack { } } -impl::Index>> Debug for FlatStack +impl::Index>> Debug for FlatStack where for<'a> R::ReadItem<'a>: Debug, { @@ -192,7 +192,7 @@ where } } -impl::Index>> FlatStack { +impl::Index>> FlatStack { /// Returns a flat stack that can absorb `capacity` indices without reallocation. /// /// Prefer [`Self::merge_capacity`] over this function to also pre-size the regions. @@ -226,11 +226,11 @@ impl::Index>> FlatStack { self.indices.push(index); } - /// Returns the element at the `offset` position. + /// Returns the element at the `index` position. #[inline] #[must_use] - pub fn get(&self, offset: usize) -> R::ReadItem<'_> { - self.region.index(self.indices.index(offset)) + pub fn get(&self, index: usize) -> R::ReadItem<'_> { + self.region.index(self.indices.index(index)) } /// Returns the number of indices in the stack. @@ -289,7 +289,7 @@ impl::Index>> FlatStack { impl FlatStack where R: Region, - S: OffsetContainer<::Index>, + S: IndexContainer<::Index>, { /// Iterate the items in this stack. #[inline] @@ -316,7 +316,7 @@ impl FlatStack { impl Extend for FlatStack where R: Region + Push, - S: OffsetContainer<::Index>, + S: IndexContainer<::Index>, { fn extend>(&mut self, iter: I) { let iter = iter.into_iter(); @@ -327,7 +327,7 @@ where } } -impl<'a, R: Region, S: OffsetContainer<::Index>> IntoIterator for &'a FlatStack { +impl<'a, R: Region, S: IndexContainer<::Index>> IntoIterator for &'a FlatStack { type Item = R::ReadItem<'a>; type IntoIter = Iter<'a, R, S::Iter<'a>>; @@ -390,7 +390,7 @@ where impl FromIterator for FlatStack where R: Region + Push, - S: OffsetContainer<::Index>, + S: IndexContainer<::Index>, { fn from_iter>(iter: I) -> Self { let iter = iter.into_iter(); @@ -424,7 +424,7 @@ pub struct PushIter(pub I); #[cfg(test)] mod tests { - use crate::impls::deduplicate::{CollapseSequence, ConsecutiveOffsetPairs}; + use crate::impls::deduplicate::{CollapseSequence, ConsecutiveIndexPairs}; use crate::impls::tuple::TupleARegion; use super::*; @@ -582,7 +582,7 @@ mod tests { test_copy::<_, <(u8, u8) as RegionPreference>::Region>((1, 2)); test_copy::<_, <(u8, u8) as RegionPreference>::Region>(&(1, 2)); - test_copy::<_, ConsecutiveOffsetPairs>>([1, 2, 3].as_slice()); + test_copy::<_, ConsecutiveIndexPairs>>([1, 2, 3].as_slice()); test_copy::<_, CollapseSequence>>([1, 2, 3].as_slice()); test_copy::<_, CollapseSequence>>(&[1, 2, 3]); diff --git a/tests/recursive.rs b/tests/recursive.rs index 2dba7a5..65e4cd1 100644 --- a/tests/recursive.rs +++ b/tests/recursive.rs @@ -1,6 +1,6 @@ //! Demonstration of how to encode recursive data structures. -use flatcontainer::impls::deduplicate::ConsecutiveOffsetPairs; +use flatcontainer::impls::deduplicate::ConsecutiveIndexPairs; use flatcontainer::{IntoOwned, Push, Region, StringRegion}; #[derive(Clone)] @@ -135,7 +135,7 @@ where #[test] fn recursive() { - let mut region = >>::default(); + let mut region = >>::default(); let r = List("abc", Some(Box::new(List("def", None)))); let index = region.push(&r);