From bce6f57f1d76844093a0d94b3f0062e3d1c4579b Mon Sep 17 00:00:00 2001 From: Alex Shabalin Date: Thu, 27 Jun 2024 15:35:53 +0200 Subject: [PATCH] Save B and BL in vector pools --- immer/extra/persist/rbts/input.hpp | 31 +++++++++++++++++++ immer/extra/persist/rbts/pool.hpp | 24 +++++++++++--- test/extra/persist/test_special_pool.cpp | 20 ++++++++++++ test/extra/persist/test_special_pool_auto.cpp | 4 +++ test/extra/persist/test_vectors.cpp | 30 ++++++++++++++++++ 5 files changed, 104 insertions(+), 5 deletions(-) diff --git a/immer/extra/persist/rbts/input.hpp b/immer/extra/persist/rbts/input.hpp index 5f02e239..ec79da39 100644 --- a/immer/extra/persist/rbts/input.hpp +++ b/immer/extra/persist/rbts/input.hpp @@ -77,6 +77,24 @@ class same_depth_children_exception : public pool_exception } }; +class incompatible_bits_parameters : public pool_exception +{ +public: + incompatible_bits_parameters(immer::detail::rbts::bits_t loader_bits, + immer::detail::rbts::bits_t loader_bits_leaf, + immer::detail::rbts::bits_t pool_bits, + immer::detail::rbts::bits_t pool_bits_leaf) + : pool_exception{ + fmt::format("B and BL parameters must be the same. Loader " + "expects {} and {} but the pool has {} and {}", + loader_bits, + loader_bits_leaf, + pool_bits, + pool_bits_leaf)} + { + } +}; + template void save(Archive& ar) const { - ar(CEREAL_NVP(leaves), CEREAL_NVP(inners), CEREAL_NVP(vectors)); + ar(CEREAL_NVP(B), + CEREAL_NVP(BL), + CEREAL_NVP(leaves), + CEREAL_NVP(inners), + CEREAL_NVP(vectors)); } }; @@ -98,6 +102,8 @@ make_output_pool_for(const immer::flex_vector&) template struct input_pool { + immer::detail::rbts::bits_t bits{}; + immer::detail::rbts::bits_t bits_leaf{}; immer::map> leaves; immer::map inners; immer::vector vectors; @@ -108,7 +114,13 @@ struct input_pool template void load(Archive& ar) { - ar(CEREAL_NVP(leaves), CEREAL_NVP(inners), CEREAL_NVP(vectors)); + auto& B = bits; + auto& BL = bits_leaf; + ar(CEREAL_NVP(B), + CEREAL_NVP(BL), + CEREAL_NVP(leaves), + CEREAL_NVP(inners), + CEREAL_NVP(vectors)); } void merge_previous(const input_pool& other) {} @@ -128,9 +140,11 @@ input_pool to_input_pool(output_pool ar) } return { - .leaves = std::move(leaves), - .inners = std::move(ar.inners), - .vectors = std::move(ar.vectors), + .bits = B, + .bits_leaf = BL, + .leaves = std::move(leaves), + .inners = std::move(ar.inners), + .vectors = std::move(ar.vectors), }; } diff --git a/test/extra/persist/test_special_pool.cpp b/test/extra/persist/test_special_pool.cpp index 465ae4c8..2f0f712f 100644 --- a/test/extra/persist/test_special_pool.cpp +++ b/test/extra/persist/test_special_pool.cpp @@ -448,16 +448,22 @@ TEST_CASE("Special pool loads empty test_data") }, "pools": { "ints": { + "B": 5, + "BL": 1, "leaves": [{"key": 1, "value": []}], "inners": [{"key": 0, "value": {"children": [], "relaxed": false}}], "vectors": [{"root": 0, "tail": 1}] }, "strings": { + "B": 5, + "BL": 1, "leaves": [{"key": 1, "value": []}], "inners": [{"key": 0, "value": {"children": [], "relaxed": false}}], "vectors": [{"root": 0, "tail": 1}] }, "flex_ints": { + "B": 5, + "BL": 1, "leaves": [{"key": 1, "value": []}], "inners": [{"key": 0, "value": {"children": [], "relaxed": false}}], "vectors": [{"root": 0, "tail": 1}] @@ -466,11 +472,15 @@ TEST_CASE("Special pool loads empty test_data") {"values": [], "children": [], "nodemap": 0, "datamap": 0, "collisions": false} ], "metas": { + "B": 5, + "BL": 1, "leaves": [{"key": 1, "value": []}], "inners": [{"key": 0, "value": {"children": [], "relaxed": false}}], "vectors": [{"root": 0, "tail": 1}] }, "meta_metas": { + "B": 5, + "BL": 1, "leaves": [{"key": 1, "value": []}], "inners": [{"key": 0, "value": {"children": [], "relaxed": false}}], "vectors": [{"root": 0, "tail": 1}] @@ -514,16 +524,22 @@ TEST_CASE("Special pool throws cereal::Exception") }, "pools": { "ints": { + "B": 5, + "BL": 1, "leaves": [{"key": 1, "value": []}], "inners": [{"key": 0, "value": {"children": [], "relaxed": false}}], "vectors": [{"root": 0, "tail": 1}] }, "strings": { + "B": 5, + "BL": 1, "leaves": [{"key": 1, "value": []}], "inners": [{"key": 0, "value": {"children": [], "relaxed": false}}], "vectors": [{"root": 0, "tail": 1}] }, "flex_ints": { + "B": 5, + "BL": 1, "leaves": [{"key": 1, "value": []}], "inners": [{"key": 0, "value": {"children": [], "relaxed": false}}], "vectors": [{"root": 0, "tail": 1}] @@ -532,11 +548,15 @@ TEST_CASE("Special pool throws cereal::Exception") {"values": [], "children": [], "nodemap": 0, "datamap": 0, "collisions": false} ], "metas": { + "B": 5, + "BL": 1, "leaves": [{"key": 1, "value": []}], "inners": [{"key": 0, "value": {"children": [], "relaxed": false}}], "vectors": [{"root": 0, "tail": 1}] }, "meta_metas": { + "B": 5, + "BL": 1, "leaves": [{"key": 1, "value": []}], "inners": [{"key": 0, "value": {"children": [], "relaxed": false}}], "vectors": [{"root": 0, "tail": 1}] diff --git a/test/extra/persist/test_special_pool_auto.cpp b/test/extra/persist/test_special_pool_auto.cpp index 832ff590..bac41ebb 100644 --- a/test/extra/persist/test_special_pool_auto.cpp +++ b/test/extra/persist/test_special_pool_auto.cpp @@ -495,6 +495,8 @@ TEST_CASE("Test loading broken table") {"ones": 1, "key": {"str": "123"}} ], "ones": { + "B": 5, + "BL": 1, "leaves": [ {"key": 1, "value": []}, {"key": 2, "value": [{"twos": 1, "twos_table": 1}]} @@ -503,6 +505,8 @@ TEST_CASE("Test loading broken table") "vectors": [{"root": 0, "tail": 1}, {"root": 0, "tail": 2}] }, "twos": { + "B": 5, + "BL": 1, "leaves": [ {"key": 1, "value": [{"two": 0}, {"two": 1}]}, {"key": 2, "value": []} diff --git a/test/extra/persist/test_vectors.cpp b/test/extra/persist/test_vectors.cpp index ebe27050..f84e4b20 100644 --- a/test/extra/persist/test_vectors.cpp +++ b/test/extra/persist/test_vectors.cpp @@ -482,6 +482,8 @@ TEST_CASE("A loop with 2 nodes") { const auto json = std::string{R"({ "value0": { + "B": 5, + "BL": 1, "leaves": [ { "key": 32, @@ -858,6 +860,8 @@ TEST_CASE("Test vector with very big objects") TEST_CASE("Test modifying vector nodes") { json_t data; + data["value0"]["B"] = 5; + data["value0"]["BL"] = 1; data["value0"]["leaves"] = { { {"key", 1}, @@ -908,6 +912,22 @@ TEST_CASE("Test modifying vector nodes") immer::persist::pool_exception); } + SECTION("Load different B") + { + auto b = GENERATE(1, 3, 6, 7); + data["value0"]["B"] = b; + REQUIRE_THROWS_AS(load_vec(data.dump(), 0), + immer::persist::rbts::incompatible_bits_parameters); + } + + SECTION("Load different BL") + { + auto bl = GENERATE(2, 3, 5, 6); + data["value0"]["BL"] = bl; + REQUIRE_THROWS_AS(load_vec(data.dump(), 0), + immer::persist::rbts::incompatible_bits_parameters); + } + SECTION("Invalid root id") { data["value0"]["vectors"][0]["root"] = 1; @@ -998,6 +1018,8 @@ TEST_CASE("Test modifying vector nodes") TEST_CASE("Test modifying flex vector nodes") { json_t data; + data["value0"]["B"] = 5; + data["value0"]["BL"] = 1; data["value0"]["leaves"] = { { {"key", 1}, @@ -1205,6 +1227,8 @@ TEST_CASE("Print shift calculation", "[.print_shift]") TEST_CASE("Test more inner nodes") { json_t data; + data["value0"]["B"] = 5; + data["value0"]["BL"] = 1; data["value0"]["leaves"] = { {{"key", 32}, {"value", {58, 59}}}, {{"key", 34}, {"value", {62, 63}}}, {{"key", 3}, {"value", {0, 1}}}, {{"key", 5}, {"value", {4, 5}}}, @@ -1350,6 +1374,8 @@ TEST_CASE("Exception while loading children") { // spdlog::set_level(spdlog::level::trace); json_t data; + data["value0"]["B"] = 5; + data["value0"]["BL"] = 1; data["value0"]["leaves"] = { { {"key", 1}, @@ -1411,6 +1437,8 @@ TEST_CASE("Exception while loading children") TEST_CASE("Test flex vector with a weird shape relaxed") { json_t data; + data["value0"]["B"] = 5; + data["value0"]["BL"] = 1; data["value0"]["leaves"] = { {{"key", 1}, {"value", {66}}}, {{"key", 36}, {"value", {64, 65}}}, @@ -1449,6 +1477,8 @@ TEST_CASE("Test flex vector with a weird shape relaxed") TEST_CASE("Test flex vector with a weird shape strict", "[.broken]") { json_t data; + data["value0"]["B"] = 5; + data["value0"]["BL"] = 1; data["value0"]["leaves"] = { {{"key", 1}, {"value", {66}}}, {{"key", 36}, {"value", {64, 65}}},