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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
use crate::{init, Pool, Recyclable};
use thread_local::CachedThreadLocal;
pub fn builder<T>() -> PoolBuilder<T>
where
T: Recyclable,
{
PoolBuilder::default()
}
pub type Supplier<T> = dyn Fn() -> T + Send + Sync;
pub struct PoolBuilder<T: Recyclable> {
pub(crate) starting_size: usize,
pub(crate) supplier: Option<Box<Supplier<T>>>,
}
impl<T> PoolBuilder<T>
where
T: Recyclable,
{
pub fn with_starting_size(mut self, starting_size: usize) -> Self {
self.starting_size = starting_size;
self
}
pub fn with_supplier<S>(mut self, supplier: S) -> Self
where
S: Fn() -> T + Send + Sync + 'static,
{
self.supplier = Some(Box::new(supplier));
self
}
pub fn build(self) -> Pool<T> {
let values = CachedThreadLocal::new();
for _ in 0..self.starting_size {
if let Some(supplier) = self.supplier.as_ref() {
values.get_or(|| init()).borrow_mut().push(supplier())
} else {
values.get_or(|| init()).borrow_mut().push(T::new())
}
}
Pool {
values,
settings: self,
}
}
pub fn build_with(self, items: Vec<T>) -> Pool<T> {
let values = CachedThreadLocal::new();
let size = items.len();
for itm in items {
values.get_or(|| init()).borrow_mut().push(itm);
}
if size < self.starting_size {
let remainder = self.starting_size - size;
for _ in 0..remainder {
if let Some(supplier) = self.supplier.as_ref() {
values.get_or(|| init()).borrow_mut().push(supplier())
} else {
values.get_or(|| init()).borrow_mut().push(T::new())
}
}
}
Pool {
values,
settings: self,
}
}
}
impl<T> Default for PoolBuilder<T>
where
T: Recyclable,
{
fn default() -> Self {
Self {
starting_size: 0,
supplier: None,
}
}
}