41 value_container::value_container()
43 , changed_data_(false)
44 , data_string_(
"@data={{}};")
49 , message_type_(
"data_container")
54 value_container::value_container(
const std::string& data_str,
55 bool parse_only_header)
60 if (parse_only_header)
62 raw_data_ptr_ = std::make_shared<const std::string>(data_str);
63 zero_copy_mode_ =
true;
65 deserialize(data_str, parse_only_header);
68 value_container::value_container(
const std::vector<uint8_t>& data_array,
69 bool parse_only_header)
73 if (parse_only_header)
75 std::string data_str(data_array.begin(), data_array.end());
76 raw_data_ptr_ = std::make_shared<const std::string>(std::move(data_str));
77 zero_copy_mode_ =
true;
79 deserialize(data_array, parse_only_header);
82 value_container::value_container(
const value_container& other,
83 bool parse_only_header)
86 if (metrics_manager::is_enabled())
88 metrics_manager::get().operations.copies.fetch_add(1, std::memory_order_relaxed);
90 binary_serializer serializer;
91 deserialize(serializer.serialize_to_string(other), parse_only_header);
94 value_container::value_container(std::shared_ptr<value_container> other,
95 bool parse_only_header)
100 binary_serializer serializer;
101 deserialize(serializer.serialize_to_string(*other), parse_only_header);
107 value_container::value_container(value_container&& other) noexcept
108 : parsed_data_(other.parsed_data_)
109 , changed_data_(other.changed_data_)
110 , data_string_(std::move(other.data_string_))
111 , source_id_(std::move(other.source_id_))
112 , source_sub_id_(std::move(other.source_sub_id_))
113 , target_id_(std::move(other.target_id_))
114 , target_sub_id_(std::move(other.target_sub_id_))
115 , message_type_(std::move(other.message_type_))
116 , version_(std::move(other.version_))
119 if (metrics_manager::is_enabled())
121 metrics_manager::get().operations.moves.fetch_add(1, std::memory_order_relaxed);
124 other.parsed_data_ =
true;
125 other.changed_data_ =
false;
128 value_container& value_container::operator=(value_container&& other)
noexcept
132 source_id_ = std::move(other.source_id_);
133 source_sub_id_ = std::move(other.source_sub_id_);
134 target_id_ = std::move(other.target_id_);
135 target_sub_id_ = std::move(other.target_sub_id_);
136 message_type_ = std::move(other.message_type_);
137 version_ = std::move(other.version_);
138 parsed_data_ = other.parsed_data_;
139 changed_data_ = other.changed_data_;
140 data_string_ = std::move(other.data_string_);
141 optimized_units_ = std::move(other.optimized_units_);
142 use_soo_ = other.use_soo_;
145 other.parsed_data_ =
true;
146 other.changed_data_ =
false;
151 value_container::~value_container() {}
153 std::shared_ptr<value_container> value_container::get_ptr()
155 return shared_from_this();
158 void value_container::set_source(std::string_view sid,
159 std::string_view ssubid)
161 std::unique_lock<std::shared_mutex> lock(mutex_);
162 source_id_ = std::string(sid);
163 source_sub_id_ = std::string(ssubid);
166 void value_container::set_target(std::string_view tid,
167 std::string_view tsubid)
169 std::unique_lock<std::shared_mutex> lock(mutex_);
170 target_id_ = std::string(tid);
171 target_sub_id_ = std::string(tsubid);
174 void value_container::set_message_type(std::string_view msg_type)
176 std::unique_lock<std::shared_mutex> lock(mutex_);
177 message_type_ = std::string(msg_type);
181 void value_container::swap_header(
void)
183 std::swap(source_id_, target_id_);
184 std::swap(source_sub_id_, target_sub_id_);
187 void value_container::clear_value(
void)
190 changed_data_ =
false;
191 data_string_ =
"@data={{}};";
192 optimized_units_.clear();
195 std::shared_ptr<value_container> value_container::copy(
196 bool containing_values)
198 binary_serializer serializer;
199 auto newC = std::make_shared<value_container>(serializer.serialize_to_string(*
this),
201 if (!containing_values && newC)
208 std::string value_container::source_id(
void)
const noexcept {
209 std::shared_lock<std::shared_mutex> lock(mutex_);
213 std::string value_container::source_sub_id(
void)
const noexcept
215 std::shared_lock<std::shared_mutex> lock(mutex_);
216 return source_sub_id_;
219 std::string value_container::target_id(
void)
const noexcept {
220 std::shared_lock<std::shared_mutex> lock(mutex_);
224 std::string value_container::target_sub_id(
void)
const noexcept
226 std::shared_lock<std::shared_mutex> lock(mutex_);
227 return target_sub_id_;
230 std::string value_container::message_type(
void)
const noexcept
232 std::shared_lock<std::shared_mutex> lock(mutex_);
233 return message_type_;
236 std::string value_container::version(
void)
const noexcept
238 std::shared_lock<std::shared_mutex> lock(mutex_);
246 std::optional<optimized_value> value_container::get(std::string_view key)
const noexcept
249 auto timer = metrics_manager::make_timer(
250 metrics_manager::get().read_latency,
251 &metrics_manager::get().timing.total_read_ns);
252 if (metrics_manager::is_enabled())
254 metrics_manager::get().operations.reads.fetch_add(1, std::memory_order_relaxed);
257 read_lock_guard lock(
this);
259 for (
const auto& val : optimized_units_) {
260 if (val.name == key) {
267 std::optional<value_view> value_container::get(std::string_view key, view_tag )
const noexcept
269 read_lock_guard lock(
this);
272 if (!zero_copy_mode_ || !raw_data_ptr_) {
283 for (
const auto& entry : *value_index_) {
284 if (entry.name == key) {
285 const char* data_ptr = raw_data_ptr_->data();
287 entry.name.data(), entry.name.size(),
288 data_ptr + entry.value_offset, entry.value_length,
298 std::vector<std::optional<optimized_value>> value_container::get(
299 std::span<const std::string_view> keys,
300 batch_options )
const noexcept
302 std::vector<std::optional<optimized_value>> results;
303 results.reserve(keys.size());
305 read_lock_guard lock(
this);
307 for (
const auto& key : keys) {
308 std::optional<optimized_value> found = std::nullopt;
309 for (
const auto& val : optimized_units_) {
310 if (val.name == key) {
315 results.push_back(std::move(found));
321 std::unordered_map<std::string, optimized_value> value_container::get_as_map(
322 std::span<const std::string_view> keys)
const
324 std::unordered_map<std::string, optimized_value> results;
325 results.reserve(keys.size());
327 read_lock_guard lock(
this);
329 for (
const auto& key : keys) {
330 for (
const auto& val : optimized_units_) {
331 if (val.name == key) {
332 results[std::string(key)] = val;
349 void value_container::set_unit_impl(
const optimized_value& val)
352 auto timer = metrics_manager::make_timer(
353 metrics_manager::get().write_latency,
354 &metrics_manager::get().timing.total_write_ns);
355 if (metrics_manager::is_enabled())
357 metrics_manager::get().operations.writes.fetch_add(1, std::memory_order_relaxed);
360 write_lock_guard lock(
this);
363 for (
auto& existing : optimized_units_) {
364 if (existing.name == val.name) {
366 changed_data_ =
true;
372 optimized_units_.push_back(val);
373 changed_data_ =
true;
375 if (use_soo_ && val.is_stack_allocated()) {
376 stack_allocations_.fetch_add(1, std::memory_order_relaxed);
378 heap_allocations_.fetch_add(1, std::memory_order_relaxed);
386 value_container& value_container::set(
const optimized_value& val)
392 value_container& value_container::set_all(std::span<const optimized_value> vals)
394 for (
const auto& val : vals) {
400 bool value_container::contains(std::string_view key)
const noexcept
402 read_lock_guard lock(
this);
404 for (
const auto& val : optimized_units_) {
405 if (val.name == key) {
416 value_container& value_container::bulk_insert(std::vector<optimized_value>&& values)
418 if (values.empty()) {
422 write_lock_guard lock(
this);
425 optimized_units_.reserve(optimized_units_.size() + values.size());
428 for (
auto& val : values) {
429 if (use_soo_ && val.is_stack_allocated()) {
430 stack_allocations_.fetch_add(1, std::memory_order_relaxed);
432 heap_allocations_.fetch_add(1, std::memory_order_relaxed);
434 optimized_units_.push_back(std::move(val));
437 changed_data_ =
true;
441 value_container& value_container::bulk_insert(
442 std::span<const optimized_value> values,
445 if (values.empty()) {
449 write_lock_guard lock(
this);
452 size_t reserve_size = reserve_hint > 0 ? reserve_hint : values.size();
453 optimized_units_.reserve(optimized_units_.size() + reserve_size);
456 for (
const auto& val : values) {
457 if (use_soo_ && val.is_stack_allocated()) {
458 stack_allocations_.fetch_add(1, std::memory_order_relaxed);
460 heap_allocations_.fetch_add(1, std::memory_order_relaxed);
462 optimized_units_.push_back(val);
465 changed_data_ =
true;
470 std::vector<bool> value_container::contains_batch(
471 std::span<const std::string_view> keys)
const noexcept
473 std::vector<bool> results;
474 results.reserve(keys.size());
476 read_lock_guard lock(
this);
478 for (
const auto& key : keys) {
480 for (
const auto& val : optimized_units_) {
481 if (val.name == key) {
486 results.push_back(found);
492 size_t value_container::remove_batch(std::span<const std::string_view> keys)
498 write_lock_guard lock(
this);
501 deserialize_values(data_string_,
false);
505 std::unordered_set<std::string_view> key_set(keys.begin(), keys.end());
508 size_t original_size = optimized_units_.size();
509 optimized_units_.erase(
510 std::remove_if(optimized_units_.begin(), optimized_units_.end(),
511 [&key_set](
const optimized_value& ov) {
512 return key_set.find(ov.name) != key_set.end();
514 optimized_units_.end());
516 size_t removed = original_size - optimized_units_.size();
518 changed_data_ =
true;
524 bool value_container::update_if(
525 std::string_view key,
526 const value_variant& expected,
527 value_variant&& new_value)
529 write_lock_guard lock(
this);
531 for (
auto& val : optimized_units_) {
532 if (val.name == key) {
534 if (val.data == expected) {
535 val.data = std::move(new_value);
536 val.type =
static_cast<value_types
>(val.data.index());
537 changed_data_ =
true;
547 std::vector<bool> value_container::update_batch_if(
548 std::span<const update_spec> updates)
550 std::vector<bool> results;
551 results.reserve(updates.size());
553 if (updates.empty()) {
557 write_lock_guard lock(
this);
559 for (
const auto& update : updates) {
560 bool updated =
false;
561 for (
auto& val : optimized_units_) {
562 if (val.name == update.key) {
563 if (val.data == update.expected) {
564 val.data = update.new_value;
565 val.type =
static_cast<value_types
>(val.data.index());
566 changed_data_ =
true;
572 results.push_back(updated);
579 std::vector<optimized_value> value_container::get_variant_values()
const
581 read_lock_guard lock(
this);
582 return optimized_units_;
589 void value_container::ensure_index_built()
const
591 read_lock_guard lock(
this);
597 void value_container::build_index()
const
599 if (index_built_ || !raw_data_ptr_) {
603 value_index_ = std::vector<value_index_entry>();
604 const std::string& data = *raw_data_ptr_;
608 std::regex reData(
"@data=\\s*\\{\\{?\\s*(.*?)\\s*\\}\\}?;");
609 std::smatch dataMatch;
610 if (!std::regex_search(data, dataMatch, reData)) {
616 size_t dataStart =
static_cast<size_t>(dataMatch.position(1));
617 std::string dataInside = dataMatch[1].str();
620 std::regex reItems(
"\\[(\\w+),\\s*(\\w+),\\s*(.*?)\\];");
621 auto it = std::sregex_iterator(dataInside.begin(), dataInside.end(), reItems);
622 auto end = std::sregex_iterator();
624 for (; it != end; ++it) {
625 value_index_entry entry;
628 size_t matchPos =
static_cast<size_t>(it->position());
629 size_t nameStart = dataStart + matchPos + 1;
630 size_t nameLen = (*it)[1].length();
633 entry.name = std::string_view(data.data() + nameStart, nameLen);
636 std::string typeStr = (*it)[2].str();
641 size_t valueStart = dataStart + matchPos + 1 + nameLen + 1 + (*it)[2].length() + 1;
643 entry.value_offset = valueStart;
644 entry.value_length = (*it)[3].length();
646 value_index_->push_back(entry);
654 void value_container::initialize(
void)
657 source_sub_id_.clear();
659 target_sub_id_.clear();
660 message_type_ =
"data_container";
670 bool value_container::deserialize(
const std::string& data_str,
671 bool parse_only_header)
674 auto timer = metrics_manager::make_timer(
675 metrics_manager::get().deserialize_latency,
676 &metrics_manager::get().timing.total_deserialize_ns);
677 if (metrics_manager::is_enabled())
679 metrics_manager::get().operations.deserializations.fetch_add(1, std::memory_order_relaxed);
683 if (data_str.empty())
687 std::regex newlineRe(
"\\r\\n?|\\n");
688 std::string clean = std::regex_replace(data_str, newlineRe,
"");
691 std::regex fullRe(
"@header=\\s*\\{\\{?\\s*(.*?)\\s*\\}\\}?;");
693 if (!std::regex_search(clean, match, fullRe))
696 return deserialize_values(clean, parse_only_header);
699 std::string headerInside = match[1].str();
700 std::regex pairRe(
"\\[(\\w+),(.*?)\\];");
701 auto it = std::sregex_iterator(headerInside.begin(), headerInside.end(),
703 auto end = std::sregex_iterator();
704 for (; it != end; ++it)
706 parsing((*it)[1].str(), std::to_string(TARGET_ID), (*it)[2].str(), target_id_);
707 parsing((*it)[1].str(), std::to_string(TARGET_SUB_ID), (*it)[2].str(), target_sub_id_);
708 parsing((*it)[1].str(), std::to_string(SOURCE_ID), (*it)[2].str(), source_id_);
709 parsing((*it)[1].str(), std::to_string(SOURCE_SUB_ID), (*it)[2].str(), source_sub_id_);
710 parsing((*it)[1].str(), std::to_string(MESSAGE_TYPE), (*it)[2].str(), message_type_);
711 parsing((*it)[1].str(), std::to_string(MESSAGE_VERSION), (*it)[2].str(), version_);
714 return deserialize_values(clean, parse_only_header);
717bool value_container::deserialize(
const std::vector<uint8_t>& data_array,
718 bool parse_only_header)
720 auto [strVal, err] = convert_string::to_string(data_array);
725 return deserialize(strVal, parse_only_header);
732const std::vector<validation_error>& value_container::get_validation_errors() const noexcept
734 return validation_errors_;
737void value_container::clear_validation_errors() noexcept
739 validation_errors_.clear();
742#if CONTAINER_HAS_RESULT
743 kcenon::common::VoidResult value_container::deserialize_result(
744 const std::string& data_str,
745 bool parse_only_header)
noexcept
747 if (deserialize(data_str, parse_only_header))
749 return kcenon::common::ok();
751 return kcenon::common::VoidResult(
752 kcenon::common::error_info{
753 error_codes::deserialization_failed,
754 error_codes::make_message(error_codes::deserialization_failed,
"string data"),
755 "container_system"});
758 kcenon::common::VoidResult value_container::deserialize_result(
759 const std::vector<uint8_t>& data_array,
760 bool parse_only_header)
noexcept
762 if (deserialize(data_array, parse_only_header))
764 return kcenon::common::ok();
766 return kcenon::common::VoidResult(
767 kcenon::common::error_info{
768 error_codes::deserialization_failed,
769 error_codes::make_message(error_codes::deserialization_failed,
"byte array data"),
770 "container_system"});
774 kcenon::common::VoidResult value_container::deserialize_result(
775 const std::string& data_string,
776 const container_schema& schema,
777 bool parse_only_header)
noexcept
780 validation_errors_.clear();
783 auto deser_result = deserialize_result(data_string, parse_only_header);
784 if (!deser_result.is_ok())
790 validation_errors_ = schema.validate_all(*
this);
791 if (!validation_errors_.empty())
793 const auto& first_error = validation_errors_.front();
794 return kcenon::common::VoidResult(
795 kcenon::common::error_info{
798 "container_schema"});
800 return kcenon::common::ok();
803 kcenon::common::VoidResult value_container::deserialize_result(
804 const std::vector<uint8_t>& data_array,
805 const container_schema& schema,
806 bool parse_only_header)
noexcept
809 validation_errors_.clear();
812 auto deser_result = deserialize_result(data_array, parse_only_header);
813 if (!deser_result.is_ok())
819 validation_errors_ = schema.validate_all(*
this);
820 if (!validation_errors_.empty())
822 const auto& first_error = validation_errors_.front();
823 return kcenon::common::VoidResult(
824 kcenon::common::error_info{
827 "container_schema"});
829 return kcenon::common::ok();
832 kcenon::common::Result<optimized_value> value_container::get_result(
833 std::string_view key)
const noexcept
835 read_lock_guard lock(
this);
837 for (
const auto& val : optimized_units_)
841 return kcenon::common::ok(val);
845 return kcenon::common::Result<optimized_value>(
846 kcenon::common::error_info{
847 error_codes::key_not_found,
848 error_codes::make_message(error_codes::key_not_found, key),
849 "container_system"});
852 kcenon::common::VoidResult value_container::set_result(
853 const optimized_value& val)
noexcept
857 if (val.name.empty())
859 return kcenon::common::VoidResult(
860 kcenon::common::error_info{
861 error_codes::empty_key,
862 error_codes::make_message(error_codes::empty_key),
863 "container_system"});
867 return kcenon::common::ok();
869 catch (
const std::bad_alloc&)
871 return kcenon::common::VoidResult(
872 kcenon::common::error_info{
873 error_codes::memory_allocation_failed,
874 error_codes::make_message(error_codes::memory_allocation_failed, val.name),
875 "container_system"});
877 catch (
const std::exception& e)
879 return kcenon::common::VoidResult(
880 kcenon::common::error_info{
881 error_codes::invalid_value,
882 std::string(
"Failed to set value: ") + e.what(),
883 "container_system"});
887 kcenon::common::VoidResult value_container::set_all_result(
888 std::span<const optimized_value> vals)
noexcept
892 for (
const auto& val : vals)
894 if (val.name.empty())
896 return kcenon::common::VoidResult(
897 kcenon::common::error_info{
898 error_codes::empty_key,
899 error_codes::make_message(error_codes::empty_key),
900 "container_system"});
904 return kcenon::common::ok();
906 catch (
const std::bad_alloc&)
908 return kcenon::common::VoidResult(
909 kcenon::common::error_info{
910 error_codes::memory_allocation_failed,
911 error_codes::make_message(error_codes::memory_allocation_failed),
912 "container_system"});
914 catch (
const std::exception& e)
916 return kcenon::common::VoidResult(
917 kcenon::common::error_info{
918 error_codes::invalid_value,
919 std::string(
"Failed to set values: ") + e.what(),
920 "container_system"});
924 kcenon::common::VoidResult value_container::remove_result(
925 std::string_view target_name)
noexcept
929 write_lock_guard lock(
this);
933 deserialize_values(data_string_,
false);
936 auto it = std::find_if(optimized_units_.begin(), optimized_units_.end(),
937 [&target_name](
const optimized_value& ov)
938 { return (ov.name == target_name); });
940 if (it == optimized_units_.end())
942 return kcenon::common::VoidResult(
943 kcenon::common::error_info{
944 error_codes::key_not_found,
945 error_codes::make_message(error_codes::key_not_found, target_name),
946 "container_system"});
950 optimized_units_.erase(
951 std::remove_if(optimized_units_.begin(), optimized_units_.end(),
952 [&target_name](
const optimized_value& ov)
953 { return (ov.name == target_name); }),
954 optimized_units_.end());
956 changed_data_ =
true;
957 return kcenon::common::ok();
959 catch (
const std::exception& e)
961 return kcenon::common::VoidResult(
962 kcenon::common::error_info{
963 error_codes::invalid_value,
964 std::string(
"Failed to remove value: ") + e.what(),
965 "container_system"});
969 kcenon::common::VoidResult value_container::load_packet_result(
970 const std::string& file_path)
noexcept
974 std::ifstream file(file_path, std::ios::binary);
977 return kcenon::common::VoidResult(
978 kcenon::common::error_info{
979 error_codes::file_not_found,
980 error_codes::make_message(error_codes::file_not_found, file_path),
981 "container_system"});
984 std::string content((std::istreambuf_iterator<char>(file)),
985 std::istreambuf_iterator<char>());
989 return kcenon::common::VoidResult(
990 kcenon::common::error_info{
991 error_codes::file_read_error,
992 error_codes::make_message(error_codes::file_read_error, file_path),
993 "container_system"});
996 return deserialize_result(content,
false);
998 catch (
const std::bad_alloc&)
1000 return kcenon::common::VoidResult(
1001 kcenon::common::error_info{
1002 error_codes::memory_allocation_failed,
1003 error_codes::make_message(error_codes::memory_allocation_failed, file_path),
1004 "container_system"});
1006 catch (
const std::exception& e)
1008 return kcenon::common::VoidResult(
1009 kcenon::common::error_info{
1010 error_codes::file_read_error,
1011 std::string(
"File read error: ") + e.what(),
1012 "container_system"});
1016 kcenon::common::VoidResult value_container::save_packet_result(
1017 const std::string& file_path)
noexcept
1021 auto serialize_res = serialize_string(serialization_format::binary);
1022 if (!serialize_res.is_ok())
1024 return kcenon::common::VoidResult(serialize_res.error());
1027 std::ofstream file(file_path, std::ios::binary | std::ios::trunc);
1030 return kcenon::common::VoidResult(
1031 kcenon::common::error_info{
1032 error_codes::file_write_error,
1033 error_codes::make_message(error_codes::file_write_error, file_path),
1034 "container_system"});
1037 const auto& content = serialize_res.value();
1038 file.write(content.data(),
static_cast<std::streamsize
>(content.size()));
1042 return kcenon::common::VoidResult(
1043 kcenon::common::error_info{
1044 error_codes::file_write_error,
1045 error_codes::make_message(error_codes::file_write_error, file_path),
1046 "container_system"});
1049 return kcenon::common::ok();
1051 catch (
const std::bad_alloc&)
1053 return kcenon::common::VoidResult(
1054 kcenon::common::error_info{
1055 error_codes::memory_allocation_failed,
1056 error_codes::make_message(error_codes::memory_allocation_failed, file_path),
1057 "container_system"});
1059 catch (
const std::exception& e)
1061 return kcenon::common::VoidResult(
1062 kcenon::common::error_info{
1063 error_codes::file_write_error,
1064 std::string(
"File write error: ") + e.what(),
1065 "container_system"});
1073 kcenon::common::VoidResult value_container::bulk_insert_result(
1074 std::vector<optimized_value>&& values)
noexcept
1078 bulk_insert(std::move(values));
1079 return kcenon::common::ok();
1081 catch (
const std::bad_alloc&)
1083 return kcenon::common::VoidResult(
1084 kcenon::common::error_info{
1085 error_codes::memory_allocation_failed,
1086 error_codes::make_message(error_codes::memory_allocation_failed),
1087 "container_system"});
1089 catch (
const std::exception& e)
1091 return kcenon::common::VoidResult(
1092 kcenon::common::error_info{
1093 error_codes::invalid_value,
1094 std::string(
"Bulk insert failed: ") + e.what(),
1095 "container_system"});
1099 kcenon::common::Result<std::vector<std::optional<optimized_value>>>
1100 value_container::get_batch_result(
1101 std::span<const std::string_view> keys)
const noexcept
1105 return kcenon::common::ok(get(keys));
1107 catch (
const std::bad_alloc&)
1109 return kcenon::common::Result<std::vector<std::optional<optimized_value>>>(
1110 kcenon::common::error_info{
1111 error_codes::memory_allocation_failed,
1112 error_codes::make_message(error_codes::memory_allocation_failed),
1113 "container_system"});
1115 catch (
const std::exception& e)
1117 return kcenon::common::Result<std::vector<std::optional<optimized_value>>>(
1118 kcenon::common::error_info{
1119 error_codes::invalid_value,
1120 std::string(
"Batch get failed: ") + e.what(),
1121 "container_system"});
1125 kcenon::common::Result<size_t> value_container::remove_batch_result(
1126 std::span<const std::string_view> keys)
noexcept
1130 return kcenon::common::ok(remove_batch(keys));
1132 catch (
const std::bad_alloc&)
1134 return kcenon::common::Result<size_t>(
1135 kcenon::common::error_info{
1136 error_codes::memory_allocation_failed,
1137 error_codes::make_message(error_codes::memory_allocation_failed),
1138 "container_system"});
1140 catch (
const std::exception& e)
1142 return kcenon::common::Result<size_t>(
1143 kcenon::common::error_info{
1144 error_codes::invalid_value,
1145 std::string(
"Batch remove failed: ") + e.what(),
1146 "container_system"});
1161 bool value_container::from_msgpack_impl(
const std::vector<uint8_t>& data)
1164 auto timer = metrics_manager::make_timer(
1165 metrics_manager::get().deserialize_latency,
1166 &metrics_manager::get().timing.total_deserialize_ns);
1167 if (metrics_manager::is_enabled())
1169 metrics_manager::get().operations.deserializations.fetch_add(1, std::memory_order_relaxed);
1179 msgpack_decoder decoder(data);
1182 auto outer_count = decoder.read_map_header();
1188 std::unique_lock<std::shared_mutex> lock(mutex_);
1190 for (
size_t i = 0; i < *outer_count; ++i)
1192 auto key = decoder.read_string();
1198 if (*key ==
"header")
1200 auto header_count = decoder.read_map_header();
1206 for (
size_t j = 0; j < *header_count; ++j)
1208 auto hkey = decoder.read_string();
1209 auto hval = decoder.read_string();
1215 if (*hkey ==
"target_id")
1219 else if (*hkey ==
"target_sub_id")
1221 target_sub_id_ = *hval;
1223 else if (*hkey ==
"source_id")
1227 else if (*hkey ==
"source_sub_id")
1229 source_sub_id_ = *hval;
1231 else if (*hkey ==
"message_type")
1233 message_type_ = *hval;
1235 else if (*hkey ==
"version")
1241 else if (*key ==
"values")
1243 auto values_count = decoder.read_map_header();
1249 for (
size_t j = 0; j < *values_count; ++j)
1251 auto vkey = decoder.read_string();
1257 optimized_value val;
1261 auto type = decoder.peek_type();
1264 case msgpack_type::nil:
1266 val.type = value_types::null_value;
1267 val.data = std::monostate{};
1270 case msgpack_type::boolean:
1272 auto b = decoder.read_bool();
1277 val.type = value_types::bool_value;
1282 case msgpack_type::positive_int:
1283 case msgpack_type::negative_int:
1285 auto n = decoder.read_int();
1291 if (*n >= 0 && *n <= INT32_MAX)
1293 val.type = value_types::int_value;
1294 val.data =
static_cast<int>(*n);
1296 else if (*n >= INT32_MIN && *n < 0)
1298 val.type = value_types::int_value;
1299 val.data =
static_cast<int>(*n);
1303 val.type = value_types::llong_value;
1304 val.data =
static_cast<long long>(*n);
1309 case msgpack_type::float32:
1311 auto f = decoder.read_float();
1316 val.type = value_types::float_value;
1321 case msgpack_type::float64:
1323 auto d = decoder.read_double();
1328 val.type = value_types::double_value;
1333 case msgpack_type::str:
1335 auto s = decoder.read_string();
1340 val.type = value_types::string_value;
1345 case msgpack_type::bin:
1347 auto b = decoder.read_binary();
1355 auto nested = std::make_shared<value_container>();
1356 if (b->size() >= 2 && nested->from_msgpack_impl(*b))
1358 val.type = value_types::container_value;
1363 val.type = value_types::bytes_value;
1369 case msgpack_type::array:
1371 auto arr_size = decoder.read_array_header();
1376 auto arr = std::make_shared<array_values>();
1377 arr->items.reserve(*arr_size);
1378 for (
size_t ai = 0; ai < *arr_size; ++ai)
1380 auto elem_type = decoder.peek_type();
1381 value_variant elem_data = std::monostate{};
1384 case msgpack_type::nil:
1387 case msgpack_type::boolean:
1388 if (
auto bv = decoder.read_bool()) elem_data = *bv;
1390 case msgpack_type::positive_int:
1391 case msgpack_type::negative_int:
1392 if (
auto nv = decoder.read_int()) elem_data =
static_cast<long long>(*nv);
1394 case msgpack_type::float32:
1395 if (
auto fv = decoder.read_float()) elem_data = *fv;
1397 case msgpack_type::float64:
1398 if (
auto dv = decoder.read_double()) elem_data = *dv;
1400 case msgpack_type::str:
1401 if (
auto sv = decoder.read_string()) elem_data = *sv;
1403 case msgpack_type::bin:
1404 if (
auto bv = decoder.read_binary()) elem_data = *bv;
1409 arr->items.push_back(std::move(elem_data));
1411 val.type = value_types::array_value;
1418 val.type = value_types::null_value;
1419 val.data = std::monostate{};
1423 optimized_units_.push_back(std::move(val));
1428 parsed_data_ =
true;
1429 changed_data_ =
false;
1434 value_container::serialization_format value_container::detect_format(
1435 const std::vector<uint8_t>& data)
1439 return serialization_format::unknown;
1444 uint8_t first_byte = data[0];
1445 if ((first_byte >= 0x80 && first_byte <= 0x8f) ||
1446 first_byte == 0xde ||
1449 return serialization_format::msgpack;
1453 std::string_view str_view(
reinterpret_cast<const char*
>(data.data()), data.size());
1454 return detect_format(str_view);
1457 value_container::serialization_format value_container::detect_format(
1458 std::string_view data)
1462 return serialization_format::unknown;
1467 while (pos < data.size() && std::isspace(
static_cast<unsigned char>(data[pos])))
1472 if (pos >= data.size())
1474 return serialization_format::unknown;
1478 char first_char = data[pos];
1481 if (first_char ==
'{' || first_char ==
'[')
1483 return serialization_format::json;
1487 if (first_char ==
'<')
1489 return serialization_format::xml;
1493 if (data.substr(pos, 7) ==
"@header")
1495 return serialization_format::binary;
1499 if (data.substr(pos, 5) ==
"@data")
1501 return serialization_format::binary;
1504 return serialization_format::unknown;
1507#if CONTAINER_HAS_COMMON_RESULT
1512 kcenon::common::Result<std::vector<uint8_t>> value_container::serialize(
1513 serialization_format fmt)
const noexcept
1516 auto timer = metrics_manager::make_timer(
1517 metrics_manager::get().serialize_latency,
1518 &metrics_manager::get().timing.total_serialize_ns);
1519 if (metrics_manager::is_enabled())
1521 metrics_manager::get().operations.serializations.fetch_add(1, std::memory_order_relaxed);
1525 auto serializer_fmt =
static_cast<kcenon::container::serialization_format
>(
1526 static_cast<int>(fmt));
1529 auto serializer = serializer_factory::create(serializer_fmt);
1532 return kcenon::common::Result<std::vector<uint8_t>>(
1533 kcenon::common::error_info{
1534 error_codes::invalid_format,
1535 "Cannot serialize with auto_detect or unknown format",
1536 "container_system"});
1539 return serializer->serialize(*
this);
1542 kcenon::common::Result<std::string> value_container::serialize_string(
1543 serialization_format fmt)
const noexcept
1546 auto timer = metrics_manager::make_timer(
1547 metrics_manager::get().serialize_latency,
1548 &metrics_manager::get().timing.total_serialize_ns);
1549 if (metrics_manager::is_enabled())
1551 metrics_manager::get().operations.serializations.fetch_add(1, std::memory_order_relaxed);
1559 case serialization_format::binary:
1561 binary_serializer serializer;
1562 return kcenon::common::ok(serializer.serialize_to_string(*
this));
1564 case serialization_format::json:
1566 json_serializer serializer;
1567 return kcenon::common::ok(serializer.serialize_to_string(*
this));
1569 case serialization_format::xml:
1571 xml_serializer serializer;
1572 return kcenon::common::ok(serializer.serialize_to_string(*
this));
1574 case serialization_format::msgpack:
1577 msgpack_serializer serializer;
1578 auto result = serializer.serialize(*
this);
1579 if (!result.is_ok())
1581 return kcenon::common::Result<std::string>(result.error());
1583 const auto& bytes = result.value();
1584 return kcenon::common::ok(std::string(bytes.begin(), bytes.end()));
1586 case serialization_format::auto_detect:
1587 case serialization_format::unknown:
1589 return kcenon::common::Result<std::string>(
1590 kcenon::common::error_info{
1591 error_codes::invalid_format,
1592 "Cannot serialize with auto_detect or unknown format",
1593 "container_system"});
1596 catch (
const std::bad_alloc&)
1598 return kcenon::common::Result<std::string>(
1599 kcenon::common::error_info{
1600 error_codes::memory_allocation_failed,
1601 error_codes::make_message(error_codes::memory_allocation_failed),
1602 "container_system"});
1604 catch (
const std::exception& e)
1606 return kcenon::common::Result<std::string>(
1607 kcenon::common::error_info{
1608 error_codes::serialization_failed,
1609 std::string(
"Serialization failed: ") + e.what(),
1610 "container_system"});
1614 kcenon::common::VoidResult value_container::deserialize(
1615 std::span<const uint8_t> data)
noexcept
1618 std::vector<uint8_t> data_vec(data.begin(), data.end());
1619 auto fmt = detect_format(data_vec);
1620 return deserialize(data, fmt);
1623 kcenon::common::VoidResult value_container::deserialize(
1624 std::span<const uint8_t> data,
1625 serialization_format fmt)
noexcept
1630 if (fmt == serialization_format::auto_detect)
1632 std::vector<uint8_t> data_vec(data.begin(), data.end());
1633 fmt = detect_format(data_vec);
1638 case serialization_format::binary:
1639 case serialization_format::json:
1640 case serialization_format::xml:
1643 std::string str_data(data.begin(), data.end());
1644 return deserialize_result(str_data,
false);
1646 case serialization_format::msgpack:
1648 std::vector<uint8_t> data_vec(data.begin(), data.end());
1649 if (from_msgpack_impl(data_vec))
1651 return kcenon::common::ok();
1653 return kcenon::common::VoidResult(
1654 kcenon::common::error_info{
1655 error_codes::deserialization_failed,
1656 error_codes::make_message(error_codes::deserialization_failed,
"Invalid MessagePack data"),
1657 "container_system"});
1659 case serialization_format::unknown:
1661 return kcenon::common::VoidResult(
1662 kcenon::common::error_info{
1663 error_codes::invalid_format,
1664 "Unknown or unsupported serialization format",
1665 "container_system"});
1668 catch (
const std::bad_alloc&)
1670 return kcenon::common::VoidResult(
1671 kcenon::common::error_info{
1672 error_codes::memory_allocation_failed,
1673 error_codes::make_message(error_codes::memory_allocation_failed),
1674 "container_system"});
1676 catch (
const std::exception& e)
1678 return kcenon::common::VoidResult(
1679 kcenon::common::error_info{
1680 error_codes::deserialization_failed,
1681 std::string(
"Deserialization failed: ") + e.what(),
1682 "container_system"});
1686 kcenon::common::VoidResult value_container::deserialize(
1687 std::string_view data)
noexcept
1690 auto fmt = detect_format(data);
1691 return deserialize(data, fmt);
1694 kcenon::common::VoidResult value_container::deserialize(
1695 std::string_view data,
1696 serialization_format fmt)
noexcept
1701 if (fmt == serialization_format::auto_detect)
1703 fmt = detect_format(data);
1708 case serialization_format::binary:
1709 case serialization_format::json:
1710 case serialization_format::xml:
1712 return deserialize_result(std::string(data),
false);
1714 case serialization_format::msgpack:
1716 std::vector<uint8_t> data_vec(data.begin(), data.end());
1717 if (from_msgpack_impl(data_vec))
1719 return kcenon::common::ok();
1721 return kcenon::common::VoidResult(
1722 kcenon::common::error_info{
1723 error_codes::deserialization_failed,
1724 error_codes::make_message(error_codes::deserialization_failed,
"Invalid MessagePack data"),
1725 "container_system"});
1727 case serialization_format::unknown:
1729 return kcenon::common::VoidResult(
1730 kcenon::common::error_info{
1731 error_codes::invalid_format,
1732 "Unknown or unsupported serialization format",
1733 "container_system"});
1736 catch (
const std::bad_alloc&)
1738 return kcenon::common::VoidResult(
1739 kcenon::common::error_info{
1740 error_codes::memory_allocation_failed,
1741 error_codes::make_message(error_codes::memory_allocation_failed),
1742 "container_system"});
1744 catch (
const std::exception& e)
1746 return kcenon::common::VoidResult(
1747 kcenon::common::error_info{
1748 error_codes::deserialization_failed,
1749 std::string(
"Deserialization failed: ") + e.what(),
1750 "container_system"});
1757 std::string value_container::datas(
void)
const
1761 return data_string_;
1765 formatter::format_to(std::back_inserter(result),
"@data={{{{");
1766 for (
auto& u : optimized_units_)
1768 std::string value_str = variant_helpers::to_string(u.data, u.type);
1770 formatter::format_to(std::back_inserter(result),
"[{},{},{}];",
1771 u.name, type_str, value_str);
1773 formatter::format_to(std::back_inserter(result),
"}}}};");
1777 size_t value_container::memory_footprint()
const
1779 std::shared_lock<std::shared_mutex> lock(mutex_);
1781 size_t total =
sizeof(value_container);
1784 total += source_id_.capacity();
1785 total += source_sub_id_.capacity();
1786 total += target_id_.capacity();
1787 total += target_sub_id_.capacity();
1788 total += message_type_.capacity();
1789 total += version_.capacity();
1792 total += data_string_.capacity();
1797 total += optimized_units_.capacity() *
sizeof(optimized_value);
1798 for (
const auto& ov : optimized_units_)
1800 total += ov.memory_footprint();
1808 pool_stats value_container::get_pool_stats()
1810#if CONTAINER_USE_MEMORY_POOL
1811 auto& allocator = internal::pool_allocator::instance();
1812 auto stats = allocator.get_stats();
1813 auto small_stats = allocator.get_small_pool_stats();
1814 auto medium_stats = allocator.get_medium_pool_stats();
1819 stats.small_pool_allocs,
1820 stats.medium_pool_allocs,
1821 stats.deallocations,
1822 small_stats.free_blocks + medium_stats.free_blocks
1825 return pool_stats(0, 0, 0);
1829 void value_container::clear_pool()
1831#if CONTAINER_USE_MEMORY_POOL
1832 internal::pool_allocator::instance().reset_stats();
1841 std::ostream&
operator<<(std::ostream& out, value_container& other)
1843 binary_serializer serializer;
1844 out << serializer.serialize_to_string(other);
1849 std::shared_ptr<value_container> other)
1853 binary_serializer serializer;
1854 out << serializer.serialize_to_string(*other);
1859 std::string&
operator<<(std::string& out, value_container& other)
1861 binary_serializer serializer;
1862 out = serializer.serialize_to_string(other);
1867 std::shared_ptr<value_container> other)
1871 binary_serializer serializer;
1872 out = serializer.serialize_to_string(*other);
1883 std::string value_container::metrics_to_json()
const
1885 auto& m = metrics_manager::get();
1888 result.reserve(2048);
1891 result +=
" \"operations\": {\n";
1892 result +=
" \"reads\": " + std::to_string(m.operations.reads.load(std::memory_order_relaxed)) +
",\n";
1893 result +=
" \"writes\": " + std::to_string(m.operations.writes.load(std::memory_order_relaxed)) +
",\n";
1894 result +=
" \"serializations\": " + std::to_string(m.operations.serializations.load(std::memory_order_relaxed)) +
",\n";
1895 result +=
" \"deserializations\": " + std::to_string(m.operations.deserializations.load(std::memory_order_relaxed)) +
",\n";
1896 result +=
" \"copies\": " + std::to_string(m.operations.copies.load(std::memory_order_relaxed)) +
",\n";
1897 result +=
" \"moves\": " + std::to_string(m.operations.moves.load(std::memory_order_relaxed)) +
"\n";
1900 result +=
" \"timing\": {\n";
1901 result +=
" \"total_serialize_ns\": " + std::to_string(m.timing.total_serialize_ns.load(std::memory_order_relaxed)) +
",\n";
1902 result +=
" \"total_deserialize_ns\": " + std::to_string(m.timing.total_deserialize_ns.load(std::memory_order_relaxed)) +
",\n";
1903 result +=
" \"total_read_ns\": " + std::to_string(m.timing.total_read_ns.load(std::memory_order_relaxed)) +
",\n";
1904 result +=
" \"total_write_ns\": " + std::to_string(m.timing.total_write_ns.load(std::memory_order_relaxed)) +
"\n";
1907 result +=
" \"latency\": {\n";
1908 result +=
" \"serialize\": {\n";
1909 result +=
" \"p50_ns\": " + std::to_string(m.serialize_latency.p50()) +
",\n";
1910 result +=
" \"p95_ns\": " + std::to_string(m.serialize_latency.p95()) +
",\n";
1911 result +=
" \"p99_ns\": " + std::to_string(m.serialize_latency.p99()) +
",\n";
1912 result +=
" \"p999_ns\": " + std::to_string(m.serialize_latency.p999()) +
",\n";
1913 result +=
" \"max_ns\": " + std::to_string(m.serialize_latency.max_ns.load(std::memory_order_relaxed)) +
",\n";
1914 result +=
" \"avg_ns\": " + std::to_string(m.serialize_latency.avg()) +
"\n";
1916 result +=
" \"deserialize\": {\n";
1917 result +=
" \"p50_ns\": " + std::to_string(m.deserialize_latency.p50()) +
",\n";
1918 result +=
" \"p95_ns\": " + std::to_string(m.deserialize_latency.p95()) +
",\n";
1919 result +=
" \"p99_ns\": " + std::to_string(m.deserialize_latency.p99()) +
",\n";
1920 result +=
" \"p999_ns\": " + std::to_string(m.deserialize_latency.p999()) +
",\n";
1921 result +=
" \"max_ns\": " + std::to_string(m.deserialize_latency.max_ns.load(std::memory_order_relaxed)) +
",\n";
1922 result +=
" \"avg_ns\": " + std::to_string(m.deserialize_latency.avg()) +
"\n";
1924 result +=
" \"read\": {\n";
1925 result +=
" \"p50_ns\": " + std::to_string(m.read_latency.p50()) +
",\n";
1926 result +=
" \"p95_ns\": " + std::to_string(m.read_latency.p95()) +
",\n";
1927 result +=
" \"p99_ns\": " + std::to_string(m.read_latency.p99()) +
",\n";
1928 result +=
" \"p999_ns\": " + std::to_string(m.read_latency.p999()) +
",\n";
1929 result +=
" \"max_ns\": " + std::to_string(m.read_latency.max_ns.load(std::memory_order_relaxed)) +
",\n";
1930 result +=
" \"avg_ns\": " + std::to_string(m.read_latency.avg()) +
"\n";
1932 result +=
" \"write\": {\n";
1933 result +=
" \"p50_ns\": " + std::to_string(m.write_latency.p50()) +
",\n";
1934 result +=
" \"p95_ns\": " + std::to_string(m.write_latency.p95()) +
",\n";
1935 result +=
" \"p99_ns\": " + std::to_string(m.write_latency.p99()) +
",\n";
1936 result +=
" \"p999_ns\": " + std::to_string(m.write_latency.p999()) +
",\n";
1937 result +=
" \"max_ns\": " + std::to_string(m.write_latency.max_ns.load(std::memory_order_relaxed)) +
",\n";
1938 result +=
" \"avg_ns\": " + std::to_string(m.write_latency.avg()) +
"\n";
1942 result +=
" \"simd\": {\n";
1943 result +=
" \"simd_operations\": " + std::to_string(m.simd.simd_operations.load(std::memory_order_relaxed)) +
",\n";
1944 result +=
" \"scalar_fallbacks\": " + std::to_string(m.simd.scalar_fallbacks.load(std::memory_order_relaxed)) +
",\n";
1945 result +=
" \"bytes_processed_simd\": " + std::to_string(m.simd.bytes_processed_simd.load(std::memory_order_relaxed)) +
",\n";
1946 result +=
" \"utilization_percent\": " + std::to_string(m.simd.utilization()) +
"\n";
1949 result +=
" \"cache\": {\n";
1950 result +=
" \"key_index_hits\": " + std::to_string(m.cache.key_index_hits.load(std::memory_order_relaxed)) +
",\n";
1951 result +=
" \"key_index_misses\": " + std::to_string(m.cache.key_index_misses.load(std::memory_order_relaxed)) +
",\n";
1952 result +=
" \"value_cache_hits\": " + std::to_string(m.cache.value_cache_hits.load(std::memory_order_relaxed)) +
",\n";
1953 result +=
" \"value_cache_misses\": " + std::to_string(m.cache.value_cache_misses.load(std::memory_order_relaxed)) +
",\n";
1954 result +=
" \"key_index_hit_rate_percent\": " + std::to_string(m.cache.key_index_hit_rate()) +
",\n";
1955 result +=
" \"value_cache_hit_rate_percent\": " + std::to_string(m.cache.value_cache_hit_rate()) +
"\n";
1963 std::string value_container::metrics_to_prometheus()
const
1965 auto& m = metrics_manager::get();
1968 result.reserve(4096);
1971 result +=
"# HELP container_operations_total Total number of container operations\n";
1972 result +=
"# TYPE container_operations_total counter\n";
1973 result +=
"container_operations_total{operation=\"read\"} " + std::to_string(m.operations.reads.load(std::memory_order_relaxed)) +
"\n";
1974 result +=
"container_operations_total{operation=\"write\"} " + std::to_string(m.operations.writes.load(std::memory_order_relaxed)) +
"\n";
1975 result +=
"container_operations_total{operation=\"serialize\"} " + std::to_string(m.operations.serializations.load(std::memory_order_relaxed)) +
"\n";
1976 result +=
"container_operations_total{operation=\"deserialize\"} " + std::to_string(m.operations.deserializations.load(std::memory_order_relaxed)) +
"\n";
1977 result +=
"container_operations_total{operation=\"copy\"} " + std::to_string(m.operations.copies.load(std::memory_order_relaxed)) +
"\n";
1978 result +=
"container_operations_total{operation=\"move\"} " + std::to_string(m.operations.moves.load(std::memory_order_relaxed)) +
"\n";
1981 result +=
"# HELP container_operation_duration_nanoseconds_total Total time spent in operations\n";
1982 result +=
"# TYPE container_operation_duration_nanoseconds_total counter\n";
1983 result +=
"container_operation_duration_nanoseconds_total{operation=\"serialize\"} " + std::to_string(m.timing.total_serialize_ns.load(std::memory_order_relaxed)) +
"\n";
1984 result +=
"container_operation_duration_nanoseconds_total{operation=\"deserialize\"} " + std::to_string(m.timing.total_deserialize_ns.load(std::memory_order_relaxed)) +
"\n";
1985 result +=
"container_operation_duration_nanoseconds_total{operation=\"read\"} " + std::to_string(m.timing.total_read_ns.load(std::memory_order_relaxed)) +
"\n";
1986 result +=
"container_operation_duration_nanoseconds_total{operation=\"write\"} " + std::to_string(m.timing.total_write_ns.load(std::memory_order_relaxed)) +
"\n";
1989 result +=
"# HELP container_serialize_latency_nanoseconds Serialize operation latency percentiles\n";
1990 result +=
"# TYPE container_serialize_latency_nanoseconds summary\n";
1991 result +=
"container_serialize_latency_nanoseconds{quantile=\"0.5\"} " + std::to_string(m.serialize_latency.p50()) +
"\n";
1992 result +=
"container_serialize_latency_nanoseconds{quantile=\"0.95\"} " + std::to_string(m.serialize_latency.p95()) +
"\n";
1993 result +=
"container_serialize_latency_nanoseconds{quantile=\"0.99\"} " + std::to_string(m.serialize_latency.p99()) +
"\n";
1994 result +=
"container_serialize_latency_nanoseconds{quantile=\"0.999\"} " + std::to_string(m.serialize_latency.p999()) +
"\n";
1995 result +=
"container_serialize_latency_nanoseconds_max " + std::to_string(m.serialize_latency.max_ns.load(std::memory_order_relaxed)) +
"\n";
1996 result +=
"container_serialize_latency_nanoseconds_count " + std::to_string(m.serialize_latency.sample_count.load(std::memory_order_relaxed)) +
"\n";
1999 result +=
"# HELP container_deserialize_latency_nanoseconds Deserialize operation latency percentiles\n";
2000 result +=
"# TYPE container_deserialize_latency_nanoseconds summary\n";
2001 result +=
"container_deserialize_latency_nanoseconds{quantile=\"0.5\"} " + std::to_string(m.deserialize_latency.p50()) +
"\n";
2002 result +=
"container_deserialize_latency_nanoseconds{quantile=\"0.95\"} " + std::to_string(m.deserialize_latency.p95()) +
"\n";
2003 result +=
"container_deserialize_latency_nanoseconds{quantile=\"0.99\"} " + std::to_string(m.deserialize_latency.p99()) +
"\n";
2004 result +=
"container_deserialize_latency_nanoseconds{quantile=\"0.999\"} " + std::to_string(m.deserialize_latency.p999()) +
"\n";
2005 result +=
"container_deserialize_latency_nanoseconds_max " + std::to_string(m.deserialize_latency.max_ns.load(std::memory_order_relaxed)) +
"\n";
2006 result +=
"container_deserialize_latency_nanoseconds_count " + std::to_string(m.deserialize_latency.sample_count.load(std::memory_order_relaxed)) +
"\n";
2009 result +=
"# HELP container_read_latency_nanoseconds Read operation latency percentiles\n";
2010 result +=
"# TYPE container_read_latency_nanoseconds summary\n";
2011 result +=
"container_read_latency_nanoseconds{quantile=\"0.5\"} " + std::to_string(m.read_latency.p50()) +
"\n";
2012 result +=
"container_read_latency_nanoseconds{quantile=\"0.95\"} " + std::to_string(m.read_latency.p95()) +
"\n";
2013 result +=
"container_read_latency_nanoseconds{quantile=\"0.99\"} " + std::to_string(m.read_latency.p99()) +
"\n";
2014 result +=
"container_read_latency_nanoseconds{quantile=\"0.999\"} " + std::to_string(m.read_latency.p999()) +
"\n";
2015 result +=
"container_read_latency_nanoseconds_max " + std::to_string(m.read_latency.max_ns.load(std::memory_order_relaxed)) +
"\n";
2016 result +=
"container_read_latency_nanoseconds_count " + std::to_string(m.read_latency.sample_count.load(std::memory_order_relaxed)) +
"\n";
2019 result +=
"# HELP container_write_latency_nanoseconds Write operation latency percentiles\n";
2020 result +=
"# TYPE container_write_latency_nanoseconds summary\n";
2021 result +=
"container_write_latency_nanoseconds{quantile=\"0.5\"} " + std::to_string(m.write_latency.p50()) +
"\n";
2022 result +=
"container_write_latency_nanoseconds{quantile=\"0.95\"} " + std::to_string(m.write_latency.p95()) +
"\n";
2023 result +=
"container_write_latency_nanoseconds{quantile=\"0.99\"} " + std::to_string(m.write_latency.p99()) +
"\n";
2024 result +=
"container_write_latency_nanoseconds{quantile=\"0.999\"} " + std::to_string(m.write_latency.p999()) +
"\n";
2025 result +=
"container_write_latency_nanoseconds_max " + std::to_string(m.write_latency.max_ns.load(std::memory_order_relaxed)) +
"\n";
2026 result +=
"container_write_latency_nanoseconds_count " + std::to_string(m.write_latency.sample_count.load(std::memory_order_relaxed)) +
"\n";
2029 result +=
"# HELP container_simd_operations_total Total SIMD operations performed\n";
2030 result +=
"# TYPE container_simd_operations_total counter\n";
2031 result +=
"container_simd_operations_total " + std::to_string(m.simd.simd_operations.load(std::memory_order_relaxed)) +
"\n";
2032 result +=
"# HELP container_scalar_fallbacks_total Total scalar fallback operations\n";
2033 result +=
"# TYPE container_scalar_fallbacks_total counter\n";
2034 result +=
"container_scalar_fallbacks_total " + std::to_string(m.simd.scalar_fallbacks.load(std::memory_order_relaxed)) +
"\n";
2035 result +=
"# HELP container_simd_bytes_processed_total Total bytes processed via SIMD\n";
2036 result +=
"# TYPE container_simd_bytes_processed_total counter\n";
2037 result +=
"container_simd_bytes_processed_total " + std::to_string(m.simd.bytes_processed_simd.load(std::memory_order_relaxed)) +
"\n";
2038 result +=
"# HELP container_simd_utilization_ratio SIMD utilization ratio\n";
2039 result +=
"# TYPE container_simd_utilization_ratio gauge\n";
2040 result +=
"container_simd_utilization_ratio " + std::to_string(m.simd.utilization() / 100.0) +
"\n";
2043 result +=
"# HELP container_cache_hits_total Total cache hits\n";
2044 result +=
"# TYPE container_cache_hits_total counter\n";
2045 result +=
"container_cache_hits_total{cache=\"key_index\"} " + std::to_string(m.cache.key_index_hits.load(std::memory_order_relaxed)) +
"\n";
2046 result +=
"container_cache_hits_total{cache=\"value\"} " + std::to_string(m.cache.value_cache_hits.load(std::memory_order_relaxed)) +
"\n";
2047 result +=
"# HELP container_cache_misses_total Total cache misses\n";
2048 result +=
"# TYPE container_cache_misses_total counter\n";
2049 result +=
"container_cache_misses_total{cache=\"key_index\"} " + std::to_string(m.cache.key_index_misses.load(std::memory_order_relaxed)) +
"\n";
2050 result +=
"container_cache_misses_total{cache=\"value\"} " + std::to_string(m.cache.value_cache_misses.load(std::memory_order_relaxed)) +
"\n";
2051 result +=
"# HELP container_cache_hit_ratio Cache hit ratio\n";
2052 result +=
"# TYPE container_cache_hit_ratio gauge\n";
2053 result +=
"container_cache_hit_ratio{cache=\"key_index\"} " + std::to_string(m.cache.key_index_hit_rate() / 100.0) +
"\n";
2054 result +=
"container_cache_hit_ratio{cache=\"value\"} " + std::to_string(m.cache.value_cache_hit_rate() / 100.0) +
"\n";
2059 bool value_container::deserialize_values(
const std::string& data,
2060 bool parse_only_header)
2062 if (!optimized_units_.empty())
2064 optimized_units_.clear();
2066 changed_data_ =
false;
2069 std::regex reData(
"@data=\\s*\\{\\{?\\s*(.*?)\\s*\\}\\}?;");
2071 if (!std::regex_search(data, match, reData))
2073 data_string_ =
"@data={{}}";
2074 parsed_data_ =
true;
2077 data_string_ = match[0];
2079 if (parse_only_header)
2081 parsed_data_ =
false;
2084 parsed_data_ =
true;
2087 std::regex reItems(
"\\[(\\w+),\\s*(\\w+),\\s*(.*?)\\];");
2088 auto it = std::sregex_iterator(data_string_.begin(), data_string_.end(),
2090 auto end = std::sregex_iterator();
2092 for (; it != end; ++it)
2094 auto nameStr = (*it)[1].str();
2095 auto typeStr = (*it)[2].str();
2096 auto dataStr = (*it)[3].str();
2109 case value_types::null_value:
2110 ov.data = std::monostate{};
2112 case value_types::bool_value:
2113 ov.data = (dataStr ==
"true" || dataStr ==
"1");
2115 case value_types::short_value:
2116 ov.data =
static_cast<short>(std::stoi(dataStr));
2118 case value_types::ushort_value:
2119 ov.data =
static_cast<unsigned short>(std::stoul(dataStr));
2121 case value_types::int_value:
2122 ov.data = std::stoi(dataStr);
2124 case value_types::uint_value:
2125 ov.data =
static_cast<unsigned int>(std::stoul(dataStr));
2127 case value_types::long_value:
2128 ov.data = std::stol(dataStr);
2130 case value_types::ulong_value:
2131 ov.data = std::stoul(dataStr);
2133 case value_types::llong_value:
2134 ov.data = std::stoll(dataStr);
2136 case value_types::ullong_value:
2137 ov.data = std::stoull(dataStr);
2139 case value_types::float_value:
2140 ov.data = std::stof(dataStr);
2142 case value_types::double_value:
2143 ov.data = std::stod(dataStr);
2145 case value_types::string_value:
2148 case value_types::bytes_value:
2151 std::vector<uint8_t> bytes(dataStr.begin(), dataStr.end());
2155 case value_types::container_value:
2158 auto nested = std::make_shared<value_container>();
2159 if (!dataStr.empty() && nested->deserialize(dataStr,
false))
2165 ov.data = std::monostate{};
2170 ov.data = std::monostate{};
2174 optimized_units_.push_back(std::move(ov));
2180 void value_container::parsing(std::string_view source_name,
2181 std::string_view target_name,
2182 std::string_view target_value,
2183 std::string& target_variable)
2185 if (source_name == target_name)
2189 if (target_value.empty())
2191 target_variable.clear();
2196 size_t start = target_value.find_first_not_of(
' ');
2197 if (start == std::string_view::npos)
2200 target_variable.clear();
2205 size_t end = target_value.find_last_not_of(
' ');
2208 target_variable = std::string(target_value.substr(start, end - start + 1));