Container System 0.1.0
High-performance C++20 type-safe container framework with SIMD-accelerated serialization
Loading...
Searching...
No Matches
kcenon::container::thread_safe_container Class Reference

Thread-safe container with lock optimization. More...

#include <thread_safe_container.h>

Inheritance diagram for kcenon::container::thread_safe_container:
Inheritance graph
Collaboration diagram for kcenon::container::thread_safe_container:
Collaboration graph

Classes

struct  Statistics
 Get statistics. More...
 

Public Types

using value_map = std::unordered_map<std::string, value>
 
using const_iterator = value_map::const_iterator
 
using iterator = value_map::iterator
 

Public Member Functions

 thread_safe_container ()=default
 Default constructor.
 
 thread_safe_container (std::initializer_list< std::pair< std::string, value > > init)
 Construct with initial values.
 
 thread_safe_container (const thread_safe_container &other)
 Copy constructor (thread-safe)
 
 thread_safe_container (thread_safe_container &&other) noexcept
 Move constructor.
 
thread_safe_containeroperator= (const thread_safe_container &other)
 Copy assignment (thread-safe)
 
thread_safe_containeroperator= (thread_safe_container &&other) noexcept
 Move assignment.
 
std::optional< valueget (std::string_view key) const
 Get value by key (thread-safe read)
 
template<concepts::ValueVariantType T>
std::optional< T > get_typed (std::string_view key) const
 Get typed value by key.
 
void set (std::string_view key, value value)
 Set value for key (thread-safe write)
 
template<concepts::ValueVariantType T>
void set_typed (std::string_view key, T &&val)
 Set typed value for key.
 
bool remove (std::string_view key)
 Remove value by key.
 
void clear ()
 Clear all values.
 
size_t size () const
 Get the number of values.
 
bool empty () const
 Check if container is empty.
 
bool contains (std::string_view key) const
 Check if key exists.
 
std::vector< std::string > keys () const
 Get all keys.
 
void set_variant (const value &val)
 Set a value directly using variant value.
 
std::optional< valueget_variant (const std::string &key) const
 Get a value as variant value.
 
void set_container (const std::string &key, std::shared_ptr< thread_safe_container > container)
 Set a nested container.
 
std::shared_ptr< thread_safe_containerget_container (const std::string &key) const
 Get a nested container.
 
template<concepts::KeyValueCallback Func>
void for_each (Func &&func) const
 Apply a function to all values (read-only)
 
template<concepts::MutableKeyValueCallback Func>
void for_each_mut (Func &&func)
 Apply a function to all values (mutable)
 
template<concepts::ValueMapCallback< value_map > Func>
void bulk_update (Func &&updater)
 Bulk update operation with minimal lock contention.
 
template<concepts::ConstValueMapCallback< value_map > Func>
auto bulk_read (Func &&reader) const
 Bulk read operation.
 
bool compare_exchange (std::string_view key, const value &expected, const value &desired)
 Atomic compare and swap.
 
Statistics get_statistics () const
 
std::string to_json () const
 Serialize container to JSON.
 
std::vector< uint8_t > serialize () const
 Serialize container to binary.
 
valueoperator[] (const std::string &key)
 Array-style access (creates if not exists)
 
std::shared_ptr< lockfree_container_readercreate_lockfree_reader ()
 Create a lock-free reader for this container.
 
std::shared_ptr< auto_refresh_readercreate_auto_refresh_reader (std::chrono::milliseconds refresh_interval)
 Create an auto-refreshing lock-free reader.
 

Static Public Member Functions

static std::shared_ptr< thread_safe_containerdeserialize (const std::vector< uint8_t > &data)
 Deserialize from binary.
 

Private Attributes

std::shared_mutex mutex_
 
value_map values_
 
std::atomic< size_t > read_count_ {0}
 
std::atomic< size_t > write_count_ {0}
 
std::atomic< size_t > bulk_read_count_ {0}
 
std::atomic< size_t > bulk_write_count_ {0}
 

Detailed Description

Thread-safe container with lock optimization.

This container provides thread-safe access to variant values with optimized locking strategies for different access patterns.

Definition at line 31 of file thread_safe_container.h.

Member Typedef Documentation

◆ const_iterator

Definition at line 35 of file thread_safe_container.h.

◆ iterator

Definition at line 36 of file thread_safe_container.h.

◆ value_map

