11void value_store::add(
const std::string& key, value val) {
13 std::unique_lock lock(mutex_);
14 values_[key] = std::move(val);
15 write_count_.fetch_add(1, std::memory_order_relaxed);
18std::optional<value> value_store::get(
const std::string& key)
const {
20 std::shared_lock lock(mutex_);
21 auto it = values_.find(key);
22 if (it != values_.end()) {
23 read_count_.fetch_add(1, std::memory_order_relaxed);
29bool value_store::contains(
const std::string& key)
const {
31 std::shared_lock lock(mutex_);
32 return values_.find(key) != values_.end();
35bool value_store::remove(
const std::string& key) {
37 std::unique_lock lock(mutex_);
38 auto it = values_.find(key);
39 if (it != values_.end()) {
46void value_store::clear() {
48 std::unique_lock lock(mutex_);
52size_t value_store::size()
const {
54 std::shared_lock lock(mutex_);
55 return values_.size();
58bool value_store::empty()
const {
62std::string value_store::serialize()
const {
64 std::shared_lock lock(mutex_);
65 return serialize_impl();
68std::string value_store::serialize_impl()
const {
69 read_count_.fetch_add(1, std::memory_order_relaxed);
71 std::string result =
"{";
74 for (
const auto& [key, val] : values_) {
84 case '"': result +=
"\\\"";
break;
85 case '\\': result +=
"\\\\";
break;
86 case '\n': result +=
"\\n";
break;
87 case '\r': result +=
"\\r";
break;
88 case '\t': result +=
"\\t";
break;
93 result += val.to_json();
100std::vector<uint8_t> value_store::serialize_binary()
const {
102 std::shared_lock lock(mutex_);
103 return serialize_binary_impl();
106std::vector<uint8_t> value_store::serialize_binary_impl()
const {
107 read_count_.fetch_add(1, std::memory_order_relaxed);
109 std::vector<uint8_t> result;
112 constexpr uint8_t version = 1;
113 result.push_back(version);
116 uint32_t count =
static_cast<uint32_t
>(values_.size());
117 result.insert(result.end(),
118 reinterpret_cast<const uint8_t*
>(&count),
119 reinterpret_cast<const uint8_t*
>(&count) +
sizeof(count));
122 for (
const auto& [key, val] : values_) {
124 uint32_t key_len =
static_cast<uint32_t
>(key.size());
125 result.insert(result.end(),
126 reinterpret_cast<const uint8_t*
>(&key_len),
127 reinterpret_cast<const uint8_t*
>(&key_len) +
sizeof(key_len));
128 result.insert(result.end(), key.begin(), key.end());
131 auto value_data = val.serialize();
132 uint32_t value_len =
static_cast<uint32_t
>(value_data.size());
133 result.insert(result.end(),
134 reinterpret_cast<const uint8_t*
>(&value_len),
135 reinterpret_cast<const uint8_t*
>(&value_len) +
sizeof(value_len));
136 result.insert(result.end(), value_data.begin(), value_data.end());
142std::unique_ptr<value_store> value_store::deserialize(std::string_view ) {
145 throw std::runtime_error(
146 "value_store::deserialize() requires JSON parser - use deserialize_binary() instead");
149std::unique_ptr<value_store> value_store::deserialize_binary(
const std::vector<uint8_t>& binary_data) {
150 auto store = std::make_unique<value_store>();
152 if (binary_data.size() < 1 +
sizeof(uint32_t)) {
153 throw std::runtime_error(
"value_store::deserialize_binary() - invalid data: too small");
159 uint8_t version = binary_data[offset++];
161 throw std::runtime_error(
"value_store::deserialize_binary() - unsupported version: "
162 + std::to_string(version));
167 std::memcpy(&count, binary_data.data() + offset,
sizeof(count));
168 offset +=
sizeof(count);
171 for (uint32_t i = 0; i < count; ++i) {
172 if (offset +
sizeof(uint32_t) > binary_data.size()) {
173 throw std::runtime_error(
"value_store::deserialize_binary() - truncated data at entry "
174 + std::to_string(i));
179 std::memcpy(&key_len, binary_data.data() + offset,
sizeof(key_len));
180 offset +=
sizeof(key_len);
182 if (offset + key_len +
sizeof(uint32_t) > binary_data.size()) {
183 throw std::runtime_error(
"value_store::deserialize_binary() - truncated key data");
187 std::string key(binary_data.begin() + offset,
188 binary_data.begin() + offset + key_len);
193 std::memcpy(&value_len, binary_data.data() + offset,
sizeof(value_len));
194 offset +=
sizeof(value_len);
196 if (offset + value_len > binary_data.size()) {
197 throw std::runtime_error(
"value_store::deserialize_binary() - truncated value data");
201 std::vector<uint8_t> value_data(binary_data.begin() + offset,
202 binary_data.begin() + offset + value_len);
207 store->values_[key] = std::move(*value_opt);
209 throw std::runtime_error(
"value_store::deserialize_binary() - failed to deserialize value for key: "
217size_t value_store::get_read_count()
const {
218 return read_count_.load(std::memory_order_relaxed);
221size_t value_store::get_write_count()
const {
222 return write_count_.load(std::memory_order_relaxed);
225void value_store::reset_statistics() {
226 read_count_.store(0, std::memory_order_relaxed);
227 write_count_.store(0, std::memory_order_relaxed);
230#if CONTAINER_HAS_COMMON_RESULT
231kcenon::common::Result<std::unique_ptr<value_store>>
232value_store::deserialize_result(std::string_view )
noexcept {
233 return kcenon::common::Result<std::unique_ptr<value_store>>(
234 kcenon::common::error_info{
235 error_codes::deserialization_failed,
236 "value_store::deserialize_result() requires JSON parser - use deserialize_binary_result() instead",
237 "container_system"});
240kcenon::common::Result<std::unique_ptr<value_store>>
241value_store::deserialize_binary_result(
const std::vector<uint8_t>& binary_data)
noexcept {
243 auto store = std::make_unique<value_store>();
245 if (binary_data.size() < 1 +
sizeof(uint32_t)) {
246 return kcenon::common::Result<std::unique_ptr<value_store>>(
247 kcenon::common::error_info{
248 error_codes::corrupted_data,
249 "value_store::deserialize_binary_result() - invalid data: too small",
250 "container_system"});
255 uint8_t version = binary_data[offset++];
257 return kcenon::common::Result<std::unique_ptr<value_store>>(
258 kcenon::common::error_info{
259 error_codes::version_mismatch,
260 "value_store::deserialize_binary_result() - unsupported version: "
261 + std::to_string(version),
262 "container_system"});
266 std::memcpy(&count, binary_data.data() + offset,
sizeof(count));
267 offset +=
sizeof(count);
269 for (uint32_t i = 0; i < count; ++i) {
270 if (offset +
sizeof(uint32_t) > binary_data.size()) {
271 return kcenon::common::Result<std::unique_ptr<value_store>>(
272 kcenon::common::error_info{
273 error_codes::corrupted_data,
274 "value_store::deserialize_binary_result() - truncated data at entry "
276 "container_system"});
280 std::memcpy(&key_len, binary_data.data() + offset,
sizeof(key_len));
281 offset +=
sizeof(key_len);
283 if (offset + key_len +
sizeof(uint32_t) > binary_data.size()) {
284 return kcenon::common::Result<std::unique_ptr<value_store>>(
285 kcenon::common::error_info{
286 error_codes::corrupted_data,
287 "value_store::deserialize_binary_result() - truncated key data",
288 "container_system"});
291 std::string key(binary_data.begin() + offset,
292 binary_data.begin() + offset + key_len);
296 std::memcpy(&value_len, binary_data.data() + offset,
sizeof(value_len));
297 offset +=
sizeof(value_len);
299 if (offset + value_len > binary_data.size()) {
300 return kcenon::common::Result<std::unique_ptr<value_store>>(
301 kcenon::common::error_info{
302 error_codes::corrupted_data,
303 "value_store::deserialize_binary_result() - truncated value data",
304 "container_system"});
307 std::vector<uint8_t> value_data(binary_data.begin() + offset,
308 binary_data.begin() + offset + value_len);
313 store->values_[key] = std::move(*value_opt);
315 return kcenon::common::Result<std::unique_ptr<value_store>>(
316 kcenon::common::error_info{
317 error_codes::value_parse_failed,
318 "value_store::deserialize_binary_result() - failed to deserialize value for key: "
320 "container_system"});
324 return kcenon::common::ok(std::move(store));
325 }
catch (
const std::bad_alloc&) {
326 return kcenon::common::Result<std::unique_ptr<value_store>>(
327 kcenon::common::error_info{
328 error_codes::memory_allocation_failed,
329 "value_store::deserialize_binary_result() - memory allocation failed",
330 "container_system"});
331 }
catch (
const std::exception& e) {
332 return kcenon::common::Result<std::unique_ptr<value_store>>(
333 kcenon::common::error_info{
334 error_codes::deserialization_failed,
335 std::string(
"value_store::deserialize_binary_result() - unexpected error: ") + e.what(),
336 "container_system"});
static std::optional< value > deserialize(const std::vector< uint8_t > &data)
Deserialize from binary format (legacy compatible)