Thread System 0.3.1
High-performance C++20 thread pool with work stealing and DAG scheduling
Loading...
Searching...
No Matches
kcenon::thread::queue_factory Class Reference

Factory for creating queue instances. More...

#include <queue_factory.h>

Collaboration diagram for kcenon::thread::queue_factory:
Collaboration graph

Classes

struct  requirements
 Queue selection requirements. More...
 

Static Public Member Functions

static auto create_standard_queue () -> std::shared_ptr< job_queue >
 Create standard job_queue.
 
static auto create_adaptive_queue (adaptive_job_queue::policy policy=adaptive_job_queue::policy::balanced) -> std::unique_ptr< adaptive_job_queue >
 Create adaptive queue (RECOMMENDED for most use cases)
 
static auto create_for_requirements (const requirements &reqs) -> std::unique_ptr< scheduler_interface >
 Create queue based on requirements.
 
static auto create_optimal () -> std::unique_ptr< scheduler_interface >
 Create optimal queue for current environment.
 
static auto create_policy_queue () -> std::unique_ptr< standard_queue >
 Create a standard policy_queue (mutex-based, unbounded)
 
static auto create_lockfree_policy_queue () -> std::unique_ptr< policy_lockfree_queue >
 Create a lock-free policy_queue.
 
static auto create_bounded_policy_queue (std::size_t max_size) -> std::unique_ptr< policy_queue< policies::mutex_sync_policy, policies::bounded_policy, policies::overflow_reject_policy > >
 Create a bounded policy_queue with specified size.
 
template<typename SyncPolicy , typename BoundPolicy , typename OverflowPolicy >
static auto create_custom_policy_queue (SyncPolicy sync_policy, BoundPolicy bound_policy, OverflowPolicy overflow_policy) -> std::unique_ptr< policy_queue< SyncPolicy, BoundPolicy, OverflowPolicy > >
 Create a policy_queue with custom policies.
 

Detailed Description

Factory for creating queue instances.

Provides convenient methods for queue creation based on requirements. Following Kent Beck's Simple Design principle, we now offer only 2 public queue types:

Queue Selection Guide (Simplified)

Queue Type Use Case Key Feature
adaptive_job_queue (Recommended) Most use cases Auto-optimizing, best of both worlds
job_queue Blocking wait required Mutex-based, exact size tracking

Recommended Usage

// Default choice: adaptive_job_queue (auto-optimizing)
// When blocking dequeue is essential
auto blocking_queue = queue_factory::create_standard_queue();
// With size limit (bounded queue merged into job_queue)
auto bounded = std::make_shared<job_queue>(1000); // max_size = 1000
// Requirements-based creation
reqs.need_exact_size = true;
// Environment-optimized
static auto create_optimal() -> std::unique_ptr< scheduler_interface >
Create optimal queue for current environment.
static auto create_standard_queue() -> std::shared_ptr< job_queue >
Create standard job_queue.
static auto create_adaptive_queue(adaptive_job_queue::policy policy=adaptive_job_queue::policy::balanced) -> std::unique_ptr< adaptive_job_queue >
Create adaptive queue (RECOMMENDED for most use cases)
static auto create_for_requirements(const requirements &reqs) -> std::unique_ptr< scheduler_interface >
Create queue based on requirements.
Note
Internal implementations (lockfree_job_queue, concurrent_queue) are now in the detail:: namespace and should not be used directly.

Definition at line 64 of file queue_factory.h.

Member Function Documentation

◆ create_adaptive_queue()

static auto kcenon::thread::queue_factory::create_adaptive_queue ( adaptive_job_queue::policy policy = adaptive_job_queue::policy::balanced) -> std::unique_ptr<adaptive_job_queue>
inlinestaticnodiscard

Create adaptive queue (RECOMMENDED for most use cases)

Parameters
policyAdaptation policy (default: balanced)
Returns
Unique pointer to new adaptive_job_queue

This is the recommended default choice for most applications.

Use this when you:

  • Want automatic optimization between mutex and lock-free modes
  • Need high throughput with variable workloads
  • Are unsure which implementation to choose
  • Want the best of both worlds (safety + performance)
Note
Internally uses lock-free queue for high-contention scenarios and mutex-based queue for low-contention scenarios.

Definition at line 120 of file queue_factory.h.

123 {
124 return std::make_unique<adaptive_job_queue>(policy);
125 }

