Struct expanding_slice_rb::ExpSliceRB[][src]

pub struct ExpSliceRB<T: Default + Copy> { /* fields omitted */ }

A self-expanding ring buffer optimized for working with slices of data. This functions similarly to VecDeque, but with handy methods for efficiently working with slices of data. This can be especially useful when working with streams of data where the input and output buffers are different sizes.

Copies/reads with slices are implemented with memcpy. This algorithm attempts to use as little memcpys and allocations as possible, and only potentially shuffles data around when the capacity of the buffer is increased.

This buffer does not contain any Producer/Consumer logic, but it could be used as a building block for a ring buffer that does.

Example

use expanding_slice_rb::ExpSliceRB;
 
// Create a ring buffer with type u32. There is no data in the buffer to start.
//
// If possible, it is a good idea to set `capacity` to the largest you expect the
// buffer to get to avoid future memory allocations.
let mut buf = ExpSliceRB::<u32>::with_capacity(3);
 
let data = [0u32, 1, 2];
 
// Memcpy data from a slice into the ring buffer. The buffer will automatically
// expand to fill new data.
buf.write(&data);
assert_eq!(buf.len(), 3);
assert_eq!(buf.capacity(), 3);
 
buf.write(&data);
assert_eq!(buf.len(), 6);
assert_eq!(buf.capacity(), 6);
 
// Memcpy the next chunk of data into the read slice. If the length of existing
// data in the buffer is less than the length of the slice, then only that amount
// of data will be copied into the front of the slice.
//
// This is streaming, meaning the copied data will be cleared from the buffer for reuse, and
// the next call to `read_into()` will start copying from where the previous call left off.
// If you don't want this behavior, use the `peek_into()` method instead.
let mut read_slice = [5u32; 4];
let mut amount_written = buf.read_into(&mut read_slice);
assert_eq!(amount_written, 4);
assert_eq!(read_slice, [0u32, 1, 2, 0]);
 
buf.write(&data);
let mut large_read_slice = [5u32; 8];
amount_written = buf.read_into(&mut large_read_slice);
assert_eq!(amount_written, 5);
assert_eq!(large_read_slice, [1u32, 2, 0, 1, 2, 5, 5, 5]);

Implementations

impl<T: Default + Copy> ExpSliceRB<T>[src]

pub fn with_capacity(capacity: usize) -> Self[src]

Create a new empty ExpSliceRB with an initial allocated capacity.

If possible, it is a good idea to set capacity to the largest you expect the buffer to get to avoid future memory allocations.

This allocates new memory and is not real-time safe.

Example

use expanding_slice_rb::ExpSliceRB;

let buf = ExpSliceRB::<u32>::with_capacity(128);

assert_eq!(buf.len(), 0);
assert_eq!(buf.capacity(), 128);

pub fn read_into(&mut self, slice: &mut [T]) -> usize[src]

Reads the next chunk of existing data into the given slice. If the length of existing data in the buffer is less than the length of the slice, then only that amount of data will be copied into the front of the slice.

This is streaming, meaning the copied data will be cleared from the buffer for reuse, and the next call to read_into() will start copying from where the previous call left off. If you don’t want this behavior, use the peek_into() method instead.

This does not allocate any memory and is real-time safe.

Returns

This returns the total amount of data that was copied into slice.

Example

use expanding_slice_rb::ExpSliceRB;

let mut buf = ExpSliceRB::<u32>::with_capacity(6);

let data = [0u32, 1, 2];
buf.write(&data);
buf.write(&data);

let mut read_slice = [5u32; 4];
let mut amount_written = buf.read_into(&mut read_slice);
assert_eq!(amount_written, 4);
assert_eq!(read_slice, [0u32, 1, 2, 0]);

buf.write(&data);
let mut large_read_slice = [5u32; 8];
amount_written = buf.read_into(&mut large_read_slice);
assert_eq!(amount_written, 5);
assert_eq!(large_read_slice, [1u32, 2, 0, 1, 2, 5, 5, 5]);

pub fn peek_into(&mut self, slice: &mut [T]) -> usize[src]

