Struct Ring

Source
pub struct Ring { /* private fields */ }
Expand description

A low-level atomic ring-buffer building block.

This type implements logic for managing the two non-overlapping regions of a ring buffer mapped to linear storage. This is useful for implementing safe, higher-level queues such as nonblocking and asyncio.

Ring models two “regions”, named the left and right region, of a conceptual fixed-length ring array. Each region can advance itself, moving data at the start of the region to the end of the other region. This allows data in each region to be read and written independently, then fed to the other region without synchronization.

When a region is mapped to a linear array, which has a start and end index, it might end up in two “chunks” where it overlaps the edge of the array. Ring provides access to the indices of the first chunks in the left and right region, as well as logic to advance each region. It does not contain the buffer itself.

Implementations§

Source§

impl Ring

Source

pub fn new(capacity: usize) -> Self

Creates a ring with a specific capacity.

The ring starts with an empty left region and a right range from index 0 to the capacity.

Source

pub fn capacity(&self) -> usize

Gets the capacity of the ring.

Source

pub fn display( &self, width: usize, left_char: char, right_char: char, ) -> Display<'_>

Returns an object that implements Display with specific formatting. This is useful for debugging the stage of the ring.

§Example
use mini_io_queue::Ring;

let ring = Ring::new(16);
ring.advance_right(4);

let s = format!("{}", ring.display(16, 'L', 'R'));
assert_eq!(s, "LLLLRRRRRRRRRRRR");
Source

pub fn left_ranges(&self) -> (Range<usize>, Range<usize>)

Gets the range of indices in both chunks of the left region. Both or one range can be empty. The ranges will never overlap.

The function guarantees that the start index of both ranges will stay the same across calls, and the end index will only increase, until the range is invalidated.

This function also guarantees that the returned ranges will never overlap with a range returned by right_ranges, as long as the ranges are not invalidated.

The ranges are invalidated by advancing the region by calling advance_left or advance_left_unchecked. Any ranges read before advancing are effectively meaningless after advancing. Invalidated ranges must not be used to slice an underlying array, or you may end up with overlapping left and right slices.

Source

pub fn left_len(&self) -> usize

Gets the total length of the left region. This will always match the combined lengths of the slices returned by left_ranges. This will always be less than or equal to the ring’s capacity.

Source

pub fn advance_left(&self, len: usize)

Advances the left region, conceptually moving len elements at the start of the left region to the end of the right region and shrinking the left region as a result.

§Panics

Panics if len is larger than the current size of the left region.

Source

pub unsafe fn advance_left_unchecked(&self, len: usize)

Advances the left region, conceptually moving len elements at the start of the left region to the end of the right region and shrinking the left region as a result.

§Safety

len must be less than or equal to the length of the left region returned by left_len.

Source

pub fn right_ranges(&self) -> (Range<usize>, Range<usize>)

Gets the range of indices in the both chunks of the right region. Both or one range can be empty. The ranges will never overlap.

The function guarantees that the start index of both ranges will stay the same across calls, and the end index will only increase, until the range is invalidated.

This function also guarantees that the returned rangse will never overlap with a range returned by left_ranges, as long as the ranges are not invalidated.

The ranges are invalidated by advancing the region by calling advance_right or advance_right_unchecked. Any ranges read before advancing are effectively meaningless after advancing. Invalidated ranges must not be used to slice an underlying array, or you may end up with overlapping left and right slices.

Source

pub fn right_len(&self) -> usize

Gets the total length of the right region. This will always match the combined lengths of the slices returned by right_ranges. This will always be less than or equal to the ring’s capacity.

Source

pub fn advance_right(&self, len: usize)

Advances the right region, conceptually moving len elements at the start of the right region to the end of the left region and shrinking the right region as a result.

§Panics

Panics if len is larger than the current size of the right region.

Source

pub unsafe fn advance_right_unchecked(&self, len: usize)

Advances the right region, conceptually moving len elements at the start of the right region to the end of the left region and shrinking the right region as a result.

§Safety

len must be less than or equal to the length of the left region returned by right_len.

Trait Implementations§

Source§

impl Debug for Ring

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for Ring

Source§

fn default() -> Ring

Returns the “default value” for a type. Read more

Auto Trait Implementations§

§

impl !Freeze for Ring

§

impl RefUnwindSafe for Ring

§

impl Send for Ring

§

impl Sync for Ring

§

impl Unpin for Ring

§

impl UnwindSafe for Ring

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

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

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.