use std::collections::VecDeque;
use std::marker::PhantomData;
use std::sync::Mutex;
pub struct BufferPool<T> {
pool: Mutex<VecDeque<Vec<T>>>,
_phantom: PhantomData<T>,
}
impl<T: Clone + Default> BufferPool<T> {
pub const fn new() -> Self {
Self {
pool: Mutex::new(VecDeque::new()),
_phantom: PhantomData,
}
}
pub fn get(&self, size: usize) -> Vec<T> {
let mut pool = self.pool.lock().unwrap_or_else(|e| e.into_inner());
pool.pop_front().map_or_else(
|| vec![T::default(); size],
|mut buffer| {
buffer.resize(size, T::default());
buffer
},
)
}
pub fn put(&self, buffer: Vec<T>) {
let mut pool = self.pool.lock().unwrap_or_else(|e| e.into_inner());
pool.push_back(buffer);
}
#[inline]
pub fn return_buffer(&self, buffer: Vec<T>) {
self.put(buffer);
}
pub fn pool_size(&self) -> usize {
self.pool.lock().unwrap_or_else(|e| e.into_inner()).len()
}
pub fn clear(&self) {
let mut pool = self.pool.lock().unwrap_or_else(|e| e.into_inner());
pool.clear();
}
}
impl<T> Default for BufferPool<T> {
fn default() -> Self {
Self {
pool: Mutex::new(VecDeque::new()),
_phantom: PhantomData,
}
}
}