Common System 0.2.0
Common interfaces and patterns for system integration
Loading...
Searching...
No Matches
kcenon::common::utils::ObjectPool< T > Class Template Referenceexport

Thread-safe object pool that reuses raw storage for expensive objects. More...

#include <object_pool.h>

Collaboration diagram for kcenon::common::utils::ObjectPool< T >:
Collaboration graph

Public Types

using value_type = T
 
using deleter_type = PoolDeleter<T>
 
using pointer_type = std::unique_ptr<T, deleter_type>
 

Public Member Functions

 ObjectPool (std::size_t growth=32)
 Construct an object pool with the specified growth factor.
 
template<typename... Args>
pointer_type acquire (bool *reused, Args &&... args)
 Acquire an object constructed with the provided arguments.
 
template<typename... Args>
pointer_type acquire (Args &&... args)
 
void release (T *ptr) noexcept
 Return raw storage to the pool (destructor already run).
 
void reserve (std::size_t count)
 Add count additional blocks to the pool.
 
void clear ()
 Destroy all cached instances and release memory.
 
std::size_t available () const
 
 ObjectPool (std::size_t growth=32)
 
template<typename... Args>
std::unique_ptr< T, std::function< void(T *)> > acquire (bool *reused, Args &&... args)
 Acquire an object constructed with the provided arguments.
 
template<typename... Args>
std::unique_ptr< T, std::function< void(T *)> > acquire (Args &&... args)
 
void release (T *ptr) noexcept
 Return raw storage to the pool (destructor already run).
 
void reserve (std::size_t count)
 Add count additional blocks to the pool.
 
void clear ()
 Destroy all cached instances and release memory.
 
std::size_t available () const
 

Private Types

using RawPtr = std::unique_ptr<T, detail::RawDelete<T>>
 

Private Member Functions

void allocate_block_unlocked (std::size_t count)
 
void allocate_block_unlocked (std::size_t count)
 

Private Attributes

std::size_t growth_
 
std::mutex mutex_
 
std::stack< T * > free_list_
 
std::vector< RawPtrstorage_
 

Detailed Description

template<typename T>
class kcenon::common::utils::ObjectPool< T >

Thread-safe object pool that reuses raw storage for expensive objects.

The pool allocates raw memory once and performs placement-new construction on acquisition. Objects are destructed when released, but the underlying storage is retained for fast reuse.

The pool allocates raw memory once and performs placement-new construction on acquisition. Objects are destructed when released, but the underlying storage is retained for fast reuse.

Template Parameters
TObject type to pool
Examples
utility_containers_example.cpp.

Definition at line 218 of file utils.cppm.

Member Typedef Documentation

◆ deleter_type

template<typename T >
using kcenon::common::utils::ObjectPool< T >::deleter_type = PoolDeleter<T>

Definition at line 65 of file object_pool.h.

◆ pointer_type

template<typename T >
using kcenon::common::utils::ObjectPool< T >::pointer_type = std::unique_ptr<T, deleter_type>

Definition at line 66 of file object_pool.h.

◆ RawPtr

template<typename T >
using kcenon::common::utils::ObjectPool< T >::RawPtr = std::unique_ptr<T, detail::RawDelete<T>>
exportprivate

Definition at line 149 of file object_pool.h.

◆ value_type

template<typename T >
typedef T kcenon::common::utils::ObjectPool< T >::value_type = T
export

Definition at line 64 of file object_pool.h.

Constructor & Destructor Documentation

◆ ObjectPool() [1/2]

template<typename T >
kcenon::common::utils::ObjectPool< T >::ObjectPool ( std::size_t growth = 32)
inlineexplicit

Construct an object pool with the specified growth factor.

Parameters
growthNumber of objects to pre-allocate per expansion (minimum 1).

Definition at line 72 of file object_pool.h.

73 : growth_(growth == 0 ? 1 : growth) {}

◆ ObjectPool() [2/2]

template<typename T >
kcenon::common::utils::ObjectPool< T >::ObjectPool ( std::size_t growth = 32)
inlineexplicitexport

Definition at line 222 of file utils.cppm.

223 : growth_(growth == 0 ? 1 : growth) {}

Member Function Documentation

◆ acquire() [1/4]

template<typename T >
template<typename... Args>
pointer_type kcenon::common::utils::ObjectPool< T >::acquire ( Args &&... args)
inline

Definition at line 106 of file object_pool.h.

106 {
107 return acquire(static_cast<bool*>(nullptr), std::forward<Args>(args)...);
108 }
pointer_type acquire(bool *reused, Args &&... args)
Acquire an object constructed with the provided arguments.
Definition object_pool.h:82

References kcenon::common::utils::ObjectPool< T >::acquire().

Here is the call graph for this function:

◆ acquire() [2/4]

template<typename T >
template<typename... Args>
std::unique_ptr< T, std::function< void(T *)> > kcenon::common::utils::ObjectPool< T >::acquire ( Args &&... args)
inlineexport

