diff --git a/src/halves/cached.rs b/src/halves/cached.rs index 2f94b29..fb8c14f 100644 --- a/src/halves/cached.rs +++ b/src/halves/cached.rs @@ -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 { - frozen: FrozenProd, +/// Caching wrapper of ring buffer. +pub struct CachingWrap { + frozen: FrozenWrap, } -/// Caching consumer of ring buffer. -pub struct CachingCons { - frozen: FrozenCons, -} +pub type CachingProd = CachingWrap; +pub type CachingCons = CachingWrap; -impl CachingProd { +impl CachingWrap { /// # 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 ToRbRef for CachingProd { - type RbRef = R; - fn rb_ref(&self) -> &R { - self.frozen.rb_ref() - } - fn into_rb_ref(self) -> R { - self.frozen.into_rb_ref() - } -} -impl CachingCons { - /// # 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 { + self.frozen.observe() } } -impl ToRbRef for CachingCons { + +impl ToRbRef for CachingWrap { type RbRef = R; fn rb_ref(&self) -> &R { @@ -61,30 +41,7 @@ impl ToRbRef for CachingCons { } } -impl Observer for CachingProd { - type Item = ::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], &mut [MaybeUninit]) { - self.frozen.unsafe_slices(start, end) - } -} - -impl Observer for CachingCons { +impl Observer for CachingWrap { type Item = ::Item; #[inline] @@ -94,11 +51,16 @@ impl Observer for CachingCons { #[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() } @@ -175,16 +137,3 @@ where ::read(self, buf) } } - -impl Observe for CachingProd { - type Obs = Obs; - fn observe(&self) -> Self::Obs { - self.frozen.observe() - } -} -impl Observe for CachingCons { - type Obs = Obs; - fn observe(&self) -> Self::Obs { - self.frozen.observe() - } -} diff --git a/src/halves/direct.rs b/src/halves/direct.rs index 908a015..6338649 100644 --- a/src/halves/direct.rs +++ b/src/halves/direct.rs @@ -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 { +pub struct Wrap { rb: R, } + +/// Observer of ring buffer. +pub type Obs = Wrap; /// Producer of ring buffer. -pub struct Prod { - rb: R, -} +pub type Prod = Wrap; /// Consumer of ring buffer. -pub struct Cons { - rb: R, -} +pub type Cons = Wrap; -impl Obs { - pub fn new(rb: R) -> Self { - Self { rb } - } -} -impl Prod { - /// # Safety - /// - /// There must be no more than one consumer wrapper. - pub unsafe fn new(rb: R) -> Self { - Self { rb } +impl Clone for Obs { + fn clone(&self) -> Self { + Self { rb: self.rb.clone() } } } -impl Cons { + +impl Wrap { /// # 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 ToRbRef for Obs { - type RbRef = R; - fn rb_ref(&self) -> &R { - &self.rb - } - fn into_rb_ref(self) -> R { - self.rb - } -} -impl ToRbRef for Prod { - type RbRef = R; - fn rb_ref(&self) -> &R { - &self.rb - } - fn into_rb_ref(self) -> R { - self.rb + + pub fn observe(&self) -> Obs { + Obs { rb: self.rb.clone() } } } -impl ToRbRef for Cons { + +impl ToRbRef for Wrap { type RbRef = R; fn rb_ref(&self) -> &R { &self.rb @@ -69,7 +46,7 @@ impl ToRbRef for Cons { } } -impl Observer for Obs { +impl Observer for Wrap { type Item = ::Item; #[inline] @@ -85,49 +62,7 @@ impl Observer for Obs { self.rb().write_index() } #[inline] - unsafe fn unsafe_slices(&self, start: usize, end: usize) -> (&mut [MaybeUninit], &mut [core::mem::MaybeUninit]) { - self.rb().unsafe_slices(start, end) - } -} - -impl Observer for Prod { - type Item = ::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], &mut [core::mem::MaybeUninit]) { - self.rb().unsafe_slices(start, end) - } -} - -impl Observer for Cons { - type Item = ::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], &mut [core::mem::MaybeUninit]) { + unsafe fn unsafe_slices(&self, start: usize, end: usize) -> (&mut [MaybeUninit], &mut [MaybeUninit]) { self.rb().unsafe_slices(start, end) } } @@ -176,22 +111,3 @@ where ::read(self, buf) } } - -impl Observe for Obs { - type Obs = Self; - fn observe(&self) -> Self::Obs { - self.clone() - } -} -impl Observe for Prod { - type Obs = Obs; - fn observe(&self) -> Self::Obs { - Obs::new(self.rb.clone()) - } -} -impl Observe for Cons { - type Obs = Obs; - fn observe(&self) -> Self::Obs { - Obs::new(self.rb.clone()) - } -} diff --git a/src/halves/frozen.rs b/src/halves/frozen.rs index 83111ea..014c1a7 100644 --- a/src/halves/frozen.rs +++ b/src/halves/frozen.rs @@ -1,9 +1,9 @@ #![allow(dead_code)] -use super::direct::{Cons, Obs, Prod}; +use super::direct::Obs; use crate::{ rb::traits::{RbRef, ToRbRef}, - traits::{Consumer, Observe, Observer, Producer}, + traits::{Consumer, Observer, Producer}, }; use core::{ cell::Cell, @@ -15,11 +15,7 @@ use core::{ #[cfg(feature = "std")] use std::io; -/// Frozen read end of some ring buffer. -/// -/// A free space of removed items is not visible for an opposite write end until [`Self::commit`]/[`Self::sync`] is called or `Self` is dropped. -/// Items inserted by an opposite write end is not visible for `Self` until [`Self::sync`] is called. -pub struct FrozenCons { +pub struct FrozenWrap { rb: R, read: Cell, write: Cell, @@ -29,83 +25,15 @@ pub struct FrozenCons { /// /// Inserted items is not visible for an opposite write end until [`Self::commit`]/[`Self::sync`] is called or `Self` is dropped. /// A free space of items removed by an opposite write end is not visible for `Self` until [`Self::sync`] is called. -pub struct FrozenProd { - rb: R, - read: Cell, - write: Cell, -} - -impl Observer for FrozenCons { - type Item = ::Item; - - #[inline] - fn capacity(&self) -> NonZeroUsize { - self.rb().capacity() - } - - #[inline] - fn read_index(&self) -> usize { - self.read.get() - } - #[inline] - fn write_index(&self) -> usize { - self.write.get() - } - - unsafe fn unsafe_slices(&self, start: usize, end: usize) -> (&mut [MaybeUninit], &mut [MaybeUninit]) { - self.rb().unsafe_slices(start, end) - } -} - -impl Observer for FrozenProd { - type Item = ::Item; - - #[inline] - fn capacity(&self) -> NonZeroUsize { - self.rb().capacity() - } +pub type FrozenProd = FrozenWrap; - #[inline] - fn read_index(&self) -> usize { - self.read.get() - } - #[inline] - fn write_index(&self) -> usize { - self.write.get() - } - - unsafe fn unsafe_slices(&self, start: usize, end: usize) -> (&mut [MaybeUninit], &mut [MaybeUninit]) { - self.rb().unsafe_slices(start, end) - } -} - -impl Consumer for FrozenCons { - #[inline] - unsafe fn set_read_index(&self, value: usize) { - self.read.set(value); - } -} - -impl Producer for FrozenProd { - #[inline] - unsafe fn set_write_index(&self, value: usize) { - self.write.set(value); - } -} - -impl Drop for FrozenCons { - fn drop(&mut self) { - self.commit(); - } -} - -impl Drop for FrozenProd { - fn drop(&mut self) { - self.commit(); - } -} +/// Frozen read end of some ring buffer. +/// +/// A free space of removed items is not visible for an opposite write end until [`Self::commit`]/[`Self::sync`] is called or `Self` is dropped. +/// Items inserted by an opposite write end is not visible for `Self` until [`Self::sync`] is called. +pub type FrozenCons = FrozenWrap; -impl FrozenCons { +impl FrozenWrap { /// Create new ring buffer cache. /// /// # Safety @@ -118,26 +46,13 @@ impl FrozenCons { rb, } } - /// Commit and destroy `Self` returning underlying consumer. - pub fn release(self) -> Cons { - unsafe { Cons::new(self.into_rb_ref()) } - } - /// Commit changes to the ring buffer. - pub fn commit(&self) { - unsafe { self.rb().set_read_index(self.read.get()) } - } - /// Fetch changes from the ring buffer. - pub fn fetch(&self) { - self.write.set(self.rb().write_index()); - } - /// Commit changes to and fetch updates from the ring buffer. - pub fn sync(&self) { - self.commit(); - self.fetch(); + pub fn observe(&self) -> Obs { + unsafe { Obs::new(self.rb.clone()) } } } -impl ToRbRef for FrozenCons { + +impl ToRbRef for FrozenWrap { type RbRef = R; fn rb_ref(&self) -> &R { @@ -150,38 +65,37 @@ impl ToRbRef for FrozenCons { } } -impl FrozenProd { - /// Create new ring buffer cache. - /// - /// # Safety - /// - /// There must be only one instance containing the same ring buffer reference. - pub unsafe fn new(rb: R) -> Self { - Self { - read: Cell::new(rb.deref().read_index()), - write: Cell::new(rb.deref().write_index()), - rb, - } - } - /// Commit and destroy `Self` returning underlying producer. - pub fn release(self) -> Prod { - unsafe { Prod::new(self.into_rb_ref()) } - } - +impl FrozenWrap { /// Commit changes to the ring buffer. pub fn commit(&self) { - unsafe { self.rb().set_write_index(self.write.get()) } + unsafe { + if P { + self.rb().set_write_index(self.write.get()); + } + if C { + self.rb().set_read_index(self.read.get()); + } + } } + /// Fetch changes from the ring buffer. pub fn fetch(&self) { - self.read.set(self.rb().read_index()); + if P { + self.read.set(self.rb().read_index()); + } + if C { + self.write.set(self.rb().write_index()); + } } + /// Commit changes to and fetch updates from the ring buffer. pub fn sync(&self) { self.commit(); self.fetch(); } +} +impl FrozenProd { /// Discard new items pushed since last sync. pub fn discard(&mut self) { let last_tail = self.rb().write_index(); @@ -192,16 +106,46 @@ impl FrozenProd { self.write.set(last_tail); } } -impl ToRbRef for FrozenProd { - type RbRef = R; - fn rb_ref(&self) -> &R { - &self.rb +impl Observer for FrozenWrap { + type Item = ::Item; + + #[inline] + fn capacity(&self) -> NonZeroUsize { + self.rb().capacity() } - fn into_rb_ref(self) -> R { + + #[inline] + fn read_index(&self) -> usize { + self.read.get() + } + #[inline] + fn write_index(&self) -> usize { + self.write.get() + } + + unsafe fn unsafe_slices(&self, start: usize, end: usize) -> (&mut [MaybeUninit], &mut [MaybeUninit]) { + self.rb().unsafe_slices(start, end) + } +} + +impl Producer for FrozenProd { + #[inline] + unsafe fn set_write_index(&self, value: usize) { + self.write.set(value); + } +} + +impl Consumer for FrozenCons { + #[inline] + unsafe fn set_read_index(&self, value: usize) { + self.read.set(value); + } +} + +impl Drop for FrozenWrap { + fn drop(&mut self) { self.commit(); - let this = ManuallyDrop::new(self); - unsafe { ptr::read(&this.rb) } } } @@ -236,16 +180,3 @@ where ::read(self, buf) } } - -impl Observe for FrozenCons { - type Obs = Obs; - fn observe(&self) -> Self::Obs { - Obs::new(self.rb.clone()) - } -} -impl Observe for FrozenProd { - type Obs = Obs; - fn observe(&self) -> Self::Obs { - Obs::new(self.rb.clone()) - } -} diff --git a/src/tests/basic.rs b/src/tests/basic.rs index dfe6520..9f19cb1 100644 --- a/src/tests/basic.rs +++ b/src/tests/basic.rs @@ -1,8 +1,5 @@ use super::Rb; -use crate::{ - storage::Static, - traits::{observer::Observe, *}, -}; +use crate::{storage::Static, traits::*}; fn indices(this: impl Observer) -> (usize, usize) { (this.read_index(), this.write_index()) diff --git a/src/traits/mod.rs b/src/traits/mod.rs index f743399..0398c8c 100644 --- a/src/traits/mod.rs +++ b/src/traits/mod.rs @@ -6,7 +6,7 @@ mod split; mod utils; pub use consumer::Consumer; -pub use observer::{Observe, Observer}; +pub use observer::Observer; pub use producer::Producer; pub use ring_buffer::RingBuffer; pub use split::{Split, SplitRef}; diff --git a/src/traits/observer.rs b/src/traits/observer.rs index 18723e7..56742fe 100644 --- a/src/traits/observer.rs +++ b/src/traits/observer.rs @@ -46,8 +46,3 @@ pub trait Observer: Sized { self.vacant_len() == 0 } } - -pub trait Observe { - type Obs: Observer; - fn observe(&self) -> Self::Obs; -}