Skip to content

Commit

Permalink
Unify Obs, Prod and Cons as generic wrapper
Browse files Browse the repository at this point in the history
  • Loading branch information
agerasev committed Aug 17, 2023
1 parent 451dc85 commit 31339ae
Show file tree
Hide file tree
Showing 6 changed files with 113 additions and 325 deletions.
93 changes: 21 additions & 72 deletions src/halves/cached.rs
Original file line number Diff line number Diff line change
@@ -1,56 +1,36 @@
use super::{
direct::Obs,
frozen::{FrozenCons, FrozenProd},
};
use super::{direct::Obs, frozen::FrozenWrap};
use crate::{
rb::traits::{RbRef, ToRbRef},
traits::{Consumer, Observe, Observer, Producer},
traits::{Consumer, Observer, Producer},
};
use core::{fmt, mem::MaybeUninit, num::NonZeroUsize};
#[cfg(feature = "std")]
use std::io;

/// Caching producer of ring buffer.
pub struct CachingProd<R: RbRef> {
frozen: FrozenProd<R>,
/// Caching wrapper of ring buffer.
pub struct CachingWrap<R: RbRef, const P: bool, const C: bool> {
frozen: FrozenWrap<R, P, C>,
}

/// Caching consumer of ring buffer.
pub struct CachingCons<R: RbRef> {
frozen: FrozenCons<R>,
}
pub type CachingProd<R> = CachingWrap<R, true, false>;
pub type CachingCons<R> = CachingWrap<R, false, true>;

impl<R: RbRef> CachingProd<R> {
impl<R: RbRef, const P: bool, const C: bool> CachingWrap<R, P, C> {
/// # Safety
///
/// There must be no more than one consumer wrapper.
pub unsafe fn new(ref_: R) -> Self {
pub unsafe fn new(rb: R) -> Self {
Self {
frozen: FrozenProd::new(ref_),
frozen: FrozenWrap::new(rb),
}
}
}
impl<R: RbRef> ToRbRef for CachingProd<R> {
type RbRef = R;

fn rb_ref(&self) -> &R {
self.frozen.rb_ref()
}
fn into_rb_ref(self) -> R {
self.frozen.into_rb_ref()
}
}
impl<R: RbRef> CachingCons<R> {
/// # Safety
///
/// There must be no more than one consumer wrapper.
pub unsafe fn new(ref_: R) -> Self {
Self {
frozen: FrozenCons::new(ref_),
}
pub fn observe(&self) -> Obs<R> {
self.frozen.observe()
}
}
impl<R: RbRef> ToRbRef for CachingCons<R> {

impl<R: RbRef, const P: bool, const C: bool> ToRbRef for CachingWrap<R, P, C> {
type RbRef = R;

fn rb_ref(&self) -> &R {
Expand All @@ -61,30 +41,7 @@ impl<R: RbRef> ToRbRef for CachingCons<R> {
}
}

impl<R: RbRef> Observer for CachingProd<R> {
type Item = <R::Target as Observer>::Item;

#[inline]
fn capacity(&self) -> NonZeroUsize {
self.frozen.capacity()
}

#[inline]
fn read_index(&self) -> usize {
self.frozen.fetch();
self.frozen.read_index()
}
#[inline]
fn write_index(&self) -> usize {
self.frozen.write_index()
}

unsafe fn unsafe_slices(&self, start: usize, end: usize) -> (&mut [MaybeUninit<Self::Item>], &mut [MaybeUninit<Self::Item>]) {
self.frozen.unsafe_slices(start, end)
}
}

impl<R: RbRef> Observer for CachingCons<R> {
impl<R: RbRef, const P: bool, const C: bool> Observer for CachingWrap<R, P, C> {
type Item = <R::Target as Observer>::Item;

#[inline]
Expand All @@ -94,11 +51,16 @@ impl<R: RbRef> Observer for CachingCons<R> {

#[inline]
fn read_index(&self) -> usize {
if P {
self.frozen.fetch();
}
self.frozen.read_index()
}
#[inline]
fn write_index(&self) -> usize {
self.frozen.fetch();
if C {
self.frozen.fetch();
}
self.frozen.write_index()
}

Expand Down Expand Up @@ -175,16 +137,3 @@ where
<Self as Consumer>::read(self, buf)
}
}

impl<R: RbRef> Observe for CachingProd<R> {
type Obs = Obs<R>;
fn observe(&self) -> Self::Obs {
self.frozen.observe()
}
}
impl<R: RbRef> Observe for CachingCons<R> {
type Obs = Obs<R>;
fn observe(&self) -> Self::Obs {
self.frozen.observe()
}
}
124 changes: 20 additions & 104 deletions src/halves/direct.rs
Original file line number Diff line number Diff line change
@@ -1,65 +1,42 @@
use crate::{
rb::traits::{RbRef, ToRbRef},
traits::{consumer::Consumer, observer::Observe, producer::Producer, Observer},
traits::{consumer::Consumer, producer::Producer, Observer},
};
use core::{fmt, mem::MaybeUninit, num::NonZeroUsize};
#[cfg(feature = "std")]
use std::io;

/// Observer of ring buffer.
#[derive(Clone)]
pub struct Obs<R: RbRef> {
pub struct Wrap<R: RbRef, const P: bool, const C: bool> {
rb: R,
}

/// Observer of ring buffer.
pub type Obs<R> = Wrap<R, false, false>;
/// Producer of ring buffer.
pub struct Prod<R: RbRef> {
rb: R,
}
pub type Prod<R> = Wrap<R, true, false>;
/// Consumer of ring buffer.
pub struct Cons<R: RbRef> {
rb: R,
}
pub type Cons<R> = Wrap<R, false, true>;

impl<R: RbRef> Obs<R> {
pub fn new(rb: R) -> Self {
Self { rb }
}
}
impl<R: RbRef> Prod<R> {
/// # Safety
///
/// There must be no more than one consumer wrapper.
pub unsafe fn new(rb: R) -> Self {
Self { rb }
impl<R: RbRef> Clone for Obs<R> {
fn clone(&self) -> Self {
Self { rb: self.rb.clone() }
}
}
impl<R: RbRef> Cons<R> {

impl<R: RbRef, const P: bool, const C: bool> Wrap<R, P, C> {
/// # Safety
///
/// There must be no more than one consumer wrapper.
/// There must be no more than one wrapper with the same parameter being `true`.
pub unsafe fn new(rb: R) -> Self {
Self { rb }
}
}
impl<R: RbRef> ToRbRef for Obs<R> {
type RbRef = R;
fn rb_ref(&self) -> &R {
&self.rb
}
fn into_rb_ref(self) -> R {
self.rb
}
}
impl<R: RbRef> ToRbRef for Prod<R> {
type RbRef = R;
fn rb_ref(&self) -> &R {
&self.rb
}
fn into_rb_ref(self) -> R {
self.rb

pub fn observe(&self) -> Obs<R> {
Obs { rb: self.rb.clone() }
}
}
impl<R: RbRef> ToRbRef for Cons<R> {

impl<R: RbRef, const P: bool, const C: bool> ToRbRef for Wrap<R, P, C> {
type RbRef = R;
fn rb_ref(&self) -> &R {
&self.rb
Expand All @@ -69,7 +46,7 @@ impl<R: RbRef> ToRbRef for Cons<R> {
}
}

impl<R: RbRef> Observer for Obs<R> {
impl<R: RbRef, const P: bool, const C: bool> Observer for Wrap<R, P, C> {
type Item = <R::Target as Observer>::Item;

#[inline]
Expand All @@ -85,49 +62,7 @@ impl<R: RbRef> Observer for Obs<R> {
self.rb().write_index()
}
#[inline]
unsafe fn unsafe_slices(&self, start: usize, end: usize) -> (&mut [MaybeUninit<Self::Item>], &mut [core::mem::MaybeUninit<Self::Item>]) {
self.rb().unsafe_slices(start, end)
}
}

impl<R: RbRef> Observer for Prod<R> {
type Item = <R::Target as Observer>::Item;

#[inline]
fn capacity(&self) -> NonZeroUsize {
self.rb().capacity()
}
#[inline]
fn read_index(&self) -> usize {
self.rb().read_index()
}
#[inline]
fn write_index(&self) -> usize {
self.rb().write_index()
}
#[inline]
unsafe fn unsafe_slices(&self, start: usize, end: usize) -> (&mut [MaybeUninit<Self::Item>], &mut [core::mem::MaybeUninit<Self::Item>]) {
self.rb().unsafe_slices(start, end)
}
}

impl<R: RbRef> Observer for Cons<R> {
type Item = <R::Target as Observer>::Item;

#[inline]
fn capacity(&self) -> NonZeroUsize {
self.rb().capacity()
}
#[inline]
fn read_index(&self) -> usize {
self.rb().read_index()
}
#[inline]
fn write_index(&self) -> usize {
self.rb().write_index()
}
#[inline]
unsafe fn unsafe_slices(&self, start: usize, end: usize) -> (&mut [MaybeUninit<Self::Item>], &mut [core::mem::MaybeUninit<Self::Item>]) {
unsafe fn unsafe_slices(&self, start: usize, end: usize) -> (&mut [MaybeUninit<Self::Item>], &mut [MaybeUninit<Self::Item>]) {
self.rb().unsafe_slices(start, end)
}
}
Expand Down Expand Up @@ -176,22 +111,3 @@ where
<Self as Consumer>::read(self, buf)
}
}

impl<R: RbRef> Observe for Obs<R> {
type Obs = Self;
fn observe(&self) -> Self::Obs {
self.clone()
}
}
impl<R: RbRef> Observe for Prod<R> {
type Obs = Obs<R>;
fn observe(&self) -> Self::Obs {
Obs::new(self.rb.clone())
}
}
impl<R: RbRef> Observe for Cons<R> {
type Obs = Obs<R>;
fn observe(&self) -> Self::Obs {
Obs::new(self.rb.clone())
}
}
Loading

0 comments on commit 31339ae

Please sign in to comment.