1#![cfg_attr(docsrs, feature(doc_cfg))]
2#![cfg_attr(docsrs, allow(unused_attributes))]
3#![doc = include_str!("../README.md")]
4
5use std::{
6 mem::ManuallyDrop,
7 ops::{Deref, DerefMut},
8 ptr,
9 sync::Arc,
10};
11
12pub use easy_pool_proc_macro::{EasyPoolArayQueue, EasyPoolMutex, EasyPoolSegQueue};
13pub use once_cell::sync::Lazy;
14pub use pool_array_queue::PoolArrayQueue;
15pub use pool_mutex::PoolMutex;
16pub use pool_seg_queue::PoolSegQueue;
17
18mod pool_array_queue;
19mod pool_mutex;
20mod pool_seg_queue;
21
22pub trait Clear {
23 fn clear(&mut self);
24}
25
26#[derive(Debug)]
27enum PoolType<T: Clear> {
28 Mutex(Arc<PoolMutex<T>>),
29 SegQueue(Arc<PoolSegQueue<T>>),
30 ArrayQueue(Arc<PoolArrayQueue<T>>),
31}
32
33#[derive(Debug)]
34pub struct PoolObjectContainer<T: Clear> {
35 ref_pool: PoolType<T>,
36 inner: ManuallyDrop<T>,
37}
38
39impl<T: Clear> PoolObjectContainer<T> {
40 fn new(val: T, ref_pool: PoolType<T>) -> Self {
41 Self {
42 inner: ManuallyDrop::new(val),
43 ref_pool,
44 }
45 }
46}
47
48impl<T: Clear> DerefMut for PoolObjectContainer<T> {
49 fn deref_mut(&mut self) -> &mut Self::Target {
50 &mut self.inner
51 }
52}
53
54impl<T: Clear> Deref for PoolObjectContainer<T> {
55 type Target = T;
56
57 fn deref(&self) -> &Self::Target {
58 &self.inner
59 }
60}
61
62impl<T: Clear> Drop for PoolObjectContainer<T> {
63 fn drop(&mut self) {
64 let val = unsafe { ptr::read(&self.inner) };
65 let mut val = ManuallyDrop::into_inner(val);
66
67 match self.ref_pool {
68 PoolType::Mutex(ref pool) => {
69 let mut lock = pool.values.lock();
70
71 if lock.len() >= pool.max_size {
72 drop(val);
73 } else {
74 val.clear();
75 lock.push(val);
76 }
77 drop(lock);
78 }
79 PoolType::SegQueue(ref pool) => {
80 if pool.values.len() >= pool.max_size {
81 drop(val);
82 } else {
83 val.clear();
84 pool.values.push(val);
85 }
86 }
87 PoolType::ArrayQueue(ref pool) => {
88 if pool.values.len() >= pool.max_size {
89 drop(val);
90 } else {
91 val.clear();
92 if let Err(val) = pool.values.push(val) {
93 drop(val);
94 }
95 }
96 }
97 }
98 }
99}
100
101#[cfg(test)]
102mod tests {
103 use super::*;
104
105 #[test]
106 fn test_clear() {
107 let pool = Arc::new(PoolMutex::new());
108 let vec = pool.create_with(|| vec![10]);
109 drop(vec);
110 assert_eq!(pool.len(), 1);
111 let vec = pool.create();
112 assert!(vec.capacity() == 1 && vec.is_empty());
113
114 let pool = Arc::new(PoolSegQueue::new(1024));
115 let vec = pool.create_with(|| vec![10]);
116 drop(vec);
117 assert_eq!(pool.len(), 1);
118 let vec = pool.create();
119 assert!(vec.capacity() == 1 && vec.is_empty());
120
121 let pool = Arc::new(PoolArrayQueue::new(1024));
122 let vec = pool.create_with(|| vec![10]);
123 drop(vec);
124 assert_eq!(pool.len(), 1);
125 let vec = pool.create();
126 assert!(vec.capacity() == 1 && vec.is_empty());
127 }
128}