use crate::{Pooled, Reset};
use alloc::sync::Arc;
use crossbeam_queue::ArrayQueue;
pub struct Pool<T: Default + Reset> {
pub(super) inner: Arc<PoolInner<T>>,
}
pub(super) type PoolInner<T> = ArrayQueue<T>;
impl<T: Default + Reset> Pool<T> {
pub fn new(capacity: usize) -> Self {
assert!(capacity > 0, "capacity must be more than 0");
Self {
inner: Arc::new(PoolInner::new(capacity)),
}
}
pub fn take(&self) -> Pooled<T> {
Pooled::new(self.inner.pop().unwrap_or_default(), self)
}
pub fn try_take(&self) -> Option<Pooled<T>> {
self.inner.pop().map(|object| Pooled::new(object, self))
}
pub fn len(&self) -> usize {
self.inner.len()
}
pub fn in_use(&self) -> usize {
Arc::weak_count(&self.inner)
}
pub fn is_empty(&self) -> bool {
self.inner.is_empty()
}
pub fn is_full(&self) -> bool {
self.inner.is_full()
}
pub fn capacity(&self) -> usize {
self.inner.capacity()
}
pub fn spare_capacity(&self) -> usize {
self.capacity() - self.len()
}
pub fn attach(&self, object: T) -> Pooled<T> {
Pooled::new(object, self)
}
}
impl<T: Default + Reset> Clone for Pool<T> {
fn clone(&self) -> Self {
Self {
inner: Arc::clone(&self.inner),
}
}
}