using kcenon::container::thread_safe_container::value_map = std::unordered_map<std::string, value>

Definition at line 34 of file thread_safe_container.h.

Constructor & Destructor Documentation

◆ thread_safe_container() [1/4]

kcenon::container::thread_safe_container::thread_safe_container ( )
default

Default constructor.

◆ thread_safe_container() [2/4]

kcenon::container::thread_safe_container::thread_safe_container ( std::initializer_list< std::pair< std::string, value > > init)

Construct with initial values.

Definition at line 14 of file thread_safe_container.cpp.

16 {
17 for (const auto& [key, value] : init) {
18 values_.emplace(key, value);
19 }
20 }

References values_.

◆ thread_safe_container() [3/4]

kcenon::container::thread_safe_container::thread_safe_container ( const thread_safe_container & other)

Copy constructor (thread-safe)

Definition at line 22 of file thread_safe_container.cpp.

23 {
24 std::shared_lock other_lock(other.mutex_);
25 values_ = other.values_;
26 read_count_ = other.read_count_.load();
27 write_count_ = other.write_count_.load();
28 bulk_read_count_ = other.bulk_read_count_.load();
29 bulk_write_count_ = other.bulk_write_count_.load();
30 }

References bulk_read_count_, bulk_write_count_, mutex_, read_count_, values_, and write_count_.

◆ thread_safe_container() [4/4]

kcenon::container::thread_safe_container::thread_safe_container ( thread_safe_container && other)
noexcept

Move constructor.

Definition at line 32 of file thread_safe_container.cpp.

33 {
34 std::unique_lock other_lock(other.mutex_);
35 values_ = std::move(other.values_);
36 read_count_ = other.read_count_.load();
37 write_count_ = other.write_count_.load();
38 bulk_read_count_ = other.bulk_read_count_.load();
39 bulk_write_count_ = other.bulk_write_count_.load();
40
41 other.read_count_ = 0;
42 other.write_count_ = 0;
43 other.bulk_read_count_ = 0;
44 other.bulk_write_count_ = 0;
45 }

Member Function Documentation

◆ bulk_read()

template<concepts::ConstValueMapCallback< value_map > Func>
auto kcenon::container::thread_safe_container::bulk_read ( Func && reader) const
inline

Bulk read operation.

Template Parameters
FuncFunction type satisfying ConstValueMapCallback concept
Parameters
readerFunction to perform bulk reads
Returns
Result of the reader function

Definition at line 214 of file thread_safe_container.h.

214 {
215 std::shared_lock lock(mutex_);
216 bulk_read_count_.fetch_add(1, std::memory_order_relaxed);
217 return reader(values_);
218 }

References bulk_read_count_, mutex_, and values_.

◆ bulk_update()

template<concepts::ValueMapCallback< value_map > Func>
void kcenon::container::thread_safe_container::bulk_update ( Func && updater)
inline

Bulk update operation with minimal lock contention.

Template Parameters
FuncFunction type satisfying ValueMapCallback concept
Parameters
updaterFunction to perform bulk updates

Definition at line 201 of file thread_safe_container.h.

201 {
202 std::unique_lock lock(mutex_);
203 updater(values_);
204 bulk_write_count_.fetch_add(1, std::memory_order_relaxed);
205 }

References bulk_write_count_, mutex_, and values_.

◆ clear()

void kcenon::container::thread_safe_container::clear ( )

Clear all values.

Definition at line 104 of file thread_safe_container.cpp.

105 {
106 std::unique_lock lock(mutex_);
107 write_count_.fetch_add(1, std::memory_order_relaxed);
108 values_.clear();
109 }

References mutex_, values_, and write_count_.

◆ compare_exchange()

bool kcenon::container::thread_safe_container::compare_exchange ( std::string_view key,
const value & expected,
const value & desired )

Atomic compare and swap.

Parameters
keyThe key to update
expectedThe expected current value
desiredThe desired new value
Returns
true if swap succeeded, false otherwise

Definition at line 185 of file thread_safe_container.cpp.

188 {
189 std::unique_lock lock(mutex_);
190 write_count_.fetch_add(1, std::memory_order_relaxed);
191
192 auto it = values_.find(std::string(key));
193 if (it != values_.end()) {
194 if (it->second == expected) {
195 it->second = desired;
196 return true;
197 }
198 }
199 return false;
200 }

