[−][src]Struct simple_ringbuf::RingBuffer
A fixed-sized collection meant to hold a limited horizon of generic data. When filled to capacity, older data will be overwritten.
Indexing and iterating over this collection will start from the most recent
element (assuming you primarily use push
,
however all iterators implement ExactSizeIterator
and
DoubleEndedIterator
, so they can be trivially traversed backwards with
the rev
method.
Be aware that the Eq
and PartialEq
implementations for this struct do not care
about buffer rotation (where in the ring a sequence starts), but they do check if two
buffers have the same capacity. So two buffers with the sequence [1,2,3]
may not compare
as equal if one can hold 10 elements and one can hold 20. If you want to compare these, a
convenience method called elem_equal
is provided.
Methods
impl<T> RingBuffer<T>
[src]
pub fn cap(&self) -> usize
[src]
The capacity of the buffer, this is the most data this buffer can store before it starts overwriting older entries.
pub fn len(&self) -> usize
[src]
The length of the buffer. This is the number
of elements currently stores. When len
and cap
are equal, the buffer will begin overwriting older
entries.
pub fn new(cap: usize) -> Self
[src]
Creates a new RingBuffer
at the given capacity,
this buffer will not grow without explicit calls to
resize
.
pub fn from_exact_size_iter<I, U>(iter: I) -> Self where
I: IntoIterator<Item = T, IntoIter = U>,
U: ExactSizeIterator<Item = T>,
[src]
I: IntoIterator<Item = T, IntoIter = U>,
U: ExactSizeIterator<Item = T>,
Creates a new RingBuffer
that exactly fits
the data in the provided iterator. It must have an exact
size or we cannot intuit the capacity.
use simple_ringbuf::RingBuffer;; let buf = RingBuffer::from_exact_size_iter(vec![1,2,3]); assert!(buf.is_justified()); let mut cmp = RingBuffer::new(3); cmp.push(1); cmp.push(2); cmp.push(3); assert_eq!(buf, cmp);
pub fn from_iter_cap<I>(
iter: I,
cap: usize
) -> (Self, Option<impl Iterator<Item = T>>) where
I: IntoIterator<Item = T>,
[src]
iter: I,
cap: usize
) -> (Self, Option<impl Iterator<Item = T>>) where
I: IntoIterator<Item = T>,
Creates a new RingBuffer
with capacity cap
that fills itself with
at most cap
elements from the provided iterator. If any of the iterator is
left over at the end, an iterator yielding those elements will be returned.
use simple_ringbuf::RingBuffer;; let (buf, rem) = RingBuffer::from_iter_cap(vec![1,2,3], 2); assert!(buf.is_justified()); let mut cmp = RingBuffer::new(2); cmp.push(1); cmp.push(2); assert_eq!(buf, cmp); assert!(rem.is_some()); let rem = rem.unwrap(); assert_eq!(vec![3], rem.collect::<Vec<_>>());
pub fn push(&mut self, elem: T) -> Option<T>
[src]
Pushes an element onto the collection. This is intended to be the primary means of using this as a log/undo buffer.
If the buffer is full, this will overwrite the element at buf[len-1]
, which is the "oldest"
element if you generally use the collection as designed.
If this method overwrites an existing element it will return it, otherwise it will
return None
.
use simple_ringbuf::RingBuffer;; let mut buf = RingBuffer::new(3); buf.push(1); buf.push(2); buf.push(3); assert_eq!(buf[0], 3); assert_eq!(buf[1], 2); assert_eq!(buf[2], 1); let el = buf.push(10); assert_eq!(el, Some(1)); assert_eq!(buf[0], 10); assert_eq!(buf[1], 3); assert_eq!(buf[2], 2);
pub fn push_back(&mut self, elem: T) -> Option<T>
[src]
Pushes an element as if it were the first element added. If the buffer
is full, this will overwrite the element at buf[0]
, which is the most
recently added element (if you use the collection as designed defaulting to
push
in most cases).
This is not intended to be the primary method of adding data, but rather reinserting an element you've removed or otherwise rewinding history.
If this method overwrites an existing element, it will return it. Otherwise it will
return None
.
use simple_ringbuf::RingBuffer;; let mut buf = RingBuffer::new(3); buf.push(1); buf.push(2); buf.push(3); assert_eq!(buf[0], 3); assert_eq!(buf[1], 2); assert_eq!(buf[2], 1); let el = buf.push(10); assert!(el.is_some()); let el = el.unwrap(); let el = buf.push_back(el); assert_eq!(el, Some(10)); assert_eq!(buf[0], 3); assert_eq!(buf[1], 2); assert_eq!(buf[2], 1);
pub fn pop(&mut self) -> Option<T>
[src]
Removes the most recently added element from the collection and returns it, shrinking the buffer from the end.
Note that if you've been using push_back
this won't
be the most recently added element per se, but rather the element at
the end
of the collection (aka at buf[0]
).
use simple_ringbuf::RingBuffer; let mut buf = RingBuffer::new(5); buf.push(5); buf.push(10); buf.push(20); assert_eq!(buf.pop(), Some(20)); assert_eq!(buf.len(), 2);
pub fn pop_oldest(&mut self) -> Option<T>
[src]
Removes the oldest element from the collection and returns it, shrinking the buffer from the beginning.
Note that if you've been using push_back
this won't be the oldest
element per se, but rather the element at the [beginning
] (buf[len-1]
).
use simple_ringbuf::RingBuffer; let mut buf = RingBuffer::new(5); buf.push(5); buf.push(10); buf.push(20); assert_eq!(buf.pop_oldest(), Some(5)); assert_eq!(buf.len(), 2);
pub fn is_empty(&self) -> bool
[src]
Determines whether the buffer is empty.
pub fn is_full(&self) -> bool
[src]
Determines whether the buffer is filled to capacity, if this is true, any subsequent writes will overwrite the oldest element.
ⓘImportant traits for RingBufIter<'a, T>pub fn iter(&self) -> RingBufIter<T>
[src]
Returns an iterator over this buffer.
pub fn justify(&mut self)
[src]
Forces a buffer to be "justified".
This means the first element is at the beginning of
the actual underlying buffer. Once a buffer gets full, or if you frequently use pop_oldest
,
this will rarely be true.
Justifying a buffer is largely useful for internal operations such as resize
, but may
be useful if you require the elements to be in a contiguous memory block for some reason.
use simple_ringbuf::RingBuffer; let mut buf = RingBuffer::new(5); buf.push(19); buf.push(26); buf.push(113); assert!(buf.is_justified()); // Buf now has a gap buf.pop_oldest(); assert!( !buf.is_justified() ); buf.justify(); assert!(buf.is_justified());
pub fn is_contiguous(&self) -> bool
[src]
Determines if a buffer is "contiguous" if
the end of the buffer is after the beginning in
the internal memory layout. That is beginning
< end
.
This likely isn't useful in most cases, but if you want to do unsafe hacky things, or
make sure the buffer is contiguous before iterating for, e.g., cache reasons
you may decide to call this before deciding whether to call justify
. (This likely
won't have any appreciable effect on speed, especially while iterating in the default order).
An empty buffer is always contiguous.
pub fn beginning(&self) -> Option<usize>
[src]
Shows where in the internal buffer the current data begins,
not particularly useful but here for convenience. This will return
None
when the buffer is empty. Note that due to how indexing works,
this is buf[end]
, buf[0]
will yield the newest element added.
pub fn end(&self) -> Option<usize>
[src]
Shows where in the internal buffer the current data ends,
not particularly useful but here for convenience. This will return
None
when the buffer is empty. Note that due to how indexing works,
this is buf[0]
, buf[end]
will yield the oldest element added.
pub fn is_justified(&self) -> bool
[src]
Determines if the buffer is "justified",
this means the first element is at the beginning of
the actual underlying buffer. Once a buffer gets full, or if you frequently use pop_oldest
,
this will rarely be true.
An empty buffer is always justified.
use simple_ringbuf::RingBuffer; let mut buf = RingBuffer::new(5); buf.push(19); buf.push(26); buf.push(113); assert!(buf.is_justified()); buf.pop(); assert!(buf.is_justified()); // Buf now has a gap buf.pop_oldest(); assert!( !buf.is_justified() ); // Empty buffer buf.pop(); assert!(buf.is_justified());
This is largely useful for internal operations such as resize
.
If you really need to check for something that will aid, e.g., iteration
speed, or you want to do unsafe hacky things, is_contiguous
is probably
closer to what you want.
pub fn resize(&mut self, new_cap: usize)
[src]
Resizes the buffer such that it can hold more or fewer total elements. This will panic is the capacity underflows the current length.
The new buffer will be justified
.
use simple_ringbuf::RingBuffer; let mut buf = RingBuffer::new(5); buf.push(2); buf.push(3); buf.resize(2); assert_eq!(buf.cap(), 2); buf.pop_oldest(); buf.resize(9); assert_eq!(buf.cap(), 9); assert_eq!(buf.len(), 1); assert!(buf.is_justified());
pub fn shrink_to_fit(&mut self)
[src]
impl<T> RingBuffer<T> where
T: PartialEq,
[src]
T: PartialEq,
pub fn elem_equal(&self, other: &Self) -> bool
[src]
Performs an element-wise comparison between two different-capacity buffers.
If your buffers are the same size you probably just want ==
.
use simple_ringbuf::RingBuffer; let mut buf = RingBuffer::new(5); buf.push(1); buf.push(2); buf.push(3); let mut buf2 = RingBuffer::new(10); buf2.push(1); buf2.push(2); buf2.push(3); assert_ne!(buf, buf2); // Not the same! assert!(buf.elem_equal(&buf2)); // This works though
Trait Implementations
impl<T> Eq for RingBuffer<T> where
T: Eq,
[src]
T: Eq,
impl<T> PartialEq<RingBuffer<T>> for RingBuffer<T> where
T: PartialEq,
[src]
T: PartialEq,
fn eq(&self, other: &Self) -> bool
[src]
#[must_use]
fn ne(&self, other: &Rhs) -> bool
1.0.0[src]
This method tests for !=
.
impl<T> Clone for RingBuffer<T> where
T: Clone,
[src]
T: Clone,
fn clone(&self) -> Self
[src]
fn clone_from(&mut self, source: &Self)
1.0.0[src]
Performs copy-assignment from source
. Read more
impl<T> Drop for RingBuffer<T>
[src]
impl<'a, T> IntoIterator for &'a RingBuffer<T>
[src]
type Item = &'a T
The type of the elements being iterated over.
type IntoIter = RingBufIter<'a, T>
Which kind of iterator are we turning this into?
fn into_iter(self) -> Self::IntoIter
[src]
impl<T> IntoIterator for RingBuffer<T>
[src]
type Item = T
The type of the elements being iterated over.
type IntoIter = RingBufIntoIter<T>
Which kind of iterator are we turning this into?
fn into_iter(self) -> Self::IntoIter
[src]
impl<T> Debug for RingBuffer<T> where
T: Debug,
[src]
T: Debug,
impl<T> Index<usize> for RingBuffer<T>
[src]
Auto Trait Implementations
impl<T> !Send for RingBuffer<T>
impl<T> !Sync for RingBuffer<T>
Blanket Implementations
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, U> Into<U> for T where
U: From<T>,
[src]
U: From<T>,
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> BorrowMut<T> for T where
T: ?Sized,
[src]
T: ?Sized,
fn borrow_mut(&mut self) -> &mut T
[src]
impl<T> Borrow<T> for T where
T: ?Sized,
[src]
T: ?Sized,
impl<T> Any for T where
T: 'static + ?Sized,
[src]
T: 'static + ?Sized,