Definition at line 258 of file utils.cppm.

258 {
259 return acquire(static_cast<bool*>(nullptr), std::forward<Args>(args)...);
260 }

References kcenon::common::utils::ObjectPool< T >::acquire().

Here is the call graph for this function:

◆ acquire() [3/4]

template<typename T >
template<typename... Args>
pointer_type kcenon::common::utils::ObjectPool< T >::acquire ( bool * reused,
Args &&... args )
inline

Acquire an object constructed with the provided arguments.

Parameters
reusedOptional pointer that receives whether an existing block was reused.
argsArguments forwarded to the object's constructor.
Returns
A unique_ptr to the acquired object with a custom deleter that returns it to the pool.

Definition at line 82 of file object_pool.h.

82 {
83 T* raw = nullptr;
84 bool reused_local = false;
85 {
86 std::lock_guard<std::mutex> lock(mutex_);
87 if (free_list_.empty()) {
89 } else {
90 reused_local = true;
91 }
92
93 raw = free_list_.top();
94 free_list_.pop();
95 }
96
97 if (reused) {
98 *reused = reused_local;
99 }
100
101 new (raw) T(std::forward<Args>(args)...);
102 return pointer_type(raw, deleter_type{this});
103 }
void allocate_block_unlocked(std::size_t count)
std::unique_ptr< T, deleter_type > pointer_type
Definition object_pool.h:66

References kcenon::common::utils::ObjectPool< T >::allocate_block_unlocked(), kcenon::common::utils::ObjectPool< T >::free_list_, kcenon::common::utils::ObjectPool< T >::growth_, and kcenon::common::utils::ObjectPool< T >::mutex_.

Referenced by kcenon::common::utils::ObjectPool< T >::acquire(), and main().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ acquire() [4/4]

template<typename T >
template<typename... Args>
std::unique_ptr< T, std::function< void(T *)> > kcenon::common::utils::ObjectPool< T >::acquire ( bool * reused,
Args &&... args )
inlineexport

Acquire an object constructed with the provided arguments.

Parameters
reusedOptional pointer that receives whether an existing block was reused.
argsArguments forwarded to the object's constructor.
Returns
A unique_ptr to the acquired object with a custom deleter.

Definition at line 232 of file utils.cppm.

232 {
233 T* raw = nullptr;
234 bool reused_local = false;
235 {
236 std::lock_guard<std::mutex> lock(mutex_);
237 if (free_list_.empty()) {
239 } else {
240 reused_local = true;
241 }
242
243 raw = free_list_.top();
244 free_list_.pop();
245 }
246
247 if (reused) {
248 *reused = reused_local;
249 }
250
251 new (raw) T(std::forward<Args>(args)...);
252 return std::unique_ptr<T, std::function<void(T*)>>(raw, [this](T* ptr) {
253 this->release(ptr);
254 });
255 }
void release(T *ptr) noexcept
Return raw storage to the pool (destructor already run).

References kcenon::common::utils::ObjectPool< T >::allocate_block_unlocked(), kcenon::common::utils::ObjectPool< T >::free_list_, kcenon::common::utils::ObjectPool< T >::growth_, kcenon::common::utils::ObjectPool< T >::mutex_, and kcenon::common::utils::ObjectPool< T >::release().

Here is the call graph for this function:

◆ allocate_block_unlocked() [1/2]

template<typename T >
void kcenon::common::utils::ObjectPool< T >::allocate_block_unlocked ( std::size_t count)
inlineprivate

Definition at line 151 of file object_pool.h.

151 {
152 for (std::size_t i = 0; i < count; ++i) {
153 RawPtr block(static_cast<T*>(::operator new(sizeof(T))));
154 free_list_.push(block.get());
155 storage_.push_back(std::move(block));
156 }
157 }
std::vector< RawPtr > storage_
std::unique_ptr< T, detail::RawDelete< T > > RawPtr

References kcenon::common::utils::ObjectPool< T >::free_list_, and kcenon::common::utils::ObjectPool< T >::storage_.

Referenced by kcenon::common::utils::ObjectPool< T >::acquire(), and kcenon::common::utils::ObjectPool< T >::reserve().

Here is the caller graph for this function:

◆ allocate_block_unlocked() [2/2]

template<typename T >
void kcenon::common::utils::ObjectPool< T >::allocate_block_unlocked ( std::size_t count)
inlineexportprivate

Definition at line 303 of file utils.cppm.

303 {
304 for (std::size_t i = 0; i < count; ++i) {
305 RawPtr block(static_cast<T*>(::operator new(sizeof(T))));
306 free_list_.push(block.get());
307 storage_.push_back(std::move(block));
308 }
309 }

References kcenon::common::utils::ObjectPool< T >::free_list_, and kcenon::common::utils::ObjectPool< T >::storage_.

◆ available() [1/2]

