1use std::ops::{Index, IndexMut, Range};
2
3#[derive(Debug, Default, Copy, Clone, PartialEq)]
4pub struct SliceIndex(u32);
5
6#[derive(Debug, Default, Copy, Clone)]
7struct SessionKey {
9 start: u32,
10 end: u32,
11}
12
13impl SessionKey {
14 fn as_range(&self) -> Range<usize> {
15 self.start as usize..self.end as usize
16 }
17}
18
19#[derive(Debug)]
20pub struct Session<'a, T> {
21 buffer: &'a mut Buffer<T>,
22}
23
24impl<'a, T: Copy> Session<'a, T> {
25 #[must_use]
28 pub fn next_slice(&mut self) -> SliceIndex {
29 self.buffer.next_slice()
30 }
31
32 pub fn insert(&mut self, pos: usize, value: T) {
34 self.buffer.insert(pos, value);
35 }
36
37 pub fn last(&self) -> Option<&T> {
40 self.buffer.last()
41 }
42
43 pub fn push(&mut self, value: T) {
50 self.buffer.push(value)
51 }
52
53 pub fn pop(&mut self) -> Option<T> {
57 self.buffer.pop()
58 }
59
60 pub fn extend(&mut self, iter: impl IntoIterator<Item = T>) {
62 self.buffer.extend(iter);
63 }
64
65 pub fn tail_drain(&mut self, size: u32) {
67 self.buffer.tail_drain(size);
68 }
69
70 pub fn slice(&self, index: SliceIndex) -> &[T] {
72 self.buffer.get(index)
73 }
74
75 pub fn slice_mut(&mut self, index: SliceIndex) -> &mut [T] {
77 self.buffer.get_mut(index)
78 }
79
80 pub fn len(&self) -> u32 {
82 self.buffer.len()
83 }
84
85 pub fn is_empty(&self) -> bool {
87 self.len() == 0
88 }
89
90 pub fn truncate(&mut self, key: SliceIndex, index: usize) {
92 self.buffer.truncate(key, index);
93 }
94}
95
96impl<'a, T: Copy> Index<usize> for Session<'a, T> {
97 type Output = T;
98
99 fn index(&self, index: usize) -> &Self::Output {
100 self.buffer.buf.index(index)
101 }
102}
103
104impl<'a, T: Copy> IndexMut<usize> for Session<'a, T> {
105 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
106 self.buffer.buf.index_mut(index)
107 }
108}
109
110#[derive(Debug)]
126pub struct Buffer<T> {
127 buf: Vec<T>,
128 keys: Vec<SessionKey>,
129}
130
131impl<T: Copy> Buffer<T> {
132 pub fn empty() -> Self {
134 Self {
135 buf: Vec::new(),
136 keys: Vec::new(),
137 }
138 }
139
140 fn push(&mut self, value: T) {
141 assert!(!self.keys.is_empty(), "tried to push to a buffer without a slice key");
142 self.buf.push(value);
143 let buf_len = self.buf.len();
144 let index = self.keys.len() - 1;
145 self.keys[index].end = buf_len as u32;
146 }
147
148 fn pop(&mut self) -> Option<T> {
149 assert!(!self.keys.is_empty(), "tried to pop from a buffer without a slice key");
150 let index = self.keys.len() - 1;
151 let output = self.buf.pop();
152 if output.is_some() {
153 self.keys[index].end -= 1;
154 }
155 output
156 }
157
158 fn insert(&mut self, index: usize, value: T) {
161 assert!(index < u32::MAX as usize);
162
163 if self.buf.len() == index {
164 self.push(value);
165 return;
166 }
167
168 self.buf.insert(index, value);
169
170 let last_key_index = self.keys.len() - 1;
176 let Some(key_index) = self
177 .keys
178 .iter_mut()
179 .rev()
180 .position(|key| key.as_range().contains(&index))
181 .map(|pos| last_key_index - pos)
182 else {
183 return;
184 };
185
186 self.keys[key_index].end += 1;
189
190 self.keys[key_index + 1..].iter_mut().for_each(|key| {
192 key.start += 1;
193 key.end += 1;
194 });
195 }
196
197 fn extend(&mut self, iter: impl IntoIterator<Item = T>) {
198 self.buf.extend(iter);
199 let buf_len = self.buf.len();
200
201 if !self.keys.is_empty() {
202 let index = self.keys.len() - 1;
203 self.keys[index].end = buf_len as u32;
204 }
205 }
206
207 pub fn new_session(&mut self) -> Session<'_, T> {
211 Session { buffer: self }
212 }
213
214 fn next_slice(&mut self) -> SliceIndex {
215 let slice = SliceIndex(self.keys.len() as u32);
216 let len = self.buf.len() as u32;
217 let key = SessionKey { start: len, end: len };
218 self.keys.push(key);
219 slice
220 }
221
222 pub fn get(&self, index: SliceIndex) -> &[T] {
223 let key = self.keys[index.0 as usize];
224 &self.buf[key.as_range()]
225 }
226
227 pub fn get_mut(&mut self, index: SliceIndex) -> &mut [T] {
228 let key = self.keys[index.0 as usize];
229 &mut self.buf[key.as_range()]
230 }
231
232 pub fn tail_drain(&mut self, size: u32) {
241 assert!(!self.keys.is_empty());
242 let key_index = self.keys.len() - 1;
243 self.keys[key_index].end -= size;
244 let pos = self.len() - size;
245 let _ = self.buf.drain(pos as usize..);
246 }
247
248 pub fn clear(&mut self) {
250 self.buf.clear();
251 self.keys.clear();
252 }
253
254 fn last(&self) -> Option<&T> {
256 self.buf.last()
257 }
258
259 fn len(&self) -> u32 {
260 self.buf.len() as u32
261 }
262
263 fn truncate(&mut self, key: SliceIndex, index: usize) {
267 assert!(
268 !self.keys.is_empty(),
269 "tried to truncate from a buffer that contains zero slice keys"
270 );
271 let last_key_index = self.keys.len() - 1;
272 assert_eq!(key.0 as usize, last_key_index, "trying to truncate before the last key");
273
274 let slice = &mut self.keys[key.0 as usize];
275 let index = index + slice.start as usize;
276 self.buf.truncate(index);
277 slice.end = self.buf.len() as u32;
278 }
279}
280
281#[cfg(test)]
282mod test {
283 use super::*;
284
285 #[test]
286 fn two_sessions() {
287 let mut buffer = Buffer::empty();
288 let mut s1 = buffer.new_session();
289 let k1 = s1.next_slice();
290 s1.extend([1, 2, 3]);
291
292 let mut s2 = buffer.new_session();
293 let k2 = s2.next_slice();
294 s2.extend([10, 20, 30]);
295
296 let b1 = buffer.get(k1);
297 let b2 = buffer.get(k2);
298
299 assert_eq!(b1, &[1, 2, 3]);
300 assert_eq!(b2, &[10, 20, 30]);
301 }
302
303 #[test]
304 fn buffer_insert_via_session() {
305 let mut buffer = Buffer::<u8>::empty();
306 let mut session = buffer.new_session();
307 let k1 = session.next_slice();
308
309 session.extend([b'a', b'b']);
310
311 let k2 = session.next_slice();
312 session.insert(1, b'x');
313 session.push(b'z');
314
315 let output = buffer.get(k1);
316 assert_eq!(output, b"axb");
317
318 let output = buffer.get(k2);
319 assert_eq!(output, b"z");
320 }
321
322 #[test]
323 fn session_pop() {
324 let mut buffer = Buffer::<u8>::empty();
325 let mut session = buffer.new_session();
326 let k1 = session.next_slice();
327 session.push(0);
328 session.pop();
329
330 assert!(buffer.buf.is_empty());
331 assert!(buffer.get(k1).is_empty());
332 }
333
334 #[test]
335 fn clear_buffer() {
336 let mut buffer = Buffer::empty();
337 let mut session = buffer.new_session();
338 let _ = session.next_slice();
339 session.push(0);
340
341 assert_eq!(buffer.keys.len(), 1);
342 assert_eq!(buffer.buf.len(), 1);
343
344 buffer.clear();
345
346 assert!(buffer.keys.is_empty());
347 assert!(buffer.buf.is_empty());
348 }
349
350 #[test]
351 fn tail_drain() {
352 let mut buffer = Buffer::<u8>::empty();
353 let mut session = buffer.new_session();
354 let _k1 = session.next_slice();
355 session.extend(0..10);
356 session.tail_drain(3);
357
358 let key = buffer.keys[0];
359 assert_eq!(key.start, 0);
360 assert_eq!(key.end, 7);
361 }
362
363 #[test]
364 #[should_panic(expected = "tried to truncate from a buffer that contains zero slice keys")]
365 fn truncate_empty_buffer() {
366 let mut buffer = Buffer::<u8>::empty();
367 buffer.truncate(SliceIndex(0), 123);
368 }
369
370 #[test]
371 #[should_panic(expected = "trying to truncate before the last key")]
372 fn truncate_before_last_key() {
373 let mut buffer = Buffer::<u8>::empty();
374 let mut session = buffer.new_session();
375
376 let k1 = session.next_slice();
377 let _k2 = session.next_slice();
378 buffer.truncate(k1, 0);
379 }
380
381 #[test]
382 fn truncate() {
383 let mut buffer = Buffer::<u8>::empty();
384 let mut session = buffer.new_session();
385 let k1 = session.next_slice();
386 session.extend([1, 2, 3]);
387 session.truncate(k1, 2);
388 assert_eq!(&[1, 2], session.slice(k1));
389 }
390}