use super::packet::RxPacket;
use std::collections::VecDeque;
pub const MUXER_RXQ_SIZE: usize = 16 * 1024;
pub struct MuxerRxQ {
queue: VecDeque<RxPacket>,
cap: usize,
}
impl MuxerRxQ {
pub fn new() -> Self {
Self::with_cap(MUXER_RXQ_SIZE)
}
pub fn with_cap(cap: usize) -> Self {
let cap = cap.max(1);
Self {
queue: VecDeque::with_capacity(cap.min(MUXER_RXQ_SIZE)),
cap,
}
}
pub fn push(&mut self, pkt: RxPacket) -> bool {
if self.queue.len() >= self.cap {
return false;
}
self.queue.push_back(pkt);
true
}
pub fn push_was_empty(&mut self, pkt: RxPacket) -> Result<bool, RxPacket> {
if self.queue.len() >= self.cap {
return Err(pkt);
}
let was_empty = self.queue.is_empty();
self.queue.push_back(pkt);
Ok(was_empty)
}
pub fn pop(&mut self) -> Option<RxPacket> {
self.queue.pop_front()
}
pub fn peek(&self) -> Option<&RxPacket> {
self.queue.front()
}
pub fn is_empty(&self) -> bool {
self.queue.is_empty()
}
pub fn len(&self) -> usize {
self.queue.len()
}
pub fn drain(&mut self) {
self.queue.clear();
}
}
#[cfg(test)]
mod tests {
use super::super::packet::Header;
use super::*;
fn pkt(len: usize) -> RxPacket {
RxPacket {
hdr: Header {
src_cid: 0,
dst_cid: 0,
src_port: 0,
dst_port: 0,
len: len as u32,
type_: 0,
op: 0,
flags: 0,
buf_alloc: 0,
fwd_cnt: 0,
},
data: vec![0u8; len],
}
}
#[test]
fn push_signals_full_at_cap_without_growing() {
let mut q = MuxerRxQ::with_cap(4);
for _ in 0..4 {
assert!(q.push(pkt(1)));
}
assert!(!q.push(pkt(1)));
assert!(q.push_was_empty(pkt(1)).is_err());
assert_eq!(q.len(), 4);
assert!(q.pop().is_some());
assert!(matches!(q.push_was_empty(pkt(1)), Ok(false)));
assert_eq!(q.len(), 4);
}
}