References mutex_, values_, and write_count_.

◆ contains()

bool kcenon::container::thread_safe_container::contains ( std::string_view key) const

Check if key exists.

Definition at line 123 of file thread_safe_container.cpp.

124 {
125 std::shared_lock lock(mutex_);
126 read_count_.fetch_add(1, std::memory_order_relaxed);
127 return values_.find(std::string(key)) != values_.end();
128 }

References mutex_, read_count_, and values_.

◆ create_auto_refresh_reader()

std::shared_ptr< auto_refresh_reader > kcenon::container::thread_safe_container::create_auto_refresh_reader ( std::chrono::milliseconds refresh_interval)
inline

Create an auto-refreshing lock-free reader.

The returned reader automatically refreshes its snapshot at the specified interval using a background thread. This is useful for scenarios where you want lock-free reads with automatic updates without managing the refresh manually.

Parameters
refresh_intervalThe interval between automatic refreshes
Returns
Shared pointer to a new auto-refresh reader
auto container = std::make_shared<thread_safe_container>();
auto reader = container->create_auto_refresh_reader(std::chrono::milliseconds(100));
// Lock-free reads are always up-to-date within refresh_interval
auto value = reader->get<int>("counter");
Enhanced type-safe value with perfect legacy compatibility.
Definition value.h:129
std::optional< T > get() const
Type-safe getter with optional return.
Definition value.h:213

Definition at line 802 of file thread_safe_container.h.

803 {
804 return std::make_shared<auto_refresh_reader>(shared_from_this(), refresh_interval);
805 }

◆ create_lockfree_reader()

std::shared_ptr< lockfree_container_reader > kcenon::container::thread_safe_container::create_lockfree_reader ( )
inline

Create a lock-free reader for this container.

The returned reader provides truly lock-free reads using the RCU pattern. Call refresh() on the reader periodically to update its snapshot.

Returns
Shared pointer to a new lock-free reader

Definition at line 797 of file thread_safe_container.h.

797 {
798 return std::make_shared<lockfree_container_reader>(shared_from_this());
799 }

◆ deserialize()

std::shared_ptr< thread_safe_container > kcenon::container::thread_safe_container::deserialize ( const std::vector< uint8_t > & data)
static

Deserialize from binary.

Definition at line 282 of file thread_safe_container.cpp.

284 {
285 if (data.size() < sizeof(uint32_t)) {
286 return nullptr;
287 }
288
289 auto container = std::make_shared<thread_safe_container>();
290 size_t offset = 0;
291
292 // Read number of entries
293 uint32_t count;
294 std::memcpy(&count, data.data() + offset, sizeof(count));
295 offset += sizeof(count);
296
297 // Read each key-value pair
298 for (uint32_t i = 0; i < count; ++i) {
299 if (offset + sizeof(uint32_t) > data.size()) {
300 return nullptr;
301 }
302
303 // Read key
304 uint32_t key_len;
305 std::memcpy(&key_len, data.data() + offset, sizeof(key_len));
306 offset += sizeof(key_len);
307
308 if (offset + key_len + sizeof(uint32_t) > data.size()) {
309 return nullptr;
310 }
311
312 std::string key(data.begin() + offset, data.begin() + offset + key_len);
313 offset += key_len;
314
315 // Read value length
316 uint32_t value_len;
317 std::memcpy(&value_len, data.data() + offset, sizeof(value_len));
318 offset += sizeof(value_len);
319
320 if (offset + value_len > data.size()) {
321 return nullptr;
322 }
323
324 // Deserialize value
325 std::vector<uint8_t> value_data(data.begin() + offset,
326 data.begin() + offset + value_len);
327 offset += value_len;
328
329 auto value_opt = value::deserialize(value_data);
330 if (value_opt) {
331 container->values_[key] = std::move(*value_opt);
332 }
333 }
334
335 return container;
336 }
static std::optional< value > deserialize(const std::vector< uint8_t > &data)
Deserialize from binary format (legacy compatible)
Definition value.cpp:555

References kcenon::container::value::deserialize().

Referenced by kcenon::container::value::deserialize_data().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ empty()

bool kcenon::container::thread_safe_container::empty ( ) const

Check if container is empty.

Definition at line 117 of file thread_safe_container.cpp.

118 {
119 std::shared_lock lock(mutex_);
120 return values_.empty();
121 }

