[−][src]Struct sized_chunks::sized_chunk::Chunk
A fixed capacity smart array.
An inline array of items with a variable length but a fixed, preallocated
capacity given by the N
type, which must be an Unsigned
type
level numeral.
It's 'smart' because it's able to reorganise its contents based on expected
behaviour. If you construct one using push_back
, it will be laid out like
a Vec
with space at the end. If you push_front
it will start filling in
values from the back instead of the front, so that you still get linear time
push as long as you don't reverse direction. If you do, and there's no room
at the end you're pushing to, it'll shift its contents over to the other
side, creating more space to push into. This technique is tuned for
Chunk
's expected use case in im::Vector: usually, chunks always see
either push_front
or push_back
, but not both unless they move around
inside the tree, in which case they're able to reorganise themselves with
reasonable efficiency to suit their new usage patterns.
It maintains a left
index and a right
index instead of a simple length
counter in order to accomplish this, much like a ring buffer would, except
that the Chunk
keeps all its items sequentially in memory so that you can
always get a &[A]
slice for them, at the price of the occasional
reordering operation. The allocated size of a Chunk
is thus usize
* 2 +
A
* N
.
This technique also lets us choose to shift the shortest side to account for
the inserted or removed element when performing insert and remove
operations, unlike Vec
where you always need to shift the right hand side.
Unlike a Vec
, the Chunk
has a fixed capacity and cannot grow beyond it.
Being intended for low level use, it expects you to know or test whether
you're pushing to a full array, and has an API more geared towards panics
than returning Option
s, on the assumption that you know what you're doing.
Of course, if you don't, you can expect it to panic immediately rather than
do something undefined and usually bad.
Isn't this just a less efficient ring buffer?
You might be wondering why you would want to use this data structure rather
than a RingBuffer
, which is similar but doesn't need to
shift its content around when it hits the sides of the allocated buffer. The
answer is that Chunk
can be dereferenced into a slice, while a ring buffer
can not. If you don't need to be able to do that, a ring buffer will
generally be the marginally more efficient choice.
Examples
// Construct a chunk with a 64 item capacity let mut chunk = Chunk::<i32, U64>::new(); // Fill it with descending numbers chunk.extend((0..64).rev()); // It derefs to a slice so we can use standard slice methods chunk.sort(); // It's got all the amenities like `FromIterator` and `Eq` let expected: Chunk<i32, U64> = (0..64).collect(); assert_eq!(expected, chunk);
Methods
impl<A, N> Chunk<A, N> where
N: ChunkLength<A>,
[src]
N: ChunkLength<A>,
pub const CAPACITY: usize
[src]
pub fn new() -> Self
[src]
Construct a new empty chunk.
pub fn unit(value: A) -> Self
[src]
Construct a new chunk with one item.
pub fn pair(left: A, right: A) -> Self
[src]
Construct a new chunk with two items.
pub fn drain_from(other: &mut Self) -> Self
[src]
Construct a new chunk and move every item from other
into the new
chunk.
Time: O(n)
pub fn collect_from<I>(iter: &mut I, count: usize) -> Self where
I: Iterator<Item = A>,
[src]
I: Iterator<Item = A>,
Construct a new chunk and populate it by taking count
items from the
iterator iter
.
Panics if the iterator contains less than count
items.
Time: O(n)
pub fn from_front(other: &mut Self, count: usize) -> Self
[src]
Construct a new chunk and populate it by taking count
items from the
front of other
.
Time: O(n) for the number of items moved
pub fn from_back(other: &mut Self, count: usize) -> Self
[src]
Construct a new chunk and populate it by taking count
items from the
back of other
.
Time: O(n) for the number of items moved
pub fn len(&self) -> usize
[src]
Get the length of the chunk.
pub fn is_empty(&self) -> bool
[src]
Test if the chunk is empty.
pub fn is_full(&self) -> bool
[src]
Test if the chunk is at capacity.
pub fn push_front(&mut self, value: A)
[src]
Push an item to the front of the chunk.
Panics if the capacity of the chunk is exceeded.
Time: O(1) if there's room at the front, O(n) otherwise
pub fn push_back(&mut self, value: A)
[src]
Push an item to the back of the chunk.
Panics if the capacity of the chunk is exceeded.
Time: O(1) if there's room at the back, O(n) otherwise
pub fn pop_front(&mut self) -> A
[src]
Pop an item off the front of the chunk.
Panics if the chunk is empty.
Time: O(1)
pub fn pop_back(&mut self) -> A
[src]
Pop an item off the back of the chunk.
Panics if the chunk is empty.
Time: O(1)
pub fn drop_left(&mut self, index: usize)
[src]
Discard all items up to but not including index
.
Panics if index
is out of bounds.
Time: O(n) for the number of items dropped
pub fn drop_right(&mut self, index: usize)
[src]
Discard all items from index
onward.
Panics if index
is out of bounds.
Time: O(n) for the number of items dropped
pub fn split_off(&mut self, index: usize) -> Self
[src]
Split a chunk into two, the original chunk containing
everything up to index
and the returned chunk containing
everything from index
onwards.
Panics if index
is out of bounds.
Time: O(n) for the number of items in the new chunk
pub fn append(&mut self, other: &mut Self)
[src]
Remove all items from other
and append them to the back of self
.
Panics if the capacity of the chunk is exceeded.
Time: O(n) for the number of items moved
pub fn drain_from_front(&mut self, other: &mut Self, count: usize)
[src]
Remove count
items from the front of other
and append them to the
back of self
.
Panics if self
doesn't have count
items left, or if other
has
fewer than count
items.
Time: O(n) for the number of items moved
pub fn drain_from_back(&mut self, other: &mut Self, count: usize)
[src]
Remove count
items from the back of other
and append them to the
front of self
.
Panics if self
doesn't have count
items left, or if other
has
fewer than count
items.
Time: O(n) for the number of items moved
pub fn set(&mut self, index: usize, value: A) -> A
[src]
Update the value at index index
, returning the old value.
Panics if index
is out of bounds.
Time: O(1)
pub fn insert(&mut self, index: usize, value: A)
[src]
Insert a new value at index index
, shifting all the following values
to the right.
Panics if the index is out of bounds.
Time: O(n) for the number of items shifted
pub fn remove(&mut self, index: usize) -> A
[src]
Remove the value at index index
, shifting all the following values to
the left.
Returns the removed value.
Panics if the index is out of bounds.
Time: O(n) for the number of items shifted
ⓘImportant traits for Drain<'a, A, N>pub fn drain(&mut self) -> Drain<A, N>
[src]
Construct an iterator that drains values from the front of the chunk.
pub fn clear(&mut self)
[src]
Discard the contents of the chunk.
Time: O(n)
pub fn as_slice(&self) -> &[A]
[src]
Get a reference to the contents of the chunk as a slice.
pub fn as_mut_slice(&mut self) -> &mut [A]
[src]
Get a reference to the contents of the chunk as a mutable slice.
Trait Implementations
impl<A, N> AsMut<[A]> for Chunk<A, N> where
N: ChunkLength<A>,
[src]
N: ChunkLength<A>,
impl<A, N> Default for Chunk<A, N> where
N: ChunkLength<A>,
[src]
N: ChunkLength<A>,
impl<A, N> Drop for Chunk<A, N> where
N: ChunkLength<A>,
[src]
N: ChunkLength<A>,
impl<A, N> Ord for Chunk<A, N> where
A: Ord,
N: ChunkLength<A>,
[src]
A: Ord,
N: ChunkLength<A>,
fn cmp(&self, other: &Self) -> Ordering
[src]
fn max(self, other: Self) -> Self
1.21.0[src]
Compares and returns the maximum of two values. Read more
fn min(self, other: Self) -> Self
1.21.0[src]
Compares and returns the minimum of two values. Read more
fn clamp(self, min: Self, max: Self) -> Self
[src]
clamp
)Restrict a value to a certain interval. Read more
impl<A, N> Clone for Chunk<A, N> where
A: Clone,
N: ChunkLength<A>,
[src]
A: Clone,
N: ChunkLength<A>,
fn clone(&self) -> Self
[src]
fn clone_from(&mut self, source: &Self)
1.0.0[src]
Performs copy-assignment from source
. Read more
impl<A, N, Slice> PartialEq<Slice> for Chunk<A, N> where
Slice: Borrow<[A]>,
A: PartialEq,
N: ChunkLength<A>,
[src]
Slice: Borrow<[A]>,
A: PartialEq,
N: ChunkLength<A>,
fn eq(&self, other: &Slice) -> bool
[src]
#[must_use]
fn ne(&self, other: &Rhs) -> bool
1.0.0[src]
This method tests for !=
.
impl<A, N> Extend<A> for Chunk<A, N> where
N: ChunkLength<A>,
[src]
N: ChunkLength<A>,
fn extend<I>(&mut self, it: I) where
I: IntoIterator<Item = A>,
[src]
I: IntoIterator<Item = A>,
Append the contents of the iterator to the back of the chunk.
Panics if the chunk exceeds its capacity.
Time: O(n) for the length of the iterator
impl<'a, A, N> Extend<&'a A> for Chunk<A, N> where
A: 'a + Copy,
N: ChunkLength<A>,
[src]
A: 'a + Copy,
N: ChunkLength<A>,
fn extend<I>(&mut self, it: I) where
I: IntoIterator<Item = &'a A>,
[src]
I: IntoIterator<Item = &'a A>,
Append the contents of the iterator to the back of the chunk.
Panics if the chunk exceeds its capacity.
Time: O(n) for the length of the iterator
impl<A, N> AsRef<[A]> for Chunk<A, N> where
N: ChunkLength<A>,
[src]
N: ChunkLength<A>,
impl<A, N, T> From<InlineArray<A, T>> for Chunk<A, N> where
N: ChunkLength<A>,
[src]
N: ChunkLength<A>,
fn from(array: InlineArray<A, T>) -> Self
[src]
impl<'a, A, N, T> From<&'a mut InlineArray<A, T>> for Chunk<A, N> where
N: ChunkLength<A>,
[src]
N: ChunkLength<A>,
fn from(array: &mut InlineArray<A, T>) -> Self
[src]
impl<A, N> Eq for Chunk<A, N> where
A: Eq,
N: ChunkLength<A>,
[src]
A: Eq,
N: ChunkLength<A>,
impl<'a, A, N> IntoIterator for &'a Chunk<A, N> where
N: ChunkLength<A>,
[src]
N: ChunkLength<A>,
type Item = &'a A
The type of the elements being iterated over.
type IntoIter = SliceIter<'a, A>
Which kind of iterator are we turning this into?
fn into_iter(self) -> Self::IntoIter
[src]
impl<'a, A, N> IntoIterator for &'a mut Chunk<A, N> where
N: ChunkLength<A>,
[src]
N: ChunkLength<A>,
type Item = &'a mut A
The type of the elements being iterated over.
type IntoIter = SliceIterMut<'a, A>
Which kind of iterator are we turning this into?
fn into_iter(self) -> Self::IntoIter
[src]
impl<A, N> IntoIterator for Chunk<A, N> where
N: ChunkLength<A>,
[src]
N: ChunkLength<A>,
type Item = A
The type of the elements being iterated over.
type IntoIter = Iter<A, N>
Which kind of iterator are we turning this into?
fn into_iter(self) -> Self::IntoIter
[src]
impl<A, N> PartialOrd<Chunk<A, N>> for Chunk<A, N> where
A: PartialOrd,
N: ChunkLength<A>,
[src]
A: PartialOrd,
N: ChunkLength<A>,
fn partial_cmp(&self, other: &Self) -> Option<Ordering>
[src]
#[must_use]
fn lt(&self, other: &Rhs) -> bool
1.0.0[src]
This method tests less than (for self
and other
) and is used by the <
operator. Read more
#[must_use]
fn le(&self, other: &Rhs) -> bool
1.0.0[src]
This method tests less than or equal to (for self
and other
) and is used by the <=
operator. Read more
#[must_use]
fn gt(&self, other: &Rhs) -> bool
1.0.0[src]
This method tests greater than (for self
and other
) and is used by the >
operator. Read more
#[must_use]
fn ge(&self, other: &Rhs) -> bool
1.0.0[src]
This method tests greater than or equal to (for self
and other
) and is used by the >=
operator. Read more
impl<A, N> Deref for Chunk<A, N> where
N: ChunkLength<A>,
[src]
N: ChunkLength<A>,
impl<A, N> DerefMut for Chunk<A, N> where
N: ChunkLength<A>,
[src]
N: ChunkLength<A>,
impl<A, N> Debug for Chunk<A, N> where
A: Debug,
N: ChunkLength<A>,
[src]
A: Debug,
N: ChunkLength<A>,
impl<A, N, I> Index<I> for Chunk<A, N> where
I: SliceIndex<[A]>,
N: ChunkLength<A>,
[src]
I: SliceIndex<[A]>,
N: ChunkLength<A>,
type Output = I::Output
The returned type after indexing.
fn index(&self, index: I) -> &Self::Output
[src]
impl<A, N, I> IndexMut<I> for Chunk<A, N> where
I: SliceIndex<[A]>,
N: ChunkLength<A>,
[src]
I: SliceIndex<[A]>,
N: ChunkLength<A>,
impl<A, N> Hash for Chunk<A, N> where
A: Hash,
N: ChunkLength<A>,
[src]
A: Hash,
N: ChunkLength<A>,
fn hash<H>(&self, hasher: &mut H) where
H: Hasher,
[src]
H: Hasher,
fn hash_slice<H>(data: &[Self], state: &mut H) where
H: Hasher,
1.3.0[src]
H: Hasher,
Feeds a slice of this type into the given [Hasher
]. Read more
impl<A, N> FromIterator<A> for Chunk<A, N> where
N: ChunkLength<A>,
[src]
N: ChunkLength<A>,
fn from_iter<I>(it: I) -> Self where
I: IntoIterator<Item = A>,
[src]
I: IntoIterator<Item = A>,
impl<A, N> Borrow<[A]> for Chunk<A, N> where
N: ChunkLength<A>,
[src]
N: ChunkLength<A>,
impl<A, N> BorrowMut<[A]> for Chunk<A, N> where
N: ChunkLength<A>,
[src]
N: ChunkLength<A>,
fn borrow_mut(&mut self) -> &mut [A]
[src]
impl<N> Write for Chunk<u8, N> where
N: ChunkLength<u8>,
[src]
N: ChunkLength<u8>,
fn write(&mut self, buf: &[u8]) -> Result<usize>
[src]
fn flush(&mut self) -> Result<()>
[src]
fn write_vectored(&mut self, bufs: &[IoSlice]) -> Result<usize, Error>
1.36.0[src]
Like write
, except that it writes from a slice of buffers. Read more
fn write_all(&mut self, buf: &[u8]) -> Result<(), Error>
1.0.0[src]
Attempts to write an entire buffer into this writer. Read more
fn write_fmt(&mut self, fmt: Arguments) -> Result<(), Error>
1.0.0[src]
Writes a formatted string into this writer, returning any error encountered. Read more
fn by_ref(&mut self) -> &mut Self
1.0.0[src]
Creates a "by reference" adaptor for this instance of Write
. Read more
impl<N: ChunkLength<u8>> Read for Chunk<u8, N>
[src]
fn read(&mut self, buf: &mut [u8]) -> Result<usize>
[src]
fn read_vectored(&mut self, bufs: &mut [IoSliceMut]) -> Result<usize, Error>
1.36.0[src]
Like read
, except that it reads into a slice of buffers. Read more
unsafe fn initializer(&self) -> Initializer
[src]
read_initializer
)Determines if this Read
er can work with buffers of uninitialized memory. Read more
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> Result<usize, Error>
1.0.0[src]
Read all bytes until EOF in this source, placing them into buf
. Read more
fn read_to_string(&mut self, buf: &mut String) -> Result<usize, Error>
1.0.0[src]
Read all bytes until EOF in this source, appending them to buf
. Read more
fn read_exact(&mut self, buf: &mut [u8]) -> Result<(), Error>
1.6.0[src]
Read the exact number of bytes required to fill buf
. Read more
fn by_ref(&mut self) -> &mut Self
1.0.0[src]
Creates a "by reference" adaptor for this instance of Read
. Read more
fn bytes(self) -> Bytes<Self>
1.0.0[src]
Transforms this Read
instance to an [Iterator
] over its bytes. Read more
fn chain<R>(self, next: R) -> Chain<Self, R> where
R: Read,
1.0.0[src]
R: Read,
Creates an adaptor which will chain this stream with another. Read more
fn take(self, limit: u64) -> Take<Self>
1.0.0[src]
Creates an adaptor which will read at most limit
bytes from it. Read more
Auto Trait Implementations
impl<A, N> Sync for Chunk<A, N> where
<N as ChunkLength<A>>::SizedType: Sync,
<N as ChunkLength<A>>::SizedType: Sync,
impl<A, N> Unpin for Chunk<A, N> where
<N as ChunkLength<A>>::SizedType: Unpin,
<N as ChunkLength<A>>::SizedType: Unpin,
impl<A, N> Send for Chunk<A, N> where
<N as ChunkLength<A>>::SizedType: Send,
<N as ChunkLength<A>>::SizedType: Send,
impl<A, N> UnwindSafe for Chunk<A, N> where
<N as ChunkLength<A>>::SizedType: UnwindSafe,
<N as ChunkLength<A>>::SizedType: UnwindSafe,
impl<A, N> RefUnwindSafe for Chunk<A, N> where
<N as ChunkLength<A>>::SizedType: RefUnwindSafe,
<N as ChunkLength<A>>::SizedType: RefUnwindSafe,
Blanket Implementations
impl<T, U> Into<U> for T where
U: From<T>,
[src]
U: From<T>,
impl<T> ToOwned for T where
T: Clone,
[src]
T: Clone,
type Owned = T
The resulting type after obtaining ownership.
fn to_owned(&self) -> T
[src]
fn clone_into(&self, target: &mut T)
[src]
impl<T> From<T> for T
[src]
impl<I> IntoIterator for I where
I: Iterator,
[src]
I: Iterator,
type Item = <I as Iterator>::Item
The type of the elements being iterated over.
type IntoIter = I
Which kind of iterator are we turning this into?
fn into_iter(self) -> I
[src]
impl<T, U> TryFrom<U> for T where
U: Into<T>,
[src]
U: Into<T>,
type Error = Infallible
The type returned in the event of a conversion error.
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>
[src]
impl<T, U> TryInto<U> for T where
U: TryFrom<T>,
[src]
U: TryFrom<T>,
type Error = <U as TryFrom<T>>::Error
The type returned in the event of a conversion error.
fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>
[src]
impl<T, V> SliceConcat<T> for V where
T: Clone,
V: Borrow<[T]>,
[src]
T: Clone,
V: Borrow<[T]>,
type Output = Vec<T>
slice_concat_trait
)The resulting type after concatenation
fn concat(slice: &[V]) -> Vec<T>
[src]
fn join(slice: &[V], sep: &T) -> Vec<T>
[src]
impl<T> Borrow<T> for T where
T: ?Sized,
[src]
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
[src]
T: ?Sized,
fn borrow_mut(&mut self) -> &mut T
[src]
impl<T> Any for T where
T: 'static + ?Sized,
[src]
T: 'static + ?Sized,
impl<T> Same<T> for T
[src]
type Output = T
Should always be Self