entrenar/monitor/inference/collector/
ring.rs1use super::super::path::DecisionPath;
4use super::super::trace::DecisionTrace;
5use super::traits::TraceCollector;
6
7pub struct RingCollector<P: DecisionPath, const N: usize> {
26 buffer: Vec<DecisionTrace<P>>,
27 head: usize,
28}
29
30impl<P: DecisionPath, const N: usize> RingCollector<P, N> {
31 pub fn new() -> Self {
33 Self { buffer: Vec::with_capacity(N), head: 0 }
34 }
35
36 pub fn recent(&self, n: usize) -> Vec<&DecisionTrace<P>> {
38 let take = n.min(self.buffer.len());
39 let mut result = Vec::with_capacity(take);
40
41 for i in 0..take {
42 let idx = if self.buffer.len() < N {
43 self.buffer.len() - 1 - i
45 } else {
46 (self.head + N - 1 - i) % N
48 };
49 result.push(&self.buffer[idx]);
50 }
51
52 result
53 }
54
55 pub fn all(&self) -> Vec<&DecisionTrace<P>> {
57 let mut result = Vec::with_capacity(self.buffer.len());
58
59 if self.buffer.is_empty() {
60 return result;
61 }
62
63 if self.buffer.len() < N {
64 for trace in &self.buffer {
66 result.push(trace);
67 }
68 } else {
69 for i in 0..N {
71 let idx = (self.head + i) % N;
72 result.push(&self.buffer[idx]);
73 }
74 }
75
76 result
77 }
78
79 pub fn last(&self) -> Option<&DecisionTrace<P>> {
81 if self.buffer.is_empty() {
82 return None;
83 }
84 if self.buffer.len() < N {
85 self.buffer.last()
86 } else {
87 let idx = (self.head + N - 1) % N;
88 Some(&self.buffer[idx])
89 }
90 }
91
92 pub fn clear(&mut self) {
94 self.buffer.clear();
95 self.head = 0;
96 }
97
98 pub const fn capacity(&self) -> usize {
100 N
101 }
102}
103
104impl<P: DecisionPath, const N: usize> TraceCollector<P> for RingCollector<P, N> {
105 fn record(&mut self, trace: DecisionTrace<P>) {
106 if self.buffer.len() < N {
107 self.buffer.push(trace);
109 } else {
110 self.buffer[self.head] = trace;
112 self.head = (self.head + 1) % N;
113 }
114 }
115
116 fn flush(&mut self) -> std::io::Result<()> {
117 Ok(())
119 }
120
121 fn len(&self) -> usize {
122 self.buffer.len()
123 }
124}
125
126impl<P: DecisionPath, const N: usize> Default for RingCollector<P, N> {
127 fn default() -> Self {
128 Self::new()
129 }
130}