References mutex_, and values_.

◆ for_each()

template<concepts::KeyValueCallback Func>
void kcenon::container::thread_safe_container::for_each ( Func && func) const
inline

Apply a function to all values (read-only)

Template Parameters
FuncFunction type satisfying KeyValueCallback concept
Parameters
funcFunction to apply to each key-value pair

Definition at line 175 of file thread_safe_container.h.

175 {
176 std::shared_lock lock(mutex_);
177 for (const auto& [key, val] : values_) {
178 func(key, val);
179 }
180 }

References mutex_, and values_.

◆ for_each_mut()

template<concepts::MutableKeyValueCallback Func>
void kcenon::container::thread_safe_container::for_each_mut ( Func && func)
inline

Apply a function to all values (mutable)

Template Parameters
FuncFunction type satisfying MutableKeyValueCallback concept
Parameters
funcFunction to apply to each key-value pair

Definition at line 188 of file thread_safe_container.h.

188 {
189 std::unique_lock lock(mutex_);
190 for (auto& [key, val] : values_) {
191 func(key, val);
192 }
193 }

References mutex_, and values_.

◆ get()

std::optional< value > kcenon::container::thread_safe_container::get ( std::string_view key) const

Get value by key (thread-safe read)

Parameters
keyThe key to look up
Returns
Optional containing the value if found

Definition at line 71 of file thread_safe_container.cpp.

72 {
73 std::shared_lock lock(mutex_);
74 read_count_.fetch_add(1, std::memory_order_relaxed);
75
76 auto it = values_.find(std::string(key));
77 if (it != values_.end()) {
78 return it->second;
79 }
80 return std::nullopt;
81 }

References mutex_, read_count_, and values_.

◆ get_container()

std::shared_ptr< thread_safe_container > kcenon::container::thread_safe_container::get_container ( const std::string & key) const

Get a nested container.

Parameters
keyThe key to look up
Returns
Shared pointer to container, nullptr if not found or not a container

Definition at line 172 of file thread_safe_container.cpp.

174 {
175 std::shared_lock lock(mutex_);
176 read_count_.fetch_add(1, std::memory_order_relaxed);
177
178 auto it = values_.find(key);
179 if (it != values_.end()) {
180 return it->second.get<std::shared_ptr<thread_safe_container>>().value_or(nullptr);
181 }
182 return nullptr;
183 }

References mutex_, read_count_, and values_.

◆ get_statistics()

thread_safe_container::Statistics kcenon::container::thread_safe_container::get_statistics ( ) const

Definition at line 202 of file thread_safe_container.cpp.

203 {
204 std::shared_lock lock(mutex_);
205 return {
206 read_count_.load(std::memory_order_relaxed),
207 write_count_.load(std::memory_order_relaxed),
208 bulk_read_count_.load(std::memory_order_relaxed),
209 bulk_write_count_.load(std::memory_order_relaxed),
210 values_.size()
211 };
212 }

References bulk_read_count_, bulk_write_count_, mutex_, read_count_, values_, and write_count_.

◆ get_typed()

template<concepts::ValueVariantType T>
std::optional< T > kcenon::container::thread_safe_container::get_typed ( std::string_view key) const
inline

Get typed value by key.

Template Parameters
TThe expected type (must be a valid variant type)
Parameters
keyThe key to look up
Returns
Optional containing the value if found and type matches

Definition at line 82 of file thread_safe_container.h.

82 {
83 std::shared_lock lock(mutex_);
84 auto it = values_.find(std::string(key));
85 if (it != values_.end()) {
86 return it->second.get<T>();
87 }
88 return std::nullopt;
89 }

References mutex_, and values_.

◆ get_variant()

std::optional< value > kcenon::container::thread_safe_container::get_variant ( const std::string & key) const

Get a value as variant value.

Parameters
keyThe key to look up
Returns
Optional containing the value if found

Definition at line 152 of file thread_safe_container.cpp.

153 {
154 std::shared_lock lock(mutex_);
155 read_count_.fetch_add(1, std::memory_order_relaxed);
156
157 auto it = values_.find(key);
158 if (it != values_.end()) {
159 return it->second;
160 }
161 return std::nullopt;
162 }

References mutex_, read_count_, and values_.

◆ keys()

std::vector< std::string > kcenon::container::thread_safe_container::keys ( ) const

Get all keys.

