use std::{cmp, collections::VecDeque};
use bytes::Bytes;
use super::{BufQStats, CheckErr, Controller};
pub struct BytesLim {
cur_len: usize,
max_len: Option<usize>,
len_hwm: usize,
cur_size: usize,
max_size: Option<usize>,
size_hwm: usize
}
impl BytesLim {
#[must_use]
pub fn new(max_len: Option<usize>, max_size: Option<usize>) -> Self {
assert!(!matches!(max_len, Some(0)), "zero-length limit");
assert!(!matches!(max_size, Some(0)), "zero-size limit");
Self {
cur_len: 0,
max_len,
len_hwm: 0,
cur_size: 0,
max_size,
size_hwm: 0
}
}
#[must_use]
pub const fn size(&self) -> usize {
self.cur_size
}
#[must_use]
pub const fn get_max_len(&self) -> Option<usize> {
self.max_len
}
#[must_use]
pub const fn get_max_size(&self) -> Option<usize> {
self.max_size
}
pub fn set_max_len(&mut self, max_len: Option<usize>) {
assert!(!matches!(max_len, Some(0)), "zero-length limit");
self.max_len = max_len;
}
pub fn set_max_size(&mut self, max_size: Option<usize>) {
assert!(!matches!(max_size, Some(0)), "zero-size limit");
self.max_size = max_size;
}
#[must_use]
pub const fn stats(&self) -> BufQStats {
BufQStats {
len: self.cur_len,
len_hwm: self.len_hwm,
size: self.cur_size,
size_hwm: self.size_hwm
}
}
pub const fn reset_hwm(&mut self) {
self.len_hwm = self.cur_len;
self.size_hwm = self.cur_size;
}
pub const fn clear_hwm(&mut self) {
self.len_hwm = 0;
self.size_hwm = 0;
}
}
impl Controller for BytesLim {
type Item = Bytes;
fn size_hint(&self) -> Option<usize> {
self.max_len
}
fn is_full(&self, q: &VecDeque<Self::Item>) -> bool {
self.max_len.is_some_and(|max_len| q.len() >= max_len)
|| self
.max_size
.is_some_and(|max_size| self.cur_size >= max_size)
}
fn is_overflow(&self, q: &VecDeque<Self::Item>) -> bool {
self.max_len.is_some_and(|max_len| q.len() > max_len)
|| self
.max_size
.is_some_and(|max_size| self.cur_size > max_size)
}
fn check(
&self,
q: &VecDeque<Self::Item>,
n: &Self::Item
) -> Result<(), CheckErr> {
if let Some(max_len) = self.max_len {
if q.len() + 1 > max_len {
return Err(CheckErr::WontFit);
}
}
if let Some(max_size) = self.max_size {
if n.len() > max_size {
return Err(CheckErr::CantFit);
}
if self.cur_size + n.len() > max_size {
return Err(CheckErr::WontFit);
}
}
Ok(())
}
fn reg(&mut self, q: &VecDeque<Self::Item>, n: &Self::Item) {
self.cur_len += 1;
self.len_hwm = cmp::max(self.len_hwm, q.len());
self.cur_size += n.len();
self.size_hwm = cmp::max(self.size_hwm, self.cur_size);
}
fn dereg(&mut self, n: &Self::Item) {
self.cur_len -= 1;
self.cur_size -= n.len();
}
}