1use crate::HeapSize;
9
10#[derive(Debug)]
13pub struct Deque<T> {
14 storage: Vec<Vec<T>>,
15
16 next_chunk_capacity: usize,
19}
20
21const MIN_CHUNK_CAPACITY: usize = 1 << 10;
24
25const MAX_CHUNK_CAPACITY: usize = MIN_CHUNK_CAPACITY * (1 << 10);
28
29impl<T> Default for Deque<T> {
30 fn default() -> Self {
31 Self::new()
32 }
33}
34
35impl<T> Deque<T> {
36 pub fn new() -> Self {
37 let mut result = Self {
38 storage: Default::default(),
39 next_chunk_capacity: MIN_CHUNK_CAPACITY,
40 };
41 result.new_chunk();
42 result
43 }
44
45 pub fn push(&mut self, val: T) -> &T {
48 let chunk = self.storage.last().unwrap();
49 if chunk.len() >= chunk.capacity() {
50 self.new_chunk();
51 }
52 let chunk = self.storage.last_mut().unwrap();
53 debug_assert!(
54 chunk.len() < chunk.capacity(),
55 "Invalid attempt to expand a chunk"
56 );
57 chunk.push(val);
58 chunk.last().unwrap()
59 }
60
61 pub fn len(&self) -> usize {
63 let mut result = 0;
64 for chunk in &self.storage {
65 result += chunk.len();
66 }
67 result
68 }
69
70 pub fn is_empty(&self) -> bool {
71 self.storage.is_empty()
72 }
73
74 pub fn iter(&self) -> impl Iterator<Item = &T> {
76 self.storage.iter().flatten()
77 }
78
79 pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut T> {
81 self.storage.iter_mut().flatten()
82 }
83
84 pub fn truncate(&mut self, len: usize) {
92 debug_assert!(len <= self.len(), "truncate beyond deque length");
93 let mut remaining = len;
94 let mut keep = 0usize; for chunk in &mut self.storage {
96 keep += 1;
97 if remaining < chunk.len() {
98 chunk.truncate(remaining);
99 break;
100 }
101 remaining -= chunk.len();
102 if remaining == 0 {
103 break;
104 }
105 }
106 self.storage.truncate(keep.max(1));
109 }
110
111 pub fn iter_from(&self, index: usize) -> impl Iterator<Item = &T> {
116 let mut skip = index;
117 let mut start_chunk = self.storage.len();
118 for (i, chunk) in self.storage.iter().enumerate() {
119 if skip < chunk.len() {
120 start_chunk = i;
121 break;
122 }
123 skip -= chunk.len();
124 }
125 self.storage[start_chunk..]
126 .iter()
127 .enumerate()
128 .flat_map(move |(i, chunk)| {
129 let s = if i == 0 { skip } else { 0 };
130 chunk[s..].iter()
131 })
132 }
133
134 fn new_chunk(&mut self) {
136 let capacity = self.next_chunk_capacity;
137 self.storage.push(Vec::with_capacity(capacity));
138
139 if capacity < MAX_CHUNK_CAPACITY {
141 self.next_chunk_capacity = capacity * 2;
142 }
143 }
144}
145
146impl<T> HeapSize for Deque<T> {
147 fn heap_size(&self) -> usize {
148 let mut result = 0;
149 for chunk in &self.storage {
150 result += chunk.heap_size();
151 }
152 result
153 }
154}
155
156#[cfg(test)]
157mod tests {
158 use super::*;
159
160 #[test]
161 fn append() {
162 let mut d = Deque::new();
163 d.push(1);
164 d.push(2);
165 assert_eq!(d.iter().count(), 2);
166 }
167
168 #[test]
169 fn multi_chunks() {
170 let mut d = Deque::<usize>::new();
171 let count = MIN_CHUNK_CAPACITY * 2;
172 let mut addr = 0usize;
173 for i in 0..count {
174 let elem = d.push(i);
175 if i == 1000 {
176 addr = elem as *const usize as usize;
177 }
178 }
179 assert_eq!(d.iter().count(), count);
180 let again = d.iter().nth(1000).unwrap();
183 assert_eq!(again as *const usize as usize, addr);
184 assert_eq!(*again, 1000);
185 }
186
187 #[test]
188 fn truncate_within_and_across_chunks() {
189 let mut d = Deque::new();
191 for i in 0..2500usize {
192 d.push(i);
193 }
194 assert_eq!(d.len(), 2500);
195 d.truncate(1500);
197 assert_eq!(d.len(), 1500);
198 assert_eq!(d.iter().copied().last(), Some(1499));
199 assert_eq!(d.iter().nth(1023).copied(), Some(1023));
201 d.push(9999);
202 assert_eq!(d.len(), 1501);
203 assert_eq!(d.iter().copied().last(), Some(9999));
204 d.truncate(500);
206 assert_eq!(d.len(), 500);
207 d.truncate(0);
209 assert_eq!(d.len(), 0);
210 d.push(1);
211 assert_eq!(d.len(), 1);
212 d.truncate(1);
214 assert_eq!(d.len(), 1);
215 }
216
217 #[test]
218 fn iter_from_positions_correctly() {
219 let mut d = Deque::new();
220 for i in 0..2500usize {
221 d.push(i);
222 }
223 let v: Vec<usize> = d.iter_from(1030).copied().take(3).collect();
225 assert_eq!(v, vec![1030, 1031, 1032]);
226 assert_eq!(d.iter_from(1024).copied().next(), Some(1024));
228 assert_eq!(d.iter_from(0).count(), 2500);
230 assert_eq!(d.iter_from(2500).count(), 0);
232 assert_eq!(d.iter_from(9999).count(), 0);
233 }
234}