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 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 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]
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> {}