Monitoring System 0.1.0
System resource monitoring with pluggable collectors and alerting
Loading...
Searching...
No Matches
hot_path_helper.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
19#pragma once
20
21#include <shared_mutex>
22
23namespace kcenon {
24namespace monitoring {
25namespace hot_path {
26
68template <typename Map, typename Key, typename CreateFn>
69auto get_or_create(Map& map, std::shared_mutex& mutex, const Key& key,
70 CreateFn create_fn) ->
71 typename std::remove_reference<decltype(*map.begin()->second)>::type* {
72 // Fast path: try with shared lock (read-only, allows concurrent readers)
73 {
74 std::shared_lock<std::shared_mutex> read_lock(mutex);
75 auto it = map.find(key);
76 if (it != map.end()) {
77 return it->second.get();
78 }
79 }
80
81 // Slow path: upgrade to write lock and double-check
82 {
83 std::unique_lock<std::shared_mutex> write_lock(mutex);
84 // Double-check after acquiring write lock
85 // Another thread may have created the entry while we were waiting
86 auto& ptr = map[key];
87 if (!ptr) {
88 ptr = create_fn();
89 }
90 return ptr.get();
91 }
92}
93
134template <typename Map, typename Key, typename CreateFn, typename InitFn>
135auto get_or_create_with_init(Map& map, std::shared_mutex& mutex, const Key& key,
136 CreateFn create_fn, InitFn init_fn) ->
137 typename std::remove_reference<decltype(*map.begin()->second)>::type* {
138 // Fast path: try with shared lock (read-only, allows concurrent readers)
139 {
140 std::shared_lock<std::shared_mutex> read_lock(mutex);
141 auto it = map.find(key);
142 if (it != map.end()) {
143 return it->second.get();
144 }
145 }
146
147 // Slow path: upgrade to write lock and double-check
148 {
149 std::unique_lock<std::shared_mutex> write_lock(mutex);
150 // Double-check after acquiring write lock
151 // Another thread may have created the entry while we were waiting
152 auto& ptr = map[key];
153 if (!ptr) {
154 ptr = create_fn();
155 // Initialize the newly created entry while still under write lock
156 init_fn(*ptr);
157 }
158 return ptr.get();
159 }
160}
161
203template <typename Map, typename Key, typename CreateFn, typename UpdateFn>
204auto get_or_create_and_update(Map& map, std::shared_mutex& mutex, const Key& key,
205 CreateFn create_fn, UpdateFn update_fn)
206 -> decltype(update_fn(*map.begin()->second)) {
207 // Get or create the entry
208 auto* ptr = get_or_create(map, mutex, key, std::move(create_fn));
209
210 // Apply the update function outside of map locks
211 // The value's own synchronization handles thread safety
212 return update_fn(*ptr);
213}
214
215} // namespace hot_path
216} // namespace monitoring
217} // namespace kcenon
auto get_or_create_with_init(Map &map, std::shared_mutex &mutex, const Key &key, CreateFn create_fn, InitFn init_fn) -> typename std::remove_reference< decltype(*map.begin() ->second)>::type *
auto get_or_create_and_update(Map &map, std::shared_mutex &mutex, const Key &key, CreateFn create_fn, UpdateFn update_fn) -> decltype(update_fn(*map.begin() ->second))
auto get_or_create(Map &map, std::shared_mutex &mutex, const Key &key, CreateFn create_fn) -> typename std::remove_reference< decltype(*map.begin() ->second)>::type *