use frame::{self, Frame}; use slab::Slab; use std::marker::PhantomData; /// Buffers frames for multiple streams. #[derive(Debug)] pub struct Buffer { slab: Slab>, } /// A sequence of frames in a `Buffer` #[derive(Debug)] pub struct Deque { indices: Option, _p: PhantomData, } /// Tracks the head & tail for a sequence of frames in a `Buffer`. #[derive(Debug, Default, Copy, Clone)] struct Indices { head: usize, tail: usize, } #[derive(Debug)] struct Slot { frame: Frame, next: Option, } impl Buffer { pub fn new() -> Self { Buffer { slab: Slab::new(), } } } impl Deque { pub fn new() -> Self { Deque { indices: None, _p: PhantomData, } } pub fn is_empty(&self) -> bool { self.indices.is_none() } pub fn push_back(&mut self, buf: &mut Buffer, frame: Frame) { let key = buf.slab.insert(Slot { frame, next: None, }); match self.indices { Some(ref mut idxs) => { buf.slab[idxs.tail].next = Some(key); idxs.tail = key; } None => { self.indices = Some(Indices { head: key, tail: key, }); } } } pub fn push_front(&mut self, buf: &mut Buffer, frame: Frame) { let key = buf.slab.insert(Slot { frame, next: None, }); match self.indices { Some(ref mut idxs) => { buf.slab[key].next = Some(idxs.head); idxs.head = key; } None => { self.indices = Some(Indices { head: key, tail: key, }); } } } pub fn pop_front(&mut self, buf: &mut Buffer) -> Option> { match self.indices { Some(mut idxs) => { let mut slot = buf.slab.remove(idxs.head); if idxs.head == idxs.tail { assert!(slot.next.is_none()); self.indices = None; } else { idxs.head = slot.next.take().unwrap(); self.indices = Some(idxs); } return Some(slot.frame); } None => None, } } pub fn peek_front<'a>(&self, buf: &'a Buffer) -> Option<&'a Frame> { match self.indices { Some(idxs) => { Some(&buf.slab[idxs.head].frame) } None => None, } } }