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        let max_depth = self.buffer.capacity();
160        if self.next_write_pos <= max_depth {
161            // If buffer is not completely filled, then just iterate through it
162            self.buffer
163                .iter()
164                .rev()
165                .chain(self.buffer[..0].iter().rev())
166        } else {
167            let wrap = self.next_write_pos % max_depth;
168            let it_end = self.buffer[..wrap].iter().rev();
169            let it_start = self.buffer[wrap..].iter().rev();
170            it_end.chain(it_start)
171        }
172    }
173}
174
175#[cfg(test)]
176mod tests {
177    #[test]
178    fn circular_buffer() {
179        use crate::CircularBuffer;
180
181        let mut cb: CircularBuffer<u64> = CircularBuffer::new(5);
182
183        // Empty buffer
184        {
185            let mut cb_iter = cb.iter();
186            assert_eq!(cb_iter.next(), None);
187            assert_eq!(cb.first_index(), None);
188            assert_eq!(cb.last_index(), None);
189        }
190
191        // Push in a value
192        cb.push(1);
193        {
194            let mut cb_iter = cb.iter();
195            assert_eq!(cb_iter.next(), Some(&1));
196            assert_eq!(cb_iter.next(), None);
197            assert_eq!(cb.first_index(), Some(0));
198            assert_eq!(cb.last_index(), Some(0));
199        }
200
201        // Push in a value
202        cb.push(2);
203        {
204            let mut cb_iter = cb.iter();
205            assert_eq!(cb_iter.next(), Some(&1));
206            assert_eq!(cb_iter.next(), Some(&2));
207            assert_eq!(cb_iter.next(), None);
208            assert_eq!(cb.first_index(), Some(0));
209            assert_eq!(cb.last_index(), Some(1));
210        }
211
212        // Push in a value
213        cb.push(3);
214        {
215            let mut cb_iter = cb.iter();
216            assert_eq!(cb_iter.next(), Some(&1));
217            assert_eq!(cb_iter.next(), Some(&2));
218            assert_eq!(cb_iter.next(), Some(&3));
219            assert_eq!(cb_iter.next(), None);
220            assert_eq!(cb.first_index(), Some(0));
221            assert_eq!(cb.last_index(), Some(2));
222        }
223
224        // Push in a value
225        cb.push(4);
226        {
227            let mut cb_iter = cb.iter();
228            assert_eq!(cb_iter.next(), Some(&1));
229            assert_eq!(cb_iter.next(), Some(&2));
230            assert_eq!(cb_iter.next(), Some(&3));
231            assert_eq!(cb_iter.next(), Some(&4));
232            assert_eq!(cb_iter.next(), None);
233            assert_eq!(cb.first_index(), Some(0));
234            assert_eq!(cb.last_index(), Some(3));
235        }
236
237        // Push in a value
238        cb.push(5);
239        {
240            let mut cb_iter = cb.iter();
241            assert_eq!(cb_iter.next(), Some(&1));
242            assert_eq!(cb_iter.next(), Some(&2));
243            assert_eq!(cb_iter.next(), Some(&3));
244            assert_eq!(cb_iter.next(), Some(&4));
245            assert_eq!(cb_iter.next(), Some(&5));
246            assert_eq!(cb_iter.next(), None);
247            assert_eq!(cb.first_index(), Some(0));
248            assert_eq!(cb.last_index(), Some(4));
249        }
250
251        // Push in a value
252        cb.push(6);
253        {
254            let mut cb_iter = cb.iter();
255            assert_eq!(cb_iter.next(), Some(&2));
256            assert_eq!(cb_iter.next(), Some(&3));
257            assert_eq!(cb_iter.next(), Some(&4));
258            assert_eq!(cb_iter.next(), Some(&5));
259            assert_eq!(cb_iter.next(), Some(&6));
260            assert_eq!(cb_iter.next(), None);
261            assert_eq!(cb.first_index(), Some(1));
262            assert_eq!(cb.last_index(), Some(5));
263        }
264
265        // Push in a value
266        cb.push(7);
267        {
268            let mut cb_iter = cb.iter();
269            assert_eq!(cb_iter.next(), Some(&3));
270            assert_eq!(cb_iter.next(), Some(&4));
271            assert_eq!(cb_iter.next(), Some(&5));
272            assert_eq!(cb_iter.next(), Some(&6));
273            assert_eq!(cb_iter.next(), Some(&7));
274            assert_eq!(cb_iter.next(), None);
275            assert_eq!(cb.first_index(), Some(2));
276            assert_eq!(cb.last_index(), Some(6));
277        }
278
279        // Push in a value
280        cb.push(8);
281        {
282            let mut cb_iter = cb.iter();
283            assert_eq!(cb_iter.next(), Some(&4));
284            assert_eq!(cb_iter.next(), Some(&5));
285            assert_eq!(cb_iter.next(), Some(&6));
286            assert_eq!(cb_iter.next(), Some(&7));
287            assert_eq!(cb_iter.next(), Some(&8));
288            assert_eq!(cb_iter.next(), None);
289            assert_eq!(cb.first_index(), Some(3));
290            assert_eq!(cb.last_index(), Some(7));
291        }
292
293        // Push in a value
294        cb.push(9);
295        {
296            let mut cb_iter = cb.iter();
297            assert_eq!(cb_iter.next(), Some(&5));
298            assert_eq!(cb_iter.next(), Some(&6));
299            assert_eq!(cb_iter.next(), Some(&7));
300            assert_eq!(cb_iter.next(), Some(&8));
301            assert_eq!(cb_iter.next(), Some(&9));
302            assert_eq!(cb_iter.next(), None);
303            assert_eq!(cb.first_index(), Some(4));
304            assert_eq!(cb.last_index(), Some(8));
305        }
306
307        // Push in a value
308        cb.push(10);
309        {
310            let mut cb_iter = cb.iter();
311            assert_eq!(cb_iter.next(), Some(&6));
312            assert_eq!(cb_iter.next(), Some(&7));
313            assert_eq!(cb_iter.next(), Some(&8));
314            assert_eq!(cb_iter.next(), Some(&9));
315            assert_eq!(cb_iter.next(), Some(&10));
316            assert_eq!(cb_iter.next(), None);
317            assert_eq!(cb.first_index(), Some(5));
318            assert_eq!(cb.last_index(), Some(9));
319        }
320
321        // Push in a value
322        cb.push(11);
323        {
324            let mut cb_iter = cb.iter();
325            assert_eq!(cb_iter.next(), Some(&7));
326            assert_eq!(cb_iter.next(), Some(&8));
327            assert_eq!(cb_iter.next(), Some(&9));
328            assert_eq!(cb_iter.next(), Some(&10));
329            assert_eq!(cb_iter.next(), Some(&11));
330            assert_eq!(cb_iter.next(), None);
331            assert_eq!(cb.first_index(), Some(6));
332            assert_eq!(cb.last_index(), Some(10));
333            assert_eq!(cb.element_at_index(5), None);
334            assert_eq!(cb.element_at_index(6), Some(&7));
335            assert_eq!(cb.element_at_index(10), Some(&11));
336            assert_eq!(cb.element_at_index(11), None);
337        }
338    }
339    #[test]
340    fn circular_buffer_rev() {
341        use crate::CircularBuffer;
342
343        let mut cb: CircularBuffer<u64> = CircularBuffer::new(5);
344
345        // Empty buffer
346        {
347            let mut cb_iter = cb.rev_iter();
348            assert_eq!(cb_iter.next(), None);
349        }
350
351        // Push in a value
352        cb.push(1);
353        {
354            let mut cb_iter = cb.rev_iter();
355            assert_eq!(cb_iter.next(), Some(&1));
356            assert_eq!(cb_iter.next(), None);
357        }
358
359        // Push in a value
360        cb.push(2);
361        {
362            let mut cb_iter = cb.rev_iter();
363            assert_eq!(cb_iter.next(), Some(&2));
364            assert_eq!(cb_iter.next(), Some(&1));
365            assert_eq!(cb_iter.next(), None);
366        }
367
368        // Push in a value
369        cb.push(3);
370        {
371            let mut cb_iter = cb.rev_iter();
372            assert_eq!(cb_iter.next(), Some(&3));
373            assert_eq!(cb_iter.next(), Some(&2));
374            assert_eq!(cb_iter.next(), Some(&1));
375            assert_eq!(cb_iter.next(), None);
376        }
377
378        // Push in a value
379        cb.push(4);
380        {
381            let mut cb_iter = cb.rev_iter();
382            assert_eq!(cb_iter.next(), Some(&4));
383            assert_eq!(cb_iter.next(), Some(&3));
384            assert_eq!(cb_iter.next(), Some(&2));
385            assert_eq!(cb_iter.next(), Some(&1));
386            assert_eq!(cb_iter.next(), None);
387        }
388
389        // Push in a value
390        cb.push(5);
391        {
392            let mut cb_iter = cb.rev_iter();
393            assert_eq!(cb_iter.next(), Some(&5));
394            assert_eq!(cb_iter.next(), Some(&4));
395            assert_eq!(cb_iter.next(), Some(&3));
396            assert_eq!(cb_iter.next(), Some(&2));
397            assert_eq!(cb_iter.next(), Some(&1));
398            assert_eq!(cb_iter.next(), None);
399        }
400
401        // Push in a value
402        cb.push(6);
403        {
404            let mut cb_iter = cb.rev_iter();
405            assert_eq!(cb_iter.next(), Some(&6));
406            assert_eq!(cb_iter.next(), Some(&5));
407            assert_eq!(cb_iter.next(), Some(&4));
408            assert_eq!(cb_iter.next(), Some(&3));
409            assert_eq!(cb_iter.next(), Some(&2));
410            assert_eq!(cb_iter.next(), None);
411        }
412
413        // Push in a value
414        cb.push(7);
415        {
416            let mut cb_iter = cb.rev_iter();
417            assert_eq!(cb_iter.next(), Some(&7));
418            assert_eq!(cb_iter.next(), Some(&6));
419            assert_eq!(cb_iter.next(), Some(&5));
420            assert_eq!(cb_iter.next(), Some(&4));
421            assert_eq!(cb_iter.next(), Some(&3));
422            assert_eq!(cb_iter.next(), None);
423        }
424
425        // Push in a value
426        cb.push(8);
427        {
428            let mut cb_iter = cb.rev_iter();
429            assert_eq!(cb_iter.next(), Some(&8));
430            assert_eq!(cb_iter.next(), Some(&7));
431            assert_eq!(cb_iter.next(), Some(&6));
432            assert_eq!(cb_iter.next(), Some(&5));
433            assert_eq!(cb_iter.next(), Some(&4));
434            assert_eq!(cb_iter.next(), None);
435        }
436
437        // Push in a value
438        cb.push(9);
439        {
440            let mut cb_iter = cb.rev_iter();
441            assert_eq!(cb_iter.next(), Some(&9));
442            assert_eq!(cb_iter.next(), Some(&8));
443            assert_eq!(cb_iter.next(), Some(&7));
444            assert_eq!(cb_iter.next(), Some(&6));
445            assert_eq!(cb_iter.next(), Some(&5));
446            assert_eq!(cb_iter.next(), None);
447        }
448
449        // Push in a value
450        cb.push(10);
451        {
452            let mut cb_iter = cb.rev_iter();
453            assert_eq!(cb_iter.next(), Some(&10));
454            assert_eq!(cb_iter.next(), Some(&9));
455            assert_eq!(cb_iter.next(), Some(&8));
456            assert_eq!(cb_iter.next(), Some(&7));
457            assert_eq!(cb_iter.next(), Some(&6));
458            assert_eq!(cb_iter.next(), None);
459        }
460
461        // Push in a value
462        cb.push(11);
463        {
464            let mut cb_iter = cb.rev_iter();
465            assert_eq!(cb_iter.next(), Some(&11));
466            assert_eq!(cb_iter.next(), Some(&10));
467            assert_eq!(cb_iter.next(), Some(&9));
468            assert_eq!(cb_iter.next(), Some(&8));
469            assert_eq!(cb_iter.next(), Some(&7));
470            assert_eq!(cb_iter.next(), None);
471        }
472    }
473    #[test]
474    fn total_elements() {
475        use crate::CircularBuffer;
476
477        let mut cb: CircularBuffer<u64> = CircularBuffer::new(5);
478
479        assert_eq!(0, cb.total_elements());
480        for i in 1..20 {
481            cb.push(i);
482            assert_eq!(i as usize, cb.total_elements());
483        }
484    }
485    #[test]
486    fn has_wrapped() {
487        use crate::CircularBuffer;
488
489        let mut cb: CircularBuffer<u64> = CircularBuffer::new(5);
490
491        assert_eq!(0, cb.total_elements());
492        for i in 1..20 {
493            cb.push(i);
494            assert_eq!(i >= 6, cb.has_wrapped());
495        }
496    }
497    #[test]
498    fn take() {
499        use crate::CircularBuffer;
500
501        let mut cb: CircularBuffer<u64> = CircularBuffer::new(5);
502        for i in 1..5 {
503            cb.push(i);
504        }
505        assert_eq!(vec![1, 2, 3, 4], cb.take());
506
507        for i in 1..6 {
508            cb.push(i);
509        }
510        assert_eq!(vec![1, 2, 3, 4, 5], cb.take());
511
512        for i in 1..7 {
513            cb.push(i);
514        }
515        assert_eq!(vec![2, 3, 4, 5, 6], cb.take());
516
517        let mut cb: CircularBuffer<u64> = CircularBuffer::new(5);
518        for i in 1..20 {
519            cb.push(i);
520        }
521        assert_eq!(vec![15, 16, 17, 18, 19], cb.take());
522    }
523}