tui_logger/
circular.rs

1use std::iter;
2/// CircularBuffer is used to store the last elements of an endless sequence.
3/// Oldest elements will be overwritten. The implementation focus on
4/// speed. So memory allocations are avoided.
5///
6/// Usage example:
7///```
8/// extern crate tui_logger;
9///
10/// use tui_logger::CircularBuffer;
11///
12/// let mut cb : CircularBuffer<u64> = CircularBuffer::new(5);
13/// cb.push(1);
14/// cb.push(2);
15/// cb.push(3);
16/// cb.push(4);
17/// cb.push(5);
18/// cb.push(6); // This will overwrite the first element
19///
20/// // Total elements pushed into the buffer is 6.
21/// assert_eq!(6,cb.total_elements());
22///
23/// // Thus the buffer has wrapped around.
24/// assert_eq!(true,cb.has_wrapped());
25///
26/// /// Iterate through the elements:
27/// {
28///     let mut iter = cb.iter();
29///     assert_eq!(Some(&2), iter.next());
30///     assert_eq!(Some(&3), iter.next());
31///     assert_eq!(Some(&4), iter.next());
32///     assert_eq!(Some(&5), iter.next());
33///     assert_eq!(Some(&6), iter.next());
34///     assert_eq!(None, iter.next());
35/// }
36///
37/// /// Iterate backwards through the elements:
38/// {
39///     let mut iter = cb.rev_iter();
40///     assert_eq!(Some(&6), iter.next());
41///     assert_eq!(Some(&5), iter.next());
42///     assert_eq!(Some(&4), iter.next());
43///     assert_eq!(Some(&3), iter.next());
44///     assert_eq!(Some(&2), iter.next());
45///     assert_eq!(None, iter.next());
46/// }
47///
48/// // The elements in the buffer are now:
49/// assert_eq!(vec![2,3,4,5,6],cb.take());
50///
51/// // After taking all elements, the buffer is empty.
52/// let now_empty : Vec<u64> = vec![];
53/// assert_eq!(now_empty,cb.take());
54///```
55pub struct CircularBuffer<T> {
56    buffer: Vec<T>,
57    next_write_pos: usize,
58}
59#[allow(dead_code)]
60impl<T> CircularBuffer<T> {
61    /// Create a new CircularBuffer, which can hold max_depth elements
62    pub fn new(max_depth: usize) -> CircularBuffer<T> {
63        CircularBuffer {
64            buffer: Vec::with_capacity(max_depth),
65            next_write_pos: 0,
66        }
67    }
68    /// Return the number of elements present in the buffer
69    pub fn len(&self) -> usize {
70        self.buffer.len()
71    }
72    pub fn is_empty(&self) -> bool {
73        self.buffer.is_empty()
74    }
75    pub fn capacity(&self) -> usize {
76        self.buffer.capacity()
77    }
78    /// Push a new element into the buffer.
79    /// Until the capacity is reached, elements are pushed.
80    /// Afterwards the oldest elements will be overwritten.
81    pub fn push(&mut self, elem: T) {
82        let max_depth = self.buffer.capacity();
83        if self.buffer.len() < max_depth {
84            self.buffer.push(elem);
85        } else {
86            self.buffer[self.next_write_pos % max_depth] = elem;
87        }
88        self.next_write_pos += 1;
89    }
90    /// Take out all elements from the buffer, leaving an empty buffer behind
91    pub fn take(&mut self) -> Vec<T> {
92        let mut consumed = vec![];
93        let max_depth = self.buffer.capacity();
94        if self.buffer.len() < max_depth {
95            consumed.append(&mut self.buffer);
96        } else {
97            let pos = self.next_write_pos % max_depth;
98            let mut xvec = self.buffer.split_off(pos);
99            consumed.append(&mut xvec);
100            consumed.append(&mut self.buffer)
101        }
102        self.next_write_pos = 0;
103        consumed
104    }
105    /// Total number of elements pushed into the buffer.
106    pub fn total_elements(&self) -> usize {
107        self.next_write_pos
108    }
109    /// If has_wrapped() is true, then elements have been overwritten
110    pub fn has_wrapped(&self) -> bool {
111        self.next_write_pos > self.buffer.capacity()
112    }
113    /// Return an iterator to step through all elements in the sequence,
114    /// as these have been pushed (FIFO)
115    pub fn iter(&mut self) -> iter::Chain<std::slice::Iter<T>, std::slice::Iter<T>> {
116        let max_depth = self.buffer.capacity();
117        if self.next_write_pos <= max_depth {
118            // If buffer is not completely filled, then just iterate through it
119            self.buffer.iter().chain(self.buffer[..0].iter())
120        } else {
121            let wrap = self.next_write_pos % max_depth;
122            let it_end = self.buffer[..wrap].iter();
123            let it_start = self.buffer[wrap..].iter();
124            it_start.chain(it_end)
125        }
126    }
127    /// Return an iterator to step through all elements in the reverse sequence,
128    /// as these have been pushed (LIFO)
129    pub fn rev_iter(
130        &mut self,
131    ) -> iter::Chain<std::iter::Rev<std::slice::Iter<T>>, std::iter::Rev<std::slice::Iter<T>>> {
132        let max_depth = self.buffer.capacity();
133        if self.next_write_pos <= max_depth {
134            // If buffer is not completely filled, then just iterate through it
135            self.buffer
136                .iter()
137                .rev()
138                .chain(self.buffer[..0].iter().rev())
139        } else {
140            let wrap = self.next_write_pos % max_depth;
141            let it_end = self.buffer[..wrap].iter().rev();
142            let it_start = self.buffer[wrap..].iter().rev();
143            it_end.chain(it_start)
144        }
145    }
146}
147
148#[cfg(test)]
149mod tests {
150    #[test]
151    fn circular_buffer() {
152        use crate::CircularBuffer;
153
154        let mut cb: CircularBuffer<u64> = CircularBuffer::new(5);
155
156        // Empty buffer
157        {
158            let mut cb_iter = cb.iter();
159            assert_eq!(cb_iter.next(), None);
160        }
161
162        // Push in a value
163        cb.push(1);
164        {
165            let mut cb_iter = cb.iter();
166            assert_eq!(cb_iter.next(), Some(&1));
167            assert_eq!(cb_iter.next(), None);
168        }
169
170        // Push in a value
171        cb.push(2);
172        {
173            let mut cb_iter = cb.iter();
174            assert_eq!(cb_iter.next(), Some(&1));
175            assert_eq!(cb_iter.next(), Some(&2));
176            assert_eq!(cb_iter.next(), None);
177        }
178
179        // Push in a value
180        cb.push(3);
181        {
182            let mut cb_iter = cb.iter();
183            assert_eq!(cb_iter.next(), Some(&1));
184            assert_eq!(cb_iter.next(), Some(&2));
185            assert_eq!(cb_iter.next(), Some(&3));
186            assert_eq!(cb_iter.next(), None);
187        }
188
189        // Push in a value
190        cb.push(4);
191        {
192            let mut cb_iter = cb.iter();
193            assert_eq!(cb_iter.next(), Some(&1));
194            assert_eq!(cb_iter.next(), Some(&2));
195            assert_eq!(cb_iter.next(), Some(&3));
196            assert_eq!(cb_iter.next(), Some(&4));
197            assert_eq!(cb_iter.next(), None);
198        }
199
200        // Push in a value
201        cb.push(5);
202        {
203            let mut cb_iter = cb.iter();
204            assert_eq!(cb_iter.next(), Some(&1));
205            assert_eq!(cb_iter.next(), Some(&2));
206            assert_eq!(cb_iter.next(), Some(&3));
207            assert_eq!(cb_iter.next(), Some(&4));
208            assert_eq!(cb_iter.next(), Some(&5));
209            assert_eq!(cb_iter.next(), None);
210        }
211
212        // Push in a value
213        cb.push(6);
214        {
215            let mut cb_iter = cb.iter();
216            assert_eq!(cb_iter.next(), Some(&2));
217            assert_eq!(cb_iter.next(), Some(&3));
218            assert_eq!(cb_iter.next(), Some(&4));
219            assert_eq!(cb_iter.next(), Some(&5));
220            assert_eq!(cb_iter.next(), Some(&6));
221            assert_eq!(cb_iter.next(), None);
222        }
223
224        // Push in a value
225        cb.push(7);
226        {
227            let mut cb_iter = cb.iter();
228            assert_eq!(cb_iter.next(), Some(&3));
229            assert_eq!(cb_iter.next(), Some(&4));
230            assert_eq!(cb_iter.next(), Some(&5));
231            assert_eq!(cb_iter.next(), Some(&6));
232            assert_eq!(cb_iter.next(), Some(&7));
233            assert_eq!(cb_iter.next(), None);
234        }
235
236        // Push in a value
237        cb.push(8);
238        {
239            let mut cb_iter = cb.iter();
240            assert_eq!(cb_iter.next(), Some(&4));
241            assert_eq!(cb_iter.next(), Some(&5));
242            assert_eq!(cb_iter.next(), Some(&6));
243            assert_eq!(cb_iter.next(), Some(&7));
244            assert_eq!(cb_iter.next(), Some(&8));
245            assert_eq!(cb_iter.next(), None);
246        }
247
248        // Push in a value
249        cb.push(9);
250        {
251            let mut cb_iter = cb.iter();
252            assert_eq!(cb_iter.next(), Some(&5));
253            assert_eq!(cb_iter.next(), Some(&6));
254            assert_eq!(cb_iter.next(), Some(&7));
255            assert_eq!(cb_iter.next(), Some(&8));
256            assert_eq!(cb_iter.next(), Some(&9));
257            assert_eq!(cb_iter.next(), None);
258        }
259
260        // Push in a value
261        cb.push(10);
262        {
263            let mut cb_iter = cb.iter();
264            assert_eq!(cb_iter.next(), Some(&6));
265            assert_eq!(cb_iter.next(), Some(&7));
266            assert_eq!(cb_iter.next(), Some(&8));
267            assert_eq!(cb_iter.next(), Some(&9));
268            assert_eq!(cb_iter.next(), Some(&10));
269            assert_eq!(cb_iter.next(), None);
270        }
271
272        // Push in a value
273        cb.push(11);
274        {
275            let mut cb_iter = cb.iter();
276            assert_eq!(cb_iter.next(), Some(&7));
277            assert_eq!(cb_iter.next(), Some(&8));
278            assert_eq!(cb_iter.next(), Some(&9));
279            assert_eq!(cb_iter.next(), Some(&10));
280            assert_eq!(cb_iter.next(), Some(&11));
281            assert_eq!(cb_iter.next(), None);
282        }
283    }
284    #[test]
285    fn circular_buffer_rev() {
286        use crate::CircularBuffer;
287
288        let mut cb: CircularBuffer<u64> = CircularBuffer::new(5);
289
290        // Empty buffer
291        {
292            let mut cb_iter = cb.rev_iter();
293            assert_eq!(cb_iter.next(), None);
294        }
295
296        // Push in a value
297        cb.push(1);
298        {
299            let mut cb_iter = cb.rev_iter();
300            assert_eq!(cb_iter.next(), Some(&1));
301            assert_eq!(cb_iter.next(), None);
302        }
303
304        // Push in a value
305        cb.push(2);
306        {
307            let mut cb_iter = cb.rev_iter();
308            assert_eq!(cb_iter.next(), Some(&2));
309            assert_eq!(cb_iter.next(), Some(&1));
310            assert_eq!(cb_iter.next(), None);
311        }
312
313        // Push in a value
314        cb.push(3);
315        {
316            let mut cb_iter = cb.rev_iter();
317            assert_eq!(cb_iter.next(), Some(&3));
318            assert_eq!(cb_iter.next(), Some(&2));
319            assert_eq!(cb_iter.next(), Some(&1));
320            assert_eq!(cb_iter.next(), None);
321        }
322
323        // Push in a value
324        cb.push(4);
325        {
326            let mut cb_iter = cb.rev_iter();
327            assert_eq!(cb_iter.next(), Some(&4));
328            assert_eq!(cb_iter.next(), Some(&3));
329            assert_eq!(cb_iter.next(), Some(&2));
330            assert_eq!(cb_iter.next(), Some(&1));
331            assert_eq!(cb_iter.next(), None);
332        }
333
334        // Push in a value
335        cb.push(5);
336        {
337            let mut cb_iter = cb.rev_iter();
338            assert_eq!(cb_iter.next(), Some(&5));
339            assert_eq!(cb_iter.next(), Some(&4));
340            assert_eq!(cb_iter.next(), Some(&3));
341            assert_eq!(cb_iter.next(), Some(&2));
342            assert_eq!(cb_iter.next(), Some(&1));
343            assert_eq!(cb_iter.next(), None);
344        }
345
346        // Push in a value
347        cb.push(6);
348        {
349            let mut cb_iter = cb.rev_iter();
350            assert_eq!(cb_iter.next(), Some(&6));
351            assert_eq!(cb_iter.next(), Some(&5));
352            assert_eq!(cb_iter.next(), Some(&4));
353            assert_eq!(cb_iter.next(), Some(&3));
354            assert_eq!(cb_iter.next(), Some(&2));
355            assert_eq!(cb_iter.next(), None);
356        }
357
358        // Push in a value
359        cb.push(7);
360        {
361            let mut cb_iter = cb.rev_iter();
362            assert_eq!(cb_iter.next(), Some(&7));
363            assert_eq!(cb_iter.next(), Some(&6));
364            assert_eq!(cb_iter.next(), Some(&5));
365            assert_eq!(cb_iter.next(), Some(&4));
366            assert_eq!(cb_iter.next(), Some(&3));
367            assert_eq!(cb_iter.next(), None);
368        }
369
370        // Push in a value
371        cb.push(8);
372        {
373            let mut cb_iter = cb.rev_iter();
374            assert_eq!(cb_iter.next(), Some(&8));
375            assert_eq!(cb_iter.next(), Some(&7));
376            assert_eq!(cb_iter.next(), Some(&6));
377            assert_eq!(cb_iter.next(), Some(&5));
378            assert_eq!(cb_iter.next(), Some(&4));
379            assert_eq!(cb_iter.next(), None);
380        }
381
382        // Push in a value
383        cb.push(9);
384        {
385            let mut cb_iter = cb.rev_iter();
386            assert_eq!(cb_iter.next(), Some(&9));
387            assert_eq!(cb_iter.next(), Some(&8));
388            assert_eq!(cb_iter.next(), Some(&7));
389            assert_eq!(cb_iter.next(), Some(&6));
390            assert_eq!(cb_iter.next(), Some(&5));
391            assert_eq!(cb_iter.next(), None);
392        }
393
394        // Push in a value
395        cb.push(10);
396        {
397            let mut cb_iter = cb.rev_iter();
398            assert_eq!(cb_iter.next(), Some(&10));
399            assert_eq!(cb_iter.next(), Some(&9));
400            assert_eq!(cb_iter.next(), Some(&8));
401            assert_eq!(cb_iter.next(), Some(&7));
402            assert_eq!(cb_iter.next(), Some(&6));
403            assert_eq!(cb_iter.next(), None);
404        }
405
406        // Push in a value
407        cb.push(11);
408        {
409            let mut cb_iter = cb.rev_iter();
410            assert_eq!(cb_iter.next(), Some(&11));
411            assert_eq!(cb_iter.next(), Some(&10));
412            assert_eq!(cb_iter.next(), Some(&9));
413            assert_eq!(cb_iter.next(), Some(&8));
414            assert_eq!(cb_iter.next(), Some(&7));
415            assert_eq!(cb_iter.next(), None);
416        }
417    }
418    #[test]
419    fn total_elements() {
420        use crate::CircularBuffer;
421
422        let mut cb: CircularBuffer<u64> = CircularBuffer::new(5);
423
424        assert_eq!(0, cb.total_elements());
425        for i in 1..20 {
426            cb.push(i);
427            assert_eq!(i as usize, cb.total_elements());
428        }
429    }
430    #[test]
431    fn has_wrapped() {
432        use crate::CircularBuffer;
433
434        let mut cb: CircularBuffer<u64> = CircularBuffer::new(5);
435
436        assert_eq!(0, cb.total_elements());
437        for i in 1..20 {
438            cb.push(i);
439            assert_eq!(i >= 6, cb.has_wrapped());
440        }
441    }
442    #[test]
443    fn take() {
444        use crate::CircularBuffer;
445
446        let mut cb: CircularBuffer<u64> = CircularBuffer::new(5);
447        for i in 1..5 {
448            cb.push(i);
449        }
450        assert_eq!(vec![1, 2, 3, 4], cb.take());
451
452        for i in 1..6 {
453            cb.push(i);
454        }
455        assert_eq!(vec![1, 2, 3, 4, 5], cb.take());
456
457        for i in 1..7 {
458            cb.push(i);
459        }
460        assert_eq!(vec![2, 3, 4, 5, 6], cb.take());
461
462        let mut cb: CircularBuffer<u64> = CircularBuffer::new(5);
463        for i in 1..20 {
464            cb.push(i);
465        }
466        assert_eq!(vec![15, 16, 17, 18, 19], cb.take());
467    }
468}