h2/proto/streams/
buffer.rs

1use slab::Slab;
2
3/// Buffers frames for multiple streams.
4#[derive(Debug)]
5pub struct Buffer<T> {
6    slab: Slab<Slot<T>>,
7}
8
9/// A sequence of frames in a `Buffer`
10#[derive(Debug)]
11pub struct Deque {
12    indices: Option<Indices>,
13}
14
15/// Tracks the head & tail for a sequence of frames in a `Buffer`.
16#[derive(Debug, Default, Copy, Clone)]
17struct Indices {
18    head: usize,
19    tail: usize,
20}
21
22#[derive(Debug)]
23struct Slot<T> {
24    value: T,
25    next: Option<usize>,
26}
27
28impl<T> Buffer<T> {
29    pub fn new() -> Self {
30        Buffer { slab: Slab::new() }
31    }
32
33    pub fn is_empty(&self) -> bool {
34        self.slab.is_empty()
35    }
36}
37
38impl Deque {
39    pub fn new() -> Self {
40        Deque { indices: None }
41    }
42
43    pub fn is_empty(&self) -> bool {
44        self.indices.is_none()
45    }
46
47    pub fn push_back<T>(&mut self, buf: &mut Buffer<T>, value: T) {
48        let key = buf.slab.insert(Slot { value, next: None });
49
50        match self.indices {
51            Some(ref mut idxs) => {
52                buf.slab[idxs.tail].next = Some(key);
53                idxs.tail = key;
54            }
55            None => {
56                self.indices = Some(Indices {
57                    head: key,
58                    tail: key,
59                });
60            }
61        }
62    }
63
64    pub fn push_front<T>(&mut self, buf: &mut Buffer<T>, value: T) {
65        let key = buf.slab.insert(Slot { value, next: None });
66
67        match self.indices {
68            Some(ref mut idxs) => {
69                buf.slab[key].next = Some(idxs.head);
70                idxs.head = key;
71            }
72            None => {
73                self.indices = Some(Indices {
74                    head: key,
75                    tail: key,
76                });
77            }
78        }
79    }
80
81    pub fn pop_front<T>(&mut self, buf: &mut Buffer<T>) -> Option<T> {
82        match self.indices {
83            Some(mut idxs) => {
84                let mut slot = buf.slab.remove(idxs.head);
85
86                if idxs.head == idxs.tail {
87                    assert!(slot.next.is_none());
88                    self.indices = None;
89                } else {
90                    idxs.head = slot.next.take().unwrap();
91                    self.indices = Some(idxs);
92                }
93
94                Some(slot.value)
95            }
96            None => None,
97        }
98    }
99}