use crate::constants::{DEFAULT_DIFF_SIZE, DEFAULT_RING_SIZE, MIN_DIFF_SIZE, MIN_RING_SIZE};
pub struct RingBuffer {
buf: Vec<u8>,
pub read_pos: usize,
pub write_pos: usize,
ring_size: usize,
diff_size: usize,
}
impl RingBuffer {
pub fn new(ring_size: usize, diff_size: usize) -> Self {
let ring_size = ring_size.max(MIN_RING_SIZE);
let diff_size = diff_size.max(MIN_DIFF_SIZE);
Self {
buf: vec![0u8; ring_size],
read_pos: 0,
write_pos: 0,
ring_size,
diff_size,
}
}
pub fn with_defaults() -> Self {
Self::new(DEFAULT_RING_SIZE, DEFAULT_DIFF_SIZE)
}
pub fn capacity(&self) -> usize {
self.ring_size
}
pub fn diff_threshold(&self) -> usize {
self.diff_size
}
pub fn has_data(&self) -> bool {
self.read_pos != self.write_pos && self.diff() > self.diff_size
}
pub fn is_empty(&self) -> bool {
self.read_pos == self.write_pos
}
pub fn diff(&self) -> usize {
self.write_pos.abs_diff(self.read_pos)
}
pub fn is_full(&self) -> bool {
(self.write_pos + 1) % self.ring_size == self.read_pos
}
pub fn put(&mut self, item: u8) -> bool {
if self.is_full() {
return false;
}
self.buf[self.write_pos] = item;
self.write_pos = (self.write_pos + 1) % self.ring_size;
true
}
pub fn get(&mut self) -> u8 {
let item = self.buf[self.read_pos];
self.read_pos = (self.read_pos + 1) % self.ring_size;
item
}
pub fn reset(&mut self) {
self.read_pos = 0;
self.write_pos = 0;
}
pub fn set_ring_size(&mut self, size: usize) {
self.ring_size = size.max(MIN_RING_SIZE);
self.buf.resize(self.ring_size, 0);
self.reset();
}
pub fn set_diff_size(&mut self, size: usize) {
self.diff_size = size.max(MIN_DIFF_SIZE);
}
pub fn reinit(&mut self, ring_size: usize, diff_size: usize) {
self.set_ring_size(ring_size);
self.set_diff_size(diff_size);
}
pub fn reinit_defaults(&mut self) {
self.reinit(DEFAULT_RING_SIZE, DEFAULT_DIFF_SIZE);
}
}