1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
use parking_lot::Mutex;
pub struct MemPool<T> {
bufs: Mutex<Vec<Vec<T>>>,
}
impl<T> MemPool<T> {
pub const fn new() -> Self {
Self {
bufs: Mutex::new(Vec::new()),
}
}
pub fn _pop(&self, size: usize) -> Vec<T> {
if let Some(mut buf) = self.bufs.lock().pop() {
if size > buf.capacity() {
// TODO fallible allocation
buf.reserve(size - buf.len());
}
return buf;
}
// TODO fallible allocation
Vec::with_capacity(size)
}
/// A version of [`Self::pop`] that initializes the [`Vec`].
/// This allows it to use [`vec!`], which, if used with `0`,
/// calls [`alloc_zeroed`], and thus can leave zero initialization to the OS.
///
/// [`alloc_zeroed`]: std::alloc::alloc_zeroed
pub fn pop_init(&self, size: usize, init_value: T) -> Vec<T>
where
T: Copy,
{
if let Some(buf) = self.bufs.lock().pop() {
if size <= buf.len() {
return buf;
}
}
// TODO fallible allocation
vec![init_value; size]
}
pub fn push(&self, buf: Vec<T>) {
self.bufs.lock().push(buf);
}
}
impl<T> Default for MemPool<T> {
fn default() -> Self {
Self::new()
}
}