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    /// Next free index of the buffer
79    pub fn first_index(&self) -> Option<usize> {
80        if self.next_write_pos == 0 {
81            None
82        } else if self.next_write_pos < self.buffer.capacity() {
83            Some(0)
84        } else {
85            Some(self.next_write_pos - self.buffer.capacity())
86        }
87    }
88    pub fn last_index(&self) -> Option<usize> {
89        if self.next_write_pos == 0 {
90            None
91        } else {
92            Some(self.next_write_pos - 1)
93        }
94    }
95    pub fn element_at_index(&self, index: usize) -> Option<&T> {
96        let max_depth = self.buffer.capacity();
97        if index >= self.next_write_pos {
98            return None;
99        }
100        if index + max_depth < self.next_write_pos {
101            return None;
102        }
103        Some(&self.buffer[index % max_depth])
104    }
105    /// Push a new element into the buffer.
106    /// Until the capacity is reached, elements are pushed.
107    /// Afterwards the oldest elements will be overwritten.
108    pub fn push(&mut self, elem: T) {
109        let max_depth = self.buffer.capacity();
110        if self.buffer.len() < max_depth {
111            self.buffer.push(elem);
112        } else {
113            self.buffer[self.next_write_pos % max_depth] = elem;
114        }
115        self.next_write_pos += 1;
116    }
117    /// Take out all elements from the buffer, leaving an empty buffer behind
118    pub fn take(&mut self) -> Vec<T> {
119        let mut consumed = vec![];
120        let max_depth = self.buffer.capacity();
121        if self.buffer.len() < max_depth {
122            consumed.append(&mut self.buffer);
123        } else {
124            let pos = self.next_write_pos % max_depth;
125            let mut xvec = self.buffer.split_off(pos);
126            consumed.append(&mut xvec);
127            consumed.append(&mut self.buffer)
128        }
129        self.next_write_pos = 0;
130        consumed
131    }
132    /// Total number of elements pushed into the buffer.
133    pub fn total_elements(&self) -> usize {
134        self.next_write_pos
135    }
136    /// If has_wrapped() is true, then elements have been overwritten
137    pub fn has_wrapped(&self) -> bool {
138        self.next_write_pos > self.buffer.capacity()
139    }
140    /// Return an iterator to step through all elements in the sequence,
141    /// as these have been pushed (FIFO)
142    pub fn iter(&mut self) -> iter::Chain<std::slice::Iter<'_, T>, std::slice::Iter<'_, T>> {
143        let max_depth = self.buffer.capacity();
144        if self.next_write_pos <= max_depth {
145            // If buffer is not completely filled, then just iterate through it
146            self.buffer.iter().chain(self.buffer[..0].iter())
147        } else {
148            let wrap = self.next_write_pos % max_depth;
149            let it_end = self.buffer[..wrap].iter();
150            let it_start = self.buffer[wrap..].iter();
151            it_start.chain(it_end)
152        }
153    }
154    /// Return an iterator to step through all elements in the reverse sequence,
155    /// as these have been pushed (LIFO)
156    pub fn rev_iter(
157        &mut self,
158    ) -> iter::Chain<std::iter::Rev<std::slice::Iter<'_, T>>, std::iter::Rev<std::slice::Iter<'_, T>>>
159    {
160        let max_depth = self.buffer.capacity();
161        if self.next_write_pos <= max_depth {
162            // If buffer is not completely filled, then just iterate through it
163            self.buffer
164                .iter()
165                .rev()
166                .chain(self.buffer[..0].iter().rev())
167        } else {
168            let wrap = self.next_write_pos % max_depth;
169            let it_end = self.buffer[..wrap].iter().rev();
170            let it_start = self.buffer[wrap..].iter().rev();
171            it_end.chain(it_start)
172        }
173    }
174}
175
176#[cfg(test)]
177mod tests {
178    #[test]
179    fn circular_buffer() {
180        use crate::CircularBuffer;
181
182        let mut cb: CircularBuffer<u64> = CircularBuffer::new(5);
183
184        // Empty buffer
185        {
186            let mut cb_iter = cb.iter();
187            assert_eq!(cb_iter.next(), None);
188            assert_eq!(cb.first_index(), None);
189            assert_eq!(cb.last_index(), None);
190        }
191
192        // Push in a value
193        cb.push(1);
194        {
195            let mut cb_iter = cb.iter();
196            assert_eq!(cb_iter.next(), Some(&1));
197            assert_eq!(cb_iter.next(), None);
198            assert_eq!(cb.first_index(), Some(0));
199            assert_eq!(cb.last_index(), Some(0));
200        }
201
202        // Push in a value
203        cb.push(2);
204        {
205            let mut cb_iter = cb.iter();
206            assert_eq!(cb_iter.next(), Some(&1));
207            assert_eq!(cb_iter.next(), Some(&2));
208            assert_eq!(cb_iter.next(), None);
209            assert_eq!(cb.first_index(), Some(0));
210            assert_eq!(cb.last_index(), Some(1));
211        }
212
213        // Push in a value
214        cb.push(3);
215        {
216            let mut cb_iter = cb.iter();
217            assert_eq!(cb_iter.next(), Some(&1));
218            assert_eq!(cb_iter.next(), Some(&2));
219            assert_eq!(cb_iter.next(), Some(&3));
220            assert_eq!(cb_iter.next(), None);
221            assert_eq!(cb.first_index(), Some(0));
222            assert_eq!(cb.last_index(), Some(2));
223        }
224
225        // Push in a value
226        cb.push(4);
227        {
228            let mut cb_iter = cb.iter();
229            assert_eq!(cb_iter.next(), Some(&1));
230            assert_eq!(cb_iter.next(), Some(&2));
231            assert_eq!(cb_iter.next(), Some(&3));
232            assert_eq!(cb_iter.next(), Some(&4));
233            assert_eq!(cb_iter.next(), None);
234            assert_eq!(cb.first_index(), Some(0));
235            assert_eq!(cb.last_index(), Some(3));
236        }
237
238        // Push in a value
239        cb.push(5);
240        {
241            let mut cb_iter = cb.iter();
242            assert_eq!(cb_iter.next(), Some(&1));
243            assert_eq!(cb_iter.next(), Some(&2));
244            assert_eq!(cb_iter.next(), Some(&3));
245            assert_eq!(cb_iter.next(), Some(&4));
246            assert_eq!(cb_iter.next(), Some(&5));
247            assert_eq!(cb_iter.next(), None);
248            assert_eq!(cb.first_index(), Some(0));
249            assert_eq!(cb.last_index(), Some(4));
250        }
251
252        // Push in a value
253        cb.push(6);
254        {
255            let mut cb_iter = cb.iter();
256            assert_eq!(cb_iter.next(), Some(&2));
257            assert_eq!(cb_iter.next(), Some(&3));
258            assert_eq!(cb_iter.next(), Some(&4));
259            assert_eq!(cb_iter.next(), Some(&5));
260            assert_eq!(cb_iter.next(), Some(&6));
261            assert_eq!(cb_iter.next(), None);
262            assert_eq!(cb.first_index(), Some(1));
263            assert_eq!(cb.last_index(), Some(5));
264        }
265
266        // Push in a value
267        cb.push(7);
268        {
269            let mut cb_iter = cb.iter();
270            assert_eq!(cb_iter.next(), Some(&3));
271            assert_eq!(cb_iter.next(), Some(&4));
272            assert_eq!(cb_iter.next(), Some(&5));
273            assert_eq!(cb_iter.next(), Some(&6));
274            assert_eq!(cb_iter.next(), Some(&7));
275            assert_eq!(cb_iter.next(), None);
276            assert_eq!(cb.first_index(), Some(2));
277            assert_eq!(cb.last_index(), Some(6));
278        }
279
280        // Push in a value
281        cb.push(8);
282        {
283            let mut cb_iter = cb.iter();
284            assert_eq!(cb_iter.next(), Some(&4));
285            assert_eq!(cb_iter.next(), Some(&5));
286            assert_eq!(cb_iter.next(), Some(&6));
287            assert_eq!(cb_iter.next(), Some(&7));
288            assert_eq!(cb_iter.next(), Some(&8));
289            assert_eq!(cb_iter.next(), None);
290            assert_eq!(cb.first_index(), Some(3));
291            assert_eq!(cb.last_index(), Some(7));
292        }
293
294        // Push in a value
295        cb.push(9);
296        {
297            let mut cb_iter = cb.iter();
298            assert_eq!(cb_iter.next(), Some(&5));
299            assert_eq!(cb_iter.next(), Some(&6));
300            assert_eq!(cb_iter.next(), Some(&7));
301            assert_eq!(cb_iter.next(), Some(&8));
302            assert_eq!(cb_iter.next(), Some(&9));
303            assert_eq!(cb_iter.next(), None);
304            assert_eq!(cb.first_index(), Some(4));
305            assert_eq!(cb.last_index(), Some(8));
306        }
307
308        // Push in a value
309        cb.push(10);
310        {
311            let mut cb_iter = cb.iter();
312            assert_eq!(cb_iter.next(), Some(&6));
313            assert_eq!(cb_iter.next(), Some(&7));
314            assert_eq!(cb_iter.next(), Some(&8));
315            assert_eq!(cb_iter.next(), Some(&9));
316            assert_eq!(cb_iter.next(), Some(&10));
317            assert_eq!(cb_iter.next(), None);
318            assert_eq!(cb.first_index(), Some(5));
319            assert_eq!(cb.last_index(), Some(9));
320        }
321
322        // Push in a value
323        cb.push(11);
324        {
325            let mut cb_iter = cb.iter();
326            assert_eq!(cb_iter.next(), Some(&7));
327            assert_eq!(cb_iter.next(), Some(&8));
328            assert_eq!(cb_iter.next(), Some(&9));
329            assert_eq!(cb_iter.next(), Some(&10));
330            assert_eq!(cb_iter.next(), Some(&11));
331            assert_eq!(cb_iter.next(), None);
332            assert_eq!(cb.first_index(), Some(6));
333            assert_eq!(cb.last_index(), Some(10));
334            assert_eq!(cb.element_at_index(5), None);
335            assert_eq!(cb.element_at_index(6), Some(&7));
336            assert_eq!(cb.element_at_index(10), Some(&11));
337            assert_eq!(cb.element_at_index(11), None);
338        }
339    }
340    #[test]
341    fn circular_buffer_rev() {
342        use crate::CircularBuffer;
343
344        let mut cb: CircularBuffer<u64> = CircularBuffer::new(5);
345
346        // Empty buffer
347        {
348            let mut cb_iter = cb.rev_iter();
349            assert_eq!(cb_iter.next(), None);
350        }
351
352        // Push in a value
353        cb.push(1);
354        {
355            let mut cb_iter = cb.rev_iter();
356            assert_eq!(cb_iter.next(), Some(&1));
357            assert_eq!(cb_iter.next(), None);
358        }
359
360        // Push in a value
361        cb.push(2);
362        {
363            let mut cb_iter = cb.rev_iter();
364            assert_eq!(cb_iter.next(), Some(&2));
365            assert_eq!(cb_iter.next(), Some(&1));
366            assert_eq!(cb_iter.next(), None);
367        }
368
369        // Push in a value
370        cb.push(3);
371        {
372            let mut cb_iter = cb.rev_iter();
373            assert_eq!(cb_iter.next(), Some(&3));
374            assert_eq!(cb_iter.next(), Some(&2));
375            assert_eq!(cb_iter.next(), Some(&1));
376            assert_eq!(cb_iter.next(), None);
377        }
378
379        // Push in a value
380        cb.push(4);
381        {
382            let mut cb_iter = cb.rev_iter();
383            assert_eq!(cb_iter.next(), Some(&4));
384            assert_eq!(cb_iter.next(), Some(&3));
385            assert_eq!(cb_iter.next(), Some(&2));
386            assert_eq!(cb_iter.next(), Some(&1));
387            assert_eq!(cb_iter.next(), None);
388        }
389
390        // Push in a value
391        cb.push(5);
392        {
393            let mut cb_iter = cb.rev_iter();
394            assert_eq!(cb_iter.next(), Some(&5));
395            assert_eq!(cb_iter.next(), Some(&4));
396            assert_eq!(cb_iter.next(), Some(&3));
397            assert_eq!(cb_iter.next(), Some(&2));
398            assert_eq!(cb_iter.next(), Some(&1));
399            assert_eq!(cb_iter.next(), None);
400        }
401
402        // Push in a value
403        cb.push(6);
404        {
405            let mut cb_iter = cb.rev_iter();
406            assert_eq!(cb_iter.next(), Some(&6));
407            assert_eq!(cb_iter.next(), Some(&5));
408            assert_eq!(cb_iter.next(), Some(&4));
409            assert_eq!(cb_iter.next(), Some(&3));
410            assert_eq!(cb_iter.next(), Some(&2));
411            assert_eq!(cb_iter.next(), None);
412        }
413
414        // Push in a value
415        cb.push(7);
416        {
417            let mut cb_iter = cb.rev_iter();
418            assert_eq!(cb_iter.next(), Some(&7));
419            assert_eq!(cb_iter.next(), Some(&6));
420            assert_eq!(cb_iter.next(), Some(&5));
421            assert_eq!(cb_iter.next(), Some(&4));
422            assert_eq!(cb_iter.next(), Some(&3));
423            assert_eq!(cb_iter.next(), None);
424        }
425
426        // Push in a value
427        cb.push(8);
428        {
429            let mut cb_iter = cb.rev_iter();
430            assert_eq!(cb_iter.next(), Some(&8));
431            assert_eq!(cb_iter.next(), Some(&7));
432            assert_eq!(cb_iter.next(), Some(&6));
433            assert_eq!(cb_iter.next(), Some(&5));
434            assert_eq!(cb_iter.next(), Some(&4));
435            assert_eq!(cb_iter.next(), None);
436        }
437
438        // Push in a value
439        cb.push(9);
440        {
441            let mut cb_iter = cb.rev_iter();
442            assert_eq!(cb_iter.next(), Some(&9));
443            assert_eq!(cb_iter.next(), Some(&8));
444            assert_eq!(cb_iter.next(), Some(&7));
445            assert_eq!(cb_iter.next(), Some(&6));
446            assert_eq!(cb_iter.next(), Some(&5));
447            assert_eq!(cb_iter.next(), None);
448        }
449
450        // Push in a value
451        cb.push(10);
452        {
453            let mut cb_iter = cb.rev_iter();
454            assert_eq!(cb_iter.next(), Some(&10));
455            assert_eq!(cb_iter.next(), Some(&9));
456            assert_eq!(cb_iter.next(), Some(&8));
457            assert_eq!(cb_iter.next(), Some(&7));
458            assert_eq!(cb_iter.next(), Some(&6));
459            assert_eq!(cb_iter.next(), None);
460        }
461
462        // Push in a value
463        cb.push(11);
464        {
465            let mut cb_iter = cb.rev_iter();
466            assert_eq!(cb_iter.next(), Some(&11));
467            assert_eq!(cb_iter.next(), Some(&10));
468            assert_eq!(cb_iter.next(), Some(&9));
469            assert_eq!(cb_iter.next(), Some(&8));
470            assert_eq!(cb_iter.next(), Some(&7));
471            assert_eq!(cb_iter.next(), None);
472        }
473    }
474    #[test]
475    fn total_elements() {
476        use crate::CircularBuffer;
477
478        let mut cb: CircularBuffer<u64> = CircularBuffer::new(5);
479
480        assert_eq!(0, cb.total_elements());
481        for i in 1..20 {
482            cb.push(i);
483            assert_eq!(i as usize, cb.total_elements());
484        }
485    }
486    #[test]
487    fn has_wrapped() {
488        use crate::CircularBuffer;
489
490        let mut cb: CircularBuffer<u64> = CircularBuffer::new(5);
491
492        assert_eq!(0, cb.total_elements());
493        for i in 1..20 {
494            cb.push(i);
495            assert_eq!(i >= 6, cb.has_wrapped());
496        }
497    }
498    #[test]
499    fn take() {
500        use crate::CircularBuffer;
501
502        let mut cb: CircularBuffer<u64> = CircularBuffer::new(5);
503        for i in 1..5 {
504            cb.push(i);
505        }
506        assert_eq!(vec![1, 2, 3, 4], cb.take());
507
508        for i in 1..6 {
509            cb.push(i);
510        }
511        assert_eq!(vec![1, 2, 3, 4, 5], cb.take());
512
513        for i in 1..7 {
514            cb.push(i);
515        }
516        assert_eq!(vec![2, 3, 4, 5, 6], cb.take());
517
518        let mut cb: CircularBuffer<u64> = CircularBuffer::new(5);
519        for i in 1..20 {
520            cb.push(i);
521        }
522        assert_eq!(vec![15, 16, 17, 18, 19], cb.take());
523    }
524}