mcc_keyvalue.h: worked
This commit is contained in:
@@ -95,8 +95,9 @@ concept mcc_variant_valid_type_c = requires { !std::is_array_v<T> && !std::is_vo
|
|||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
concept mcc_keyvalue_record_c = requires(T t) {
|
concept mcc_keyvalue_record_c = requires(T t) {
|
||||||
requires std::same_as<decltype(t.key), const std::string_view>; // immutable key!!!
|
requires std::same_as<decltype(t.key), const std::string_view>; // key name is immutable!!!
|
||||||
requires mcc_variant_valid_type_c<decltype(t.value)>;
|
requires mcc_variant_valid_type_c<decltype(t.value)>;
|
||||||
|
// requires mcc_serialization_params_c<decltype(t.serial_pars)>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -122,6 +123,12 @@ template <mcc_keyvalue_desc_c DESCR_T,
|
|||||||
class MccKeyValueHolder
|
class MccKeyValueHolder
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
enum OutputPolicy {
|
||||||
|
OPOLICY_CHANGED_ONLY, // serialize only changed and previously deserialized (by fromCharRange method) key-value
|
||||||
|
// pairs
|
||||||
|
OPOLICY_FULL // serialize entire set of key-value pairs
|
||||||
|
};
|
||||||
|
|
||||||
static constexpr std::string_view COMMENT_SEQ{COMM_SEQ == nullptr ? constants::MCC_KV_COMMENT_SEQ_ARR
|
static constexpr std::string_view COMMENT_SEQ{COMM_SEQ == nullptr ? constants::MCC_KV_COMMENT_SEQ_ARR
|
||||||
: COMM_SEQ[0] == '\0' ? constants::MCC_KV_COMMENT_SEQ_ARR
|
: COMM_SEQ[0] == '\0' ? constants::MCC_KV_COMMENT_SEQ_ARR
|
||||||
: COMM_SEQ};
|
: COMM_SEQ};
|
||||||
@@ -143,7 +150,7 @@ public:
|
|||||||
((_hashes[I] = utils::FNV1aHash(std::get<I>(_keyValue).key)), ...);
|
((_hashes[I] = utils::FNV1aHash(std::get<I>(_keyValue).key)), ...);
|
||||||
}(std::make_index_sequence<NUMBER_OF_RECORDS>());
|
}(std::make_index_sequence<NUMBER_OF_RECORDS>());
|
||||||
|
|
||||||
_loadedKey.insert_range(_hashes);
|
_changedKey.insert_range(_hashes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -238,7 +245,7 @@ public:
|
|||||||
|
|
||||||
_headComment.clear();
|
_headComment.clear();
|
||||||
_inlineComment.clear();
|
_inlineComment.clear();
|
||||||
_loadedKey.clear();
|
_changedKey.clear();
|
||||||
|
|
||||||
auto recs = std::views::split(buffer, std::move(rec_delim));
|
auto recs = std::views::split(buffer, std::move(rec_delim));
|
||||||
|
|
||||||
@@ -272,7 +279,7 @@ public:
|
|||||||
return MccKeyValueHolderErrorCode::ERROR_DESERIAL;
|
return MccKeyValueHolderErrorCode::ERROR_DESERIAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
_loadedKey.insert(key_hash);
|
_changedKey.insert(key_hash);
|
||||||
|
|
||||||
return MccKeyValueHolderErrorCode::ERROR_OK;
|
return MccKeyValueHolderErrorCode::ERROR_OK;
|
||||||
});
|
});
|
||||||
@@ -300,7 +307,8 @@ public:
|
|||||||
return ec;
|
return ec;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <traits::mcc_output_char_range R,
|
template <OutputPolicy OPOLICY = MccKeyValueHolder::OPOLICY_CHANGED_ONLY,
|
||||||
|
traits::mcc_output_char_range R,
|
||||||
traits::mcc_input_char_range RecDelimT = std::string_view,
|
traits::mcc_input_char_range RecDelimT = std::string_view,
|
||||||
mcc_serialization_params_c SerParamsT = mcc_serialization_params_t>
|
mcc_serialization_params_c SerParamsT = mcc_serialization_params_t>
|
||||||
std::error_code toCharRange(R& output_buffer,
|
std::error_code toCharRange(R& output_buffer,
|
||||||
@@ -311,41 +319,46 @@ public:
|
|||||||
|
|
||||||
auto write_rec = [&output_buffer, &rec_delim, &ec, &ser_params, this]<size_t I = 0>(this auto& self) {
|
auto write_rec = [&output_buffer, &rec_delim, &ec, &ser_params, this]<size_t I = 0>(this auto& self) {
|
||||||
if constexpr (I < NUMBER_OF_RECORDS) {
|
if constexpr (I < NUMBER_OF_RECORDS) {
|
||||||
if (_loadedKey.count(_hashes[I])) {
|
if constexpr (OPOLICY == MccKeyValueHolder::OPOLICY_CHANGED_ONLY) {
|
||||||
auto key = std::get<I>(_keyValue).key;
|
if (_changedKey.count(_hashes[I]) == 0) {
|
||||||
auto val = std::get<I>(_keyValue).value;
|
self.template operator()<I + 1>();
|
||||||
using val_t = std::remove_cvref_t<decltype(val)>;
|
|
||||||
|
|
||||||
std::string buff;
|
|
||||||
auto err = MccSerializer<val_t>{}(buff, val, ser_params);
|
|
||||||
if (err) {
|
|
||||||
ec = MccKeyValueHolderErrorCode::ERROR_SERIAL;
|
|
||||||
return;
|
return;
|
||||||
} else {
|
|
||||||
size_t hash = _hashes[I];
|
|
||||||
// write head comment
|
|
||||||
if (_headComment[hash].size()) {
|
|
||||||
for (auto const& comm : _headComment[hash]) {
|
|
||||||
if (comm.has_value()) {
|
|
||||||
std::format_to(std::back_inserter(output_buffer), "{}{}", COMM_SEQ, comm.value());
|
|
||||||
}
|
|
||||||
std::ranges::copy(rec_delim, std::back_inserter(output_buffer));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// key and value
|
|
||||||
std::format_to(std::back_inserter(output_buffer), "{}{}{}", key, KEY_VALUE_DELIM, buff);
|
|
||||||
|
|
||||||
// inline comment
|
|
||||||
if (_inlineComment[hash].size()) {
|
|
||||||
std::format_to(std::back_inserter(output_buffer), " {}{}", COMMENT_SEQ,
|
|
||||||
_inlineComment[hash]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// record delimiter
|
|
||||||
std::ranges::copy(rec_delim, std::back_inserter(output_buffer));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// if (_changedKey.count(_hashes[I])) {
|
||||||
|
auto key = std::get<I>(_keyValue).key;
|
||||||
|
auto val = std::get<I>(_keyValue).value;
|
||||||
|
using val_t = std::remove_cvref_t<decltype(val)>;
|
||||||
|
|
||||||
|
std::string buff;
|
||||||
|
auto err = MccSerializer<val_t>{}(buff, val, ser_params);
|
||||||
|
if (err) {
|
||||||
|
ec = MccKeyValueHolderErrorCode::ERROR_SERIAL;
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
size_t hash = _hashes[I];
|
||||||
|
// write head comment
|
||||||
|
if (_headComment[hash].size()) {
|
||||||
|
for (auto const& comm : _headComment[hash]) {
|
||||||
|
if (comm.has_value()) {
|
||||||
|
std::format_to(std::back_inserter(output_buffer), "{}{}", COMM_SEQ, comm.value());
|
||||||
|
}
|
||||||
|
std::ranges::copy(rec_delim, std::back_inserter(output_buffer));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// key and value
|
||||||
|
std::format_to(std::back_inserter(output_buffer), "{}{}{}", key, KEY_VALUE_DELIM, buff);
|
||||||
|
|
||||||
|
// inline comment
|
||||||
|
if (_inlineComment[hash].size()) {
|
||||||
|
std::format_to(std::back_inserter(output_buffer), " {}{}", COMMENT_SEQ, _inlineComment[hash]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// record delimiter
|
||||||
|
std::ranges::copy(rec_delim, std::back_inserter(output_buffer));
|
||||||
|
}
|
||||||
|
// }
|
||||||
|
|
||||||
self.template operator()<I + 1>();
|
self.template operator()<I + 1>();
|
||||||
}
|
}
|
||||||
@@ -367,7 +380,7 @@ protected:
|
|||||||
std::unordered_map<size_t, std::vector<std::optional<std::string>>>
|
std::unordered_map<size_t, std::vector<std::optional<std::string>>>
|
||||||
_headComment{}; // comment string/strings before key
|
_headComment{}; // comment string/strings before key
|
||||||
std::unordered_map<size_t, std::string> _inlineComment{}; // inline (after key=value pair) comment
|
std::unordered_map<size_t, std::string> _inlineComment{}; // inline (after key=value pair) comment
|
||||||
std::unordered_set<size_t> _loadedKey{}; // loaded keys (see fromCharRange)
|
std::unordered_set<size_t> _changedKey{}; // loaded keys (see fromCharRange)
|
||||||
|
|
||||||
//
|
//
|
||||||
// NOTE: deduced this is needed here to use "forKey" method in getter and setter (const and non-const contexts)!!!
|
// NOTE: deduced this is needed here to use "forKey" method in getter and setter (const and non-const contexts)!!!
|
||||||
@@ -395,6 +408,56 @@ protected:
|
|||||||
|
|
||||||
return MccKeyValueHolderErrorCode::ERROR_INVALID_KEY;
|
return MccKeyValueHolderErrorCode::ERROR_INVALID_KEY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <size_t I = 0,
|
||||||
|
OutputPolicy OPOLICY = MccKeyValueHolder::OPOLICY_CHANGED_ONLY,
|
||||||
|
traits::mcc_output_char_range R,
|
||||||
|
traits::mcc_input_char_range RecDelimT,
|
||||||
|
mcc_serialization_params_c SerParamsT>
|
||||||
|
std::error_code writeRecord(R& output_buffer, RecDelimT rec_delim, SerParamsT const& ser_params)
|
||||||
|
{
|
||||||
|
if constexpr (I < NUMBER_OF_RECORDS) {
|
||||||
|
if constexpr (OPOLICY == MccKeyValueHolder::OPOLICY_CHANGED_ONLY) {
|
||||||
|
if (_changedKey.count(_hashes[I]) == 0) {
|
||||||
|
return MccKeyValueHolderErrorCode::ERROR_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto key = std::get<I>(_keyValue).key;
|
||||||
|
auto val = std::get<I>(_keyValue).value;
|
||||||
|
using val_t = std::remove_cvref_t<decltype(val)>;
|
||||||
|
|
||||||
|
std::string buff;
|
||||||
|
auto err = MccSerializer<val_t>{}(buff, val, ser_params);
|
||||||
|
if (err) {
|
||||||
|
return MccKeyValueHolderErrorCode::ERROR_SERIAL;
|
||||||
|
} else {
|
||||||
|
size_t hash = _hashes[I];
|
||||||
|
// write head comment
|
||||||
|
if (_headComment[hash].size()) {
|
||||||
|
for (auto const& comm : _headComment[hash]) {
|
||||||
|
if (comm.has_value()) {
|
||||||
|
std::format_to(std::back_inserter(output_buffer), "{}{}", COMM_SEQ, comm.value());
|
||||||
|
}
|
||||||
|
std::ranges::copy(rec_delim, std::back_inserter(output_buffer));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// key and value
|
||||||
|
std::format_to(std::back_inserter(output_buffer), "{}{}{}", key, KEY_VALUE_DELIM, buff);
|
||||||
|
|
||||||
|
// inline comment
|
||||||
|
if (_inlineComment[hash].size()) {
|
||||||
|
std::format_to(std::back_inserter(output_buffer), " {}{}", COMMENT_SEQ, _inlineComment[hash]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// record delimiter
|
||||||
|
std::ranges::copy(rec_delim, std::back_inserter(output_buffer));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return MccKeyValueHolderErrorCode::ERROR_OK;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <mcc_variant_valid_type_c T>
|
template <mcc_variant_valid_type_c T>
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ cc= 2026-05-15T05:53:20.921723918 # date UTC
|
|||||||
)--";
|
)--";
|
||||||
|
|
||||||
static std::string STR1 = R"--(
|
static std::string STR1 = R"--(
|
||||||
|
|
||||||
aaa = dewl_ewkj23+23998
|
aaa = dewl_ewkj23+23998
|
||||||
|
|
||||||
#
|
#
|
||||||
@@ -60,13 +59,14 @@ int main()
|
|||||||
|
|
||||||
std::string buff;
|
std::string buff;
|
||||||
|
|
||||||
err = kv.toCharRange(buff);
|
err = kv.toCharRange<decltype(kv)::OPOLICY_FULL>(buff);
|
||||||
|
// err = kv.toCharRange(buff);
|
||||||
if (err) {
|
if (err) {
|
||||||
std::println("ERR = {}", err);
|
std::println("ERR = {}", err);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::println("--(\n{}\n)--'", buff);
|
std::println("--(\n{}\n)--", buff);
|
||||||
|
|
||||||
std::print("KEYS: ");
|
std::print("KEYS: ");
|
||||||
for (auto const& k : kv.keys()) {
|
for (auto const& k : kv.keys()) {
|
||||||
|
|||||||
Reference in New Issue
Block a user