use crate::stream::send::state::transmission;
use crossbeam_queue::{ArrayQueue, SegQueue};
use s2n_quic_core::{ensure, varint::VarInt};
use std::collections::VecDeque;
pub use transmission::Info;
#[derive(Debug)]
pub struct Event<Buffer> {
pub packet_number: VarInt,
pub info: Info<Buffer>,
pub has_more_app_data: bool,
}
pub struct Queue<Buffer> {
queue: SegQueue<Vec<Event<Buffer>>>,
free_batches: ArrayQueue<Vec<Event<Buffer>>>,
}
impl<Buffer> Default for Queue<Buffer> {
#[inline]
fn default() -> Self {
Self {
queue: SegQueue::new(),
free_batches: ArrayQueue::new(32),
}
}
}
impl<Buffer> Queue<Buffer> {
#[inline]
pub fn alloc_batch(&self, batch_size: usize) -> Vec<Event<Buffer>> {
self.free_batches
.pop()
.filter(|batch| batch.capacity() >= batch_size)
.unwrap_or_else(|| Vec::with_capacity(batch_size))
}
#[inline]
pub fn push_batch(&self, batch: Vec<Event<Buffer>>) {
ensure!(!batch.is_empty());
self.queue.push(batch);
}
#[inline]
pub fn drain(&self) -> impl Iterator<Item = Event<Buffer>> + '_ {
Drain {
queue: self,
current: VecDeque::new(),
}
}
}
pub struct Drain<'a, Buffer> {
current: VecDeque<Event<Buffer>>,
queue: &'a Queue<Buffer>,
}
impl<'a, Buffer> Iterator for Drain<'a, Buffer> {
type Item = Event<Buffer>;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
loop {
if let Some(event) = self.current.pop_front() {
return Some(event);
}
if let Some(events) = self.queue.queue.pop() {
let prev = core::mem::replace(&mut self.current, events.into());
debug_assert!(prev.is_empty());
let _ = self.queue.free_batches.push(prev.into());
} else {
return None;
}
}
}
}