Serialize Ast via SLK
Reviewers: mtomic, llugovic Reviewed By: mtomic Subscribers: pullbot Differential Revision: https://phabricator.memgraph.io/D1764
This commit is contained in:
parent
00506b9962
commit
8ed1e3509d
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,8 @@
|
|||||||
#>cpp
|
#>cpp
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
#include "query/frontend/ast/ast.hpp"
|
#include "query/frontend/ast/ast.hpp"
|
||||||
#include "query/frontend/ast/ast_serialization.capnp.h"
|
#include "query/frontend/ast/ast_serialization.capnp.h"
|
||||||
#include "query/serialization.hpp"
|
#include "query/serialization.hpp"
|
||||||
@ -12,12 +14,72 @@ cpp<#
|
|||||||
(lcp:namespace query)
|
(lcp:namespace query)
|
||||||
|
|
||||||
#>cpp
|
#>cpp
|
||||||
|
/// Primary function for saving Ast nodes via SLK.
|
||||||
|
void SaveAstPointer(const Tree *ast, slk::Builder *builder,
|
||||||
|
std::vector<int32_t> *saved_uids);
|
||||||
|
|
||||||
Tree *Load(AstStorage *ast, const capnp::Tree::Reader &tree,
|
Tree *Load(AstStorage *ast, const capnp::Tree::Reader &tree,
|
||||||
std::vector<int> *loaded_uids);
|
std::vector<int32_t> *loaded_uids);
|
||||||
|
|
||||||
|
Tree *Load(AstStorage *ast, slk::Reader *reader,
|
||||||
|
std::vector<int32_t> *loaded_uids);
|
||||||
|
|
||||||
|
/// Primary function for loading Ast nodes via SLK.
|
||||||
|
template <class TAst>
|
||||||
|
TAst *LoadAstPointer(AstStorage *ast, slk::Reader *reader,
|
||||||
|
std::vector<int32_t> *loaded_uids) {
|
||||||
|
static_assert(std::is_base_of<query::Tree, TAst>::value);
|
||||||
|
bool has_ptr = false;
|
||||||
|
slk::Load(&has_ptr, reader);
|
||||||
|
if (!has_ptr) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
auto *ret = dynamic_cast<TAst *>(Load(ast, reader, loaded_uids));
|
||||||
|
if (!ret) {
|
||||||
|
throw slk::SlkDecodeException("Loading unknown Ast node type");
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
cpp<#
|
cpp<#
|
||||||
|
|
||||||
(lcp:in-impl
|
(lcp:in-impl
|
||||||
#>cpp
|
#>cpp
|
||||||
|
void SaveAstPointer(const Tree *ast, slk::Builder *builder,
|
||||||
|
std::vector<int32_t> *saved_uids) {
|
||||||
|
slk::Save(static_cast<bool>(ast), builder);
|
||||||
|
if (!ast) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
slk::Save(ast->uid_, builder);
|
||||||
|
if (utils::Contains(*saved_uids, ast->uid_)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
slk::Save(*ast, builder, saved_uids);
|
||||||
|
CHECK(!utils::Contains(*saved_uids, ast->uid_)) << "Serializing cyclic AST";
|
||||||
|
saved_uids->push_back(ast->uid_);
|
||||||
|
}
|
||||||
|
|
||||||
|
Tree *Load(AstStorage *ast, slk::Reader *reader,
|
||||||
|
std::vector<int32_t> *loaded_uids) {
|
||||||
|
// Check if element already deserialized and if yes, return existing
|
||||||
|
// element from storage.
|
||||||
|
int32_t uid;
|
||||||
|
slk::Load(&uid, reader);
|
||||||
|
if (utils::Contains(*loaded_uids, uid)) {
|
||||||
|
auto found = std::find_if(ast->storage_.begin(), ast->storage_.end(),
|
||||||
|
[&](const auto &n) { return n->uid_ == uid; });
|
||||||
|
CHECK(found != ast->storage_.end());
|
||||||
|
return found->get();
|
||||||
|
}
|
||||||
|
std::unique_ptr<Tree> root;
|
||||||
|
slk::ConstructAndLoad(&root, reader, ast, loaded_uids);
|
||||||
|
root->uid_ = uid;
|
||||||
|
ast->storage_.emplace_back(std::move(root));
|
||||||
|
loaded_uids->push_back(uid);
|
||||||
|
ast->max_existing_uid_ = std::max(ast->max_existing_uid_, uid);
|
||||||
|
return ast->storage_.back().get();
|
||||||
|
}
|
||||||
|
|
||||||
Tree *Load(AstStorage *ast, const capnp::Tree::Reader &tree,
|
Tree *Load(AstStorage *ast, const capnp::Tree::Reader &tree,
|
||||||
std::vector<int> *loaded_uids) {
|
std::vector<int> *loaded_uids) {
|
||||||
// Check if element already deserialized and if yes, return existing
|
// Check if element already deserialized and if yes, return existing
|
||||||
|
@ -19,6 +19,9 @@ function(add_unit_test test_cpp)
|
|||||||
add_dependencies(memgraph__unit ${target_name})
|
add_dependencies(memgraph__unit ${target_name})
|
||||||
endfunction(add_unit_test)
|
endfunction(add_unit_test)
|
||||||
|
|
||||||
|
add_unit_test(ast_serialization.cpp)
|
||||||
|
target_link_libraries(${test_prefix}ast_serialization mg-distributed kvstore_dummy_lib)
|
||||||
|
|
||||||
add_unit_test(bolt_encoder.cpp)
|
add_unit_test(bolt_encoder.cpp)
|
||||||
target_link_libraries(${test_prefix}bolt_encoder mg-single-node kvstore_dummy_lib)
|
target_link_libraries(${test_prefix}bolt_encoder mg-single-node kvstore_dummy_lib)
|
||||||
|
|
||||||
|
2424
tests/unit/ast_serialization.cpp
Normal file
2424
tests/unit/ast_serialization.cpp
Normal file
File diff suppressed because it is too large
Load Diff
@ -11,17 +11,11 @@
|
|||||||
|
|
||||||
#include "query/context.hpp"
|
#include "query/context.hpp"
|
||||||
#include "query/frontend/ast/ast.hpp"
|
#include "query/frontend/ast/ast.hpp"
|
||||||
// TODO: FIXME
|
|
||||||
// #include "query/frontend/ast/ast_serialization.hpp"
|
|
||||||
#include "query/frontend/ast/cypher_main_visitor.hpp"
|
#include "query/frontend/ast/cypher_main_visitor.hpp"
|
||||||
#include "query/frontend/opencypher/parser.hpp"
|
#include "query/frontend/opencypher/parser.hpp"
|
||||||
#include "query/frontend/stripped.hpp"
|
#include "query/frontend/stripped.hpp"
|
||||||
#include "query/typed_value.hpp"
|
#include "query/typed_value.hpp"
|
||||||
|
|
||||||
// TODO: FIXME
|
|
||||||
// #include "capnp/message.h"
|
|
||||||
// #include "query/frontend/ast/ast_serialization.capnp.h"
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
using namespace query;
|
using namespace query;
|
||||||
@ -140,52 +134,13 @@ class CachedAstGenerator : public Base {
|
|||||||
Query *query_;
|
Query *query_;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* TODO: FIXME
|
|
||||||
class CapnpAstGenerator : public Base {
|
|
||||||
public:
|
|
||||||
CapnpAstGenerator(const std::string &query)
|
|
||||||
: Base(query),
|
|
||||||
storage_([&]() {
|
|
||||||
::frontend::opencypher::Parser parser(query);
|
|
||||||
CypherMainVisitor visitor(context_, db_accessor_.get());
|
|
||||||
visitor.visit(parser.tree());
|
|
||||||
|
|
||||||
::capnp::MallocMessageBuilder message;
|
|
||||||
{
|
|
||||||
query::capnp::Tree::Builder builder =
|
|
||||||
message.initRoot<query::capnp::Tree>();
|
|
||||||
std::vector<int> saved_uids;
|
|
||||||
Save(*visitor.query(), &builder, &saved_uids);
|
|
||||||
}
|
|
||||||
|
|
||||||
AstStorage new_ast;
|
|
||||||
{
|
|
||||||
const query::capnp::Tree::Reader reader =
|
|
||||||
message.getRoot<query::capnp::Tree>();
|
|
||||||
std::vector<int> loaded_uids;
|
|
||||||
Load(&new_ast, reader, &loaded_uids);
|
|
||||||
}
|
|
||||||
return new_ast;
|
|
||||||
}()),
|
|
||||||
query_(storage_.query()) {}
|
|
||||||
|
|
||||||
AstStorage storage_;
|
|
||||||
Query *query_;
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class CypherMainVisitorTest : public ::testing::Test {};
|
class CypherMainVisitorTest : public ::testing::Test {};
|
||||||
|
|
||||||
/* TODO: FIXME I have removed `CapnpAstGenerator` from the lower list
|
|
||||||
typedef ::testing::Types<AstGenerator, OriginalAfterCloningAstGenerator,
|
|
||||||
ClonedAstGenerator, CachedAstGenerator,
|
|
||||||
CapnpAstGenerator>
|
|
||||||
AstGeneratorTypes;
|
|
||||||
*/
|
|
||||||
typedef ::testing::Types<AstGenerator, OriginalAfterCloningAstGenerator,
|
typedef ::testing::Types<AstGenerator, OriginalAfterCloningAstGenerator,
|
||||||
ClonedAstGenerator, CachedAstGenerator>
|
ClonedAstGenerator, CachedAstGenerator>
|
||||||
AstGeneratorTypes;
|
AstGeneratorTypes;
|
||||||
|
|
||||||
TYPED_TEST_CASE(CypherMainVisitorTest, AstGeneratorTypes);
|
TYPED_TEST_CASE(CypherMainVisitorTest, AstGeneratorTypes);
|
||||||
|
|
||||||
TYPED_TEST(CypherMainVisitorTest, SyntaxException) {
|
TYPED_TEST(CypherMainVisitorTest, SyntaxException) {
|
||||||
|
Loading…
Reference in New Issue
Block a user