Reads the next chunk of existing data into the given slice. If the length of existing data in the buffer is less than the length of the slice, then only that amount of data will be copied into the front of the slice.

As apposed to read_into(), this method is not streaming and does not effect the length of existing data in the buffer.

This does not allocate any memory and is real-time safe.

Returns

This returns the total amount of data that was copied into slice.

Example

use expanding_slice_rb::ExpSliceRB;

let mut buf = ExpSliceRB::<u32>::with_capacity(6);

let data = [0u32, 1, 2];
buf.write(&data);
buf.write(&data);
assert_eq!(buf.len(), 6);

let mut read_slice = [5u32; 4];
let mut amount_written = buf.peek_into(&mut read_slice);
assert_eq!(amount_written, 4);
assert_eq!(read_slice, [0u32, 1, 2, 0]);
assert_eq!(buf.len(), 6);

Returns

This returns the total amount of data that was copied into slice.

pub fn write(&mut self, slice: &[T])[src]

Append additional data into the buffer to be read later. More memory may be allocated if the buffer is not large enough.

This may allocate new memory and is not real-time safe.

Example

use expanding_slice_rb::ExpSliceRB;

let mut buf = ExpSliceRB::<u32>::with_capacity(6);

let data = [0u32, 1, 2];

buf.write(&data);
assert_eq!(buf.len(), 3);
assert_eq!(buf.capacity(), 6);

buf.write(&data);
assert_eq!(buf.len(), 6);
assert_eq!(buf.capacity(), 6);

buf.write(&data);
assert_eq!(buf.len(), 9);
assert_eq!(buf.capacity(), 9);

Panics

  • Panics if any newly allocated capacity overflows usize.

pub fn try_write(&mut self, slice: &[T]) -> Result<(), ()>[src]

Append additional data into the buffer to be read later. If the data cannot fit into the buffer, then no data is copied and and error is returned.

This does not allocate any memory and is real-time safe.

Example

use expanding_slice_rb::ExpSliceRB;

let mut buf = ExpSliceRB::<u32>::with_capacity(6);

let data = [0u32, 1, 2];

assert_eq!(buf.try_write(&data), Ok(()));
assert_eq!(buf.try_write(&data), Ok(()));
assert_eq!(buf.try_write(&data), Err(()));

pub fn reserve(&mut self, additional: usize)[src]

Reserves capacity for at least additional more elements to be inserted into the buffer.

Due to the algorithm, no data will actually be initialized. However, more memory may need to be allocated.

This may allocate new memory and is not real-time safe.

Panics

  • Panics if the new capacity overflows usize.

pub fn clear(&mut self)[src]

Removes all existing data in the buffer.

This does not allocate any memory and is real-time safe.

Due to the algorithm, no data will actually be initialized.

pub fn clear_and_shrink_to_capacity(&mut self, capacity: usize)[src]

Removes all existing data in the buffer and sets the allocated capacity of the buffer. This will also call Vec::shrink_to_fit() on the internal Vec.

Due to the algorithm, no data will actually be initialized.

This may allocate or deallocate memory and is not real-time safe.

pub fn capacity(&self) -> usize[src]

Returns the allocated capacity of the internal buffer. (This may be different from the allocated capacity of the internal Vec.)

pub fn raw_capacity(&self) -> usize[src]

Returns the raw allocated capacity of the internal Vec. Note this may be different from the allocated capacity of the buffer.

pub fn len(&self) -> usize[src]

Returns the length of existing data in the buffer. This is not the same as the allocated capacity of the buffer.

pub fn data_left(&self) -> usize[src]

Returns the amount of unused data available in the buffer.

This can be useful in conjunction with the try_write() method.

pub fn is_empty(&self) -> bool[src]

Return true if the buffer has no existing data, false otherwise.

Auto Trait Implementations

impl<T> RefUnwindSafe for ExpSliceRB<T> where
    T: RefUnwindSafe

impl<T> Send for ExpSliceRB<T> where
    T: Send

impl<T> Sync for ExpSliceRB<T> where
    T: Sync

impl<T> Unpin for ExpSliceRB<T> where
    T: Unpin

impl<T> UnwindSafe for ExpSliceRB<T> where
    T: UnwindSafe

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.