1use std::collections::VecDeque;
2use std::pin::Pin;
3
4pub struct Block<T>(VecDeque<T>);
5
6impl<T> Block<T> {
7 fn new(capacity: usize) -> Block<T> {
8 Block(VecDeque::with_capacity(capacity))
9 }
10
11 fn is_empty(&self) -> bool {
12 self.0.len() == 0
13 }
14
15 fn get(&self, index: usize) -> Option<Pin<&T>> {
16 self.0.get(index).map(|p| unsafe { Pin::new_unchecked(p) })
17 }
18
19 fn get_mut(&mut self, index: usize) -> Option<Pin<&mut T>> {
20 self.0.get_mut(index).map(|p| unsafe { Pin::new_unchecked(p) })
21 }
22
23 fn push_back(&mut self, item: T) {
24 assert!(self.0.len() < self.0.capacity());
25 self.0.push_back(item);
26 }
27
28 fn pop_front(&mut self) {
29 self.0.drain(0..1);
30 }
31
32 fn replace(&mut self, index: usize, item: T) {
33 *self.0.get_mut(index).unwrap() = item;
34 }
35}
36
37#[derive(Default)]
38pub struct PinnedQueue<T> {
39 blocks: VecDeque<Block<T>>,
40 head: usize,
41 len: usize,
42}
43
44impl<T> PinnedQueue<T> {
45 pub const fn new() -> PinnedQueue<T> {
46 PinnedQueue { blocks: VecDeque::new(), head: 0, len: 0 }
47 }
48
49 pub fn len(&self) -> usize {
51 self.len
52 }
53
54 pub fn is_empty(&self) -> bool {
55 self.len == 0
56 }
57
58 pub fn get(&self, index: usize) -> Option<Pin<&T>> {
60 if index > self.len {
61 None
62 } else {
63 let (outer, inner) = split_index(self.head, index);
64 self.blocks[outer].get(inner)
65 }
66 }
67
68 pub fn get_mut(&mut self, index: usize) -> Option<Pin<&mut T>> {
70 if index > self.len {
71 None
72 } else {
73 let (outer, inner) = split_index(self.head, index);
74 self.blocks[outer].get_mut(inner)
75 }
76 }
77
78 pub fn last_mut(&mut self) -> Option<Pin<&mut T>> {
80 self.get_mut(self.len)
81 }
82
83 pub fn push_back(&mut self, item: T) {
85 let head_outer = outer_index(self.head);
86 let outer = outer_index(self.head + self.len);
87
88 if outer - head_outer >= self.blocks.len() {
89 self.blocks.push_back(Block::new(1 << outer));
90 }
91
92 self.blocks[outer - head_outer].push_back(item);
93 self.len += 1;
94 }
95
96 pub fn pop_front(&mut self) -> bool {
98 if self.is_empty() {
99 return false;
100 }
101
102 self.len -= 1;
103 self.head += 1;
104 self.blocks[0].pop_front();
105
106 if self.blocks[0].is_empty() {
107 self.blocks.pop_front();
108 }
109 true
110 }
111
112 pub fn replace(&mut self, index: usize, item: T) {
114 let (outer, inner) = split_index(self.head, index);
115 self.blocks[outer].replace(inner, item);
116 }
117}
118
119fn outer_index(index: usize) -> usize {
120 (usize::BITS - (index + 1).leading_zeros() - 1) as usize
121}
122
123fn split_index(head: usize, index: usize) -> (usize, usize) {
124 let outer = outer_index(index + head);
125 let inner = (head + index + 1) & (!(1 << outer));
126 let head_outer = outer_index(head);
127 let head_inner = (head + 1) & (!(1 << head_outer));
128 if head_inner > inner {
129 (outer - head_outer - 1, head_inner - inner)
130 } else {
131 (outer - head_outer, inner - head_inner)
132 }
133}
134
135#[cfg(test)]
136mod tests {
137 use crate::{outer_index, split_index};
138
139 #[test]
140 fn outer() {
141 assert_eq!(0, outer_index(0));
142 assert_eq!(1, outer_index(1));
143 assert_eq!(1, outer_index(2));
144 assert_eq!(2, outer_index(3));
145 assert_eq!(16, outer_index(65535));
146 }
147
148 #[test]
149 fn split() {
150 assert_eq!((0, 0), split_index(0, 0));
151 assert_eq!((1, 0), split_index(0, 1));
152 assert_eq!((1, 1), split_index(0, 2));
153
154 assert_eq!((0, 0), split_index(1, 0));
155 assert_eq!((0, 1), split_index(1, 1));
156 assert_eq!((1, 0), split_index(1, 2));
157
158 assert_eq!((3, 1), split_index(2, 15));
159 }
160}