Referenced by practical_use_cases(), and simple_factory_usage().

Here is the caller graph for this function:

◆ create_bounded_policy_queue()

auto kcenon::thread::queue_factory::create_bounded_policy_queue ( std::size_t max_size) -> std::unique_ptr<policy_queue< policies::mutex_sync_policy, policies::bounded_policy, policies::overflow_reject_policy>>
staticnodiscard

Create a bounded policy_queue with specified size.

Parameters
max_sizeMaximum number of jobs the queue can hold
Returns
Unique pointer to bounded queue

This creates a policy_queue with:

  • mutex_sync_policy: Thread-safe with blocking support
  • bounded_policy: Limited to max_size items
  • overflow_reject_policy: Returns error when full
auto result = queue->schedule(std::make_unique<my_job>());
if (result.is_err()) {
// Queue was full
}
static auto create_bounded_policy_queue(std::size_t max_size) -> std::unique_ptr< policy_queue< policies::mutex_sync_policy, policies::bounded_policy, policies::overflow_reject_policy > >
Create a bounded policy_queue with specified size.
A template class representing either a value or an error.

Definition at line 67 of file queue_factory.cpp.

72{
73 return std::make_unique<policy_queue<
74 policies::mutex_sync_policy,
75 policies::bounded_policy,
76 policies::overflow_reject_policy>>(policies::bounded_policy(max_size));
77}

◆ create_custom_policy_queue()

template<typename SyncPolicy , typename BoundPolicy , typename OverflowPolicy >
static auto kcenon::thread::queue_factory::create_custom_policy_queue ( SyncPolicy sync_policy,
BoundPolicy bound_policy,
OverflowPolicy overflow_policy ) -> std::unique_ptr<policy_queue<SyncPolicy, BoundPolicy, OverflowPolicy>>
inlinestaticnodiscard

Create a policy_queue with custom policies.

Template Parameters
SyncPolicySynchronization policy type
BoundPolicyBounding policy type
OverflowPolicyOverflow handling policy type
Parameters
sync_policySync policy instance
bound_policyBound policy instance
overflow_policyOverflow policy instance
Returns
Unique pointer to the configured policy_queue

This factory method allows full customization of queue behavior.

policies::overflow_drop_oldest_policy{}
);
Policy that limits queue size to a maximum.
Synchronization policy using mutex and condition variable.
static auto create_custom_policy_queue(SyncPolicy sync_policy, BoundPolicy bound_policy, OverflowPolicy overflow_policy) -> std::unique_ptr< policy_queue< SyncPolicy, BoundPolicy, OverflowPolicy > >
Create a policy_queue with custom policies.

Definition at line 249 of file queue_factory.h.

254 {
255 static_assert(is_sync_policy_v<SyncPolicy>,
256 "SyncPolicy must be a valid sync policy type");
257 static_assert(is_bound_policy_v<BoundPolicy>,
258 "BoundPolicy must be a valid bound policy type");
260 "OverflowPolicy must be a valid overflow policy type");
261
262 return std::make_unique<policy_queue<SyncPolicy, BoundPolicy, OverflowPolicy>>(
263 std::move(sync_policy),
264 std::move(bound_policy),
265 std::move(overflow_policy)
266 );
267 }
constexpr bool is_overflow_policy_v
Check if type is an overflow policy.
constexpr bool is_bound_policy_v
Check if type is a bound policy.
constexpr bool is_sync_policy_v
Check if type is a sync policy.

References kcenon::thread::is_bound_policy_v, kcenon::thread::is_overflow_policy_v, and kcenon::thread::is_sync_policy_v.

◆ create_for_requirements()

auto kcenon::thread::queue_factory::create_for_requirements ( const requirements & reqs) -> std::unique_ptr<scheduler_interface>
staticnodiscard

Create queue based on requirements.

Parameters
reqsRequirements specification
Returns
Scheduler interface pointer to appropriate queue type

Selection logic:

  • If need_exact_size or need_atomic_empty or need_batch_operations or need_blocking_wait: returns job_queue
  • If prefer_lock_free and no accuracy needs: returns lockfree_job_queue
  • Otherwise: returns adaptive_job_queue

Definition at line 12 of file queue_factory.cpp.

