1 | use slab::Slab; |
2 | |
3 | /// Buffers frames for multiple streams. |
4 | #[derive (Debug)] |
5 | pub struct Buffer<T> { |
6 | slab: Slab<Slot<T>>, |
7 | } |
8 | |
9 | /// A sequence of frames in a `Buffer` |
10 | #[derive (Debug)] |
11 | pub 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)] |
17 | struct Indices { |
18 | head: usize, |
19 | tail: usize, |
20 | } |
21 | |
22 | #[derive (Debug)] |
23 | struct Slot<T> { |
24 | value: T, |
25 | next: Option<usize>, |
26 | } |
27 | |
28 | impl<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 | |
38 | impl 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 | } |
100 | |