mod serialization;
use std::cell::{Ref, RefCell, RefMut};
use std::rc::{Rc, Weak};
pub use serialization::AutoReturnBufferDeserializer;
#[derive(Debug)]
pub struct BufferPool<const SIZE: usize> {
buffers: Vec<Rc<RefCell<[u8; SIZE]>>>,
}
#[derive(Clone, Debug)]
pub struct AutoReturnBuffer<const SIZE: usize> {
pub collector: Weak<RefCell<BufferPool<SIZE>>>,
pub inner: Rc<RefCell<[u8; SIZE]>>,
}
impl<const SIZE: usize> BufferPool<SIZE> {
pub fn create_buffer_pool() -> Rc<RefCell<BufferPool<SIZE>>> {
Rc::new(RefCell::new(BufferPool {
buffers: Vec::new(),
}))
}
pub fn get_from_buffer_pool(pool: &Rc<RefCell<BufferPool<SIZE>>>) -> AutoReturnBuffer<SIZE> {
let buffer = pool.borrow_mut().buffers.pop();
if let Some(buffer) = buffer {
AutoReturnBuffer {
collector: Rc::downgrade(pool),
inner: buffer,
}
} else {
AutoReturnBuffer {
collector: Rc::downgrade(pool),
inner: Rc::new(RefCell::new([0; SIZE])),
}
}
}
}
impl<const SIZE: usize> Drop for AutoReturnBuffer<SIZE> {
fn drop(&mut self) {
if Rc::strong_count(&self.inner) == 1 {
if let Some(pool) = self.collector.upgrade() {
pool.borrow_mut().buffers.push(self.inner.clone());
}
}
}
}
impl<const SIZE: usize> AutoReturnBuffer<SIZE> {
pub fn borrow_mut(&self) -> RefMut<[u8; SIZE]> {
self.inner.borrow_mut()
}
pub fn borrow(&self) -> Ref<[u8; SIZE]> {
self.inner.borrow()
}
}
impl<const SIZE: usize> PartialEq for AutoReturnBuffer<SIZE> {
fn eq(&self, other: &Self) -> bool {
*self.inner.borrow() == *other.inner.borrow()
}
}
impl<const SIZE: usize> Eq for AutoReturnBuffer<SIZE> {}