circle_buffer/
lib.rs

1extern crate num;
2
3use std::ops::{Index, IndexMut};
4use std::slice::{Iter, IterMut};
5use num::Zero;
6
7/// A circular buffer.
8pub struct CircleBuffer<T> where T: Clone {
9    capacity: usize,
10    vec: Vec<T>,
11    cur_start: usize,
12}
13
14impl<T> CircleBuffer<T> where T: Clone {
15    /// Creates a new empty `CircleBuffer<T>` with capacity.
16    ///
17    /// # Examples
18    ///
19    /// ```
20    /// use circle_buffer::CircleBuffer;
21    ///
22    /// let mut cbuf: CircleBuffer<i32> = CircleBuffer::with_capacity(3);
23    /// ```
24    pub fn with_capacity(capacity: usize) -> CircleBuffer<T> {
25        CircleBuffer {
26            capacity: capacity,
27            vec: Vec::with_capacity(capacity * 2 - 1),
28            cur_start: 0,
29        }
30    }
31
32    /// Returns the capacity of the buffer.
33    ///
34    /// # Examples
35    ///
36    /// ```
37    /// use circle_buffer::CircleBuffer;
38    ///
39    /// let mut cbuf: CircleBuffer<i32> = CircleBuffer::with_capacity(3);
40    /// assert_eq!(3, cbuf.capacity());
41    /// ```
42    pub fn capacity(&self) -> usize {
43        self.capacity
44    }
45
46    /// Returns the current number of elements in the buffer.
47    ///
48    /// # Examples
49    /// 
50    /// ```
51    /// use circle_buffer::CircleBuffer;
52    ///
53    /// let mut cbuf: CircleBuffer<i32> = CircleBuffer::with_capacity(10);
54    /// cbuf.push(1);
55    /// cbuf.push(1);
56    /// cbuf.push(1);
57    ///
58    /// assert_eq!(cbuf.len(), 3);
59    /// ```
60    pub fn len(&self) -> usize {
61        let len = self.vec.len();
62        if len > self.capacity {
63            self.capacity
64        }else{
65            len
66        }
67    }
68
69    /// Returns true if the buffer contains no elements.
70    ///
71    /// # Examples
72    ///
73    /// ```
74    /// use circle_buffer::CircleBuffer;
75    ///
76    /// let mut cbuf: CircleBuffer<i32> = CircleBuffer::with_capacity(3);
77    /// assert!(cbuf.is_empty());
78    ///
79    /// cbuf.push(1);
80    /// assert!(!cbuf.is_empty())
81    /// ```
82    pub fn is_empty(&self) -> bool {
83        self.vec.len() == 0
84    }
85
86    /// Pushes a new element into the buffer.
87    /// Once the capacity is reached, pushing new items will overwrite old ones.
88    ///
89    /// # Examples
90    /// 
91    /// ```
92    /// use circle_buffer::CircleBuffer;
93    ///
94    /// let mut cbuf: CircleBuffer<i32> = CircleBuffer::with_capacity(3);
95    /// cbuf.push(1);
96    /// cbuf.push(2);
97    /// cbuf.push(3);
98    /// cbuf.push(4);
99    ///
100    /// assert_eq!(cbuf.len(), 3);
101    ///
102    /// assert_eq!(cbuf[0], 2);
103    /// assert_eq!(cbuf[1], 3);
104    /// assert_eq!(cbuf[2], 4);
105    ///
106    /// let mut sum = 0;
107    /// for x in cbuf.as_slice() {
108    ///     sum += x;
109    /// }
110    /// assert_eq!(sum, 9);
111    /// ```
112    pub fn push(&mut self, value: T){
113        if self.vec.len() < self.capacity {
114            self.vec.push(value);
115
116        } else if self.vec.len() < self.capacity * 2 - 1 {
117            let v = value.clone();
118            self.vec.push(value);
119            self.vec[self.cur_start] = v;
120
121            self.cur_start += 1;
122
123        } else {
124            let v = value.clone();
125
126            let index = self.cur_start + self.capacity;
127            if index < self.capacity * 2 - 1 {
128                self.vec[index] = value;
129            }
130
131            self.vec[self.cur_start] = v;
132
133            self.cur_start += 1;
134            if self.cur_start >= self.capacity {
135                self.cur_start = 0;
136            }
137        }
138    }
139
140    /// Extracts a slice containing the entire buffer.
141    pub fn as_slice(&self) -> &[T] {
142        if self.vec.len() < self.capacity {
143            self.vec.as_slice()
144        }else{
145            &self.vec.as_slice()[self.cur_start..self.cur_start + self.capacity]
146        }
147    }
148
149    /// Extracts a mutable slice of the entire buffer.
150    pub fn as_mut_slice(&mut self) -> &mut [T] {
151        if self.vec.len() < self.capacity {
152            self.vec.as_mut_slice()
153        }else{
154            &mut self.vec.as_mut_slice()[self.cur_start..self.cur_start + self.capacity]
155        }
156    }
157
158    /// Returns an iterator over the buffer's contents.
159    /// The iterator goes from the most recently pushed items to the oldest ones.
160    ///
161    /// # Examples
162    ///
163    /// ```
164    /// use circle_buffer::CircleBuffer;
165    ///
166    /// let mut buffer = CircleBuffer::with_capacity(3);
167    /// buffer.push(1);
168    /// buffer.push(2);
169    /// buffer.push(3);
170    /// let add1: Vec<i32> = buffer.iter().map(|x| x + 1).collect();
171    /// assert_eq!(add1, vec![2, 3, 4]);
172    ///
173    /// buffer.push(4);
174    /// buffer.push(5);
175    /// let add2: Vec<i32> = buffer.iter().map(|x| x + 2).collect();
176    /// assert_eq!(add2, vec![5, 6, 7]);
177    /// ```
178    pub fn iter(&self) -> Iter<T> {
179        self.vec[self.cur_start..self.cur_start + self.len()].iter()
180    }
181
182    /// Returns a mutable iterator over the buffer's contents.
183    /// The iterator goes from the most recently pushed items to the oldest ones.
184    ///
185    /// # Examples
186    ///
187    /// ```
188    /// use circle_buffer::CircleBuffer;
189    ///
190    /// let mut buffer = CircleBuffer::with_capacity(3);
191    /// buffer.push(1);
192    /// buffer.push(2);
193    /// buffer.push(3);
194    /// for x in buffer.iter_mut() {
195    ///     *x += 1;
196    /// }
197    /// assert_eq!(buffer.as_slice(), &[2, 3, 4]);
198    ///
199    /// buffer.push(4);
200    /// buffer.push(5);
201    /// for x in buffer.iter_mut() {
202    ///     *x += 2;
203    /// }
204    /// assert_eq!(buffer.as_slice(), &[6, 6, 7]);
205    /// ```
206    pub fn iter_mut(&mut self) -> IterMut<T> {
207        let end_index = self.cur_start + self.len();
208        self.vec[self.cur_start..end_index].iter_mut()
209    }
210}
211
212impl<T> CircleBuffer<T> where T: Clone + Zero {
213    /// Fill all elements with zeros.
214    ///
215    /// # Examples
216    ///
217    /// ```
218    /// use circle_buffer::CircleBuffer;
219    ///
220    /// let mut cbuf: CircleBuffer<i32> = CircleBuffer::with_capacity(3);
221    /// cbuf.push(1);
222    /// cbuf.zero_clear();
223    /// assert!(cbuf.len() == 3);
224    /// assert_eq!(cbuf.as_slice(), &[0, 0, 0]);
225    ///
226    /// cbuf.push(2);
227    /// assert_eq!(cbuf.as_slice(), &[0, 0, 2]);
228    /// ```
229    pub fn zero_clear(&mut self){
230        self.vec = vec![T::zero(); self.capacity * 2 - 1];
231        self.cur_start = 0;
232    }
233}
234
235impl<T> Index<usize> for CircleBuffer<T> where T: Clone {
236    type Output = T;
237
238    fn index(&self, index: usize) -> &T {
239        assert!(index < self.vec.len());
240        &self.as_slice()[index]
241    }
242}
243
244impl<T> IndexMut<usize> for CircleBuffer<T> where T: Clone {
245    fn index_mut(&mut self, index: usize) -> &mut T {
246        assert!(index < self.vec.len());
247        &mut self.as_mut_slice()[index]
248    }
249}
250
251#[cfg(test)]
252mod tests {
253    use super::*;
254
255    #[test]
256    fn test_push() {
257        let mut buffer = CircleBuffer::with_capacity(3);
258        buffer.push(1);
259        assert_eq!(&[1], buffer.as_slice());
260        buffer.push(2);
261        assert_eq!(&[1, 2], buffer.as_slice());
262        buffer.push(3);
263        assert_eq!(&[1, 2, 3], buffer.as_slice());
264        buffer.push(4);
265        assert_eq!(&[2, 3, 4], buffer.as_slice());
266        buffer.push(5);
267        assert_eq!(&[3, 4, 5], buffer.as_slice());
268        buffer.push(6);
269        assert_eq!(&[4, 5, 6], buffer.as_slice());
270        buffer.push(7);
271        assert_eq!(&[5, 6, 7], buffer.as_slice());
272        buffer.push(8);
273        assert_eq!(&[6, 7, 8], buffer.as_slice());
274        buffer.push(9);
275        assert_eq!(&[7, 8, 9], buffer.as_slice());
276        buffer.push(10);
277        assert_eq!(&[8, 9, 10], buffer.as_slice());
278        buffer.push(11);
279        assert_eq!(&[9, 10, 11], buffer.as_slice());
280        buffer.push(12);
281        assert_eq!(&[10, 11, 12], buffer.as_slice());
282        buffer.push(13);
283        assert_eq!(&[11, 12, 13], buffer.as_slice());
284        buffer.push(14);
285        assert_eq!(&[12, 13, 14], buffer.as_slice());
286        buffer.push(15);
287        assert_eq!(&[13, 14, 15], buffer.as_slice());
288        buffer.push(16);
289        assert_eq!(&[14, 15, 16], buffer.as_slice());
290        buffer.push(17);
291        assert_eq!(&[15, 16, 17], buffer.as_slice());
292    }
293
294    #[test]
295    fn test_capacity() {
296        let mut buffer = CircleBuffer::with_capacity(3);
297        assert_eq!(3, buffer.capacity());
298        buffer.push(1);
299        assert_eq!(3, buffer.capacity());
300        buffer.push(2);
301        assert_eq!(3, buffer.capacity());
302        buffer.push(3);
303        assert_eq!(3, buffer.capacity());
304        buffer.push(4);
305        assert_eq!(3, buffer.capacity());
306        buffer.push(5);
307        assert_eq!(3, buffer.capacity());
308    }
309
310    #[test]
311    fn test_len() {
312        let mut buffer = CircleBuffer::with_capacity(3);
313        assert_eq!(0, buffer.len());
314        buffer.push(1);
315        assert_eq!(1, buffer.len());
316        buffer.push(2);
317        assert_eq!(2, buffer.len());
318        buffer.push(3);
319        assert_eq!(3, buffer.len());
320        buffer.push(4);
321        assert_eq!(3, buffer.len());
322        buffer.push(5);
323        assert_eq!(3, buffer.len());
324    }
325
326    #[test]
327    fn test_is_empty() {
328        let mut buffer = CircleBuffer::with_capacity(3);
329        assert_eq!(true, buffer.is_empty());
330        buffer.push(1);
331        assert_eq!(false, buffer.is_empty());
332    }
333
334    #[test]
335    fn test_index() {
336        let mut buffer = CircleBuffer::with_capacity(3);
337        buffer.push(1);
338        assert_eq!(1, buffer[0]);
339        buffer.push(2);
340        assert_eq!(1, buffer[0]);
341        assert_eq!(2, buffer[1]);
342        buffer.push(3);
343        assert_eq!(1, buffer[0]);
344        assert_eq!(2, buffer[1]);
345        assert_eq!(3, buffer[2]);
346        buffer.push(4);
347        assert_eq!(2, buffer[0]);
348        assert_eq!(3, buffer[1]);
349        assert_eq!(4, buffer[2]);
350        buffer.push(5);
351        assert_eq!(3, buffer[0]);
352        assert_eq!(4, buffer[1]);
353        assert_eq!(5, buffer[2]);
354    }
355
356    #[test]
357    fn test_index_mut() {
358        let mut buffer = CircleBuffer::with_capacity(3);
359        buffer.push(1);
360        assert_eq!(1, buffer[0]);
361        buffer.push(2);
362        assert_eq!(1, buffer[0]);
363        assert_eq!(2, buffer[1]);
364        buffer.push(3);
365        assert_eq!(1, buffer[0]);
366        assert_eq!(2, buffer[1]);
367        assert_eq!(3, buffer[2]);
368        buffer.push(4);
369        assert_eq!(2, buffer[0]);
370        assert_eq!(3, buffer[1]);
371        assert_eq!(4, buffer[2]);
372
373        buffer[0] = 1;
374        assert_eq!(1, buffer[0]);
375        assert_eq!(3, buffer[1]);
376        assert_eq!(4, buffer[2]);
377    }
378
379    #[test]
380    fn test_iter() {
381        let mut buffer = CircleBuffer::with_capacity(3);
382        buffer.push(1);
383        buffer.push(2);
384        buffer.push(3);
385        let add1: Vec<i32> = buffer.iter().map(|x| x + 1).collect();
386        assert_eq!(add1, vec![2, 3, 4]);
387
388        buffer.push(4);
389        buffer.push(5);
390        let add2: Vec<i32> = buffer.iter().map(|x| x + 2).collect();
391        assert_eq!(add2, vec![5, 6, 7]);
392    }
393
394    #[test]
395    fn test_iter_mut() {
396        let mut buffer = CircleBuffer::with_capacity(3);
397        buffer.push(1);
398        buffer.push(2);
399        buffer.push(3);
400        for x in buffer.iter_mut() {
401            *x += 1;
402        }
403        assert_eq!(buffer.as_slice(), &[2, 3, 4]);
404
405        buffer.push(4);
406        buffer.push(5);
407        for x in buffer.iter_mut() {
408            *x += 2;
409        }
410        assert_eq!(buffer.as_slice(), &[6, 6, 7]);
411    }
412}