[][src]Struct simple_ringbuf::RingBuffer

pub struct RingBuffer<T> { /* fields omitted */ }

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]

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]

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]

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]

impl<T> PartialEq<RingBuffer<T>> for RingBuffer<T> where
    T: PartialEq
[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]

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?

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?

impl<T> Debug for RingBuffer<T> where
    T: Debug
[src]

impl<T> Index<usize> for RingBuffer<T>[src]

type Output = T

The returned type after indexing.

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]

type Owned = T

The resulting type after obtaining ownership.

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

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

impl<I> IntoIterator for I where
    I: Iterator
[src]

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?

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.

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

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

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