1pub const DEFAULT_SIZE: u16 = 6_000;
5pub const DEFAULT_THRESHOLD: u16 = 5_000;
7
8#[derive(Debug, Clone, Copy)]
10pub struct BufferState {
11 pub total_size: u16,
13 pub free_space: u16,
15 pub threshold: u16,
17 pub last_update_time: u64,
19}
20
21impl BufferState {
22 pub const DEFAULT: Self = Self {
23 total_size: DEFAULT_SIZE,
24 free_space: DEFAULT_SIZE,
25 threshold: DEFAULT_THRESHOLD,
26 last_update_time: 0,
27 };
28
29 pub fn new() -> Self {
31 Self::DEFAULT
32 }
33
34 pub fn update_free_space(&mut self, free_space: u16, current_time: u64) {
36 self.free_space = free_space;
37 self.last_update_time = current_time;
38 }
39
40 pub fn update_total_size(&mut self, total_size: u16) {
42 self.total_size = total_size;
43
44 if total_size > 1000 {
47 self.threshold = total_size - 1000;
48 } else {
49 self.threshold = total_size / 6 * 5;
51 }
52 }
53
54 pub fn should_send(&self) -> bool {
56 self.free_space >= self.threshold
57 }
58
59 pub fn estimate_current_free_space(&self, current_time: u64, dac_rate: u32) -> u16 {
61 if dac_rate == 0 || self.last_update_time == 0 {
62 return self.free_space;
63 }
64
65 let delta_ms = if current_time > self.last_update_time {
67 current_time - self.last_update_time
68 } else {
69 0
71 };
72
73 let points_per_ms = dac_rate as f32 / 1000.0;
75
76 let points_consumed = (delta_ms as f32 * points_per_ms) as u16;
78
79 let estimated_free = self
81 .free_space
82 .saturating_add(points_consumed)
83 .min(self.total_size);
84
85 estimated_free
86 }
87
88 pub fn consume(&mut self, points_sent: u16) {
90 self.free_space = self.free_space.saturating_sub(points_sent);
91 }
92}
93
94impl Default for BufferState {
95 fn default() -> Self {
96 Self::DEFAULT
97 }
98}
99
100#[cfg(test)]
101mod tests {
102 use super::*;
103
104 #[test]
105 fn test_buffer_defaults() {
106 let buffer = BufferState::new();
107
108 assert_eq!(buffer.total_size, DEFAULT_SIZE);
109 assert_eq!(buffer.free_space, DEFAULT_SIZE);
110 assert_eq!(buffer.threshold, DEFAULT_THRESHOLD);
111 assert_eq!(buffer.last_update_time, 0);
112 }
113
114 #[test]
115 fn test_update_free_space() {
116 let mut buffer = BufferState::new();
117
118 buffer.update_free_space(3000, 100);
120 assert_eq!(buffer.free_space, 3000);
121 assert_eq!(buffer.last_update_time, 100);
122
123 buffer.update_free_space(4000, 200);
125 assert_eq!(buffer.free_space, 4000);
126 assert_eq!(buffer.last_update_time, 200);
127 }
128
129 #[test]
130 fn test_update_total_size() {
131 let mut buffer = BufferState::new();
132
133 buffer.update_total_size(8000);
135 assert_eq!(buffer.total_size, 8000);
136 assert_eq!(buffer.threshold, 7000); buffer.update_total_size(600);
140 assert_eq!(buffer.total_size, 600);
141 assert_eq!(buffer.threshold, 500); }
143
144 #[test]
145 fn test_should_send() {
146 let mut buffer = BufferState::new();
147 buffer.threshold = 4000;
148
149 buffer.free_space = 3999;
151 assert!(!buffer.should_send());
152
153 buffer.free_space = 4000;
155 assert!(buffer.should_send());
156
157 buffer.free_space = 4001;
159 assert!(buffer.should_send());
160 }
161
162 #[test]
163 fn test_estimate_current_free_space() {
164 let mut buffer = BufferState::new();
165 buffer.total_size = 6000;
166 buffer.free_space = 3000;
167 buffer.last_update_time = 1000;
168
169 let estimate = buffer.estimate_current_free_space(2000, 0);
171 assert_eq!(estimate, 3000); let estimate = buffer.estimate_current_free_space(2000, 1000);
176 assert_eq!(estimate, 4000); buffer.free_space = 5500;
180 let estimate = buffer.estimate_current_free_space(2000, 1000);
181 assert_eq!(estimate, 6000); buffer.free_space = 3000;
185 buffer.last_update_time = 2000;
186 let estimate = buffer.estimate_current_free_space(1000, 1000);
187 assert_eq!(estimate, 3000); }
189
190 #[test]
191 fn test_consume() {
192 let mut buffer = BufferState::new();
193 buffer.free_space = 5000;
194
195 buffer.consume(1000);
197 assert_eq!(buffer.free_space, 4000);
198
199 buffer.consume(5000);
201 assert_eq!(buffer.free_space, 0); }
203
204 #[test]
205 fn test_integrated_buffer_scenario() {
206 let mut buffer = BufferState::new();
208
209 buffer.update_total_size(6000);
211 buffer.update_free_space(6000, 100);
212
213 buffer.consume(1000);
215 assert_eq!(buffer.free_space, 5000);
216
217 let estimate = buffer.estimate_current_free_space(600, 1000);
220 assert_eq!(estimate, 5500); buffer.update_free_space(5400, 600); buffer.consume(2000);
227 assert_eq!(buffer.free_space, 3400);
228
229 assert!(!buffer.should_send()); }
232}