|
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.
|
Key-based, contiguous, GC-like interning pool for copyable or movable objects. More...
#include <compare>#include <vector>#include <shared_mutex>#include <atomic>#include <cstddef>#include <cstdint>#include <tuple>#include <memory>#include <mutex>#include <algorithm>#include <type_traits>#include <stdexcept>#include "jh/typing/monostate.h"#include "jh/core/ordered_map.h"#include "jh/conceptual/hashable.h"#include "jh/synchronous/control_buf.h"#include "jh/synchronous/strong_lock.h"Go to the source code of this file.
Classes | |
| struct | jh::conc::extension::value_factory< V > |
| Default value construction policy for flat_pool. More... | |
| struct | jh::conc::extension::value_factory< std::shared_ptr< T > > |
Value construction policy specialization for std::shared_ptr. More... | |
| struct | jh::conc::extension::value_factory< std::unique_ptr< T > > |
Value construction policy specialization for std::unique_ptr. More... | |
| class | jh::conc::flat_pool< Key, Value, Hash, Alloc > |
| Hash-ordered, contiguous resource interning pool. More... | |
| struct | jh::conc::flat_pool< Key, Value, Hash, Alloc >::ptr |
| Reference-counted handle to a pooled object. More... | |
Namespaces | |
| namespace | jh::conc |
| Aggregated namespace for concurrency-aware resource containers. | |
| namespace | jh::conc::extension |
Public customization and extension points for jh::conc containers. | |
Key-based, contiguous, GC-like interning pool for copyable or movable objects.
jh::conc::flat_pool is a concurrent object interning container that deduplicates objects using an explicit external key and stores them inside a contiguous memory pool. Each unique key corresponds to at most one active slot at any time, and acquisitions return lightweight reference-counted handles (flat_pool::ptr) bound to stable indices.
Object identity is defined entirely by an external Key type. The key must be:
Lookup and deduplication are performed solely through the key. The stored object itself is never inspected for equality. This allows the pool to perform lookups before construction and avoids provisional object creation.
Keys are accepted in cv/ref-qualified form during acquisition. These equivalent key representations are used only for identification and are not retained unless insertion succeeds.
For map-like pools (Value != jh::typed::monostate), values are constructed using a std::tuple of arguments supplied at acquisition time.
std::tie or std::forward_as_tuple. Value creation is customizable via the public extension point jh::conc::extension::value_factory<Value>, enabling user-defined construction strategies without modifying or subclassing the pool.
flat_pool deliberately adopts a GC-like lifetime model:
Instead of invoking destructors eagerly, the pool prefers slot reuse through assignment. This avoids repeated destructor / constructor cycles and significantly reduces allocation pressure for objects whose initialization may involve expensive memory allocation or resource setup.
Because destruction is deferred and non-deterministic, flat_pool is not suitable for objects whose correctness depends on immediate destruction when references are released.
In a manner of speaking, this design can be viewed as transforming shared_ptr, which performs allocation individually, into a bunch of smart pointers that allocate keys, values, index tables, and control blocks all in contiguous memory managed by the pool.
All synchronization is handled internally by the pool using shared and exclusive locks. No external atomic or smart-pointer-level synchronization is relied upon.
The pool stores objects in contiguous memory. To protect against vector reallocation during concurrent access, dereferencing a handle in multithreaded contexts requires holding a no_reallocate_guard.
pointer_poolflat_pool and pointer_pool address complementary problem domains:
flat_pool: pointer_pool (observe_pool): jh::weak_ptr_hash and jh::weak_ptr_eq.) shared_ptr can cause greater jitter than POSIX. shared_ptr If your objects:
then flat_pool is the preferred structure.
If your objects:
then a pointer-based pool should be used instead.
flat_pool is algorithmically data-race-free (DRF) and does not rely on undefined behavior under the ISO C++ memory model. std::atomic_thread_fence(std::memory_order_seq_cst) barriers are introduced on Windows builds to strengthen ordering at the language level. This removes ISO-level UB risks and preserves correctness within the C++ abstract machine. std::shared_mutex implementations) do not necessarily provide POSIX-equivalent global ordering behavior. Under extreme multi-core contention, rare visibility or reordering phenomena may still be observed. flat_pool; rather, it reflects platform-level memory ordering characteristics outside the control of the library. 1.4.x
2025