template<typename T >
std::size_t kcenon::common::utils::ObjectPool< T >::available ( ) const
inlinenodiscard

Definition at line 143 of file object_pool.h.

143 {
144 std::lock_guard<std::mutex> lock(mutex_);
145 return free_list_.size();
146 }

References kcenon::common::utils::ObjectPool< T >::free_list_, and kcenon::common::utils::ObjectPool< T >::mutex_.

Referenced by main().

Here is the caller graph for this function:

◆ available() [2/2]

template<typename T >
std::size_t kcenon::common::utils::ObjectPool< T >::available ( ) const
inlinenodiscardexport

Definition at line 295 of file utils.cppm.

295 {
296 std::lock_guard<std::mutex> lock(mutex_);
297 return free_list_.size();
298 }

References kcenon::common::utils::ObjectPool< T >::free_list_, and kcenon::common::utils::ObjectPool< T >::mutex_.

◆ clear() [1/2]

template<typename T >
void kcenon::common::utils::ObjectPool< T >::clear ( )
inline

Destroy all cached instances and release memory.

Definition at line 137 of file object_pool.h.

137 {
138 std::lock_guard<std::mutex> lock(mutex_);
139 free_list_ = std::stack<T*>();
140 storage_.clear();
141 }

References kcenon::common::utils::ObjectPool< T >::free_list_, kcenon::common::utils::ObjectPool< T >::mutex_, and kcenon::common::utils::ObjectPool< T >::storage_.

Referenced by main().

Here is the caller graph for this function:

◆ clear() [2/2]

template<typename T >
void kcenon::common::utils::ObjectPool< T >::clear ( )
inlineexport

Destroy all cached instances and release memory.

Definition at line 289 of file utils.cppm.

289 {
290 std::lock_guard<std::mutex> lock(mutex_);
291 free_list_ = std::stack<T*>();
292 storage_.clear();
293 }

References kcenon::common::utils::ObjectPool< T >::free_list_, kcenon::common::utils::ObjectPool< T >::mutex_, and kcenon::common::utils::ObjectPool< T >::storage_.

◆ release() [1/2]

template<typename T >
void kcenon::common::utils::ObjectPool< T >::release ( T * ptr)
inlinenoexcept

Return raw storage to the pool (destructor already run).

Definition at line 113 of file object_pool.h.

113 {
114 if (!ptr) {
115 return;
116 }
117
118 ptr->~T();
119 std::lock_guard<std::mutex> lock(mutex_);
120 free_list_.push(ptr);
121 }

References kcenon::common::utils::ObjectPool< T >::free_list_, and kcenon::common::utils::ObjectPool< T >::mutex_.

Referenced by kcenon::common::utils::ObjectPool< T >::acquire().

Here is the caller graph for this function:

◆ release() [2/2]

template<typename T >
void kcenon::common::utils::ObjectPool< T >::release ( T * ptr)
inlineexportnoexcept

Return raw storage to the pool (destructor already run).

Definition at line 265 of file utils.cppm.

265 {
266 if (!ptr) {
267 return;
268 }
269
270 ptr->~T();
271 std::lock_guard<std::mutex> lock(mutex_);
272 free_list_.push(ptr);
273 }

References kcenon::common::utils::ObjectPool< T >::free_list_, and kcenon::common::utils::ObjectPool< T >::mutex_.

◆ reserve() [1/2]

template<typename T >
void kcenon::common::utils::ObjectPool< T >::reserve ( std::size_t count)
inline

Add count additional blocks to the pool.

Definition at line 126 of file object_pool.h.

126 {
127 if (count == 0) {
128 return;
129 }
130 std::lock_guard<std::mutex> lock(mutex_);
132 }

References kcenon::common::utils::ObjectPool< T >::allocate_block_unlocked(), and kcenon::common::utils::ObjectPool< T >::mutex_.

Referenced by main().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ reserve() [2/2]

template<typename T >
void kcenon::common::utils::ObjectPool< T >::reserve ( std::size_t count)
inlineexport

Add count additional blocks to the pool.

Definition at line 278 of file utils.cppm.

278 {
279 if (count == 0) {
280 return;
281 }
282 std::lock_guard<std::mutex> lock(mutex_);
284 }

References kcenon::common::utils::ObjectPool< T >::allocate_block_unlocked(), and kcenon::common::utils::ObjectPool< T >::mutex_.

Here is the call graph for this function:

Member Data Documentation

◆ free_list_

◆ growth_

template<typename T >
std::size_t kcenon::common::utils::ObjectPool< T >::growth_
exportprivate

Definition at line 159 of file object_pool.h.

Referenced by kcenon::common::utils::ObjectPool< T >::acquire().

◆ mutex_

◆ storage_

template<typename T >
std::vector< RawPtr > kcenon::common::utils::ObjectPool< T >::storage_
exportprivate

The documentation for this class was generated from the following files: