use std::alloc::LayoutError;
use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::{Arc, RwLock, RwLockReadGuard, RwLockWriteGuard};
pub struct Buffer<T: Clone + Default + Send + Sync> {
inner: Arc<BufferInner<T>>,
}
struct BufferInner<T: Clone + Default + Send + Sync> {
data: RwLock<Box<[T]>>,
reference: AtomicUsize,
}
impl<T: Clone + Default + Send + Sync> Buffer<T> {
pub fn new(len: usize) -> Self {
Self {
inner: Arc::new(BufferInner {
data: RwLock::new(vec![T::default(); len].into_boxed_slice()),
reference: AtomicUsize::new(1),
}),
}
}
pub fn from_slice(slice: &[T]) -> Self {
Self {
inner: Arc::new(BufferInner {
data: RwLock::new(slice.to_vec().into_boxed_slice()),
reference: AtomicUsize::new(1),
}),
}
}
pub fn read(&self) -> BufferReadGuard<'_, T> {
BufferReadGuard {
guard: self.inner.data.read().unwrap(),
}
}
pub fn try_read(&self) -> Option<BufferReadGuard<'_, T>> {
self.inner
.data
.try_read()
.ok()
.map(|guard| BufferReadGuard { guard })
}
pub fn write(&self) -> BufferWriteGuard<'_, T> {
BufferWriteGuard {
guard: self.inner.data.write().unwrap(),
}
}
pub fn try_write(&self) -> Option<BufferWriteGuard<'_, T>> {
self.inner
.data
.try_write()
.ok()
.map(|guard| BufferWriteGuard { guard })
}
pub fn resize(&self, len: usize) {
let mut guard = self.inner.data.write().unwrap();
*guard = vec![T::default(); len].into_boxed_slice();
}
pub fn len(&self) -> usize {
self.inner.data.read().unwrap().len()
}
pub fn is_empty(&self) -> bool {
self.len() == 0
}
pub fn ref_count(&self) -> usize {
self.inner.reference.load(Ordering::Acquire)
}
}
pub struct BufferReadGuard<'a, T: Clone + Default + Send + Sync> {
guard: RwLockReadGuard<'a, Box<[T]>>,
}
impl<'a, T: Clone + Default + Send + Sync> std::ops::Deref for BufferReadGuard<'a, T> {
type Target = [T];
fn deref(&self) -> &Self::Target {
&self.guard
}
}
impl<'a, T: Clone + Default + Send + Sync> BufferReadGuard<'a, T> {
pub fn len(&self) -> usize {
self.guard.len()
}
pub fn is_empty(&self) -> bool {
self.guard.is_empty()
}
}
pub struct BufferWriteGuard<'a, T: Clone + Default + Send + Sync> {
guard: RwLockWriteGuard<'a, Box<[T]>>,
}
impl<'a, T: Clone + Default + Send + Sync> std::ops::Deref for BufferWriteGuard<'a, T> {
type Target = [T];
fn deref(&self) -> &Self::Target {
&self.guard
}
}
impl<'a, T: Clone + Default + Send + Sync> std::ops::DerefMut for BufferWriteGuard<'a, T> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.guard
}
}
impl<'a, T: Clone + Default + Send + Sync> BufferWriteGuard<'a, T> {
pub fn len(&self) -> usize {
self.guard.len()
}
pub fn is_empty(&self) -> bool {
self.guard.is_empty()
}
}
impl<T: Clone + Default + Send + Sync> Clone for Buffer<T> {
fn clone(&self) -> Self {
self.inner.reference.fetch_add(1, Ordering::AcqRel);
Self {
inner: Arc::clone(&self.inner),
}
}
}
impl<T: Clone + Default + Send + Sync> Drop for Buffer<T> {
fn drop(&mut self) {
self.inner.reference.fetch_sub(1, Ordering::AcqRel);
}
}
unsafe impl<T: Clone + Default + Send + Sync> Send for Buffer<T> {}
unsafe impl<T: Clone + Default + Send + Sync> Sync for Buffer<T> {}
impl<T: Clone + Default + Send + Sync> Default for Buffer<T> {
fn default() -> Self {
Self::new(0)
}
}
pub struct PushBuffer<T: Copy + Default + Send + Sync> {
inner: Arc<PushBufferInner<T>>,
}
struct PushBufferInner<T: Copy + Default + Send + Sync> {
data: RwLock<PushBufferData<T>>,
}
struct PushBufferData<T: Copy + Default> {
buffer: Box<[T]>,
index: usize,
}
impl<T: Copy + Default + Send + Sync> PushBuffer<T> {
pub fn new(len: usize) -> Result<Self, LayoutError> {
Ok(Self {
inner: Arc::new(PushBufferInner {
data: RwLock::new(PushBufferData {
buffer: vec![T::default(); len].into_boxed_slice(),
index: 0,
}),
}),
})
}
pub fn from_slice(slice: &[T]) -> Self {
Self {
inner: Arc::new(PushBufferInner {
data: RwLock::new(PushBufferData {
buffer: slice.to_vec().into_boxed_slice(),
index: 0,
}),
}),
}
}
pub fn read(&self) -> PushBufferReadGuard<'_, T> {
PushBufferReadGuard {
guard: self.inner.data.read().unwrap(),
}
}
pub fn try_read(&self) -> Option<PushBufferReadGuard<'_, T>> {
self.inner
.data
.try_read()
.ok()
.map(|guard| PushBufferReadGuard { guard })
}
pub fn write(&self) -> PushBufferWriteGuard<'_, T> {
PushBufferWriteGuard {
guard: self.inner.data.write().unwrap(),
}
}
pub fn try_write(&self) -> Option<PushBufferWriteGuard<'_, T>> {
self.inner
.data
.try_write()
.ok()
.map(|guard| PushBufferWriteGuard { guard })
}
pub fn resize(&self, len: usize) -> Result<(), LayoutError> {
let mut guard = self.inner.data.write().unwrap();
guard.buffer = vec![T::default(); len].into_boxed_slice();
guard.index = 0;
Ok(())
}
pub fn push(&self, value: T) {
let mut guard = self.inner.data.write().unwrap();
let len = guard.buffer.len();
if len == 0 {
return;
}
if guard.index < len {
let idx = guard.index;
guard.buffer[idx] = value;
guard.index += 1;
} else {
guard.buffer.copy_within(1..len, 0);
guard.buffer[len - 1] = value;
}
}
pub fn get_index(&self) -> usize {
self.inner.data.read().unwrap().index
}
pub fn set_index(&self, index: usize) {
let mut guard = self.inner.data.write().unwrap();
guard.index = index.min(guard.buffer.len());
}
pub fn len(&self) -> usize {
self.inner.data.read().unwrap().buffer.len()
}
pub fn is_empty(&self) -> bool {
self.len() == 0
}
}
pub struct PushBufferReadGuard<'a, T: Copy + Default + Send + Sync> {
guard: RwLockReadGuard<'a, PushBufferData<T>>,
}
impl<'a, T: Copy + Default + Send + Sync> PushBufferReadGuard<'a, T> {
pub fn len(&self) -> usize {
self.guard.buffer.len()
}
pub fn is_empty(&self) -> bool {
self.guard.buffer.is_empty()
}
pub fn get_index(&self) -> usize {
self.guard.index
}
}
impl<'a, T: Copy + Default + Send + Sync> std::ops::Deref for PushBufferReadGuard<'a, T> {
type Target = [T];
fn deref(&self) -> &Self::Target {
&self.guard.buffer
}
}
impl<'a, T: Copy + Default + Send + Sync> std::ops::Index<usize> for PushBufferReadGuard<'a, T> {
type Output = T;
fn index(&self, index: usize) -> &Self::Output {
&self.guard.buffer[index]
}
}
pub struct PushBufferWriteGuard<'a, T: Copy + Default + Send + Sync> {
guard: RwLockWriteGuard<'a, PushBufferData<T>>,
}
impl<'a, T: Copy + Default + Send + Sync> PushBufferWriteGuard<'a, T> {
pub fn len(&self) -> usize {
self.guard.buffer.len()
}
pub fn is_empty(&self) -> bool {
self.guard.buffer.is_empty()
}
pub fn get_index(&self) -> usize {
self.guard.index
}
pub fn push(&mut self, value: T) {
let len = self.guard.buffer.len();
if len == 0 {
return;
}
if self.guard.index < len {
let idx = self.guard.index;
self.guard.buffer[idx] = value;
self.guard.index += 1;
} else {
self.guard.buffer.copy_within(1..len, 0);
self.guard.buffer[len - 1] = value;
}
}
}
impl<'a, T: Copy + Default + Send + Sync> std::ops::Deref for PushBufferWriteGuard<'a, T> {
type Target = [T];
fn deref(&self) -> &Self::Target {
&self.guard.buffer
}
}
impl<'a, T: Copy + Default + Send + Sync> std::ops::DerefMut for PushBufferWriteGuard<'a, T> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.guard.buffer
}
}
impl<'a, T: Copy + Default + Send + Sync> std::ops::Index<usize> for PushBufferWriteGuard<'a, T> {
type Output = T;
fn index(&self, index: usize) -> &Self::Output {
&self.guard.buffer[index]
}
}
impl<'a, T: Copy + Default + Send + Sync> std::ops::IndexMut<usize>
for PushBufferWriteGuard<'a, T>
{
fn index_mut(&mut self, index: usize) -> &mut Self::Output {
&mut self.guard.buffer[index]
}
}
impl<T: Copy + Default + Send + Sync> Clone for PushBuffer<T> {
fn clone(&self) -> Self {
Self {
inner: Arc::clone(&self.inner),
}
}
}
unsafe impl<T: Copy + Default + Send + Sync> Send for PushBuffer<T> {}
unsafe impl<T: Copy + Default + Send + Sync> Sync for PushBuffer<T> {}
pub struct CircularBuffer<T: Copy + Default + Send + Sync> {
inner: Arc<CircularBufferInner<T>>,
}
struct CircularBufferInner<T: Copy + Default + Send + Sync> {
data: RwLock<CircularBufferData<T>>,
}
struct CircularBufferData<T: Copy + Default> {
buffer: Box<[T]>,
read: usize,
write: usize,
mask: usize, }
impl<T: Copy + Default + Send + Sync> CircularBuffer<T> {
pub fn new(len: usize) -> Result<Self, LayoutError> {
let actual_len = len.next_power_of_two().max(1);
Ok(Self {
inner: Arc::new(CircularBufferInner {
data: RwLock::new(CircularBufferData {
buffer: vec![T::default(); actual_len].into_boxed_slice(),
read: 0,
write: 0,
mask: actual_len - 1,
}),
}),
})
}
pub fn from_slice(slice: &[T]) -> Self {
let len = slice.len().next_power_of_two().max(1);
let mut buffer = vec![T::default(); len];
buffer[..slice.len()].copy_from_slice(slice);
Self {
inner: Arc::new(CircularBufferInner {
data: RwLock::new(CircularBufferData {
buffer: buffer.into_boxed_slice(),
read: 0,
write: slice.len() & (len - 1),
mask: len - 1,
}),
}),
}
}
pub fn read(&self) -> CircularBufferReadGuard<'_, T> {
CircularBufferReadGuard {
guard: self.inner.data.read().unwrap(),
}
}
pub fn try_read(&self) -> Option<CircularBufferReadGuard<'_, T>> {
self.inner
.data
.try_read()
.ok()
.map(|guard| CircularBufferReadGuard { guard })
}
pub fn write(&self) -> CircularBufferWriteGuard<'_, T> {
CircularBufferWriteGuard {
guard: self.inner.data.write().unwrap(),
}
}
pub fn try_write(&self) -> Option<CircularBufferWriteGuard<'_, T>> {
self.inner
.data
.try_write()
.ok()
.map(|guard| CircularBufferWriteGuard { guard })
}
pub fn resize(&self, len: usize) -> Result<(), LayoutError> {
let actual_len = len.next_power_of_two().max(1);
let mut guard = self.inner.data.write().unwrap();
guard.buffer = vec![T::default(); actual_len].into_boxed_slice();
guard.read = 0;
guard.write = 0;
guard.mask = actual_len - 1;
Ok(())
}
pub fn push(&self, value: T) {
let mut guard = self.inner.data.write().unwrap();
let idx = guard.write;
guard.buffer[idx] = value;
guard.write = (guard.write + 1) & guard.mask;
}
pub fn next(&self) -> T {
let mut guard = self.inner.data.write().unwrap();
let value = guard.buffer[guard.read];
guard.read = (guard.read + 1) & guard.mask;
value
}
pub fn peek(&self) -> T {
let guard = self.inner.data.read().unwrap();
guard.buffer[guard.read]
}
pub fn capacity(&self) -> usize {
self.inner.data.read().unwrap().buffer.len()
}
pub fn len(&self) -> usize {
self.inner.data.read().unwrap().mask + 1
}
pub fn is_empty(&self) -> bool {
self.capacity() == 0
}
pub fn clear(&self) {
let mut guard = self.inner.data.write().unwrap();
guard.buffer.fill(T::default());
guard.read = 0;
guard.write = 0;
}
}
pub struct CircularBufferReadGuard<'a, T: Copy + Default + Send + Sync> {
guard: RwLockReadGuard<'a, CircularBufferData<T>>,
}
impl<'a, T: Copy + Default + Send + Sync> CircularBufferReadGuard<'a, T> {
pub fn len(&self) -> usize {
self.guard.mask + 1
}
pub fn is_empty(&self) -> bool {
self.len() == 0
}
pub fn capacity(&self) -> usize {
self.guard.buffer.len()
}
pub fn get_read(&self) -> usize {
self.guard.read
}
pub fn get_write(&self) -> usize {
self.guard.write
}
pub fn peek(&self) -> T {
self.guard.buffer[self.guard.read]
}
pub fn read_offset(&self, offset: usize) -> T {
self.guard.buffer[(self.guard.read + offset) & self.guard.mask]
}
}
impl<'a, T: Copy + Default + Send + Sync> std::ops::Deref for CircularBufferReadGuard<'a, T> {
type Target = [T];
fn deref(&self) -> &Self::Target {
&self.guard.buffer
}
}
impl<'a, T: Copy + Default + Send + Sync> std::ops::Index<usize>
for CircularBufferReadGuard<'a, T>
{
type Output = T;
fn index(&self, index: usize) -> &Self::Output {
&self.guard.buffer[index & self.guard.mask]
}
}
pub struct CircularBufferWriteGuard<'a, T: Copy + Default + Send + Sync> {
guard: RwLockWriteGuard<'a, CircularBufferData<T>>,
}
impl<'a, T: Copy + Default + Send + Sync> CircularBufferWriteGuard<'a, T> {
pub fn len(&self) -> usize {
self.guard.mask + 1
}
pub fn is_empty(&self) -> bool {
self.len() == 0
}
pub fn capacity(&self) -> usize {
self.guard.buffer.len()
}
pub fn get_read(&self) -> usize {
self.guard.read
}
pub fn get_write(&self) -> usize {
self.guard.write
}
#[inline]
pub fn push(&mut self, value: T) {
let idx = self.guard.write;
self.guard.buffer[idx] = value;
self.guard.write = (self.guard.write + 1) & self.guard.mask;
}
#[inline]
#[allow(clippy::should_implement_trait)]
pub fn next(&mut self) -> T {
let value = self.guard.buffer[self.guard.read];
self.guard.read = (self.guard.read + 1) & self.guard.mask;
value
}
pub fn peek(&self) -> T {
self.guard.buffer[self.guard.read]
}
pub fn read_offset(&self, offset: usize) -> T {
self.guard.buffer[(self.guard.read + offset) & self.guard.mask]
}
pub fn write_offset(&mut self, offset: usize, value: T) {
let idx = (self.guard.write + offset) & self.guard.mask;
self.guard.buffer[idx] = value;
}
pub fn set_read(&mut self, index: usize) {
self.guard.read = index & self.guard.mask;
}
pub fn set_write(&mut self, index: usize) {
self.guard.write = index & self.guard.mask;
}
pub fn clear(&mut self) {
self.guard.buffer.fill(T::default());
self.guard.read = 0;
self.guard.write = 0;
}
}
impl<'a, T: Copy + Default + Send + Sync> std::ops::Deref for CircularBufferWriteGuard<'a, T> {
type Target = [T];
fn deref(&self) -> &Self::Target {
&self.guard.buffer
}
}
impl<'a, T: Copy + Default + Send + Sync> std::ops::DerefMut for CircularBufferWriteGuard<'a, T> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.guard.buffer
}
}
impl<'a, T: Copy + Default + Send + Sync> std::ops::Index<usize>
for CircularBufferWriteGuard<'a, T>
{
type Output = T;
fn index(&self, index: usize) -> &Self::Output {
&self.guard.buffer[index & self.guard.mask]
}
}
impl<'a, T: Copy + Default + Send + Sync> std::ops::IndexMut<usize>
for CircularBufferWriteGuard<'a, T>
{
fn index_mut(&mut self, index: usize) -> &mut Self::Output {
let idx = index & self.guard.mask;
&mut self.guard.buffer[idx]
}
}
impl<T: Copy + Default + Send + Sync> Clone for CircularBuffer<T> {
fn clone(&self) -> Self {
Self {
inner: Arc::clone(&self.inner),
}
}
}
unsafe impl<T: Copy + Default + Send + Sync> Send for CircularBuffer<T> {}
unsafe impl<T: Copy + Default + Send + Sync> Sync for CircularBuffer<T> {}