14{
15 // If accuracy is required, use mutex-based queue
16 if (reqs.need_exact_size || reqs.need_atomic_empty ||
17 reqs.need_batch_operations || reqs.need_blocking_wait) {
18 return std::make_unique<job_queue>();
19 }
20
21 // If lock-free is preferred and no accuracy needs
22 // Use adaptive_job_queue with performance_first policy instead of direct lockfree_job_queue
23 // (lockfree_job_queue is now an internal implementation detail)
24 if (reqs.prefer_lock_free) {
25 return std::make_unique<adaptive_job_queue>(adaptive_job_queue::policy::performance_first);
26 }
27
28 // Default: adaptive queue for flexibility
29 return std::make_unique<adaptive_job_queue>();
30}
@ performance_first
Always use lock-free mode.

References kcenon::thread::adaptive_job_queue::performance_first.

Referenced by requirements_based_selection().

Here is the caller graph for this function:

◆ create_lockfree_policy_queue()

auto kcenon::thread::queue_factory::create_lockfree_policy_queue ( ) -> std::unique_ptr<policy_lockfree_queue>
staticnodiscard

Create a lock-free policy_queue.

Returns
Unique pointer to policy_lockfree_queue

This creates a policy_queue with:

  • lockfree_sync_policy: High-throughput, non-blocking
  • unbounded_policy: No size limits
  • overflow_reject_policy: Rejects on overflow (not applicable for unbounded)

Use this for high-contention scenarios.

Note
size() returns approximate values, empty() is non-atomic

Definition at line 62 of file queue_factory.cpp.

63{
64 return std::make_unique<policy_lockfree_queue>();
65}

◆ create_optimal()

auto kcenon::thread::queue_factory::create_optimal ( ) -> std::unique_ptr<scheduler_interface>
staticnodiscard

Create optimal queue for current environment.

Returns
Scheduler interface pointer to queue

Considers:

  • CPU architecture (x86 vs ARM memory model)
  • Number of CPU cores
  • Default: adaptive_job_queue for flexibility

Selection:

Definition at line 32 of file queue_factory.cpp.

33{
34 // Check architecture for memory model strength
35#if defined(__x86_64__) || defined(_M_X64) || defined(__i386__) || defined(_M_IX86)
36 constexpr bool strong_memory_model = true;
37#else
38 // ARM and other architectures have weaker memory models
39 constexpr bool strong_memory_model = false;
40#endif
41
42 // ARM and other weak memory model architectures: prefer mutex for safety
43 if (!strong_memory_model) {
44 return std::make_unique<job_queue>();
45 }
46
47 // Low core count: mutex is efficient enough
48 const auto core_count = std::thread::hardware_concurrency();
49 if (core_count <= 2) {
50 return std::make_unique<job_queue>();
51 }
52
53 // Default: adaptive for best of both worlds
54 return std::make_unique<adaptive_job_queue>();
55}

Referenced by optimal_selection().

Here is the caller graph for this function:

◆ create_policy_queue()

auto kcenon::thread::queue_factory::create_policy_queue ( ) -> std::unique_ptr<standard_queue>
staticnodiscard

Create a standard policy_queue (mutex-based, unbounded)

Returns
Unique pointer to standard_queue

This creates a policy_queue with:

  • mutex_sync_policy: Thread-safe with blocking support
  • unbounded_policy: No size limits
  • overflow_reject_policy: Rejects on overflow (not applicable for unbounded)

Use this as the modern replacement for legacy job_queue.

queue->schedule(std::make_unique<my_job>());
static auto create_policy_queue() -> std::unique_ptr< standard_queue >
Create a standard policy_queue (mutex-based, unbounded)

Definition at line 57 of file queue_factory.cpp.

58{
59 return std::make_unique<standard_queue>();
60}

◆ create_standard_queue()

static auto kcenon::thread::queue_factory::create_standard_queue ( ) -> std::shared_ptr<job_queue>
inlinestaticnodiscard

Create standard job_queue.

Returns
Shared pointer to new job_queue (same as std::make_shared<job_queue>())

Use this when you need:

  • Exact size() and empty() checks
  • Batch operations
  • Blocking dequeue with condition variable wait
Note
For bounded queue functionality, use:
auto bounded = std::make_shared<job_queue>(1000); // max_size = 1000
See also
create_adaptive_queue() for the recommended default choice

Definition at line 100 of file queue_factory.h.

100 {
101 return std::make_shared<job_queue>();
102 }

Referenced by practical_use_cases(), and simple_factory_usage().

Here is the caller graph for this function:

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