ai_agent/utils/
circular_buffer.rs1use std::collections::VecDeque;
5
6pub struct CircularBuffer<T> {
9 buffer: VecDeque<T>,
10 capacity: usize,
11}
12
13impl<T> CircularBuffer<T> {
14 pub fn new(capacity: usize) -> Self {
16 Self {
17 buffer: VecDeque::with_capacity(capacity),
18 capacity,
19 }
20 }
21
22 pub fn add(&mut self, item: T) {
25 if self.buffer.len() >= self.capacity {
26 self.buffer.pop_front();
27 }
28 self.buffer.push_back(item);
29 }
30
31 pub fn add_all(&mut self, items: impl IntoIterator<Item = T>) {
33 for item in items {
34 self.add(item);
35 }
36 }
37
38 pub fn get_recent(&self, count: usize) -> Vec<&T> {
41 self.buffer.iter().rev().take(count).collect::<Vec<_>>()
42 }
43
44 pub fn to_vec(&self) -> Vec<&T> {
46 self.buffer.iter().collect()
47 }
48
49 pub fn clear(&mut self) {
51 self.buffer.clear();
52 }
53
54 pub fn len(&self) -> usize {
56 self.buffer.len()
57 }
58
59 pub fn is_empty(&self) -> bool {
61 self.buffer.is_empty()
62 }
63}
64
65impl<T: Clone> Clone for CircularBuffer<T> {
66 fn clone(&self) -> Self {
67 Self {
68 buffer: self.buffer.clone(),
69 capacity: self.capacity,
70 }
71 }
72}
73
74#[cfg(test)]
75mod tests {
76 use super::*;
77
78 #[test]
79 fn test_basic_operations() {
80 let mut buffer = CircularBuffer::new(3);
81 assert_eq!(buffer.len(), 0);
82
83 buffer.add(1);
84 buffer.add(2);
85 buffer.add(3);
86 assert_eq!(buffer.len(), 3);
87
88 buffer.add(4);
90 assert_eq!(buffer.len(), 3);
91 assert_eq!(buffer.to_vec(), vec![&2, &3, &4]);
92 }
93
94 #[test]
95 fn test_get_recent() {
96 let mut buffer = CircularBuffer::new(5);
97 for i in 1..=10 {
98 buffer.add(i);
99 }
100
101 let recent = buffer.get_recent(3);
102 assert_eq!(recent, vec![&10, &9, &8]);
103 }
104
105 #[test]
106 fn test_clear() {
107 let mut buffer = CircularBuffer::new(3);
108 buffer.add(1);
109 buffer.add(2);
110 buffer.clear();
111 assert_eq!(buffer.len(), 0);
112 }
113}