Definition at line 130 of file thread_safe_container.cpp.

131 {
132 std::shared_lock lock(mutex_);
133 read_count_.fetch_add(1, std::memory_order_relaxed);
134
135 std::vector<std::string> result;
136 result.reserve(values_.size());
137
138 for (const auto& [key, value] : values_) {
139 result.push_back(key);
140 }
141
142 return result;
143 }

References mutex_, read_count_, and values_.

◆ operator=() [1/2]

thread_safe_container & kcenon::container::thread_safe_container::operator= ( const thread_safe_container & other)

Copy assignment (thread-safe)

Definition at line 47 of file thread_safe_container.cpp.

48 {
49 if (this != &other) {
50 // Acquire both locks atomically to prevent deadlock
51 // std::scoped_lock ensures locks are acquired in a consistent order
52 std::scoped_lock lock(mutex_, other.mutex_);
53 values_ = other.values_;
54 write_count_.fetch_add(1, std::memory_order_relaxed);
55 }
56 return *this;
57 }

References mutex_, values_, and write_count_.

◆ operator=() [2/2]

thread_safe_container & kcenon::container::thread_safe_container::operator= ( thread_safe_container && other)
noexcept

Move assignment.

Definition at line 59 of file thread_safe_container.cpp.

60 {
61 if (this != &other) {
62 // Acquire both locks atomically to prevent deadlock
63 // std::scoped_lock ensures locks are acquired in a consistent order
64 std::scoped_lock lock(mutex_, other.mutex_);
65 values_ = std::move(other.values_);
66 write_count_.fetch_add(1, std::memory_order_relaxed);
67 }
68 return *this;
69 }

◆ operator[]()

value & kcenon::container::thread_safe_container::operator[] ( const std::string & key)

Array-style access (creates if not exists)

Definition at line 338 of file thread_safe_container.cpp.

339 {
340 std::unique_lock lock(mutex_);
341 write_count_.fetch_add(1, std::memory_order_relaxed);
342
343 auto it = values_.find(key);
344 if (it == values_.end()) {
345 auto [new_it, inserted] = values_.emplace(key, value(key));
346 return new_it->second;
347 }
348 return it->second;
349 }

References mutex_, values_, and write_count_.

◆ remove()

bool kcenon::container::thread_safe_container::remove ( std::string_view key)

Remove value by key.

Parameters
keyThe key to remove
Returns
true if removed, false if not found

Definition at line 91 of file thread_safe_container.cpp.

92 {
93 std::unique_lock lock(mutex_);
94 write_count_.fetch_add(1, std::memory_order_relaxed);
95
96 auto it = values_.find(std::string(key));
97 if (it != values_.end()) {
98 values_.erase(it);
99 return true;
100 }
101 return false;
102 }

References mutex_, values_, and write_count_.

◆ serialize()

std::vector< uint8_t > kcenon::container::thread_safe_container::serialize ( ) const

Serialize container to binary.

Definition at line 248 of file thread_safe_container.cpp.

249 {
250 std::shared_lock lock(mutex_);
251 read_count_.fetch_add(1, std::memory_order_relaxed);
252
253 std::vector<uint8_t> result;
254
255 // Header: number of entries (4 bytes)
256 uint32_t count = static_cast<uint32_t>(values_.size());
257 result.insert(result.end(),
258 reinterpret_cast<const uint8_t*>(&count),
259 reinterpret_cast<const uint8_t*>(&count) + sizeof(count));
260
261 // Serialize each key-value pair
262 for (const auto& [key, value] : values_) {
263 // Key length and key
264 uint32_t key_len = static_cast<uint32_t>(key.size());
265 result.insert(result.end(),
266 reinterpret_cast<const uint8_t*>(&key_len),
267 reinterpret_cast<const uint8_t*>(&key_len) + sizeof(key_len));
268 result.insert(result.end(), key.begin(), key.end());
269
270 // Value serialization
271 auto value_data = value.serialize();
272 uint32_t value_len = static_cast<uint32_t>(value_data.size());
273 result.insert(result.end(),
274 reinterpret_cast<const uint8_t*>(&value_len),
275 reinterpret_cast<const uint8_t*>(&value_len) + sizeof(value_len));
276 result.insert(result.end(), value_data.begin(), value_data.end());
277 }
278
279 return result;
280 }

References mutex_, read_count_, kcenon::container::value::serialize(), and values_.

