diff --git a/indexer/complex/serdes.hpp b/indexer/complex/serdes.hpp index de685e3e9a..9953845373 100644 --- a/indexer/complex/serdes.hpp +++ b/indexer/complex/serdes.hpp @@ -13,8 +13,6 @@ #include #include -#include - namespace complex { class ComplexSerdes @@ -43,7 +41,7 @@ public: { ReaderSource src(reader); auto const version = DeserializeVersion(src); - return version ? Deserialize(src, *version, forest) : false; + return Deserialize(src, version, forest); } template @@ -94,14 +92,8 @@ private: template static void Serialize(Sink & sink, tree_node::types::Ptr const & tree) { - uint32_t const base = tree_node::Min(tree, [](auto const & data) { - auto const it = std::min_element(std::cbegin(data), std::cend(data)); - CHECK(it != std::cend(data), ()); - return *it; - }); - WriteVarUint(sink, base); tree_node::PreOrderVisit(tree, [&](auto const & node) { - coding_utils::DeltaEncode(sink, node->GetData(), base); + coding_utils::WriteCollectionPrimitive(sink, node->GetData()); auto const size = base::checked_cast(node->GetChildren().size()); WriteVarUint(sink, size); }); @@ -110,14 +102,10 @@ private: template static bool Deserialize(Src & src, tree_node::types::Ptr & tree) { - auto const base = ReadVarUint(src); std::function &)> deserializeTree; deserializeTree = [&](auto & tree) { - if (src.Size() == 0) - return true; - Ids ids; - coding_utils::DeltaDecode(src, std::back_inserter(ids), base); + coding_utils::ReadCollectionPrimitive(src, std::back_inserter(ids)); tree = tree_node::MakeTreeNode(std::move(ids)); auto const size = ReadVarUint(src); tree_node::types::Ptrs children(size); @@ -142,14 +130,9 @@ private: } template - static boost::optional DeserializeVersion(Src & src) + static Version DeserializeVersion(Src & src) { - if (src.Size() < sizeof(kLatestVersion)) - { - LOG(LERROR, ("Unable to deserialize complexes: wrong header version.")); - return {}; - } - return static_cast(ReadPrimitiveFromSource::type>(src)); + return static_cast(ReadPrimitiveFromSource>(src)); } }; } // namespace complex diff --git a/indexer/complex/serdes_utils.hpp b/indexer/complex/serdes_utils.hpp index fb083a7f2c..f654c97cfd 100644 --- a/indexer/complex/serdes_utils.hpp +++ b/indexer/complex/serdes_utils.hpp @@ -8,102 +8,8 @@ namespace coding_utils { -namespace detail -{ -// WriteVarIntegral is abstraction over WriteVarUint and WriteVarInt functions. -// WriteVarIntegral may be used in generic code. -template < - typename T, typename Sink, - typename std::enable_if_t::value && std::is_unsigned::value, int> = 0> -void WriteVarIntegral(Sink & dst, T value) -{ - WriteVarUint(dst, value); -} -template < - typename T, typename Sink, - typename std::enable_if_t::value && std::is_signed::value, int> = 0> -void WriteVarIntegral(Sink & dst, T value) -{ - WriteVarInt(dst, value); -} - -// ReadVarIntegral is abstraction over ReadVarUint and ReadVarInt functions. -// ReadVarIntegral may be used in generic code. -template < - typename T, typename Source, - typename std::enable_if_t::value && std::is_unsigned::value, int> = 0> -T ReadVarIntegral(Source & src) -{ - return ReadVarUint(src); -} -template < - typename T, typename Source, - typename std::enable_if_t::value && std::is_signed::value, int> = 0> -T ReadVarIntegral(Source & src) -{ - return ReadVarInt(src); -} -} // namespace detail - // Type of collection size. It used for reading and writing collections. -using CollectionSizeType = uint32_t; - -// DeltaEncodeAs encodes data in the form of differences between sequential data. -// It required sorted |container|. |fn| may used used to access structure fields or data modification. -template -void DeltaEncodeAs(Sink & sink, Cont const & container, Fn && fn) -{ - ASSERT((std::is_sorted(std::cbegin(container), std::cend(container), - [&](auto const & lhs, auto const & rhs) { return fn(lhs) < fn(rhs); })), - ()); - - auto const contSize = base::checked_cast(container.size()); - WriteVarUint(sink, contSize); - if (contSize == 0) - return; - - auto first = std::begin(container); - auto const last = std::end(container); - auto acc = fn(*first); - detail::WriteVarIntegral(sink, acc); - while (++first != last) - { - auto const val = fn(*first); - auto const delta = base::checked_cast(val - acc); - WriteVarUint(sink, delta); - acc = val; - } -} - -// DeltaDecodeAs decodes data from the form of differences between sequential data. -// |fn| may used used to initialize an object or data modification. -template -void DeltaDecodeAs(Source & src, OutIt it, Fn && fn) -{ - auto contSize = ReadVarUint(src); - if (contSize == 0) - return; - - auto sum = detail::ReadVarIntegral(src); - *it++ = fn(sum); - while (--contSize) - { - sum += base::checked_cast(ReadVarUint(src)); - *it++ = fn(sum); - } -} - -template -void DeltaEncode(Sink & sink, Cont const & container, ValueType base = {}) -{ - DeltaEncodeAs(sink, container, [&](ValueType val) { return val - base; }); -} - -template -void DeltaDecode(Source & src, OutIt it, ValueType base = {}) -{ - DeltaDecodeAs(src, it, [&](ValueType val) { return val + base; }); -} +using CollectionSizeType = uint64_t; // WriteCollectionPrimitive writes collection. It used WriteToSink function. template diff --git a/indexer/complex/tree_node.hpp b/indexer/complex/tree_node.hpp index c1c6fd616c..4bd7820c91 100644 --- a/indexer/complex/tree_node.hpp +++ b/indexer/complex/tree_node.hpp @@ -198,16 +198,6 @@ size_t CountIf(types::Ptr const & node, Fn && fn) return count; } -template -decltype(auto) Min(types::Ptr const & node, Fn && fn) -{ - auto m = std::numeric_limitsGetData()))>::max(); - PreOrderVisit(node, [&](auto const & node) { - m = std::min(fn(node->GetData()), m); - }); - return m; -} - template void Print(types::Ptr const & node, std::ostream & stream, std::string prefix = "", bool isTail = true) diff --git a/indexer/indexer_tests/complex_serdes_utils_tests.cpp b/indexer/indexer_tests/complex_serdes_utils_tests.cpp index e0fa37e73d..2d5401e9a8 100644 --- a/indexer/indexer_tests/complex_serdes_utils_tests.cpp +++ b/indexer/indexer_tests/complex_serdes_utils_tests.cpp @@ -15,21 +15,6 @@ namespace { using ByteVector = std::vector; -template -void DeltaEncodeDecodelTest(T const & cont, ValueType base = {}) -{ - ByteVector buffer; - MemWriter writer(buffer); - WriterSink sink(writer); - coding_utils::DeltaEncode(sink, cont, base); - - MemReader reader(buffer.data(), buffer.size()); - ReaderSource src(reader); - T res; - coding_utils::DeltaDecode(src, std::inserter(res, std::end(res)), base); - TEST_EQUAL(cont, res, ()); -} - template void CollectionPrimitiveTest(T const & cont) { @@ -45,47 +30,6 @@ void CollectionPrimitiveTest(T const & cont) TEST_EQUAL(cont, res, ()); } -UNIT_TEST(Utils_DeltaEncodeDecode) -{ - { - std::vector cont; - DeltaEncodeDecodelTest(cont); - } - { - std::list cont{1, 2, 3, 4}; - cont.sort(); - DeltaEncodeDecodelTest(cont); - } - { - std::list cont{6, 7, 30, 40}; - cont.sort(); - DeltaEncodeDecodelTest(cont, 6); - } - { - std::list cont{-1, -2, -3, -4}; - cont.sort(); - DeltaEncodeDecodelTest(cont); - } - { - std::vector cont{1, 2, 3, 4, 32, 124}; - std::sort(std::begin(cont), std::end(cont)); - DeltaEncodeDecodelTest(cont, 1); - } - { - std::vector cont{-1, -2, -3, -4, 23, 67}; - std::sort(std::begin(cont), std::end(cont)); - DeltaEncodeDecodelTest(cont); - } - { - std::set cont{1, 2, 3, 4, 999, 100124, 243}; - DeltaEncodeDecodelTest(cont); - } - { - std::set cont{-1, -2, -3, -4}; - DeltaEncodeDecodelTest(cont); - } -} - UNIT_TEST(Utils_CollectionPrimitive) { {