|
JH-Toolkit v1.4.1
An engineering-oriented C++20 toolkit with duck-typed concepts, static design, async coroutines, and semantic containers โ header-only, RTTI-free, and concurrency-friendly.
|
Weak pointer-observed pool for immutable or structurally immutable objects. More...
#include <jh/concurrent/pointer_pool.h>
Public Member Functions | |
| pointer_pool (std::uint64_t reserve_size=MIN_RESERVED_SIZE) | |
| Constructs a pool with an initial reserved capacity. | |
| pointer_pool (const pointer_pool &)=delete | |
| Deleted copy constructor. | |
| pointer_pool & | operator= (const pointer_pool &)=delete |
| Deleted copy assignment operator. | |
| pointer_pool (pointer_pool &&other) noexcept | |
| Move constructor. | |
| pointer_pool & | operator= (pointer_pool &&other) noexcept |
| Move assignment operator. | |
| template<typename... Args> | |
| std::shared_ptr< T > | acquire (Args &&... args) const =delete |
Deleted acquire() for const pointer_pool. | |
| template<typename... Args> | |
| std::shared_ptr< T > | acquire (Args &&... args) |
| Retrieves an object from the pool, or creates a new one if none exists. | |
| void | cleanup () |
| Removes expired weak references from the pool. | |
| void | cleanup_shrink () |
| Removes expired entries and conditionally shrinks the reserved capacity. | |
| std::uint64_t | size () const |
| Gets the current number of elements in the pool. | |
| std::uint64_t | capacity () const |
| Gets the current reserved size of the pool. | |
| void | clear () |
| Clears all entries and resets the pool to its initial state. | |
Static Public Attributes | |
| static std::uint64_t constexpr | MIN_RESERVED_SIZE = 16 |
| The minimum reserved capacity for the pool. | |
Weak pointer-observed pool for immutable or structurally immutable objects.
This construct-first, lock-then-insert pattern is required because lookup is defined by the object's own equality; no external key or pre-hash structure can be used.
std::weak_ptr while ownership remains external. std::shared_mutex. acquire() are safe. std::shared_ptr objects remain valid even if the pool is cleared or destroyed. jh::observe_pool, these are automatically derived from std::hash<T>() or adl hash(t) or t.hash(), and operator==() to ensure consistent behavior.std::atomic_thread_fence(std::memory_order_seq_cst) barriers are inserted to strengthen ordering at the language level. This eliminates ISO-level UB risks and preserves correctness within the C++ abstract machine. std::shared_mutex) do not necessarily provide POSIX-equivalent global ordering behavior. Under extreme multi-core contention, rare visibility or reordering phenomena may still be observed. pointer_pool may expose such behavior more readily due to heavier synchronization and hash-table interaction, but the underlying limitation applies to all concurrent pools in this module.
|
inlineexplicit |
Constructs a pool with an initial reserved capacity.
| reserve_size | The initial capacity to reserve for the internal hash set. Defaults to MIN_RESERVED_SIZE (16). |
Initializes the pool's internal storage and establishes the adaptive resizing baseline. This constructor performs no object construction; it only reserves memory for the underlying std::unordered_set that stores weak references.
MIN_RESERVED_SIZE (16), ensuring predictable allocation behavior and avoiding frequent reallocation during low-load periods.
|
delete |
Deleted copy constructor.
Copying is disabled because two pools observing the same set of immutable objects have no meaningful deduplication relationship. A duplicated observer would only increase contention and break the one-pool-per-type principle for resource or handle management.
std::reference_wrapper or shared_ptr instead of copying the pool.
|
inlinenoexcept |
Move constructor.
Transfers internal weak references and capacity state from another pool. The source pool is locked during transfer and cleared afterward to ensure a valid empty state.
weak_ptr, live instances remain valid and unaffected. After a move, entries may temporarily exist in both the old and new pool, but this is acceptable for deduplication use.
|
inline |
Retrieves an object from the pool, or creates a new one if none exists.
Constructs a temporary instance of T using the forwarded arguments, then attempts to insert it into the pool. If a logically equivalent instance already exists (as determined by Eq), it is reused and the newly created temporary object is discarded. Otherwise, the new instance is inserted and returned.
| Args | Constructor argument types for T. |
| args | Arguments forwarded to T's constructor. |
std::shared_ptr<T> representing the pooled object.Acquisition Flow:
shared_ptr returned.
|
delete |
Deleted acquire() for const pointer_pool.
Prevents acquiring or inserting objects through a constant pool reference. Since acquisition may modify the internal pool state, it is not permitted on const instances.
| Args | Constructor argument types for T. |
acquire() is accidentally called on a constant pool reference. Immutable access to existing shared objects should be performed through previously returned std::shared_ptr instances.
|
inlinenodiscard |
Gets the current reserved size of the pool.
|
inline |
Removes expired weak references from the pool.
Scans the internal container and erases all weak_ptr entries that have expired (that is, their corresponding shared_ptr instances have been destroyed).
This operation reclaims hash table slots and prevents unbounded growth when many pooled objects are released.
|
inline |
Removes expired entries and conditionally shrinks the reserved capacity.
Performs the same expired-entry cleanup as cleanup(), then evaluates the current usage ratio to determine whether capacity should be reduced.
If the number of active entries falls below 0.25 of the current reserved size (the low-watermark ratio), the reserved capacity is reduced to one half of its previous value. The pool will never shrink below MIN_RESERVED_SIZE.
This function is intended for manual maintenance when predictable memory release is desired. It complements the automatic, event-driven resizing that may also perform half shrinkage during expansion checks.
|
inline |
Clears all entries and resets the pool to its initial state.
Removes all elements from the internal container and resets capacity_ to MIN_RESERVED_SIZE. This operation is functionally equivalent to clear() on standard containers, but is thread-safe and ensures consistent internal state for concurrent environments.
Because the pool only stores weak_ptr references, clearing it merely removes observation records and does not affect the lifetime of externally held shared_ptr instances. For immutable data types, deduplication integrity remains intact.
clear() is not recommended, as it abandons tracking of active handles and may cause side effects. capacity() is reset to MIN_RESERVED_SIZE, fully restoring the pool to its initial baseline. clear() always resets the capacity to its minimum for a deterministic clean state.
|
delete |
Deleted copy assignment operator.
Copy assignment is not supported for the same reasons as copy construction: duplicating the pool would create two independent observers of the same logical object space, defeating deduplication semantics.
|
inlinenoexcept |
Move assignment operator.
Moves the weak reference set and capacity state from another pool. Both pools are locked during transfer to ensure atomicity.
std::shared_ptr instances.
|
inlinenodiscard |
Gets the current number of elements in the pool.
|
staticconstexpr |
The minimum reserved capacity for the pool.
Defines the lower bound of the adaptive capacity management system. The pool will never shrink below this threshold even when mostly empty, ensuring predictable memory usage and avoiding excessive reallocation.