1use std::sync::Arc;
2use parking_lot::Mutex;
3
4pub struct ResultBuffer {
7 data: Vec<u8>,
8}
9
10impl ResultBuffer {
11 const DEFAULT_CAPACITY: usize = 4096;
12
13 pub fn new() -> Self {
14 Self {
15 data: Vec::with_capacity(Self::DEFAULT_CAPACITY),
16 }
17 }
18
19 pub fn as_mut(&mut self) -> &mut Vec<u8> {
20 &mut self.data
21 }
22
23 pub fn as_slice(&self) -> &[u8] {
24 &self.data
25 }
26
27 pub fn clear(&mut self) {
28 self.data.clear();
29 }
30
31 pub fn len(&self) -> usize {
32 self.data.len()
33 }
34
35 pub fn is_empty(&self) -> bool {
36 self.data.is_empty()
37 }
38}
39
40pub struct BufferPool {
43 buffers: Arc<Mutex<Vec<ResultBuffer>>>,
44 max_cached: usize,
45}
46
47impl BufferPool {
48 pub fn new(max_cached: usize) -> Self {
49 Self {
50 buffers: Arc::new(Mutex::new(Vec::with_capacity(max_cached))),
51 max_cached,
52 }
53 }
54
55 pub fn acquire(&self) -> ResultBuffer {
56 let mut buffers = self.buffers.lock();
57 buffers.pop().unwrap_or_else(ResultBuffer::new)
58 }
59
60 pub fn release(&self, mut buffer: ResultBuffer) {
61 buffer.clear();
62 let mut buffers = self.buffers.lock();
63 if buffers.len() < self.max_cached {
64 buffers.push(buffer);
65 }
66 }
67
68 pub fn size(&self) -> usize {
69 self.buffers.lock().len()
70 }
71}
72
73#[cfg(test)]
74mod tests {
75 use super::*;
76
77 #[test]
78 fn test_result_buffer_creation() {
79 let buf = ResultBuffer::new();
80 assert!(buf.is_empty());
81 assert!(buf.len() == 0);
82 }
83
84 #[test]
85 fn test_buffer_pool_acquire_release() {
86 let pool = BufferPool::new(2);
87 let buf = pool.acquire();
88 assert_eq!(pool.size(), 0);
89 pool.release(buf);
90 assert_eq!(pool.size(), 1);
91 }
92
93 #[test]
94 fn test_buffer_pool_respects_max_cached() {
95 let pool = BufferPool::new(1);
96 let buf1 = pool.acquire();
97 let buf2 = pool.acquire();
98 pool.release(buf1);
99 pool.release(buf2);
100 assert_eq!(pool.size(), 1);
102 }
103}