Struct slice_ring_buf::SliceRbRef
source · pub struct SliceRbRef<'a, T: Copy + Clone + Default> { /* private fields */ }
Expand description
A fast ring buffer implementation optimized for working with slices.
Copies/reads with slices are implemented with memcpy. This works the same as
SliceRB
except it uses a reference as its data source instead of an internal Vec.
Implementations§
source§impl<'a, T: Copy + Clone + Default> SliceRbRef<'a, T>
impl<'a, T: Copy + Clone + Default> SliceRbRef<'a, T>
sourcepub fn new(slice: &'a mut [T]) -> Self
pub fn new(slice: &'a mut [T]) -> Self
Creates a new SliceRbRef
with the given data.
Safety
- Using this struct may cause undefined behavior if the given data in
slice
was not initialized first - The data in
slice
must be valid and properly aligned. Seestd::slice::from_raw_parts
for more details. - The size in bytes of the data in
slice
should be no larger thanisize::MAX
. See [std::ptr::offset
] for more information when indexing very large buffers on 32-bit and 16-bit platforms.
Example
use slice_ring_buf::SliceRbRef;
let mut data = [1u32, 2, 3, 4];
let rb = SliceRbRef::new(&mut data[..]);
assert_eq!(rb.len(), 4);
assert_eq!(rb[0], 1);
assert_eq!(rb[1], 2);
assert_eq!(rb[2], 3);
assert_eq!(rb[3], 4);
Panics
- This will panic if the length of
slice
is 0.
sourcepub fn clear(&mut self)
pub fn clear(&mut self)
Clears all values in the ring buffer to the default value.///
Example
use slice_ring_buf::SliceRbRef;
let mut data = [1u32, 2, 3, 4];
let mut rb = SliceRbRef::new(&mut data[..]);
rb.clear();
assert_eq!(rb[0], 0);
assert_eq!(rb[1], 0);
assert_eq!(rb[2], 0);
assert_eq!(rb[3], 0);
sourcepub fn as_slices(&self, start: isize) -> (&[T], &[T])
pub fn as_slices(&self, start: isize) -> (&[T], &[T])
Returns two slices that contain all the data in the ring buffer
starting at the index start
.
Safety
- Using this may cause undefined behavior if the given data in
slice
inSliceRbRef::new()
was not initialized first.
Returns
- The first slice is the starting chunk of data. This will never be empty.
- The second slice is the second contiguous chunk of data. This may or may not be empty depending if the buffer needed to wrap around to the beginning of its internal memory layout.
Performance
Prefer to use this to manipulate data in bulk over indexing one element at a time.
Example
use slice_ring_buf::SliceRbRef;
let mut data = [1u32, 2, 3, 4];
let mut rb = SliceRbRef::new(&mut data[..]);
let (s1, s2) = rb.as_slices(-4);
assert_eq!(s1, &[1, 2, 3, 4]);
assert_eq!(s2, &[]);
let (s1, s2) = rb.as_slices(3);
assert_eq!(s1, &[4]);
assert_eq!(s2, &[1, 2, 3]);
sourcepub fn as_slices_len(&self, start: isize, len: usize) -> (&[T], &[T])
pub fn as_slices_len(&self, start: isize, len: usize) -> (&[T], &[T])
Returns two slices of data in the ring buffer
starting at the index start
and with length len
.
start
- The starting indexlen
- The length of data to read. Iflen
is greater than the capacity of the ring buffer, then that capacity will be used instead.
Safety
- Using this may cause undefined behavior if the given data in
slice
inSliceRbRef::new()
was not initialized first.
Returns
- The first slice is the starting chunk of data.
- The second slice is the second contiguous chunk of data. This may or may not be empty depending if the buffer needed to wrap around to the beginning of its internal memory layout.
Performance
Prefer to use this to manipulate data in bulk over indexing one element at a time.
Example
use slice_ring_buf::SliceRbRef;
let mut data = [1u32, 2, 3, 4];
let mut rb = SliceRbRef::new(&mut data[..]);
let (s1, s2) = rb.as_slices_len(-4, 3);
assert_eq!(s1, &[1, 2, 3]);
assert_eq!(s2, &[]);
let (s1, s2) = rb.as_slices_len(3, 5);
assert_eq!(s1, &[4]);
assert_eq!(s2, &[1, 2, 3]);
sourcepub fn as_slices_latest(&self, start: isize, len: usize) -> (&[T], &[T])
pub fn as_slices_latest(&self, start: isize, len: usize) -> (&[T], &[T])
Returns two slices of data in the ring buffer
starting at the index start
and with length len
. If len
is greater
than the length of the ring buffer, then the buffer’s length will be used
instead, while still preserving the position of the last element.
start
- The starting indexlen
- The length of data to read. Iflen
is greater than the length of the ring buffer, then the buffer’s length will be used instead, while still preserving the position of the last element.
Safety
- Using this may cause undefined behavior if the given data in
slice
inSliceRbRef::new()
was not initialized first.
Returns
- The first slice is the starting chunk of data.
- The second slice is the second contiguous chunk of data. This may or may not be empty depending if the buffer needed to wrap around to the beginning of its internal memory layout.
Performance
Prefer to use this to manipulate data in bulk over indexing one element at a time.
Example
use slice_ring_buf::SliceRbRef;
let mut data = [1u32, 2, 3, 4];
let rb = SliceRbRef::new(&mut data[..]);
let (s1, s2) = rb.as_slices_latest(-4, 3);
assert_eq!(s1, &[1, 2, 3]);
assert_eq!(s2, &[]);
let (s1, s2) = rb.as_slices_latest(0, 5);
assert_eq!(s1, &[2, 3, 4]);
assert_eq!(s2, &[1]);
sourcepub fn as_mut_slices(&mut self, start: isize) -> (&mut [T], &mut [T])
pub fn as_mut_slices(&mut self, start: isize) -> (&mut [T], &mut [T])
Returns two mutable slices that contain all the data in the ring buffer
starting at the index start
.
Safety
- Using this may cause undefined behavior if the given data in
slice
inSliceRbRef::new()
was not initialized first.
Returns
- The first slice is the starting chunk of data. This will never be empty.
- The second slice is the second contiguous chunk of data. This may or may not be empty depending if the buffer needed to wrap around to the beginning of its internal memory layout.
Performance
Prefer to use this to manipulate data in bulk over indexing one element at a time.
Example
use slice_ring_buf::SliceRbRef;
let mut data = [1u32, 2, 3, 4];
let mut rb = SliceRbRef::new(&mut data[..]);
let (s1, s2) = rb.as_mut_slices(-4);
assert_eq!(s1, &mut [1, 2, 3, 4]);
assert_eq!(s2, &mut []);
let (s1, s2) = rb.as_mut_slices(3);
assert_eq!(s1, &mut [4]);
assert_eq!(s2, &mut [1, 2, 3]);
sourcepub fn as_mut_slices_len(
&mut self,
start: isize,
len: usize
) -> (&mut [T], &mut [T])
pub fn as_mut_slices_len( &mut self, start: isize, len: usize ) -> (&mut [T], &mut [T])
Returns two mutable slices of data in the ring buffer
starting at the index start
and with length len
.
start
- The starting indexlen
- The length of data to read. Iflen
is greater than the capacity of the ring buffer, then that capacity will be used instead.
Safety
- Using this may cause undefined behavior if the given data in
slice
inSliceRbRef::new()
was not initialized first.
Returns
- The first slice is the starting chunk of data.
- The second slice is the second contiguous chunk of data. This may or may not be empty depending if the buffer needed to wrap around to the beginning of its internal memory layout.
Performance
Prefer to use this to manipulate data in bulk over indexing one element at a time.
Example
use slice_ring_buf::SliceRbRef;
let mut data = [1u32, 2, 3, 4];
let mut rb = SliceRbRef::new(&mut data[..]);
let (s1, s2) = rb.as_mut_slices_len(-4, 3);
assert_eq!(s1, &mut [1, 2, 3]);
assert_eq!(s2, &mut []);
let (s1, s2) = rb.as_mut_slices_len(3, 5);
assert_eq!(s1, &mut [4]);
assert_eq!(s2, &mut [1, 2, 3]);
sourcepub fn as_mut_slices_latest(
&mut self,
start: isize,
len: usize
) -> (&mut [T], &mut [T])
pub fn as_mut_slices_latest( &mut self, start: isize, len: usize ) -> (&mut [T], &mut [T])
Returns two mutable slices of data in the ring buffer
starting at the index start
and with length len
. If len
is greater
than the length of the ring buffer, then the buffer’s length will be used
instead, while still preserving the position of the last element.
start
- The starting indexlen
- The length of data to read. Iflen
is greater than the length of the ring buffer, then the buffer’s length will be used instead, while still preserving the position of the last element.
Safety
- Using this may cause undefined behavior if the given data in
slice
inSliceRbRef::new()
was not initialized first.
Returns
- The first slice is the starting chunk of data.
- The second slice is the second contiguous chunk of data. This may or may not be empty depending if the buffer needed to wrap around to the beginning of its internal memory layout.
Performance
Prefer to use this to manipulate data in bulk over indexing one element at a time.
Example
use slice_ring_buf::SliceRbRef;
let mut data = [1u32, 2, 3, 4];
let mut rb = SliceRbRef::new(&mut data[..]);
let (s1, s2) = rb.as_mut_slices_latest(-4, 3);
assert_eq!(s1, &mut [1, 2, 3]);
assert_eq!(s2, &mut []);
let (s1, s2) = rb.as_mut_slices_latest(0, 5);
assert_eq!(s1, &mut [2, 3, 4]);
assert_eq!(s2, &mut [1]);
sourcepub fn read_into(&self, slice: &mut [T], start: isize)
pub fn read_into(&self, slice: &mut [T], start: isize)
Copies the data from the ring buffer starting from the index start
into the given slice. If the length of slice
is larger than the
capacity of the ring buffer, then the data will be reapeated until
the given slice is filled.
Safety
-
Using this may cause undefined behavior if the given data in
slice
inSliceRbRef::new()
was not initialized first. -
slice
- This slice to copy the data into. -
start
- The index of the ring buffer to start copying from.
Performance
Prefer to use this to manipulate data in bulk over indexing one element at a time.
Example
use slice_ring_buf::SliceRbRef;
let mut data = [1u32, 2, 3, 4];
let mut rb = SliceRbRef::new(&mut data[..]);
let mut read_buf = [0u32; 3];
rb.read_into(&mut read_buf[..], -3);
assert_eq!(read_buf, [2, 3, 4]);
let mut read_buf = [0u32; 9];
rb.read_into(&mut read_buf[..], 2);
assert_eq!(read_buf, [3, 4, 1, 2, 3, 4, 1, 2, 3]);
sourcepub fn write_latest(&mut self, slice: &[T], start: isize)
pub fn write_latest(&mut self, slice: &[T], start: isize)
Copies data from the given slice into the ring buffer starting from
the index start
.
Earlier data will not be copied if it will be overwritten by newer data, avoiding unecessary memcpy’s. The correct placement of the newer data will still be preserved.
slice
- This slice to copy data from.start
- The index of the ring buffer to start copying from.
Performance
Prefer to use this to manipulate data in bulk over indexing one element at a time.
Example
use slice_ring_buf::SliceRbRef;
let mut data = [0u32; 4];
let mut rb = SliceRbRef::new(&mut data[..]);
let input = [1u32, 2, 3];
rb.write_latest(&input[..], -3);
assert_eq!(rb[0], 0);
assert_eq!(rb[1], 1);
assert_eq!(rb[2], 2);
assert_eq!(rb[3], 3);
let input = [1u32, 2, 3, 4, 5, 6, 7, 8, 9];
rb.write_latest(&input[..], 2);
assert_eq!(rb[0], 7);
assert_eq!(rb[1], 8);
assert_eq!(rb[2], 9);
assert_eq!(rb[3], 6);
sourcepub fn write_latest_2(&mut self, first: &[T], second: &[T], start: isize)
pub fn write_latest_2(&mut self, first: &[T], second: &[T], start: isize)
Copies data from two given slices into the ring buffer starting from
the index start
. The first
slice will be copied first then second
will be copied next.
Earlier data will not be copied if it will be overwritten by newer data, avoiding unecessary memcpy’s. The correct placement of the newer data will still be preserved.
first
- This first slice to copy data from.second
- This second slice to copy data from.start
- The index of the ring buffer to start copying from.
Performance
Prefer to use this to manipulate data in bulk over indexing one element at a time.
Example
use slice_ring_buf::{SliceRB, SliceRbRef};
let mut input_rb = SliceRB::<u32>::from_len(4);
input_rb[0] = 1;
input_rb[1] = 2;
input_rb[2] = 3;
input_rb[3] = 4;
let mut output_data = [0u32; 4];
let mut output_rb = SliceRbRef::new(&mut output_data[..]);
// s1 == &[1, 2], s2 == &[]
let (s1, s2) = input_rb.as_slices_len(0, 2);
output_rb.write_latest_2(s1, s2, -3);
assert_eq!(output_rb[0], 0);
assert_eq!(output_rb[1], 1);
assert_eq!(output_rb[2], 2);
assert_eq!(output_rb[3], 0);
let mut output_data = [0u32; 2];
let mut output_rb = SliceRbRef::new(&mut output_data[..]);
// s1 == &[4], s2 == &[1, 2, 3]
let (s1, s2) = input_rb.as_slices_len(3, 4);
// rb[1] = 4 -> rb[0] = 1 -> rb[1] = 2 -> rb[0] = 3
output_rb.write_latest_2(s1, s2, 1);
assert_eq!(output_rb[0], 3);
assert_eq!(output_rb[1], 2);
sourcepub fn len(&self) -> usize
pub fn len(&self) -> usize
Returns the length of the ring buffer.
Example
use slice_ring_buf::SliceRbRef;
let mut data = [0u32; 4];
let mut rb = SliceRbRef::new(&mut data[..]);
assert_eq!(rb.len(), 4);
sourcepub fn constrain(&self, i: isize) -> isize
pub fn constrain(&self, i: isize) -> isize
Returns the actual index of the ring buffer from the given
i
index.
- First, a bounds check will be performed. If it is within bounds, then it is simply returned.
- If it is not in bounds, then performance will
be limited by the modulo (remainder) operation on an
isize
value.
Performance
Prefer to manipulate data in bulk with methods that return slices. If you
need to index multiple elements one at a time, prefer to use
SliceRbRef::at(&mut i)
over SliceRbRef[i]
to reduce the number of
modulo operations to perform.
Example
use slice_ring_buf::SliceRbRef;
let mut data = [0u32; 4];
let mut rb = SliceRbRef::new(&mut data[..]);
assert_eq!(rb.constrain(2), 2);
assert_eq!(rb.constrain(4), 0);
assert_eq!(rb.constrain(-3), 1);
assert_eq!(rb.constrain(7), 3);
sourcepub fn raw_data(&self) -> &[T]
pub fn raw_data(&self) -> &[T]
Returns all the data in the buffer. The starting index will
always be 0
.
Example
use slice_ring_buf::SliceRbRef;
let mut data = [1u32, 2, 3, 4];
let mut rb = SliceRbRef::new(&mut data[..]);
let raw_data = rb.raw_data();
assert_eq!(raw_data, &[1u32, 2, 3, 4]);
sourcepub fn raw_data_mut(&mut self) -> &mut [T]
pub fn raw_data_mut(&mut self) -> &mut [T]
Returns all the data in the buffer as mutable. The starting
index will always be 0
.
Example
use slice_ring_buf::SliceRbRef;
let mut data = [1u32, 2, 3, 4];
let mut rb = SliceRbRef::new(&mut data[..]);
let raw_data = rb.raw_data_mut();
assert_eq!(raw_data, &mut [1u32, 2, 3, 4]);
sourcepub fn raw_at(&self, i: usize) -> &T
pub fn raw_at(&self, i: usize) -> &T
Returns the element at the index of type usize
.
Please note this does NOT wrap around. This is equivalent to indexing a normal slice type.
Example
use slice_ring_buf::SliceRbRef;
let mut data = [1u32, 2, 3, 4];
let mut rb = SliceRbRef::new(&mut data[..]);
assert_eq!(*rb.raw_at(0), 1);
assert_eq!(*rb.raw_at(3), 4);
// These will panic!
// assert_eq!(*rb.raw_at(-3), 2);
// assert_eq!(*rb.raw_at(4), 1);
Panics
- This will panic if
i
is out of bounds of the internal slice.
sourcepub fn raw_at_mut(&mut self, i: usize) -> &mut T
pub fn raw_at_mut(&mut self, i: usize) -> &mut T
Returns the element at the index of type usize
as mutable.
Please note this does NOT wrap around. This is equivalent to indexing a normal slice type.
Example
use slice_ring_buf::SliceRbRef;
let mut data = [0u32; 4];
let mut rb = SliceRbRef::new(&mut data[..]);
*rb.raw_at_mut(0) = 1;
*rb.raw_at_mut(3) = 4;
assert_eq!(rb[0], 1);
assert_eq!(rb[3], 4);
// These will panic!
// *rb.raw_at_mut(-3) = 2;
// *rb.raw_at_mut(4) = 1;
Panics
- This will panic if
i
is out of bounds of the internal slice.
sourcepub fn at(&self, i: &mut isize) -> &T
pub fn at(&self, i: &mut isize) -> &T
Returns the element at the index of type usize
while also
constraining the index i
. This is more efficient
than calling both methods individually.
Performance
Prefer to manipulate data in bulk with methods that return slices. If you
need to index multiple elements one at a time, prefer to use
this over SliceRbRef[i]
to reduce the number of
modulo operations to perform.
Example
use slice_ring_buf::SliceRbRef;
let mut data = [1u32, 2, 3, 4];
let mut rb = SliceRbRef::new(&mut data[..]);
let mut i = -3;
assert_eq!(*rb.at(&mut i), 2);
assert_eq!(i, 1);
sourcepub fn at_mut(&mut self, i: &mut isize) -> &mut T
pub fn at_mut(&mut self, i: &mut isize) -> &mut T
Returns the element at the index of type usize
as mutable while also
constraining the index i
. This is more efficient
than calling both methods individually.
Performance
Prefer to manipulate data in bulk with methods that return slices. If you
need to index multiple elements one at a time, prefer to use
this over SliceRbRef[i]
to reduce the number of
modulo operations to perform.
Example
use slice_ring_buf::SliceRbRef;
let mut data = [0u32; 4];
let mut rb = SliceRbRef::new(&mut data[..]);
let mut i = -3;
*rb.at_mut(&mut i) = 2;
assert_eq!(rb[1], 2);
assert_eq!(i, 1);