PACS System 0.1.0
PACS DICOM system library
Loading...
Searching...
No Matches
pool_manager.h
Go to the documentation of this file.
1// BSD 3-Clause License
2// Copyright (c) 2021-2025, 🍀☀🌕🌥 🌊
3// See the LICENSE file in the project root for full license information.
4
17#pragma once
18
19#include "dicom_element.h"
20#include "dicom_dataset.h"
21
22#include <kcenon/common/utils/object_pool.h>
23
24#include <atomic>
25#include <chrono>
26#include <cstddef>
27#include <cstdint>
28#include <functional>
29#include <memory>
30#include <mutex>
31
32namespace kcenon::pacs::core {
33
38 std::atomic<uint64_t> total_acquisitions{0};
39 std::atomic<uint64_t> pool_hits{0};
40 std::atomic<uint64_t> pool_misses{0};
41 std::atomic<uint64_t> total_releases{0};
42
47 [[nodiscard]] auto hit_ratio() const noexcept -> double {
48 const uint64_t total = total_acquisitions.load(std::memory_order_relaxed);
49 if (total == 0) {
50 return 0.0;
51 }
52 return static_cast<double>(pool_hits.load(std::memory_order_relaxed))
53 / static_cast<double>(total);
54 }
55
59 void reset() noexcept {
60 total_acquisitions.store(0, std::memory_order_relaxed);
61 pool_hits.store(0, std::memory_order_relaxed);
62 pool_misses.store(0, std::memory_order_relaxed);
63 total_releases.store(0, std::memory_order_relaxed);
64 }
65};
66
71template <typename T>
73public:
74 using pool_type = kcenon::common::utils::ObjectPool<T>;
75 using unique_ptr_type = std::unique_ptr<T, std::function<void(T*)>>;
76
77 explicit tracked_pool(std::size_t initial_size = 32)
78 : pool_(initial_size) {
79 pool_.reserve(initial_size);
80 }
81
87 template <typename... Args>
88 auto acquire(Args&&... args) -> unique_ptr_type {
89 bool reused = false;
90 auto ptr = pool_.acquire(&reused, std::forward<Args>(args)...);
91
92 stats_.total_acquisitions.fetch_add(1, std::memory_order_relaxed);
93 if (reused) {
94 stats_.pool_hits.fetch_add(1, std::memory_order_relaxed);
95 } else {
96 stats_.pool_misses.fetch_add(1, std::memory_order_relaxed);
97 }
98
99 return ptr;
100 }
101
106 [[nodiscard]] auto statistics() const noexcept -> const pool_statistics& {
107 return stats_;
108 }
109
114 [[nodiscard]] auto available() const -> std::size_t {
115 return pool_.available();
116 }
117
122 void reserve(std::size_t count) {
123 pool_.reserve(count);
124 }
125
129 void clear() {
130 pool_.clear();
131 }
132
133private:
136};
137
157public:
159 static constexpr std::size_t DEFAULT_ELEMENT_POOL_SIZE = 1024;
160 static constexpr std::size_t DEFAULT_DATASET_POOL_SIZE = 128;
161
166 static auto get() noexcept -> pool_manager&;
167
174 auto acquire_element(dicom_tag tag, encoding::vr_type vr)
175 -> tracked_pool<dicom_element>::unique_ptr_type;
176
181 auto acquire_dataset()
182 -> tracked_pool<dicom_dataset>::unique_ptr_type;
183
188 [[nodiscard]] auto element_statistics() const noexcept -> const pool_statistics&;
189
194 [[nodiscard]] auto dataset_statistics() const noexcept -> const pool_statistics&;
195
200 void reserve_elements(std::size_t count);
201
206 void reserve_datasets(std::size_t count);
207
211 void clear_all();
212
216 void reset_statistics();
217
218 // Non-copyable, non-movable
219 pool_manager(const pool_manager&) = delete;
221 auto operator=(const pool_manager&) -> pool_manager& = delete;
222 auto operator=(pool_manager&&) -> pool_manager& = delete;
223
224private:
225 pool_manager();
226 ~pool_manager() = default;
227
230};
231
232// ============================================================================
233// Convenience Factory Functions
234// ============================================================================
235
246[[nodiscard]] inline auto make_pooled_element(dicom_tag tag, encoding::vr_type vr)
247 -> tracked_pool<dicom_element>::unique_ptr_type {
248 return pool_manager::get().acquire_element(tag, vr);
249}
250
259[[nodiscard]] inline auto make_pooled_element(dicom_tag tag, encoding::vr_type vr,
260 std::string_view value)
262 auto elem = pool_manager::get().acquire_element(tag, vr);
263 elem->set_string(value);
264 return elem;
265}
266
275[[nodiscard]] inline auto make_pooled_dataset()
277 return pool_manager::get().acquire_dataset();
278}
279
280} // namespace kcenon::pacs::core
281
void reset_statistics()
Reset all statistics.
static constexpr std::size_t DEFAULT_DATASET_POOL_SIZE
tracked_pool< dicom_element > element_pool_
void clear_all()
Clear all pools.
auto element_statistics() const noexcept -> const pool_statistics &
Get element pool statistics.
auto acquire_element(dicom_tag tag, encoding::vr_type vr) -> tracked_pool< dicom_element >::unique_ptr_type
Acquire a dicom_element from the pool.
void reserve_elements(std::size_t count)
Reserve capacity in element pool.
static auto get() noexcept -> pool_manager &
Get the thread-local pool manager instance.
static constexpr std::size_t DEFAULT_ELEMENT_POOL_SIZE
Default pool sizes.
void reserve_datasets(std::size_t count)
Reserve capacity in dataset pool.
auto dataset_statistics() const noexcept -> const pool_statistics &
Get dataset pool statistics.
auto acquire_dataset() -> tracked_pool< dicom_dataset >::unique_ptr_type
Acquire a dicom_dataset from the pool.
tracked_pool< dicom_dataset > dataset_pool_
Pool wrapper with statistics tracking.
auto available() const -> std::size_t
Get the number of available objects in the pool.
void reserve(std::size_t count)
Reserve additional capacity in the pool.
void clear()
Clear the pool and release all memory.
auto statistics() const noexcept -> const pool_statistics &
Get the pool statistics.
kcenon::common::utils::ObjectPool< T > pool_type
tracked_pool(std::size_t initial_size=32)
auto acquire(Args &&... args) -> unique_ptr_type
Acquire an object from the pool.
std::unique_ptr< T, std::function< void(T *)> > unique_ptr_type
DICOM Dataset - ordered collection of Data Elements.
DICOM Data Element representation (Tag, VR, Value)
auto make_pooled_element(dicom_tag tag, encoding::vr_type vr) -> tracked_pool< dicom_element >::unique_ptr_type
Create a pooled dicom_element.
auto make_pooled_dataset() -> tracked_pool< dicom_dataset >::unique_ptr_type
Create a pooled dicom_dataset.
vr_type
DICOM Value Representation (VR) types.
Definition vr_type.h:29
Statistics for object pool usage monitoring.
std::atomic< uint64_t > total_releases
std::atomic< uint64_t > total_acquisitions
void reset() noexcept
Reset all statistics.
std::atomic< uint64_t > pool_hits
std::atomic< uint64_t > pool_misses
auto hit_ratio() const noexcept -> double
Calculate hit ratio (0.0 to 1.0)
vr_encoding vr