#[cfg(not(feature = "std"))]
use alloc::vec::Vec;
use core::mem::size_of;
use super::aligned_vec::AlignedVec;
use super::alloc::*;
pub struct MemoryPool<T> {
buffers: Vec<Vec<T>>,
max_cached: usize,
max_bytes: usize,
cached_bytes: usize,
}
impl<T> Default for MemoryPool<T> {
fn default() -> Self {
Self::new()
}
}
impl<T> MemoryPool<T> {
pub fn new() -> Self {
Self {
buffers: Vec::new(),
max_cached: 16,
max_bytes: 16 * 1024 * 1024, cached_bytes: 0,
}
}
pub fn with_limits(max_cached: usize, max_bytes: usize) -> Self {
Self {
buffers: Vec::new(),
max_cached,
max_bytes,
cached_bytes: 0,
}
}
pub fn acquire(&mut self, min_capacity: usize) -> Vec<T> {
let pos = self
.buffers
.iter()
.position(|b| b.capacity() >= min_capacity);
if let Some(idx) = pos {
let mut buffer = self.buffers.remove(idx);
self.cached_bytes -= buffer.capacity() * size_of::<T>();
buffer.clear();
buffer
} else {
Vec::with_capacity(min_capacity)
}
}
pub fn release(&mut self, mut buffer: Vec<T>) {
let bytes = buffer.capacity() * size_of::<T>();
if self.buffers.len() >= self.max_cached {
return;
}
if self.cached_bytes + bytes > self.max_bytes {
return;
}
buffer.clear();
self.cached_bytes += bytes;
let pos = self
.buffers
.iter()
.position(|b| b.capacity() >= buffer.capacity())
.unwrap_or(self.buffers.len());
self.buffers.insert(pos, buffer);
}
pub fn cached_count(&self) -> usize {
self.buffers.len()
}
pub fn cached_bytes(&self) -> usize {
self.cached_bytes
}
pub fn clear(&mut self) {
self.buffers.clear();
self.cached_bytes = 0;
}
pub fn shrink_to_limits(&mut self) {
while self.buffers.len() > self.max_cached || self.cached_bytes > self.max_bytes {
if let Some(buffer) = self.buffers.pop() {
self.cached_bytes -= buffer.capacity() * size_of::<T>();
} else {
break;
}
}
}
}
pub struct AlignedPool<T, const ALIGN: usize = DEFAULT_ALIGN> {
buffers: Vec<AlignedVec<T, ALIGN>>,
max_cached: usize,
}
impl<T: Clone, const ALIGN: usize> Default for AlignedPool<T, ALIGN> {
fn default() -> Self {
Self::new()
}
}
impl<T: Clone, const ALIGN: usize> AlignedPool<T, ALIGN> {
pub fn new() -> Self {
Self {
buffers: Vec::new(),
max_cached: 8,
}
}
pub fn with_limit(max_cached: usize) -> Self {
Self {
buffers: Vec::new(),
max_cached,
}
}
pub fn acquire(&mut self, min_capacity: usize) -> AlignedVec<T, ALIGN> {
let pos = self
.buffers
.iter()
.position(|b| b.capacity() >= min_capacity);
if let Some(idx) = pos {
let mut buffer = self.buffers.remove(idx);
buffer.clear();
buffer
} else {
AlignedVec::with_capacity(min_capacity)
}
}
pub fn release(&mut self, mut buffer: AlignedVec<T, ALIGN>) {
if self.buffers.len() >= self.max_cached {
return;
}
buffer.clear();
let pos = self
.buffers
.iter()
.position(|b| b.capacity() >= buffer.capacity())
.unwrap_or(self.buffers.len());
self.buffers.insert(pos, buffer);
}
pub fn clear(&mut self) {
self.buffers.clear();
}
}