mirror of
https://codeberg.org/comaps/comaps
synced 2025-12-24 06:53:46 +00:00
committed by
Konstantin Pastbin
parent
c9cbb64f12
commit
76ffc99abd
132
libs/indexer/complex/serdes.hpp
Normal file
132
libs/indexer/complex/serdes.hpp
Normal file
@@ -0,0 +1,132 @@
|
||||
#pragma once
|
||||
|
||||
#include "indexer/complex/serdes_utils.hpp"
|
||||
#include "indexer/complex/tree_node.hpp"
|
||||
|
||||
#include "coding/reader.hpp"
|
||||
#include "coding/varint.hpp"
|
||||
#include "coding/writer.hpp"
|
||||
|
||||
#include "base/logging.hpp"
|
||||
#include "base/stl_helpers.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace complex
|
||||
{
|
||||
class ComplexSerdes
|
||||
{
|
||||
public:
|
||||
using Ids = std::vector<uint32_t>;
|
||||
|
||||
enum class Version : uint8_t
|
||||
{
|
||||
// There aren't optimized serialization and deserialization. It's experimental verison.
|
||||
// todo(m.andrianov): Explore better ways for serialization and deserialization.
|
||||
V0,
|
||||
};
|
||||
|
||||
static Version const kLatestVersion;
|
||||
|
||||
template <typename Sink>
|
||||
static void Serialize(Sink & sink, tree_node::Forest<Ids> const & forest)
|
||||
{
|
||||
SerializeLatestVersion(sink);
|
||||
Serialize(sink, kLatestVersion, forest);
|
||||
}
|
||||
|
||||
template <typename Reader>
|
||||
static void Deserialize(Reader & reader, tree_node::Forest<Ids> & forest)
|
||||
{
|
||||
ReaderSource<decltype(reader)> src(reader);
|
||||
auto const version = DeserializeVersion(src);
|
||||
Deserialize(src, version, forest);
|
||||
}
|
||||
|
||||
template <typename Sink>
|
||||
static void Serialize(Sink & sink, Version version, tree_node::Forest<Ids> const & forest)
|
||||
{
|
||||
switch (version)
|
||||
{
|
||||
case Version::V0: V0::Serialize(sink, forest); break;
|
||||
default: UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Src>
|
||||
static void Deserialize(Src & src, Version version, tree_node::Forest<Ids> & forest)
|
||||
{
|
||||
switch (version)
|
||||
{
|
||||
case Version::V0: V0::Deserialize(src, forest); break;
|
||||
default: UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
class V0
|
||||
{
|
||||
public:
|
||||
template <typename Sink>
|
||||
static void Serialize(Sink & sink, tree_node::Forest<Ids> const & forest)
|
||||
{
|
||||
forest.ForEachTree([&](auto const & tree) { Serialize(sink, tree); });
|
||||
}
|
||||
|
||||
template <typename Src>
|
||||
static void Deserialize(Src & src, tree_node::Forest<Ids> & forest)
|
||||
{
|
||||
while (src.Size() > 0)
|
||||
{
|
||||
tree_node::types::Ptr<Ids> tree;
|
||||
Deserialize(src, tree);
|
||||
forest.Append(tree);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename Sink>
|
||||
static void Serialize(Sink & sink, tree_node::types::Ptr<Ids> const & tree)
|
||||
{
|
||||
tree_node::PreOrderVisit(tree, [&](auto const & node) {
|
||||
coding_utils::WriteCollectionPrimitive(sink, node->GetData());
|
||||
auto const size = base::checked_cast<coding_utils::CollectionSizeType>(node->GetChildren().size());
|
||||
WriteVarUint(sink, size);
|
||||
});
|
||||
}
|
||||
|
||||
template <typename Src>
|
||||
static void Deserialize(Src & src, tree_node::types::Ptr<Ids> & tree)
|
||||
{
|
||||
std::function<void(tree_node::types::Ptr<Ids> &)> deserializeTree;
|
||||
deserializeTree = [&](auto & tree) {
|
||||
Ids ids;
|
||||
coding_utils::ReadCollectionPrimitive(src, std::back_inserter(ids));
|
||||
tree = tree_node::MakeTreeNode(std::move(ids));
|
||||
auto const size = ReadVarUint<coding_utils::CollectionSizeType>(src);
|
||||
tree_node::types::Ptrs<Ids> children(size);
|
||||
for (auto & n : children)
|
||||
{
|
||||
deserializeTree(n);
|
||||
n->SetParent(tree);
|
||||
}
|
||||
tree->SetChildren(std::move(children));
|
||||
};
|
||||
deserializeTree(tree);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Sink>
|
||||
static void SerializeLatestVersion(Sink & sink)
|
||||
{
|
||||
WriteToSink(sink, base::Underlying(kLatestVersion));
|
||||
}
|
||||
|
||||
template <typename Src>
|
||||
static Version DeserializeVersion(Src & src)
|
||||
{
|
||||
return static_cast<Version>(ReadPrimitiveFromSource<std::underlying_type_t<Version>>(src));
|
||||
}
|
||||
};
|
||||
} // namespace complex
|
||||
Reference in New Issue
Block a user