Here is the call graph for this function:

◆ set()

void kcenon::container::thread_safe_container::set ( std::string_view key,
value value )

Set value for key (thread-safe write)

Parameters
keyThe key to set
valueThe value to store

Definition at line 83 of file thread_safe_container.cpp.

84 {
85 std::unique_lock lock(mutex_);
86 write_count_.fetch_add(1, std::memory_order_relaxed);
87
88 values_[std::string(key)] = std::move(value);
89 }

References mutex_, values_, and write_count_.

Referenced by set_typed().

Here is the caller graph for this function:

◆ set_container()

void kcenon::container::thread_safe_container::set_container ( const std::string & key,
std::shared_ptr< thread_safe_container > container )

Set a nested container.

Parameters
keyThe key for the nested container
containerThe container to store

Definition at line 164 of file thread_safe_container.cpp.

166 {
167 std::unique_lock lock(mutex_);
168 write_count_.fetch_add(1, std::memory_order_relaxed);
169 values_[key] = value(key, std::move(container));
170 }

References mutex_, values_, and write_count_.

◆ set_typed()

template<concepts::ValueVariantType T>
void kcenon::container::thread_safe_container::set_typed ( std::string_view key,
T && val )
inline

Set typed value for key.

Template Parameters
TThe value type (must be a valid variant type)
Parameters
keyThe key to set
valueThe value to store

Definition at line 105 of file thread_safe_container.h.

105 {
106 set(key, value(key, std::forward<T>(val)));
107 }
void set(std::string_view key, value value)
Set value for key (thread-safe write)

References set().

Here is the call graph for this function:

◆ set_variant()

void kcenon::container::thread_safe_container::set_variant ( const value & val)

Set a value directly using variant value.

Parameters
valThe value to store (key is extracted from value's name)

Definition at line 145 of file thread_safe_container.cpp.

146 {
147 std::unique_lock lock(mutex_);
148 write_count_.fetch_add(1, std::memory_order_relaxed);
149 values_[std::string(val.name())] = val;
150 }

References mutex_, kcenon::container::value::name(), values_, and write_count_.

Here is the call graph for this function:

◆ size()

size_t kcenon::container::thread_safe_container::size ( ) const

Get the number of values.

Definition at line 111 of file thread_safe_container.cpp.

112 {
113 std::shared_lock lock(mutex_);
114 return values_.size();
115 }

References mutex_, and values_.

◆ to_json()

std::string kcenon::container::thread_safe_container::to_json ( ) const

Serialize container to JSON.

Definition at line 214 of file thread_safe_container.cpp.

215 {
216 std::shared_lock lock(mutex_);
217 read_count_.fetch_add(1, std::memory_order_relaxed);
218
219 std::string result = "{";
220 bool first = true;
221
222 for (const auto& [key, value] : values_) {
223 if (!first) {
224 result += ",";
225 }
226 first = false;
227
228 // Escape key for JSON
229 result += "\"";
230 for (char c : key) {
231 switch (c) {
232 case '"': result += "\\\""; break;
233 case '\\': result += "\\\\"; break;
234 case '\n': result += "\\n"; break;
235 case '\r': result += "\\r"; break;
236 case '\t': result += "\\t"; break;
237 default: result += c;
238 }
239 }
240 result += "\":";
241 result += value.to_json();
242 }
243
244 result += "}";
245 return result;
246 }

References mutex_, read_count_, kcenon::container::value::to_json(), and values_.

Here is the call graph for this function:

Member Data Documentation

◆ bulk_read_count_

std::atomic<size_t> kcenon::container::thread_safe_container::bulk_read_count_ {0}
mutableprivate

Definition at line 303 of file thread_safe_container.h.

303{0};

Referenced by bulk_read(), get_statistics(), and thread_safe_container().

◆ bulk_write_count_

std::atomic<size_t> kcenon::container::thread_safe_container::bulk_write_count_ {0}
mutableprivate

Definition at line 304 of file thread_safe_container.h.

304{0};

Referenced by bulk_update(), get_statistics(), and thread_safe_container().

◆ mutex_

◆ read_count_

std::atomic<size_t> kcenon::container::thread_safe_container::read_count_ {0}
mutableprivate

◆ values_

◆ write_count_

std::atomic<size_t> kcenon::container::thread_safe_container::write_count_ {0}
mutableprivate

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