From 4b9970ccf8e83372d9ff48cdb8317dbcb5fb1bbd Mon Sep 17 00:00:00 2001 From: Marko Culinovic Date: Thu, 12 Apr 2018 14:00:51 +0200 Subject: [PATCH] Save and load pointers in ast capnp serialization Summary: Pointers in AstTreeStorage can point to same nodes. These nodes should be serialized(saved) only once when serializing Ast tree. Same goes for deserializing(loading). When deserializing nodes, one should not use storage Create method, because it will add node which isn't completely loaded to storage vector. Therefore, one should use new Deserialize method which doesn't add node to storage vector. Inserting node into storage vector is defered until all node data is loaded. Pass pointer to saved uids set, instead of storage Delete unused set Reviewers: teon.banek, msantl Reviewed By: teon.banek Subscribers: pullbot Differential Revision: https://phabricator.memgraph.io/D1344 --- src/query/frontend/ast/ast.cpp | 2029 ++++++++++++++++------------ src/query/frontend/ast/ast.hpp | 608 ++++++--- tests/unit/cypher_main_visitor.cpp | 8 +- 3 files changed, 1585 insertions(+), 1060 deletions(-) diff --git a/src/query/frontend/ast/ast.cpp b/src/query/frontend/ast/ast.cpp index 9230324ed..188c9c0c5 100644 --- a/src/query/frontend/ast/ast.cpp +++ b/src/query/frontend/ast/ast.cpp @@ -1,5 +1,6 @@ #include "query/frontend/ast/ast.hpp" +#include // Include archives before registering most derived types. #include "boost/archive/binary_iarchive.hpp" #include "boost/archive/binary_oarchive.hpp" @@ -44,85 +45,121 @@ ReturnBody CloneReturnBody(AstTreeStorage &storage, const ReturnBody &body) { return new_body; } -// capnproto serialization +// Capnproto serialization. -Tree *AstTreeStorage::Load(capnp::Tree::Reader &tree) { +Tree *AstTreeStorage::Load(const capnp::Tree::Reader &tree, + std::vector *loaded_uids) { + auto uid = tree.getUid(); + + // Check if element already deserialized and if yes, return existing + // element from storage. + if (utils::Contains(*loaded_uids, uid)) { + auto found = std::find_if(storage_.begin(), storage_.end(), + [&](const auto &n) { return n->uid() == uid; }); + DCHECK(found != storage_.end()); + return found->get(); + } + + Tree *ret = nullptr; switch (tree.which()) { case capnp::Tree::EXPRESSION: { auto expr_reader = tree.getExpression(); - auto *ret = Expression::Construct(expr_reader, *this); - ret->Load(tree, *this); - return ret; + ret = Expression::Construct(expr_reader, this); + ret->Load(tree, this, loaded_uids); + break; } case capnp::Tree::WHERE: { auto where_reader = tree.getWhere(); - auto *ret = Where::Construct(where_reader, *this); - ret->Load(tree, *this); - return ret; + ret = Where::Construct(where_reader, this); + ret->Load(tree, this, loaded_uids); + break; } case capnp::Tree::CLAUSE: { auto clause_reader = tree.getClause(); - auto *ret = Clause::Construct(clause_reader, *this); - ret->Load(tree, *this); - return ret; + ret = Clause::Construct(clause_reader, this); + ret->Load(tree, this, loaded_uids); + break; } case capnp::Tree::CYPHER_UNION: { auto cu_reader = tree.getCypherUnion(); - auto *ret = CypherUnion::Construct(cu_reader, *this); - ret->Load(tree, *this); - return ret; + ret = CypherUnion::Construct(cu_reader, this); + ret->Load(tree, this, loaded_uids); + break; } case capnp::Tree::NAMED_EXPRESSION: { auto ne_reader = tree.getNamedExpression(); - auto *ret = NamedExpression::Construct(ne_reader, *this); - ret->Load(tree, *this); - return ret; + ret = NamedExpression::Construct(ne_reader, this); + ret->Load(tree, this, loaded_uids); + break; } case capnp::Tree::PATTERN: { auto pattern_reader = tree.getPattern(); - auto *ret = Pattern::Construct(pattern_reader, *this); - ret->Load(tree, *this); - return ret; + ret = Pattern::Construct(pattern_reader, this); + ret->Load(tree, this, loaded_uids); + break; } case capnp::Tree::PATTERN_ATOM: { auto pa_reader = tree.getPatternAtom(); - auto *ret = PatternAtom::Construct(pa_reader, *this); - ret->Load(tree, *this); - return ret; + ret = PatternAtom::Construct(pa_reader, this); + ret->Load(tree, this, loaded_uids); + break; } case capnp::Tree::QUERY: { - auto query_reader = tree.getQuery(); - auto *ret = Query::Construct(query_reader, *this); - ret->Load(tree, *this); - return ret; + this->query()->Load(tree, this, loaded_uids); + ret = this->query(); + break; } case capnp::Tree::SINGLE_QUERY: { auto single_reader = tree.getSingleQuery(); - auto *ret = SingleQuery::Construct(single_reader, *this); - ret->Load(tree, *this); - return ret; + ret = SingleQuery::Construct(single_reader, this); + ret->Load(tree, this, loaded_uids); + break; } } + DCHECK(ret != nullptr); + loaded_uids->emplace_back(ret->uid_); + auto previous_max = std::max_element( + storage_.begin(), storage_.end(), + [](const std::unique_ptr &a, const std::unique_ptr &b) { + return a->uid() < b->uid(); + }); + next_uid_ = (*previous_max)->uid() + 1; + return ret; } // Tree. -void Tree::Save(capnp::Tree::Builder &tree_builder) { - tree_builder.setUid(uid_); +void Tree::Save(capnp::Tree::Builder *tree_builder, + std::vector *saved_uids) { + tree_builder->setUid(uid_); } -void Tree::Load(capnp::Tree::Reader &reader, AstTreeStorage &storage) { +bool Tree::IsSaved(const std::vector &saved_uids) { + return utils::Contains(saved_uids, uid_); +} + +void Tree::Load(const capnp::Tree::Reader &reader, AstTreeStorage *storage, + std::vector *loaded_uids) { uid_ = reader.getUid(); } -// Expression. -void Expression::Save(capnp::Tree::Builder &tree_builder) { - Tree::Save(tree_builder); - auto expr_builder = tree_builder.initExpression(); - Save(expr_builder); +void Tree::AddToSaved(std::vector *saved_uids) { + saved_uids->emplace_back(uid_); } -Expression *Expression::Construct(capnp::Expression::Reader &reader, - AstTreeStorage &storage) { +// Expression. +void Expression::Save(capnp::Tree::Builder *tree_builder, + std::vector *saved_uids) { + Tree::Save(tree_builder, saved_uids); + if (IsSaved(*saved_uids)) { + return; + } + auto expr_builder = tree_builder->initExpression(); + Save(&expr_builder, saved_uids); + AddToSaved(saved_uids); +} + +Expression *Expression::Construct(const capnp::Expression::Reader &reader, + AstTreeStorage *storage) { switch (reader.which()) { case capnp::Expression::BINARY_OPERATOR: { auto bop_reader = reader.getBinaryOperator(); @@ -180,14 +217,15 @@ Expression *Expression::Construct(capnp::Expression::Reader &reader, } // Base Literal. -void BaseLiteral::Save(capnp::Expression::Builder &expr_builder) { - Expression::Save(expr_builder); - auto base_literal_builder = expr_builder.initBaseLiteral(); - Save(base_literal_builder); +void BaseLiteral::Save(capnp::Expression::Builder *expr_builder, + std::vector *saved_uids) { + Expression::Save(expr_builder, saved_uids); + auto base_literal_builder = expr_builder->initBaseLiteral(); + Save(&base_literal_builder, saved_uids); } -BaseLiteral *BaseLiteral::Construct(capnp::BaseLiteral::Reader &reader, - AstTreeStorage &storage) { +BaseLiteral *BaseLiteral::Construct(const capnp::BaseLiteral::Reader &reader, + AstTreeStorage *storage) { switch (reader.which()) { case capnp::BaseLiteral::PRIMITIVE_LITERAL: { auto literal = reader.getPrimitiveLiteral(); @@ -205,48 +243,64 @@ BaseLiteral *BaseLiteral::Construct(capnp::BaseLiteral::Reader &reader, } // Primitive Literal. -void PrimitiveLiteral::Save(capnp::BaseLiteral::Builder &base_literal_builder) { - BaseLiteral::Save(base_literal_builder); - auto primitive_literal_builder = base_literal_builder.initPrimitiveLiteral(); +void PrimitiveLiteral::Save(capnp::BaseLiteral::Builder *base_literal_builder, + std::vector *saved_uids) { + BaseLiteral::Save(base_literal_builder, saved_uids); + auto primitive_literal_builder = base_literal_builder->initPrimitiveLiteral(); primitive_literal_builder.setTokenPosition(token_position_); auto typed_value_builder = primitive_literal_builder.getValue(); utils::SaveCapnpTypedValue(value_, typed_value_builder); } +void PrimitiveLiteral::Load(const capnp::Tree::Reader &reader, + AstTreeStorage *storage, + std::vector *loaded_uids) { + BaseLiteral::Load(reader, storage, loaded_uids); + auto pl_reader = + reader.getExpression().getBaseLiteral().getPrimitiveLiteral(); + auto typed_value_reader = pl_reader.getValue(); + utils::LoadCapnpTypedValue(value_, typed_value_reader); + token_position_ = pl_reader.getTokenPosition(); +} + PrimitiveLiteral *PrimitiveLiteral::Construct( - capnp::PrimitiveLiteral::Reader &reader, AstTreeStorage &storage) { - auto typed_value_reader = reader.getValue(); - TypedValue value; - utils::LoadCapnpTypedValue(value, typed_value_reader); - return storage.Create(value, reader.getTokenPosition()); + const capnp::PrimitiveLiteral::Reader &reader, AstTreeStorage *storage) { + return storage->Create(); } // List Literal. -void ListLiteral::Save(capnp::BaseLiteral::Builder &base_literal_builder) { - BaseLiteral::Save(base_literal_builder); - auto list_literal_builder = base_literal_builder.initListLiteral(); +void ListLiteral::Save(capnp::BaseLiteral::Builder *base_literal_builder, + std::vector *saved_uids) { + BaseLiteral::Save(base_literal_builder, saved_uids); + auto list_literal_builder = base_literal_builder->initListLiteral(); ::capnp::List::Builder tree_builders = list_literal_builder.initElements(elements_.size()); for (size_t i = 0; i < elements_.size(); ++i) { auto tree_builder = tree_builders[i]; - elements_[i]->Save(tree_builder); + elements_[i]->Save(&tree_builder, saved_uids); } } -ListLiteral *ListLiteral::Construct(capnp::ListLiteral::Reader &reader, - AstTreeStorage &storage) { - auto *list = storage.Create(); - for (auto tree_reader : reader.getElements()) { - auto tree = storage.Load(tree_reader); - list->elements_.push_back(dynamic_cast(tree)); +void ListLiteral::Load(const capnp::Tree::Reader &base_reader, + AstTreeStorage *storage, std::vector *loaded_uids) { + BaseLiteral::Load(base_reader, storage, loaded_uids); + auto reader = base_reader.getExpression().getBaseLiteral().getListLiteral(); + for (const auto tree_reader : reader.getElements()) { + auto tree = storage->Load(tree_reader, loaded_uids); + elements_.push_back(dynamic_cast(tree)); } - return list; +} + +ListLiteral *ListLiteral::Construct(const capnp::ListLiteral::Reader &reader, + AstTreeStorage *storage) { + return storage->Create(); } // Map Literal. -void MapLiteral::Save(capnp::BaseLiteral::Builder &base_literal_builder) { - BaseLiteral::Save(base_literal_builder); - auto map_literal_builder = base_literal_builder.initMapLiteral(); +void MapLiteral::Save(capnp::BaseLiteral::Builder *base_literal_builder, + std::vector *saved_uids) { + BaseLiteral::Save(base_literal_builder, saved_uids); + auto map_literal_builder = base_literal_builder->initMapLiteral(); ::capnp::List::Builder map_builder = map_literal_builder.initElements(elements_.size()); size_t i = 0; @@ -257,63 +311,73 @@ void MapLiteral::Save(capnp::BaseLiteral::Builder &base_literal_builder) { auto storage_property_builder = key_builder.getSecond(); entry.first.second.Save(storage_property_builder); auto value_builder = entry_builder.getValue(); - if (entry.second) entry.second->Save(value_builder); + if (entry.second) entry.second->Save(&value_builder, saved_uids); ++i; } } -MapLiteral *MapLiteral::Construct(capnp::MapLiteral::Reader &reader, - AstTreeStorage &storage) { - auto *map = storage.Create(); +void MapLiteral::Load(const capnp::Tree::Reader &base_reader, + AstTreeStorage *storage, std::vector *loaded_uids) { + BaseLiteral::Load(base_reader, storage, loaded_uids); + auto reader = base_reader.getExpression().getBaseLiteral().getMapLiteral(); for (auto entry_reader : reader.getElements()) { auto key_pair_reader = entry_reader.getKey(); auto key_first = key_pair_reader.getFirst().cStr(); auto storage_property_reader = key_pair_reader.getSecond(); storage::Property key_second; key_second.Load(storage_property_reader); - auto value_reader = entry_reader.getValue(); - auto value = storage.Load(value_reader); + const auto value_reader = entry_reader.getValue(); + auto value = storage->Load(value_reader, loaded_uids); auto key = std::make_pair(key_first, key_second); // TODO Maybe check for nullptr expression? - map->elements_.emplace(key, dynamic_cast(value)); + elements_.emplace(key, dynamic_cast(value)); } - return map; +} + +MapLiteral *MapLiteral::Construct(const capnp::MapLiteral::Reader &reader, + AstTreeStorage *storage) { + return storage->Create(); } // Binary Operator. -void BinaryOperator::Save(capnp::Expression::Builder &expr_builder) { - Expression::Save(expr_builder); - auto builder = expr_builder.initBinaryOperator(); - Save(builder); +void BinaryOperator::Save(capnp::Expression::Builder *expr_builder, + std::vector *saved_uids) { + Expression::Save(expr_builder, saved_uids); + auto builder = expr_builder->initBinaryOperator(); + Save(&builder, saved_uids); } -void BinaryOperator::Save(capnp::BinaryOperator::Builder &builder) { +void BinaryOperator::Save(capnp::BinaryOperator::Builder *builder, + std::vector *saved_uids) { if (expression1_) { - auto expr1_builder = builder.getExpression1(); - expression1_->Save(expr1_builder); + auto expr1_builder = builder->getExpression1(); + expression1_->Save(&expr1_builder, saved_uids); } if (expression2_) { - auto expr2_builder = builder.getExpression2(); - expression2_->Save(expr2_builder); + auto expr2_builder = builder->getExpression2(); + expression2_->Save(&expr2_builder, saved_uids); } } -void BinaryOperator::Load(capnp::Tree::Reader &reader, - AstTreeStorage &storage) { - Expression::Load(reader, storage); +void BinaryOperator::Load(const capnp::Tree::Reader &reader, + AstTreeStorage *storage, + std::vector *loaded_uids) { + Expression::Load(reader, storage, loaded_uids); auto bop_reader = reader.getExpression().getBinaryOperator(); if (bop_reader.hasExpression1()) { - auto expr1_reader = bop_reader.getExpression1(); - expression1_ = dynamic_cast(storage.Load(expr1_reader)); + const auto expr1_reader = bop_reader.getExpression1(); + expression1_ = + dynamic_cast(storage->Load(expr1_reader, loaded_uids)); } if (bop_reader.hasExpression2()) { - auto expr2_reader = bop_reader.getExpression2(); - expression2_ = dynamic_cast(storage.Load(expr2_reader)); + const auto expr2_reader = bop_reader.getExpression2(); + expression2_ = + dynamic_cast(storage->Load(expr2_reader, loaded_uids)); } } -BinaryOperator *BinaryOperator::Construct(capnp::BinaryOperator::Reader &reader, - AstTreeStorage &storage) { +BinaryOperator *BinaryOperator::Construct( + const capnp::BinaryOperator::Reader &reader, AstTreeStorage *storage) { switch (reader.which()) { case capnp::BinaryOperator::ADDITION_OPERATOR: { auto literal = reader.getAdditionOperator(); @@ -386,169 +450,186 @@ BinaryOperator *BinaryOperator::Construct(capnp::BinaryOperator::Reader &reader, } } -void OrOperator::Save(capnp::BinaryOperator::Builder &builder) { - BinaryOperator::Save(builder); - builder.initOrOperator(); +void OrOperator::Save(capnp::BinaryOperator::Builder *builder, + std::vector *saved_uids) { + BinaryOperator::Save(builder, saved_uids); + builder->initOrOperator(); } -OrOperator *OrOperator::Construct(capnp::OrOperator::Reader &, - AstTreeStorage &storage) { - return storage.Create(); +OrOperator *OrOperator::Construct(const capnp::OrOperator::Reader &, + AstTreeStorage *storage) { + return storage->Create(); } -void XorOperator::Save(capnp::BinaryOperator::Builder &builder) { - BinaryOperator::Save(builder); - builder.initXorOperator(); +void XorOperator::Save(capnp::BinaryOperator::Builder *builder, + std::vector *saved_uids) { + BinaryOperator::Save(builder, saved_uids); + builder->initXorOperator(); } -XorOperator *XorOperator::Construct(capnp::XorOperator::Reader &, - AstTreeStorage &storage) { - return storage.Create(); +XorOperator *XorOperator::Construct(const capnp::XorOperator::Reader &, + AstTreeStorage *storage) { + return storage->Create(); } -void AndOperator::Save(capnp::BinaryOperator::Builder &builder) { - BinaryOperator::Save(builder); - builder.initAndOperator(); +void AndOperator::Save(capnp::BinaryOperator::Builder *builder, + std::vector *saved_uids) { + BinaryOperator::Save(builder, saved_uids); + builder->initAndOperator(); } -AndOperator *AndOperator::Construct(capnp::AndOperator::Reader &, - AstTreeStorage &storage) { - return storage.Create(); +AndOperator *AndOperator::Construct(const capnp::AndOperator::Reader &, + AstTreeStorage *storage) { + return storage->Create(); } -void AdditionOperator::Save(capnp::BinaryOperator::Builder &builder) { - BinaryOperator::Save(builder); - builder.initAdditionOperator(); +void AdditionOperator::Save(capnp::BinaryOperator::Builder *builder, + std::vector *saved_uids) { + BinaryOperator::Save(builder, saved_uids); + builder->initAdditionOperator(); } -AdditionOperator *AdditionOperator::Construct(capnp::AdditionOperator::Reader &, - AstTreeStorage &storage) { - return storage.Create(); +AdditionOperator *AdditionOperator::Construct( + const capnp::AdditionOperator::Reader &, AstTreeStorage *storage) { + return storage->Create(); } -void SubtractionOperator::Save(capnp::BinaryOperator::Builder &builder) { - BinaryOperator::Save(builder); - builder.initSubtractionOperator(); +void SubtractionOperator::Save(capnp::BinaryOperator::Builder *builder, + std::vector *saved_uids) { + BinaryOperator::Save(builder, saved_uids); + builder->initSubtractionOperator(); } SubtractionOperator *SubtractionOperator::Construct( - capnp::SubtractionOperator::Reader &, AstTreeStorage &storage) { - return storage.Create(); + capnp::SubtractionOperator::Reader &, AstTreeStorage *storage) { + return storage->Create(); } -void MultiplicationOperator::Save(capnp::BinaryOperator::Builder &builder) { - BinaryOperator::Save(builder); - builder.initMultiplicationOperator(); +void MultiplicationOperator::Save(capnp::BinaryOperator::Builder *builder, + std::vector *saved_uids) { + BinaryOperator::Save(builder, saved_uids); + builder->initMultiplicationOperator(); } MultiplicationOperator *MultiplicationOperator::Construct( - capnp::MultiplicationOperator::Reader &, AstTreeStorage &storage) { - return storage.Create(); + capnp::MultiplicationOperator::Reader &, AstTreeStorage *storage) { + return storage->Create(); } -void DivisionOperator::Save(capnp::BinaryOperator::Builder &builder) { - BinaryOperator::Save(builder); - builder.initDivisionOperator(); +void DivisionOperator::Save(capnp::BinaryOperator::Builder *builder, + std::vector *saved_uids) { + BinaryOperator::Save(builder, saved_uids); + builder->initDivisionOperator(); } -DivisionOperator *DivisionOperator::Construct(capnp::DivisionOperator::Reader &, - AstTreeStorage &storage) { - return storage.Create(); +DivisionOperator *DivisionOperator::Construct( + const capnp::DivisionOperator::Reader &, AstTreeStorage *storage) { + return storage->Create(); } -void ModOperator::Save(capnp::BinaryOperator::Builder &builder) { - BinaryOperator::Save(builder); - builder.initModOperator(); +void ModOperator::Save(capnp::BinaryOperator::Builder *builder, + std::vector *saved_uids) { + BinaryOperator::Save(builder, saved_uids); + builder->initModOperator(); } -ModOperator *ModOperator::Construct(capnp::ModOperator::Reader &, - AstTreeStorage &storage) { - return storage.Create(); +ModOperator *ModOperator::Construct(const capnp::ModOperator::Reader &, + AstTreeStorage *storage) { + return storage->Create(); } -void NotEqualOperator::Save(capnp::BinaryOperator::Builder &builder) { - BinaryOperator::Save(builder); - builder.initNotEqualOperator(); +void NotEqualOperator::Save(capnp::BinaryOperator::Builder *builder, + std::vector *saved_uids) { + BinaryOperator::Save(builder, saved_uids); + builder->initNotEqualOperator(); } -NotEqualOperator *NotEqualOperator::Construct(capnp::NotEqualOperator::Reader &, - AstTreeStorage &storage) { - return storage.Create(); +NotEqualOperator *NotEqualOperator::Construct( + const capnp::NotEqualOperator::Reader &, AstTreeStorage *storage) { + return storage->Create(); } -void EqualOperator::Save(capnp::BinaryOperator::Builder &builder) { - BinaryOperator::Save(builder); - builder.initEqualOperator(); +void EqualOperator::Save(capnp::BinaryOperator::Builder *builder, + std::vector *saved_uids) { + BinaryOperator::Save(builder, saved_uids); + builder->initEqualOperator(); } -EqualOperator *EqualOperator::Construct(capnp::EqualOperator::Reader &, - AstTreeStorage &storage) { - return storage.Create(); +EqualOperator *EqualOperator::Construct(const capnp::EqualOperator::Reader &, + AstTreeStorage *storage) { + return storage->Create(); } -void LessOperator::Save(capnp::BinaryOperator::Builder &builder) { - BinaryOperator::Save(builder); - builder.initLessOperator(); +void LessOperator::Save(capnp::BinaryOperator::Builder *builder, + std::vector *saved_uids) { + BinaryOperator::Save(builder, saved_uids); + builder->initLessOperator(); } -LessOperator *LessOperator::Construct(capnp::LessOperator::Reader &, - AstTreeStorage &storage) { - return storage.Create(); +LessOperator *LessOperator::Construct(const capnp::LessOperator::Reader &, + AstTreeStorage *storage) { + return storage->Create(); } -void GreaterOperator::Save(capnp::BinaryOperator::Builder &builder) { - BinaryOperator::Save(builder); - builder.initGreaterOperator(); +void GreaterOperator::Save(capnp::BinaryOperator::Builder *builder, + std::vector *saved_uids) { + BinaryOperator::Save(builder, saved_uids); + builder->initGreaterOperator(); } -GreaterOperator *GreaterOperator::Construct(capnp::GreaterOperator::Reader &, - AstTreeStorage &storage) { - return storage.Create(); +GreaterOperator *GreaterOperator::Construct( + const capnp::GreaterOperator::Reader &, AstTreeStorage *storage) { + return storage->Create(); } -void LessEqualOperator::Save(capnp::BinaryOperator::Builder &builder) { - BinaryOperator::Save(builder); - builder.initLessEqualOperator(); +void LessEqualOperator::Save(capnp::BinaryOperator::Builder *builder, + std::vector *saved_uids) { + BinaryOperator::Save(builder, saved_uids); + builder->initLessEqualOperator(); } LessEqualOperator *LessEqualOperator::Construct( - capnp::LessEqualOperator::Reader &, AstTreeStorage &storage) { - return storage.Create(); + const capnp::LessEqualOperator::Reader &, AstTreeStorage *storage) { + return storage->Create(); } -void GreaterEqualOperator::Save(capnp::BinaryOperator::Builder &builder) { - BinaryOperator::Save(builder); - builder.initGreaterEqualOperator(); +void GreaterEqualOperator::Save(capnp::BinaryOperator::Builder *builder, + std::vector *saved_uids) { + BinaryOperator::Save(builder, saved_uids); + builder->initGreaterEqualOperator(); } GreaterEqualOperator *GreaterEqualOperator::Construct( - capnp::GreaterEqualOperator::Reader &, AstTreeStorage &storage) { - return storage.Create(); + const capnp::GreaterEqualOperator::Reader &, AstTreeStorage *storage) { + return storage->Create(); } -void InListOperator::Save(capnp::BinaryOperator::Builder &builder) { - BinaryOperator::Save(builder); - builder.initInListOperator(); +void InListOperator::Save(capnp::BinaryOperator::Builder *builder, + std::vector *saved_uids) { + BinaryOperator::Save(builder, saved_uids); + builder->initInListOperator(); } -InListOperator *InListOperator::Construct(capnp::InListOperator::Reader &, - AstTreeStorage &storage) { - return storage.Create(); +InListOperator *InListOperator::Construct(const capnp::InListOperator::Reader &, + AstTreeStorage *storage) { + return storage->Create(); } -void ListMapIndexingOperator::Save(capnp::BinaryOperator::Builder &builder) { - BinaryOperator::Save(builder); - builder.initListMapIndexingOperator(); +void ListMapIndexingOperator::Save(capnp::BinaryOperator::Builder *builder, + std::vector *saved_uids) { + BinaryOperator::Save(builder, saved_uids); + builder->initListMapIndexingOperator(); } ListMapIndexingOperator *ListMapIndexingOperator::Construct( - capnp::ListMapIndexingOperator::Reader &, AstTreeStorage &storage) { - return storage.Create(); + capnp::ListMapIndexingOperator::Reader &, AstTreeStorage *storage) { + return storage->Create(); } -void Aggregation::Save(capnp::BinaryOperator::Builder &builder) { - BinaryOperator::Save(builder); - auto ag_builder = builder.initAggregation(); +void Aggregation::Save(capnp::BinaryOperator::Builder *builder, + std::vector *saved_uids) { + BinaryOperator::Save(builder, saved_uids); + auto ag_builder = builder->initAggregation(); switch (op_) { case Op::AVG: ag_builder.setOp(capnp::Aggregation::Op::AVG); @@ -574,8 +655,8 @@ void Aggregation::Save(capnp::BinaryOperator::Builder &builder) { } } -Aggregation *Aggregation::Construct(capnp::Aggregation::Reader &reader, - AstTreeStorage &storage) { +Aggregation *Aggregation::Construct(const capnp::Aggregation::Reader &reader, + AstTreeStorage *storage) { Op op; switch (reader.getOp()) { case capnp::Aggregation::Op::AVG: @@ -600,34 +681,39 @@ Aggregation *Aggregation::Construct(capnp::Aggregation::Reader &reader, op = Op::SUM; break; } - return storage.Create(op); + return storage->Create(op); } // Unary Operator. -void UnaryOperator::Save(capnp::Expression::Builder &expr_builder) { - Expression::Save(expr_builder); - auto builder = expr_builder.initUnaryOperator(); - Save(builder); +void UnaryOperator::Save(capnp::Expression::Builder *expr_builder, + std::vector *saved_uids) { + Expression::Save(expr_builder, saved_uids); + auto builder = expr_builder->initUnaryOperator(); + Save(&builder, saved_uids); } -void UnaryOperator::Save(capnp::UnaryOperator::Builder &builder) { +void UnaryOperator::Save(capnp::UnaryOperator::Builder *builder, + std::vector *saved_uids) { if (expression_) { - auto expr_builder = builder.getExpression(); - expression_->Save(expr_builder); + auto expr_builder = builder->getExpression(); + expression_->Save(&expr_builder, saved_uids); } } -void UnaryOperator::Load(capnp::Tree::Reader &reader, AstTreeStorage &storage) { - Expression::Load(reader, storage); +void UnaryOperator::Load(const capnp::Tree::Reader &reader, + AstTreeStorage *storage, + std::vector *loaded_uids) { + Expression::Load(reader, storage, loaded_uids); if (reader.hasExpression()) { - auto expr_reader = + const auto expr_reader = reader.getExpression().getUnaryOperator().getExpression(); - expression_ = dynamic_cast(storage.Load(expr_reader)); + expression_ = + dynamic_cast(storage->Load(expr_reader, loaded_uids)); } } -UnaryOperator *UnaryOperator::Construct(capnp::UnaryOperator::Reader &reader, - AstTreeStorage &storage) { +UnaryOperator *UnaryOperator::Construct( + const capnp::UnaryOperator::Reader &reader, AstTreeStorage *storage) { switch (reader.which()) { case capnp::UnaryOperator::IS_NULL_OPERATOR: { auto op = reader.getIsNullOperator(); @@ -649,371 +735,467 @@ UnaryOperator *UnaryOperator::Construct(capnp::UnaryOperator::Reader &reader, } // IsNull Operator. -void IsNullOperator::Save(capnp::UnaryOperator::Builder &builder) { - UnaryOperator::Save(builder); - builder.initIsNullOperator(); +void IsNullOperator::Save(capnp::UnaryOperator::Builder *builder, + std::vector *saved_uids) { + UnaryOperator::Save(builder, saved_uids); + builder->initIsNullOperator(); } -IsNullOperator *IsNullOperator::Construct(capnp::IsNullOperator::Reader &, - AstTreeStorage &storage) { - return storage.Create(); +IsNullOperator *IsNullOperator::Construct(const capnp::IsNullOperator::Reader &, + AstTreeStorage *storage) { + return storage->Create(); } // Not Operator. -void NotOperator::Save(capnp::UnaryOperator::Builder &builder) { - UnaryOperator::Save(builder); - builder.initNotOperator(); +void NotOperator::Save(capnp::UnaryOperator::Builder *builder, + std::vector *saved_uids) { + UnaryOperator::Save(builder, saved_uids); + builder->initNotOperator(); } -NotOperator *NotOperator::Construct(capnp::NotOperator::Reader &, - AstTreeStorage &storage) { - return storage.Create(); +NotOperator *NotOperator::Construct(const capnp::NotOperator::Reader &, + AstTreeStorage *storage) { + return storage->Create(); } // UnaryPlus Operator. -void UnaryPlusOperator::Save(capnp::UnaryOperator::Builder &builder) { - UnaryOperator::Save(builder); - builder.initUnaryPlusOperator(); +void UnaryPlusOperator::Save(capnp::UnaryOperator::Builder *builder, + std::vector *saved_uids) { + UnaryOperator::Save(builder, saved_uids); + builder->initUnaryPlusOperator(); } UnaryPlusOperator *UnaryPlusOperator::Construct( - capnp::UnaryPlusOperator::Reader &, AstTreeStorage &storage) { - return storage.Create(); + const capnp::UnaryPlusOperator::Reader &, AstTreeStorage *storage) { + return storage->Create(); } // UnaryMinus Operator. -void UnaryMinusOperator::Save(capnp::UnaryOperator::Builder &builder) { - UnaryOperator::Save(builder); - builder.initUnaryMinusOperator(); +void UnaryMinusOperator::Save(capnp::UnaryOperator::Builder *builder, + std::vector *saved_uids) { + UnaryOperator::Save(builder, saved_uids); + builder->initUnaryMinusOperator(); } UnaryMinusOperator *UnaryMinusOperator::Construct( - capnp::UnaryMinusOperator::Reader &, AstTreeStorage &storage) { - return storage.Create(); + capnp::UnaryMinusOperator::Reader &, AstTreeStorage *storage) { + return storage->Create(); } // ListSlicing Operator. -void ListSlicingOperator::Save(capnp::Expression::Builder &expr_builder) { - Expression::Save(expr_builder); - auto builder = expr_builder.initListSlicingOperator(); - Save(builder); +void ListSlicingOperator::Save(capnp::Expression::Builder *expr_builder, + std::vector *saved_uids) { + Expression::Save(expr_builder, saved_uids); + auto builder = expr_builder->initListSlicingOperator(); + Save(&builder, saved_uids); } -void ListSlicingOperator::Save(capnp::ListSlicingOperator::Builder &builder) { +void ListSlicingOperator::Save(capnp::ListSlicingOperator::Builder *builder, + std::vector *saved_uids) { if (list_) { - auto list_builder = builder.getList(); - list_->Save(list_builder); + auto list_builder = builder->getList(); + list_->Save(&list_builder, saved_uids); } if (lower_bound_) { - auto lb_builder = builder.getLowerBound(); - lower_bound_->Save(lb_builder); + auto lb_builder = builder->getLowerBound(); + lower_bound_->Save(&lb_builder, saved_uids); } if (upper_bound_) { - auto up_builder = builder.getUpperBound(); - upper_bound_->Save(up_builder); + auto up_builder = builder->getUpperBound(); + upper_bound_->Save(&up_builder, saved_uids); + } +} + +void ListSlicingOperator::Load(const capnp::Tree::Reader &base_reader, + AstTreeStorage *storage, + std::vector *loaded_uids) { + Expression::Load(base_reader, storage, loaded_uids); + auto reader = base_reader.getExpression().getListSlicingOperator(); + if (reader.hasList()) { + const auto list_reader = reader.getList(); + list_ = dynamic_cast(storage->Load(list_reader, loaded_uids)); + } + if (reader.hasUpperBound()) { + const auto ub_reader = reader.getUpperBound(); + upper_bound_ = + dynamic_cast(storage->Load(ub_reader, loaded_uids)); + } + if (reader.hasLowerBound()) { + const auto lb_reader = reader.getLowerBound(); + lower_bound_ = + dynamic_cast(storage->Load(lb_reader, loaded_uids)); } } ListSlicingOperator *ListSlicingOperator::Construct( - capnp::ListSlicingOperator::Reader &reader, AstTreeStorage &storage) { - Expression *list = nullptr; - Expression *upper_bound = nullptr; - Expression *lower_bound = nullptr; - if (reader.hasList()) { - auto list_reader = reader.getList(); - list = dynamic_cast(storage.Load(list_reader)); - } - if (reader.hasUpperBound()) { - auto ub_reader = reader.getUpperBound(); - upper_bound = dynamic_cast(storage.Load(ub_reader)); - } - if (reader.hasLowerBound()) { - auto lb_reader = reader.getLowerBound(); - lower_bound = dynamic_cast(storage.Load(lb_reader)); - } - return storage.Create(list, lower_bound, upper_bound); + const capnp::ListSlicingOperator::Reader &reader, AstTreeStorage *storage) { + return storage->Create(nullptr, nullptr, nullptr); } // If Operator. -void IfOperator::Save(capnp::Expression::Builder &expr_builder) { - Expression::Save(expr_builder); - auto builder = expr_builder.initIfOperator(); - Save(builder); +void IfOperator::Save(capnp::Expression::Builder *expr_builder, + std::vector *saved_uids) { + Expression::Save(expr_builder, saved_uids); + auto builder = expr_builder->initIfOperator(); + Save(&builder, saved_uids); } -void IfOperator::Save(capnp::IfOperator::Builder &builder) { - auto condition_builder = builder.getCondition(); - condition_->Save(condition_builder); - auto then_builder = builder.getThenExpression(); - then_expression_->Save(then_builder); - auto else_builder = builder.getElseExpression(); - else_expression_->Save(else_builder); +void IfOperator::Save(capnp::IfOperator::Builder *builder, + std::vector *saved_uids) { + auto condition_builder = builder->getCondition(); + condition_->Save(&condition_builder, saved_uids); + auto then_builder = builder->getThenExpression(); + then_expression_->Save(&then_builder, saved_uids); + auto else_builder = builder->getElseExpression(); + else_expression_->Save(&else_builder, saved_uids); } -IfOperator *IfOperator::Construct(capnp::IfOperator::Reader &reader, - AstTreeStorage &storage) { - auto condition_reader = reader.getCondition(); - auto condition = dynamic_cast(storage.Load(condition_reader)); - auto then_reader = reader.getThenExpression(); - auto then_expression = dynamic_cast(storage.Load(then_reader)); - auto else_reader = reader.getElseExpression(); - auto else_expression = dynamic_cast(storage.Load(else_reader)); - return storage.Create(condition, then_expression, - else_expression); +void IfOperator::Load(const capnp::Tree::Reader &base_reader, + AstTreeStorage *storage, std::vector *loaded_uids) { + Expression::Load(base_reader, storage, loaded_uids); + auto reader = base_reader.getExpression().getIfOperator(); + const auto condition_reader = reader.getCondition(); + condition_ = + dynamic_cast(storage->Load(condition_reader, loaded_uids)); + const auto then_reader = reader.getThenExpression(); + then_expression_ = + dynamic_cast(storage->Load(then_reader, loaded_uids)); + const auto else_reader = reader.getElseExpression(); + else_expression_ = + dynamic_cast(storage->Load(else_reader, loaded_uids)); +} + +IfOperator *IfOperator::Construct(const capnp::IfOperator::Reader &reader, + AstTreeStorage *storage) { + return storage->Create(nullptr, nullptr, nullptr); } // All -void All::Save(capnp::Expression::Builder &expr_builder) { - Expression::Save(expr_builder); - auto builder = expr_builder.initAll(); - Save(builder); +void All::Save(capnp::Expression::Builder *expr_builder, + std::vector *saved_uids) { + Expression::Save(expr_builder, saved_uids); + auto builder = expr_builder->initAll(); + Save(&builder, saved_uids); } -void All::Save(capnp::All::Builder &builder) { - auto identifier_builder = builder.getIdentifier(); - identifier_->Save(identifier_builder); - auto expr_builder = builder.getListExpression(); - list_expression_->Save(expr_builder); - auto where_builder = builder.getWhere(); - where_->Save(where_builder); +void All::Save(capnp::All::Builder *builder, std::vector *saved_uids) { + auto identifier_builder = builder->getIdentifier(); + identifier_->Save(&identifier_builder, saved_uids); + auto expr_builder = builder->getListExpression(); + list_expression_->Save(&expr_builder, saved_uids); + auto where_builder = builder->getWhere(); + where_->Save(&where_builder, saved_uids); } -All *All::Construct(capnp::All::Reader &reader, AstTreeStorage &storage) { - auto id_reader = reader.getIdentifier(); - auto identifier = dynamic_cast(storage.Load(id_reader)); - auto expr_reader = reader.getListExpression(); - auto list_expression = dynamic_cast(storage.Load(expr_reader)); - auto where_reader = reader.getWhere(); - auto where = dynamic_cast(storage.Load(where_reader)); - return storage.Create(identifier, list_expression, where); +void All::Load(const capnp::Tree::Reader &base_reader, AstTreeStorage *storage, + std::vector *loaded_uids) { + Expression::Load(base_reader, storage, loaded_uids); + auto reader = base_reader.getExpression().getAll(); + const auto id_reader = reader.getIdentifier(); + identifier_ = + dynamic_cast(storage->Load(id_reader, loaded_uids)); + const auto expr_reader = reader.getListExpression(); + list_expression_ = + dynamic_cast(storage->Load(expr_reader, loaded_uids)); + const auto where_reader = reader.getWhere(); + where_ = dynamic_cast(storage->Load(where_reader, loaded_uids)); +} + +All *All::Construct(const capnp::All::Reader &reader, AstTreeStorage *storage) { + return storage->Create(nullptr, nullptr, nullptr); } // Function -void Function::Save(capnp::Expression::Builder &expr_builder) { - Expression::Save(expr_builder); - auto builder = expr_builder.initFunction(); - Save(builder); +void Function::Save(capnp::Expression::Builder *expr_builder, + std::vector *saved_uids) { + Expression::Save(expr_builder, saved_uids); + auto builder = expr_builder->initFunction(); + Save(&builder, saved_uids); } -void Function::Save(capnp::Function::Builder &builder) { - builder.setFunctionName(function_name_); +void Function::Save(capnp::Function::Builder *builder, + std::vector *saved_uids) { + builder->setFunctionName(function_name_); ::capnp::List::Builder tree_builders = - builder.initArguments(arguments_.size()); + builder->initArguments(arguments_.size()); for (size_t i = 0; i < arguments_.size(); ++i) { auto tree_builder = tree_builders[i]; - arguments_[i]->Save(tree_builder); + arguments_[i]->Save(&tree_builder, saved_uids); } } -Function *Function::Construct(capnp::Function::Reader &reader, - AstTreeStorage &storage) { - auto name = reader.getFunctionName().cStr(); - std::vector arguments; - for (auto tree_reader : reader.getArguments()) { - auto tree = storage.Load(tree_reader); - arguments.push_back(dynamic_cast(tree)); +void Function::Load(const capnp::Tree::Reader &base_reader, + AstTreeStorage *storage, std::vector *loaded_uids) { + Expression::Load(base_reader, storage, loaded_uids); + auto reader = base_reader.getExpression().getFunction(); + function_name_ = reader.getFunctionName().cStr(); + for (const auto tree_reader : reader.getArguments()) { + auto tree = storage->Load(tree_reader, loaded_uids); + arguments_.push_back(dynamic_cast(tree)); } - return storage.Create(name, arguments); + function_ = NameToFunction(function_name_); +} + +Function *Function::Construct(const capnp::Function::Reader &reader, + AstTreeStorage *storage) { + return storage->Create(); } // Identifier -void Identifier::Save(capnp::Expression::Builder &expr_builder) { - Expression::Save(expr_builder); - auto builder = expr_builder.initIdentifier(); - Save(builder); +void Identifier::Save(capnp::Expression::Builder *expr_builder, + std::vector *saved_uids) { + Expression::Save(expr_builder, saved_uids); + auto builder = expr_builder->initIdentifier(); + Save(&builder, saved_uids); } -void Identifier::Save(capnp::Identifier::Builder &builder) { - builder.setName(name_); - builder.setUserDeclared(user_declared_); +void Identifier::Save(capnp::Identifier::Builder *builder, + std::vector *saved_uids) { + builder->setName(name_); + builder->setUserDeclared(user_declared_); } -Identifier *Identifier::Construct(capnp::Identifier::Reader &reader, - AstTreeStorage &storage) { +Identifier *Identifier::Construct(const capnp::Identifier::Reader &reader, + AstTreeStorage *storage) { auto name = reader.getName().cStr(); auto user_declared = reader.getUserDeclared(); - return storage.Create(name, user_declared); + return storage->Create(name, user_declared); } // LabelsTest -void LabelsTest::Save(capnp::Expression::Builder &expr_builder) { - Expression::Save(expr_builder); - auto builder = expr_builder.initLabelsTest(); - Save(builder); +void LabelsTest::Save(capnp::Expression::Builder *expr_builder, + std::vector *saved_uids) { + Expression::Save(expr_builder, saved_uids); + auto builder = expr_builder->initLabelsTest(); + Save(&builder, saved_uids); } -void LabelsTest::Save(capnp::LabelsTest::Builder &builder) { +void LabelsTest::Save(capnp::LabelsTest::Builder *builder, + std::vector *saved_uids) { if (expression_) { - auto expr_builder = builder.initExpression(); - expression_->Save(expr_builder); + auto expr_builder = builder->initExpression(); + expression_->Save(&expr_builder, saved_uids); } ::capnp::List::Builder common_builders = - builder.initLabels(labels_.size()); + builder->initLabels(labels_.size()); for (size_t i = 0; i < labels_.size(); ++i) { auto common_builder = common_builders[i]; labels_[i].Save(common_builder); } } -LabelsTest *LabelsTest::Construct(capnp::LabelsTest::Reader &reader, - AstTreeStorage &storage) { - Expression *expression = nullptr; +void LabelsTest::Load(const capnp::Tree::Reader &base_reader, + AstTreeStorage *storage, std::vector *loaded_uids) { + Expression::Load(base_reader, storage, loaded_uids); + auto reader = base_reader.getExpression().getLabelsTest(); if (reader.hasExpression()) { - auto expr_reader = reader.getExpression(); - expression = dynamic_cast(storage.Load(expr_reader)); + const auto expr_reader = reader.getExpression(); + expression_ = + dynamic_cast(storage->Load(expr_reader, loaded_uids)); } - std::vector labels; for (auto label_reader : reader.getLabels()) { storage::Label label; label.Load(label_reader); - labels.push_back(label); + labels_.push_back(label); } - return storage.Create(expression, labels); +} + +LabelsTest *LabelsTest::Construct(const capnp::LabelsTest::Reader &reader, + AstTreeStorage *storage) { + return storage->Create(nullptr, std::vector()); } // ParameterLookup -void ParameterLookup::Save(capnp::Expression::Builder &expr_builder) { - Expression::Save(expr_builder); - auto builder = expr_builder.initParameterLookup(); - Save(builder); +void ParameterLookup::Save(capnp::Expression::Builder *expr_builder, + std::vector *saved_uids) { + Expression::Save(expr_builder, saved_uids); + auto builder = expr_builder->initParameterLookup(); + Save(&builder, saved_uids); } -void ParameterLookup::Save(capnp::ParameterLookup::Builder &builder) { - builder.setTokenPosition(token_position_); +void ParameterLookup::Save(capnp::ParameterLookup::Builder *builder, + std::vector *saved_uids) { + builder->setTokenPosition(token_position_); } ParameterLookup *ParameterLookup::Construct( - capnp::ParameterLookup::Reader &reader, AstTreeStorage &storage) { + const capnp::ParameterLookup::Reader &reader, AstTreeStorage *storage) { auto token_position = reader.getTokenPosition(); - return storage.Create(token_position); + return storage->Create(token_position); } // PropertyLookup -void PropertyLookup::Save(capnp::Expression::Builder &expr_builder) { - Expression::Save(expr_builder); - auto builder = expr_builder.initPropertyLookup(); - Save(builder); +void PropertyLookup::Save(capnp::Expression::Builder *expr_builder, + std::vector *saved_uids) { + Expression::Save(expr_builder, saved_uids); + auto builder = expr_builder->initPropertyLookup(); + Save(&builder, saved_uids); } -void PropertyLookup::Save(capnp::PropertyLookup::Builder &builder) { +void PropertyLookup::Save(capnp::PropertyLookup::Builder *builder, + std::vector *saved_uids) { if (expression_) { - auto expr_builder = builder.initExpression(); - expression_->Save(expr_builder); + auto expr_builder = builder->initExpression(); + expression_->Save(&expr_builder, saved_uids); } - builder.setPropertyName(property_name_); - auto storage_property_builder = builder.initProperty(); + builder->setPropertyName(property_name_); + auto storage_property_builder = builder->initProperty(); property_.Save(storage_property_builder); } -PropertyLookup *PropertyLookup::Construct(capnp::PropertyLookup::Reader &reader, - AstTreeStorage &storage) { - Expression *expression = nullptr; +void PropertyLookup::Load(const capnp::Tree::Reader &base_reader, + AstTreeStorage *storage, + std::vector *loaded_uids) { + Expression::Load(base_reader, storage, loaded_uids); + auto reader = base_reader.getExpression().getPropertyLookup(); if (reader.hasExpression()) { - auto expr_reader = reader.getExpression(); - expression = dynamic_cast(storage.Load(expr_reader)); + const auto expr_reader = reader.getExpression(); + expression_ = + dynamic_cast(storage->Load(expr_reader, loaded_uids)); } - auto property_name = reader.getPropertyName().cStr(); + property_name_ = reader.getPropertyName().cStr(); auto storage_property_reader = reader.getProperty(); - storage::Property property; - property.Load(storage_property_reader); - return storage.Create(expression, property_name, property); + property_.Load(storage_property_reader); +} + +PropertyLookup *PropertyLookup::Construct( + const capnp::PropertyLookup::Reader &reader, AstTreeStorage *storage) { + return storage->Create(nullptr, "", storage::Property()); } // Reduce -void Reduce::Save(capnp::Expression::Builder &expr_builder) { - Expression::Save(expr_builder); - auto builder = expr_builder.initReduce(); - Save(builder); +void Reduce::Save(capnp::Expression::Builder *expr_builder, + std::vector *saved_uids) { + Expression::Save(expr_builder, saved_uids); + auto builder = expr_builder->initReduce(); + Save(&builder, saved_uids); } -void Reduce::Save(capnp::Reduce::Builder &builder) { - auto acc_builder = builder.initAccumulator(); - accumulator_->Save(acc_builder); - auto init_builder = builder.initInitializer(); - initializer_->Save(init_builder); - auto id_builder = builder.initIdentifier(); - identifier_->Save(id_builder); - auto list_builder = builder.initList(); - list_->Save(list_builder); - auto expr_builder = builder.initExpression(); - expression_->Save(expr_builder); +void Reduce::Save(capnp::Reduce::Builder *builder, + std::vector *saved_uids) { + auto acc_builder = builder->initAccumulator(); + accumulator_->Save(&acc_builder, saved_uids); + auto init_builder = builder->initInitializer(); + initializer_->Save(&init_builder, saved_uids); + auto id_builder = builder->initIdentifier(); + identifier_->Save(&id_builder, saved_uids); + auto list_builder = builder->initList(); + list_->Save(&list_builder, saved_uids); + auto expr_builder = builder->initExpression(); + expression_->Save(&expr_builder, saved_uids); } -Reduce *Reduce::Construct(capnp::Reduce::Reader &reader, - AstTreeStorage &storage) { - auto acc_reader = reader.getAccumulator(); - auto accumulator = dynamic_cast(storage.Load(acc_reader)); - auto init_reader = reader.getInitializer(); - auto initializer = dynamic_cast(storage.Load(init_reader)); - auto id_reader = reader.getIdentifier(); - auto identifier = dynamic_cast(storage.Load(id_reader)); - auto list_reader = reader.getList(); - auto list = dynamic_cast(storage.Load(list_reader)); - auto expr_reader = reader.getExpression(); - auto expression = dynamic_cast(storage.Load(expr_reader)); - return storage.Create(accumulator, initializer, identifier, list, - expression); +void Reduce::Load(const capnp::Tree::Reader &base_reader, + AstTreeStorage *storage, std::vector *loaded_uids) { + Expression::Load(base_reader, storage, loaded_uids); + auto reader = base_reader.getExpression().getReduce(); + const auto acc_reader = reader.getAccumulator(); + accumulator_ = + dynamic_cast(storage->Load(acc_reader, loaded_uids)); + const auto init_reader = reader.getInitializer(); + initializer_ = + dynamic_cast(storage->Load(init_reader, loaded_uids)); + const auto id_reader = reader.getIdentifier(); + identifier_ = + dynamic_cast(storage->Load(id_reader, loaded_uids)); + const auto list_reader = reader.getList(); + list_ = dynamic_cast(storage->Load(list_reader, loaded_uids)); + const auto expr_reader = reader.getExpression(); + expression_ = + dynamic_cast(storage->Load(expr_reader, loaded_uids)); +} + +Reduce *Reduce::Construct(const capnp::Reduce::Reader &reader, + AstTreeStorage *storage) { + return storage->Create(nullptr, nullptr, nullptr, nullptr, nullptr); } // Single -void Single::Save(capnp::Expression::Builder &expr_builder) { - Expression::Save(expr_builder); - auto builder = expr_builder.initSingle(); - Save(builder); +void Single::Save(capnp::Expression::Builder *expr_builder, + std::vector *saved_uids) { + Expression::Save(expr_builder, saved_uids); + auto builder = expr_builder->initSingle(); + Save(&builder, saved_uids); } -void Single::Save(capnp::Single::Builder &builder) { - auto where_builder = builder.initWhere(); - where_->Save(where_builder); - auto id_builder = builder.initIdentifier(); - identifier_->Save(id_builder); - auto expr_builder = builder.initListExpression(); - list_expression_->Save(expr_builder); +void Single::Save(capnp::Single::Builder *builder, + std::vector *saved_uids) { + auto where_builder = builder->initWhere(); + where_->Save(&where_builder, saved_uids); + auto id_builder = builder->initIdentifier(); + identifier_->Save(&id_builder, saved_uids); + auto expr_builder = builder->initListExpression(); + list_expression_->Save(&expr_builder, saved_uids); } -Single *Single::Construct(capnp::Single::Reader &reader, - AstTreeStorage &storage) { - auto id_reader = reader.getIdentifier(); - auto identifier = dynamic_cast(storage.Load(id_reader)); - auto list_reader = reader.getListExpression(); - auto list_expression = dynamic_cast(storage.Load(list_reader)); - auto where_reader = reader.getWhere(); - auto where = dynamic_cast(storage.Load(where_reader)); - return storage.Create(identifier, list_expression, where); +void Single::Load(const capnp::Tree::Reader &base_reader, + AstTreeStorage *storage, std::vector *loaded_uids) { + Expression::Load(base_reader, storage, loaded_uids); + auto reader = base_reader.getExpression().getSingle(); + const auto id_reader = reader.getIdentifier(); + identifier_ = + dynamic_cast(storage->Load(id_reader, loaded_uids)); + const auto list_reader = reader.getListExpression(); + list_expression_ = + dynamic_cast(storage->Load(list_reader, loaded_uids)); + const auto where_reader = reader.getWhere(); + where_ = dynamic_cast(storage->Load(where_reader, loaded_uids)); +} + +Single *Single::Construct(const capnp::Single::Reader &reader, + AstTreeStorage *storage) { + return storage->Create(nullptr, nullptr, nullptr); } // Where -void Where::Save(capnp::Tree::Builder &tree_builder) { - Tree::Save(tree_builder); - auto builder = tree_builder.initWhere(); - Save(builder); +void Where::Save(capnp::Tree::Builder *tree_builder, + std::vector *saved_uids) { + Tree::Save(tree_builder, saved_uids); + if (IsSaved(*saved_uids)) { + return; + } + auto builder = tree_builder->initWhere(); + Save(&builder, saved_uids); + AddToSaved(saved_uids); } -void Where::Save(capnp::Where::Builder &builder) { +void Where::Save(capnp::Where::Builder *builder, std::vector *saved_uids) { if (expression_) { - auto expr_builder = builder.initExpression(); - expression_->Save(expr_builder); + auto expr_builder = builder->initExpression(); + expression_->Save(&expr_builder, saved_uids); } } -Where *Where::Construct(capnp::Where::Reader &reader, AstTreeStorage &storage) { - Expression *expression = nullptr; +void Where::Load(const capnp::Tree::Reader &base_reader, + AstTreeStorage *storage, std::vector *loaded_uids) { + Tree::Load(base_reader, storage, loaded_uids); + auto reader = base_reader.getWhere(); if (reader.hasExpression()) { - auto expr_reader = reader.getExpression(); - expression = dynamic_cast(storage.Load(expr_reader)); + const auto expr_reader = reader.getExpression(); + expression_ = + dynamic_cast(storage->Load(expr_reader, loaded_uids)); } - return storage.Create(expression); +} + +Where *Where::Construct(const capnp::Where::Reader &reader, + AstTreeStorage *storage) { + return storage->Create(); } // Clause. -void Clause::Save(capnp::Tree::Builder &tree_builder) { - Tree::Save(tree_builder); - auto clause_builder = tree_builder.initClause(); - Save(clause_builder); +void Clause::Save(capnp::Tree::Builder *tree_builder, + std::vector *saved_uids) { + Tree::Save(tree_builder, saved_uids); + if (IsSaved(*saved_uids)) { + return; + } + auto clause_builder = tree_builder->initClause(); + Save(&clause_builder, saved_uids); + AddToSaved(saved_uids); } -Clause *Clause::Construct(capnp::Clause::Reader &reader, - AstTreeStorage &storage) { +Clause *Clause::Construct(const capnp::Clause::Reader &reader, + AstTreeStorage *storage) { switch (reader.which()) { case capnp::Clause::CREATE: { auto create_reader = reader.getCreate(); @@ -1072,249 +1254,294 @@ Clause *Clause::Construct(capnp::Clause::Reader &reader, } // Create. -void Create::Save(capnp::Clause::Builder &builder) { - Clause::Save(builder); - auto create_builder = builder.initCreate(); - Create::Save(create_builder); +void Create::Save(capnp::Clause::Builder *builder, + std::vector *saved_uids) { + Clause::Save(builder, saved_uids); + auto create_builder = builder->initCreate(); + Create::Save(&create_builder, saved_uids); } -void Create::Save(capnp::Create::Builder &builder) { +void Create::Save(capnp::Create::Builder *builder, + std::vector *saved_uids) { ::capnp::List::Builder tree_builders = - builder.initPatterns(patterns_.size()); + builder->initPatterns(patterns_.size()); for (size_t i = 0; i < patterns_.size(); ++i) { auto tree_builder = tree_builders[i]; - patterns_[i]->Save(tree_builder); + patterns_[i]->Save(&tree_builder, saved_uids); } } -Create *Create::Construct(capnp::Create::Reader &reader, - AstTreeStorage &storage) { - std::vector patterns; - for (auto tree_reader : reader.getPatterns()) { - auto tree = storage.Load(tree_reader); - patterns.push_back(dynamic_cast(tree)); +void Create::Load(const capnp::Tree::Reader &base_reader, + AstTreeStorage *storage, std::vector *loaded_uids) { + Clause::Load(base_reader, storage, loaded_uids); + auto reader = base_reader.getClause().getCreate(); + for (const auto pattern_reader : reader.getPatterns()) { + auto tree = storage->Load(pattern_reader, loaded_uids); + patterns_.push_back(dynamic_cast(tree)); } - return storage.Create(patterns); +} + +Create *Create::Construct(const capnp::Create::Reader &reader, + AstTreeStorage *storage) { + return storage->Create(); } // CreateIndex. -void CreateIndex::Save(capnp::Clause::Builder &builder) { - Clause::Save(builder); - auto create_builder = builder.initCreateIndex(); - CreateIndex::Save(create_builder); +void CreateIndex::Save(capnp::Clause::Builder *builder, + std::vector *saved_uids) { + Clause::Save(builder, saved_uids); + auto create_builder = builder->initCreateIndex(); + CreateIndex::Save(&create_builder, saved_uids); } -void CreateIndex::Save(capnp::CreateIndex::Builder &builder) { - auto label_builder = builder.getLabel(); +void CreateIndex::Save(capnp::CreateIndex::Builder *builder, + std::vector *saved_uids) { + auto label_builder = builder->getLabel(); label_.Save(label_builder); - auto property_builder = builder.getProperty(); + auto property_builder = builder->getProperty(); property_.Save(property_builder); } -CreateIndex *CreateIndex::Construct(capnp::CreateIndex::Reader &reader, - AstTreeStorage &storage) { +CreateIndex *CreateIndex::Construct(const capnp::CreateIndex::Reader &reader, + AstTreeStorage *storage) { auto label_reader = reader.getLabel(); storage::Label label; label.Load(label_reader); auto property_reader = reader.getProperty(); storage::Property property; property.Load(property_reader); - return storage.Create(label, property); + return storage->Create(label, property); } // Delete. -void Delete::Save(capnp::Clause::Builder &builder) { - Clause::Save(builder); - auto del_builder = builder.initDelete(); - Delete::Save(del_builder); +void Delete::Save(capnp::Clause::Builder *builder, + std::vector *saved_uids) { + Clause::Save(builder, saved_uids); + auto del_builder = builder->initDelete(); + Delete::Save(&del_builder, saved_uids); } -void Delete::Save(capnp::Delete::Builder &builder) { +void Delete::Save(capnp::Delete::Builder *builder, + std::vector *saved_uids) { ::capnp::List::Builder tree_builders = - builder.initExpressions(expressions_.size()); + builder->initExpressions(expressions_.size()); for (size_t i = 0; i < expressions_.size(); ++i) { auto tree_builder = tree_builders[i]; - expressions_[i]->Save(tree_builder); + expressions_[i]->Save(&tree_builder, saved_uids); } - builder.setDetach(detach_); + builder->setDetach(detach_); } -Delete *Delete::Construct(capnp::Delete::Reader &reader, - AstTreeStorage &storage) { - std::vector expressions; - for (auto tree_reader : reader.getExpressions()) { - auto tree = storage.Load(tree_reader); - expressions.push_back(dynamic_cast(tree)); +void Delete::Load(const capnp::Tree::Reader &base_reader, + AstTreeStorage *storage, std::vector *loaded_uids) { + Clause::Load(base_reader, storage, loaded_uids); + auto reader = base_reader.getClause().getDelete(); + for (const auto tree_reader : reader.getExpressions()) { + auto tree = storage->Load(tree_reader, loaded_uids); + expressions_.push_back(dynamic_cast(tree)); } - auto detach = reader.getDetach(); - return storage.Create(detach, expressions); + detach_ = reader.getDetach(); +} + +Delete *Delete::Construct(const capnp::Delete::Reader &reader, + AstTreeStorage *storage) { + return storage->Create(); } // Match. -void Match::Save(capnp::Clause::Builder &clause_builder) { - Clause::Save(clause_builder); - auto builder = clause_builder.initMatch(); - Match::Save(builder); +void Match::Save(capnp::Clause::Builder *clause_builder, + std::vector *saved_uids) { + Clause::Save(clause_builder, saved_uids); + auto builder = clause_builder->initMatch(); + Match::Save(&builder, saved_uids); } -void Match::Save(capnp::Match::Builder &builder) { +void Match::Save(capnp::Match::Builder *builder, std::vector *saved_uids) { ::capnp::List::Builder tree_builders = - builder.initPatterns(patterns_.size()); + builder->initPatterns(patterns_.size()); for (size_t i = 0; i < patterns_.size(); ++i) { auto tree_builder = tree_builders[i]; - patterns_[i]->Save(tree_builder); + patterns_[i]->Save(&tree_builder, saved_uids); } if (where_) { - auto where_builder = builder.initWhere(); - where_->Save(where_builder); + auto where_builder = builder->initWhere(); + where_->Save(&where_builder, saved_uids); } - builder.setOptional(optional_); + builder->setOptional(optional_); } -Match *Match::Construct(capnp::Match::Reader &reader, AstTreeStorage &storage) { - std::vector patterns; - for (auto tree_reader : reader.getPatterns()) { - auto tree = storage.Load(tree_reader); - patterns.push_back(dynamic_cast(tree)); +void Match::Load(const capnp::Tree::Reader &base_reader, + AstTreeStorage *storage, std::vector *loaded_uids) { + Clause::Load(base_reader, storage, loaded_uids); + auto reader = base_reader.getClause().getMatch(); + for (const auto tree_reader : reader.getPatterns()) { + auto tree = storage->Load(tree_reader, loaded_uids); + patterns_.push_back(dynamic_cast(tree)); } - Where *where = nullptr; if (reader.hasWhere()) { - auto where_reader = reader.getWhere(); - where = dynamic_cast(storage.Load(where_reader)); + const auto where_reader = reader.getWhere(); + where_ = dynamic_cast(storage->Load(where_reader, loaded_uids)); } - auto optional = reader.getOptional(); - return storage.Create(optional, where, patterns); + optional_ = reader.getOptional(); +} + +Match *Match::Construct(const capnp::Match::Reader &reader, + AstTreeStorage *storage) { + return storage->Create(); } // Merge. -void Merge::Save(capnp::Clause::Builder &clause_builder) { - Clause::Save(clause_builder); - auto builder = clause_builder.initMerge(); - Merge::Save(builder); +void Merge::Save(capnp::Clause::Builder *clause_builder, + std::vector *saved_uids) { + Clause::Save(clause_builder, saved_uids); + auto builder = clause_builder->initMerge(); + Merge::Save(&builder, saved_uids); } -void Merge::Save(capnp::Merge::Builder &builder) { +void Merge::Save(capnp::Merge::Builder *builder, std::vector *saved_uids) { ::capnp::List::Builder match_builder = - builder.initOnMatch(on_match_.size()); + builder->initOnMatch(on_match_.size()); for (size_t i = 0; i < on_match_.size(); ++i) { auto tree_builder = match_builder[i]; - on_match_[i]->Save(tree_builder); + on_match_[i]->Save(&tree_builder, saved_uids); } ::capnp::List::Builder create_builder = - builder.initOnCreate(on_create_.size()); + builder->initOnCreate(on_create_.size()); for (size_t i = 0; i < on_create_.size(); ++i) { auto tree_builder = create_builder[i]; - on_create_[i]->Save(tree_builder); + on_create_[i]->Save(&tree_builder, saved_uids); } if (pattern_) { - auto pattern_builder = builder.getPattern(); - pattern_->Save(pattern_builder); + auto pattern_builder = builder->getPattern(); + pattern_->Save(&pattern_builder, saved_uids); } } -Merge *Merge::Construct(capnp::Merge::Reader &reader, AstTreeStorage &storage) { - std::vector on_match; - for (auto tree_reader : reader.getOnMatch()) { - auto tree = storage.Load(tree_reader); - on_match.push_back(dynamic_cast(tree)); +void Merge::Load(const capnp::Tree::Reader &base_reader, + AstTreeStorage *storage, std::vector *loaded_uids) { + Clause::Load(base_reader, storage, loaded_uids); + auto reader = base_reader.getClause().getMerge(); + for (const auto tree_reader : reader.getOnMatch()) { + auto tree = storage->Load(tree_reader, loaded_uids); + on_match_.push_back(dynamic_cast(tree)); } - std::vector on_create; - for (auto tree_reader : reader.getOnCreate()) { - auto tree = storage.Load(tree_reader); - on_create.push_back(dynamic_cast(tree)); + for (const auto tree_reader : reader.getOnCreate()) { + auto tree = storage->Load(tree_reader, loaded_uids); + on_create_.push_back(dynamic_cast(tree)); } - Pattern *pattern = nullptr; if (reader.hasPattern()) { - auto pattern_reader = reader.getPattern(); - pattern = dynamic_cast(storage.Load(pattern_reader)); + const auto pattern_reader = reader.getPattern(); + pattern_ = + dynamic_cast(storage->Load(pattern_reader, loaded_uids)); } - return storage.Create(pattern, on_match, on_create); +} +Merge *Merge::Construct(const capnp::Merge::Reader &reader, + AstTreeStorage *storage) { + return storage->Create(); } // RemoveLabels. -void RemoveLabels::Save(capnp::Clause::Builder &clause_builder) { - Clause::Save(clause_builder); - auto builder = clause_builder.initRemoveLabels(); - RemoveLabels::Save(builder); +void RemoveLabels::Save(capnp::Clause::Builder *clause_builder, + std::vector *saved_uids) { + Clause::Save(clause_builder, saved_uids); + auto builder = clause_builder->initRemoveLabels(); + RemoveLabels::Save(&builder, saved_uids); } -void RemoveLabels::Save(capnp::RemoveLabels::Builder &builder) { +void RemoveLabels::Save(capnp::RemoveLabels::Builder *builder, + std::vector *saved_uids) { if (identifier_) { - auto id_builder = builder.getIdentifier(); - identifier_->Save(id_builder); + auto id_builder = builder->getIdentifier(); + identifier_->Save(&id_builder, saved_uids); } ::capnp::List::Builder common_builders = - builder.initLabels(labels_.size()); + builder->initLabels(labels_.size()); for (size_t i = 0; i < labels_.size(); ++i) { auto common_builder = common_builders[i]; labels_[i].Save(common_builder); } } - -RemoveLabels *RemoveLabels::Construct(capnp::RemoveLabels::Reader &reader, - AstTreeStorage &storage) { - Identifier *identifier = nullptr; +void RemoveLabels::Load(const capnp::Tree::Reader &base_reader, + AstTreeStorage *storage, + std::vector *loaded_uids) { + Clause::Load(base_reader, storage, loaded_uids); + auto reader = base_reader.getClause().getRemoveLabels(); if (reader.hasIdentifier()) { - auto id_reader = reader.getIdentifier(); - identifier = dynamic_cast(storage.Load(id_reader)); + const auto id_reader = reader.getIdentifier(); + identifier_ = + dynamic_cast(storage->Load(id_reader, loaded_uids)); } - std::vector labels; for (auto label_reader : reader.getLabels()) { storage::Label label; label.Load(label_reader); - labels.push_back(label); + labels_.push_back(label); } - return storage.Create(identifier, labels); +} + +RemoveLabels *RemoveLabels::Construct(const capnp::RemoveLabels::Reader &reader, + AstTreeStorage *storage) { + return storage->Create(); } // RemoveProperty. -void RemoveProperty::Save(capnp::Clause::Builder &clause_builder) { - Clause::Save(clause_builder); - auto builder = clause_builder.initRemoveProperty(); - RemoveProperty::Save(builder); +void RemoveProperty::Save(capnp::Clause::Builder *clause_builder, + std::vector *saved_uids) { + Clause::Save(clause_builder, saved_uids); + auto builder = clause_builder->initRemoveProperty(); + RemoveProperty::Save(&builder, saved_uids); } -void RemoveProperty::Save(capnp::RemoveProperty::Builder &builder) { +void RemoveProperty::Save(capnp::RemoveProperty::Builder *builder, + std::vector *saved_uids) { if (property_lookup_) { - auto pl_builder = builder.getPropertyLookup(); - property_lookup_->Save(pl_builder); + auto pl_builder = builder->getPropertyLookup(); + property_lookup_->Save(&pl_builder, saved_uids); } } -RemoveProperty *RemoveProperty::Construct(capnp::RemoveProperty::Reader &reader, - AstTreeStorage &storage) { - PropertyLookup *property_lookup; +void RemoveProperty::Load(const capnp::Tree::Reader &base_reader, + AstTreeStorage *storage, + std::vector *loaded_uids) { + Clause::Load(base_reader, storage, loaded_uids); + auto reader = base_reader.getClause().getRemoveProperty(); if (reader.hasPropertyLookup()) { - auto pl_reader = reader.getPropertyLookup(); - property_lookup = dynamic_cast(storage.Load(pl_reader)); + const auto pl_reader = reader.getPropertyLookup(); + property_lookup_ = + dynamic_cast(storage->Load(pl_reader, loaded_uids)); } - return storage.Create(property_lookup); +} + +RemoveProperty *RemoveProperty::Construct( + const capnp::RemoveProperty::Reader &reader, AstTreeStorage *storage) { + return storage->Create(); } // Return. -void Return::Save(capnp::Clause::Builder &clause_builder) { - Clause::Save(clause_builder); - auto builder = clause_builder.initReturn(); - Return::Save(builder); +void Return::Save(capnp::Clause::Builder *clause_builder, + std::vector *saved_uids) { + Clause::Save(clause_builder, saved_uids); + auto builder = clause_builder->initReturn(); + Return::Save(&builder, saved_uids); } -void SaveReturnBody(capnp::ReturnBody::Builder &rb_builder, ReturnBody &body) { - rb_builder.setDistinct(body.distinct); - rb_builder.setAllIdentifiers(body.all_identifiers); +void SaveReturnBody(capnp::ReturnBody::Builder *rb_builder, ReturnBody &body, + std::vector *saved_uids) { + rb_builder->setDistinct(body.distinct); + rb_builder->setAllIdentifiers(body.all_identifiers); ::capnp::List::Builder named_expressions = - rb_builder.initNamedExpressions(body.named_expressions.size()); + rb_builder->initNamedExpressions(body.named_expressions.size()); for (size_t i = 0; i < body.named_expressions.size(); ++i) { auto tree_builder = named_expressions[i]; - body.named_expressions[i]->Save(tree_builder); + body.named_expressions[i]->Save(&tree_builder, saved_uids); } ::capnp::List::Builder order_by = - rb_builder.initOrderBy(body.order_by.size()); + rb_builder->initOrderBy(body.order_by.size()); for (size_t i = 0; i < body.order_by.size(); ++i) { auto pair_builder = order_by[i]; auto ordering = body.order_by[i].first == Ordering::ASC @@ -1322,31 +1549,32 @@ void SaveReturnBody(capnp::ReturnBody::Builder &rb_builder, ReturnBody &body) { : capnp::Ordering::DESC; pair_builder.setOrdering(ordering); auto tree_builder = pair_builder.getExpression(); - body.order_by[i].second->Save(tree_builder); + body.order_by[i].second->Save(&tree_builder, saved_uids); } if (body.skip) { - auto skip_builder = rb_builder.getSkip(); - body.skip->Save(skip_builder); + auto skip_builder = rb_builder->getSkip(); + body.skip->Save(&skip_builder, saved_uids); } if (body.limit) { - auto limit_builder = rb_builder.getLimit(); - body.limit->Save(limit_builder); + auto limit_builder = rb_builder->getLimit(); + body.limit->Save(&limit_builder, saved_uids); } } -void Return::Save(capnp::Return::Builder &builder) { - auto rb_builder = builder.initReturnBody(); - SaveReturnBody(rb_builder, body_); +void Return::Save(capnp::Return::Builder *builder, + std::vector *saved_uids) { + auto rb_builder = builder->initReturnBody(); + SaveReturnBody(&rb_builder, body_, saved_uids); } void LoadReturnBody(capnp::ReturnBody::Reader &rb_reader, ReturnBody &body, - AstTreeStorage &storage) { + AstTreeStorage *storage, std::vector *loaded_uids) { body.distinct = rb_reader.getDistinct(); body.all_identifiers = rb_reader.getAllIdentifiers(); - for (auto tree_reader : rb_reader.getNamedExpressions()) { - auto tree = storage.Load(tree_reader); + for (const auto tree_reader : rb_reader.getNamedExpressions()) { + auto tree = storage->Load(tree_reader, loaded_uids); body.named_expressions.push_back(dynamic_cast(tree)); } @@ -1354,302 +1582,390 @@ void LoadReturnBody(capnp::ReturnBody::Reader &rb_reader, ReturnBody &body, auto ordering = pair_reader.getOrdering() == capnp::Ordering::ASC ? Ordering::ASC : Ordering::DESC; - auto tree_reader = pair_reader.getExpression(); + const auto tree_reader = pair_reader.getExpression(); // TODO Check if expression is null? - auto tree = dynamic_cast(storage.Load(tree_reader)); + auto tree = + dynamic_cast(storage->Load(tree_reader, loaded_uids)); body.order_by.push_back(std::make_pair(ordering, tree)); } if (rb_reader.hasSkip()) { - auto skip_reader = rb_reader.getSkip(); - body.skip = dynamic_cast(storage.Load(skip_reader)); + const auto skip_reader = rb_reader.getSkip(); + body.skip = + dynamic_cast(storage->Load(skip_reader, loaded_uids)); } if (rb_reader.hasLimit()) { - auto limit_reader = rb_reader.getLimit(); - body.limit = dynamic_cast(storage.Load(limit_reader)); + const auto limit_reader = rb_reader.getLimit(); + body.limit = + dynamic_cast(storage->Load(limit_reader, loaded_uids)); } } -Return *Return::Construct(capnp::Return::Reader &reader, - AstTreeStorage &storage) { +void Return::Load(const capnp::Tree::Reader &base_reader, + AstTreeStorage *storage, std::vector *loaded_uids) { + Clause::Load(base_reader, storage, loaded_uids); + auto reader = base_reader.getClause().getReturn(); auto rb_reader = reader.getReturnBody(); - ReturnBody body; - LoadReturnBody(rb_reader, body, storage); - return storage.Create(body); + LoadReturnBody(rb_reader, body_, storage, loaded_uids); +} + +Return *Return::Construct(const capnp::Return::Reader &reader, + AstTreeStorage *storage) { + return storage->Create(); } // SetLabels. -void SetLabels::Save(capnp::Clause::Builder &clause_builder) { - Clause::Save(clause_builder); - auto builder = clause_builder.initSetLabels(); - SetLabels::Save(builder); +void SetLabels::Save(capnp::Clause::Builder *clause_builder, + std::vector *saved_uids) { + Clause::Save(clause_builder, saved_uids); + auto builder = clause_builder->initSetLabels(); + SetLabels::Save(&builder, saved_uids); } -void SetLabels::Save(capnp::SetLabels::Builder &builder) { +void SetLabels::Save(capnp::SetLabels::Builder *builder, + std::vector *saved_uids) { if (identifier_) { - auto id_builder = builder.getIdentifier(); - identifier_->Save(id_builder); + auto id_builder = builder->getIdentifier(); + identifier_->Save(&id_builder, saved_uids); } ::capnp::List::Builder common_builders = - builder.initLabels(labels_.size()); + builder->initLabels(labels_.size()); for (size_t i = 0; i < labels_.size(); ++i) { auto common_builder = common_builders[i]; labels_[i].Save(common_builder); } } -SetLabels *SetLabels::Construct(capnp::SetLabels::Reader &reader, - AstTreeStorage &storage) { - Identifier *identifier = nullptr; +void SetLabels::Load(const capnp::Tree::Reader &base_reader, + AstTreeStorage *storage, std::vector *loaded_uids) { + Clause::Load(base_reader, storage, loaded_uids); + auto reader = base_reader.getClause().getSetLabels(); if (reader.hasIdentifier()) { - auto id_reader = reader.getIdentifier(); - identifier = dynamic_cast(storage.Load(id_reader)); + const auto id_reader = reader.getIdentifier(); + identifier_ = + dynamic_cast(storage->Load(id_reader, loaded_uids)); } - std::vector labels; for (auto label_reader : reader.getLabels()) { storage::Label label; label.Load(label_reader); - labels.push_back(label); + labels_.push_back(label); } - return storage.Create(identifier, labels); +} + +SetLabels *SetLabels::Construct(const capnp::SetLabels::Reader &reader, + AstTreeStorage *storage) { + return storage->Create(); } // SetProperty. -void SetProperty::Save(capnp::Clause::Builder &clause_builder) { - Clause::Save(clause_builder); - auto builder = clause_builder.initSetProperty(); - SetProperty::Save(builder); +void SetProperty::Save(capnp::Clause::Builder *clause_builder, + std::vector *saved_uids) { + Clause::Save(clause_builder, saved_uids); + auto builder = clause_builder->initSetProperty(); + SetProperty::Save(&builder, saved_uids); } -void SetProperty::Save(capnp::SetProperty::Builder &builder) { +void SetProperty::Save(capnp::SetProperty::Builder *builder, + std::vector *saved_uids) { if (property_lookup_) { - auto pl_builder = builder.getPropertyLookup(); - property_lookup_->Save(pl_builder); + auto pl_builder = builder->getPropertyLookup(); + property_lookup_->Save(&pl_builder, saved_uids); } if (expression_) { - auto expr_builder = builder.getExpression(); - expression_->Save(expr_builder); + auto expr_builder = builder->getExpression(); + expression_->Save(&expr_builder, saved_uids); } } -SetProperty *SetProperty::Construct(capnp::SetProperty::Reader &reader, - AstTreeStorage &storage) { - PropertyLookup *property_lookup = nullptr; +void SetProperty::Load(const capnp::Tree::Reader &base_reader, + AstTreeStorage *storage, std::vector *loaded_uids) { + Clause::Load(base_reader, storage, loaded_uids); + auto reader = base_reader.getClause().getSetProperty(); if (reader.hasPropertyLookup()) { - auto pl_reader = reader.getPropertyLookup(); - property_lookup = dynamic_cast(storage.Load(pl_reader)); + const auto pl_reader = reader.getPropertyLookup(); + property_lookup_ = + dynamic_cast(storage->Load(pl_reader, loaded_uids)); } - Expression *expression; if (reader.hasExpression()) { - auto expr_reader = reader.getExpression(); - expression = dynamic_cast(storage.Load(expr_reader)); + const auto expr_reader = reader.getExpression(); + expression_ = + dynamic_cast(storage->Load(expr_reader, loaded_uids)); } - return storage.Create(property_lookup, expression); +} + +SetProperty *SetProperty::Construct(const capnp::SetProperty::Reader &reader, + AstTreeStorage *storage) { + return storage->Create(); } // SetProperties. -void SetProperties::Save(capnp::Clause::Builder &clause_builder) { - Clause::Save(clause_builder); - auto builder = clause_builder.initSetProperties(); - SetProperties::Save(builder); +void SetProperties::Save(capnp::Clause::Builder *clause_builder, + std::vector *saved_uids) { + Clause::Save(clause_builder, saved_uids); + auto builder = clause_builder->initSetProperties(); + SetProperties::Save(&builder, saved_uids); } -void SetProperties::Save(capnp::SetProperties::Builder &builder) { +void SetProperties::Save(capnp::SetProperties::Builder *builder, + std::vector *saved_uids) { if (identifier_) { - auto id_builder = builder.getIdentifier(); - identifier_->Save(id_builder); + auto id_builder = builder->getIdentifier(); + identifier_->Save(&id_builder, saved_uids); } if (expression_) { - auto expr_builder = builder.getExpression(); - expression_->Save(expr_builder); + auto expr_builder = builder->getExpression(); + expression_->Save(&expr_builder, saved_uids); } - builder.setUpdate(update_); + builder->setUpdate(update_); } -SetProperties *SetProperties::Construct(capnp::SetProperties::Reader &reader, - AstTreeStorage &storage) { - Identifier *identifier = nullptr; +void SetProperties::Load(const capnp::Tree::Reader &base_reader, + AstTreeStorage *storage, + std::vector *loaded_uids) { + Clause::Load(base_reader, storage, loaded_uids); + auto reader = base_reader.getClause().getSetProperties(); if (reader.hasIdentifier()) { - auto id_reader = reader.getIdentifier(); - identifier = dynamic_cast(storage.Load(id_reader)); + const auto id_reader = reader.getIdentifier(); + identifier_ = + dynamic_cast(storage->Load(id_reader, loaded_uids)); } - Expression *expression = nullptr; if (reader.hasExpression()) { - auto expr_reader = reader.getExpression(); - expression = dynamic_cast(storage.Load(expr_reader)); + const auto expr_reader = reader.getExpression(); + expression_ = + dynamic_cast(storage->Load(expr_reader, loaded_uids)); } - auto update = reader.getUpdate(); - return storage.Create(identifier, expression, update); + update_ = reader.getUpdate(); +} + +SetProperties *SetProperties::Construct( + const capnp::SetProperties::Reader &reader, AstTreeStorage *storage) { + return storage->Create(); } // Unwind. -void Unwind::Save(capnp::Clause::Builder &clause_builder) { - Clause::Save(clause_builder); - auto builder = clause_builder.initUnwind(); - Unwind::Save(builder); +void Unwind::Save(capnp::Clause::Builder *clause_builder, + std::vector *saved_uids) { + Clause::Save(clause_builder, saved_uids); + auto builder = clause_builder->initUnwind(); + Unwind::Save(&builder, saved_uids); } -void Unwind::Save(capnp::Unwind::Builder &builder) { +void Unwind::Save(capnp::Unwind::Builder *builder, + std::vector *saved_uids) { if (named_expression_) { - auto expr_builder = builder.getNamedExpression(); - named_expression_->Save(expr_builder); + auto expr_builder = builder->getNamedExpression(); + named_expression_->Save(&expr_builder, saved_uids); } } -Unwind *Unwind::Construct(capnp::Unwind::Reader &reader, - AstTreeStorage &storage) { - NamedExpression *expression = nullptr; +void Unwind::Load(const capnp::Tree::Reader &base_reader, + AstTreeStorage *storage, std::vector *loaded_uids) { + Clause::Load(base_reader, storage, loaded_uids); + auto reader = base_reader.getClause().getUnwind(); if (reader.hasNamedExpression()) { - auto expr_reader = reader.getNamedExpression(); - expression = dynamic_cast(storage.Load(expr_reader)); + const auto expr_reader = reader.getNamedExpression(); + named_expression_ = dynamic_cast( + storage->Load(expr_reader, loaded_uids)); } - return storage.Create(expression); +} + +Unwind *Unwind::Construct(const capnp::Unwind::Reader &reader, + AstTreeStorage *storage) { + return storage->Create(); } // With. -void With::Save(capnp::Clause::Builder &clause_builder) { - Clause::Save(clause_builder); - auto builder = clause_builder.initWith(); - With::Save(builder); +void With::Save(capnp::Clause::Builder *clause_builder, + std::vector *saved_uids) { + Clause::Save(clause_builder, saved_uids); + auto builder = clause_builder->initWith(); + With::Save(&builder, saved_uids); } -void With::Save(capnp::With::Builder &builder) { +void With::Save(capnp::With::Builder *builder, std::vector *saved_uids) { if (where_) { - auto where_builder = builder.getWhere(); - where_->Save(where_builder); + auto where_builder = builder->getWhere(); + where_->Save(&where_builder, saved_uids); } - auto rb_builder = builder.initReturnBody(); - SaveReturnBody(rb_builder, body_); + auto rb_builder = builder->initReturnBody(); + SaveReturnBody(&rb_builder, body_, saved_uids); } -With *With::Construct(capnp::With::Reader &reader, AstTreeStorage &storage) { - Where *where = nullptr; +void With::Load(const capnp::Tree::Reader &base_reader, AstTreeStorage *storage, + std::vector *loaded_uids) { + Clause::Load(base_reader, storage, loaded_uids); + auto reader = base_reader.getClause().getWith(); if (reader.hasWhere()) { - auto where_reader = reader.getWhere(); - where = dynamic_cast(storage.Load(where_reader)); + const auto where_reader = reader.getWhere(); + where_ = dynamic_cast(storage->Load(where_reader, loaded_uids)); } auto rb_reader = reader.getReturnBody(); - ReturnBody body; - LoadReturnBody(rb_reader, body, storage); - return storage.Create(body, where); + LoadReturnBody(rb_reader, body_, storage, loaded_uids); +} + +With *With::Construct(const capnp::With::Reader &reader, + AstTreeStorage *storage) { + return storage->Create(); } // CypherUnion -void CypherUnion::Save(capnp::Tree::Builder &tree_builder) { - Tree::Save(tree_builder); - auto builder = tree_builder.initCypherUnion(); - Save(builder); +void CypherUnion::Save(capnp::Tree::Builder *tree_builder, + std::vector *saved_uids) { + Tree::Save(tree_builder, saved_uids); + if (IsSaved(*saved_uids)) { + return; + } + auto builder = tree_builder->initCypherUnion(); + Save(&builder, saved_uids); + AddToSaved(saved_uids); } -void CypherUnion::Save(capnp::CypherUnion::Builder &builder) { +void CypherUnion::Save(capnp::CypherUnion::Builder *builder, + std::vector *saved_uids) { if (single_query_) { - auto sq_builder = builder.initSingleQuery(); - single_query_->Save(sq_builder); + auto sq_builder = builder->initSingleQuery(); + single_query_->Save(&sq_builder, saved_uids); } - builder.setDistinct(distinct_); + builder->setDistinct(distinct_); ::capnp::List::Builder symbol_builders = - builder.initUnionSymbols(union_symbols_.size()); + builder->initUnionSymbols(union_symbols_.size()); for (size_t i = 0; i < union_symbols_.size(); ++i) { auto symbol_builder = symbol_builders[i]; union_symbols_[i].Save(symbol_builder); } } -CypherUnion *CypherUnion::Construct(capnp::CypherUnion::Reader &reader, - AstTreeStorage &storage) { - SingleQuery *single_query = nullptr; +void CypherUnion::Load(const capnp::Tree::Reader &base_reader, + AstTreeStorage *storage, std::vector *loaded_uids) { + Tree::Load(base_reader, storage, loaded_uids); + auto reader = base_reader.getCypherUnion(); if (reader.hasSingleQuery()) { - auto sq_reader = reader.getSingleQuery(); - single_query = dynamic_cast(storage.Load(sq_reader)); + const auto sq_reader = reader.getSingleQuery(); + single_query_ = + dynamic_cast(storage->Load(sq_reader, loaded_uids)); } - auto distinct = reader.getDistinct(); - std::vector symbols; + distinct_ = reader.getDistinct(); for (auto symbol_reader : reader.getUnionSymbols()) { Symbol symbol; symbol.Load(symbol_reader); - symbols.push_back(symbol); + union_symbols_.push_back(symbol); } - return storage.Create(distinct, single_query, symbols); +} + +CypherUnion *CypherUnion::Construct(const capnp::CypherUnion::Reader &reader, + AstTreeStorage *storage) { + return storage->Create(); } // NamedExpression -void NamedExpression::Save(capnp::Tree::Builder &tree_builder) { - Tree::Save(tree_builder); - auto builder = tree_builder.initNamedExpression(); - Save(builder); +void NamedExpression::Save(capnp::Tree::Builder *tree_builder, + std::vector *saved_uids) { + Tree::Save(tree_builder, saved_uids); + if (IsSaved(*saved_uids)) { + return; + } + auto builder = tree_builder->initNamedExpression(); + Save(&builder, saved_uids); + AddToSaved(saved_uids); } -void NamedExpression::Save(capnp::NamedExpression::Builder &builder) { - builder.setName(name_); - builder.setTokenPosition(token_position_); +void NamedExpression::Save(capnp::NamedExpression::Builder *builder, + std::vector *saved_uids) { + builder->setName(name_); + builder->setTokenPosition(token_position_); if (expression_) { - auto expr_builder = builder.getExpression(); - expression_->Save(expr_builder); + auto expr_builder = builder->getExpression(); + expression_->Save(&expr_builder, saved_uids); + } +} + +void NamedExpression::Load(const capnp::Tree::Reader &base_reader, + AstTreeStorage *storage, + std::vector *loaded_uids) { + Tree::Load(base_reader, storage, loaded_uids); + auto reader = base_reader.getNamedExpression(); + name_ = reader.getName().cStr(); + token_position_ = reader.getTokenPosition(); + if (reader.hasExpression()) { + const auto expr_reader = reader.getExpression(); + expression_ = + dynamic_cast(storage->Load(expr_reader, loaded_uids)); } } NamedExpression *NamedExpression::Construct( - capnp::NamedExpression::Reader &reader, AstTreeStorage &storage) { - auto name = reader.getName().cStr(); - auto token_position = reader.getTokenPosition(); - Expression *expression = nullptr; - if (reader.hasExpression()) { - auto expr_reader = reader.getExpression(); - expression = dynamic_cast(storage.Load(expr_reader)); - } - return storage.Create(name, expression, token_position); + const capnp::NamedExpression::Reader &reader, AstTreeStorage *storage) { + return storage->Create(); } // Pattern -void Pattern::Save(capnp::Tree::Builder &tree_builder) { - Tree::Save(tree_builder); - auto builder = tree_builder.initPattern(); - Save(builder); +void Pattern::Save(capnp::Tree::Builder *tree_builder, + std::vector *saved_uids) { + Tree::Save(tree_builder, saved_uids); + if (IsSaved(*saved_uids)) { + return; + } + auto builder = tree_builder->initPattern(); + Save(&builder, saved_uids); + AddToSaved(saved_uids); } -void Pattern::Save(capnp::Pattern::Builder &builder) { +void Pattern::Save(capnp::Pattern::Builder *builder, + std::vector *saved_uids) { if (identifier_) { - auto id_builder = builder.getIdentifier(); - identifier_->Save(id_builder); + auto id_builder = builder->getIdentifier(); + identifier_->Save(&id_builder, saved_uids); } ::capnp::List::Builder tree_builders = - builder.initAtoms(atoms_.size()); + builder->initAtoms(atoms_.size()); for (size_t i = 0; i < atoms_.size(); ++i) { auto tree_builder = tree_builders[i]; - atoms_[i]->Save(tree_builder); + atoms_[i]->Save(&tree_builder, saved_uids); } } -Pattern *Pattern::Construct(capnp::Pattern::Reader &reader, - AstTreeStorage &storage) { - auto pattern = storage.Create(); +void Pattern::Load(const capnp::Tree::Reader &base_reader, + AstTreeStorage *storage, std::vector *loaded_uids) { + Tree::Load(base_reader, storage, loaded_uids); + auto reader = base_reader.getPattern(); if (reader.hasIdentifier()) { - auto id_reader = reader.getIdentifier(); - pattern->identifier_ = dynamic_cast(storage.Load(id_reader)); + const auto id_reader = reader.getIdentifier(); + identifier_ = + dynamic_cast(storage->Load(id_reader, loaded_uids)); } - for (auto tree_reader : reader.getAtoms()) { - auto tree = storage.Load(tree_reader); - pattern->atoms_.push_back(dynamic_cast(tree)); + for (const auto tree_reader : reader.getAtoms()) { + auto tree = storage->Load(tree_reader, loaded_uids); + atoms_.push_back(dynamic_cast(tree)); } - return pattern; +} + +Pattern *Pattern::Construct(const capnp::Pattern::Reader &reader, + AstTreeStorage *storage) { + return storage->Create(); } // PatternAtom. -void PatternAtom::Save(capnp::Tree::Builder &tree_builder) { - Tree::Save(tree_builder); - auto pattern_builder = tree_builder.initPatternAtom(); - Save(pattern_builder); +void PatternAtom::Save(capnp::Tree::Builder *tree_builder, + std::vector *saved_uids) { + Tree::Save(tree_builder, saved_uids); + if (IsSaved(*saved_uids)) { + return; + } + auto pattern_builder = tree_builder->initPatternAtom(); + Save(&pattern_builder, saved_uids); + AddToSaved(saved_uids); } -void PatternAtom::Save(capnp::PatternAtom::Builder &builder) { +void PatternAtom::Save(capnp::PatternAtom::Builder *builder, + std::vector *saved_uids) { if (identifier_) { - auto id_builder = builder.getIdentifier(); - identifier_->Save(id_builder); + auto id_builder = builder->getIdentifier(); + identifier_->Save(&id_builder, saved_uids); } } -PatternAtom *PatternAtom::Construct(capnp::PatternAtom::Reader &reader, - AstTreeStorage &storage) { +PatternAtom *PatternAtom::Construct(const capnp::PatternAtom::Reader &reader, + AstTreeStorage *storage) { switch (reader.which()) { case capnp::PatternAtom::EDGE_ATOM: { auto edge_reader = reader.getEdgeAtom(); @@ -1662,25 +1978,29 @@ PatternAtom *PatternAtom::Construct(capnp::PatternAtom::Reader &reader, } } -void PatternAtom::Load(capnp::Tree::Reader &reader, AstTreeStorage &storage) { - Tree::Load(reader, storage); +void PatternAtom::Load(const capnp::Tree::Reader &reader, + AstTreeStorage *storage, std::vector *loaded_uids) { + Tree::Load(reader, storage, loaded_uids); auto pa_reader = reader.getPatternAtom(); if (pa_reader.hasIdentifier()) { - auto id_reader = pa_reader.getIdentifier(); - identifier_ = dynamic_cast(storage.Load(id_reader)); + const auto id_reader = pa_reader.getIdentifier(); + identifier_ = + dynamic_cast(storage->Load(id_reader, loaded_uids)); } } // NodeAtom -void NodeAtom::Save(capnp::PatternAtom::Builder &pattern_builder) { - PatternAtom::Save(pattern_builder); - auto builder = pattern_builder.initNodeAtom(); - Save(builder); +void NodeAtom::Save(capnp::PatternAtom::Builder *pattern_builder, + std::vector *saved_uids) { + PatternAtom::Save(pattern_builder, saved_uids); + auto builder = pattern_builder->initNodeAtom(); + Save(&builder, saved_uids); } -void NodeAtom::Save(capnp::NodeAtom::Builder &builder) { +void NodeAtom::Save(capnp::NodeAtom::Builder *builder, + std::vector *saved_uids) { ::capnp::List::Builder map_builder = - builder.initProperties(properties_.size()); + builder->initProperties(properties_.size()); size_t i = 0; for (auto &entry : properties_) { auto entry_builder = map_builder[i]; @@ -1689,100 +2009,108 @@ void NodeAtom::Save(capnp::NodeAtom::Builder &builder) { auto storage_property_builder = key_builder.getSecond(); entry.first.second.Save(storage_property_builder); auto value_builder = entry_builder.getValue(); - if (entry.second) entry.second->Save(value_builder); + if (entry.second) entry.second->Save(&value_builder, saved_uids); ++i; } ::capnp::List::Builder common_builders = - builder.initLabels(labels_.size()); + builder->initLabels(labels_.size()); for (size_t i = 0; i < labels_.size(); ++i) { auto common_builder = common_builders[i]; labels_[i].Save(common_builder); } } -NodeAtom *NodeAtom::Construct(capnp::NodeAtom::Reader &reader, - AstTreeStorage &storage) { - auto *atom = storage.Create(); +void NodeAtom::Load(const capnp::Tree::Reader &base_reader, + AstTreeStorage *storage, std::vector *loaded_uids) { + PatternAtom::Load(base_reader, storage, loaded_uids); + auto reader = base_reader.getPatternAtom().getNodeAtom(); for (auto entry_reader : reader.getProperties()) { auto key_pair_reader = entry_reader.getKey(); auto key_first = key_pair_reader.getFirst().cStr(); auto storage_property_reader = key_pair_reader.getSecond(); storage::Property property; property.Load(storage_property_reader); - auto value_reader = entry_reader.getValue(); - auto value = storage.Load(value_reader); + const auto value_reader = entry_reader.getValue(); + auto value = storage->Load(value_reader, loaded_uids); auto key = std::make_pair(key_first, property); // TODO Maybe check if expression is nullptr? - atom->properties_.emplace(key, dynamic_cast(value)); + properties_.emplace(key, dynamic_cast(value)); } for (auto label_reader : reader.getLabels()) { storage::Label label; label.Load(label_reader); - atom->labels_.push_back(label); + labels_.push_back(label); } - return atom; +} + +NodeAtom *NodeAtom::Construct(const capnp::NodeAtom::Reader &reader, + AstTreeStorage *storage) { + return storage->Create(); } // EdgeAtom -void EdgeAtom::Save(capnp::PatternAtom::Builder &pattern_builder) { - PatternAtom::Save(pattern_builder); - auto builder = pattern_builder.initEdgeAtom(); - Save(builder); +void EdgeAtom::Save(capnp::PatternAtom::Builder *pattern_builder, + std::vector *saved_uids) { + PatternAtom::Save(pattern_builder, saved_uids); + auto builder = pattern_builder->initEdgeAtom(); + Save(&builder, saved_uids); } void SaveLambda(query::EdgeAtom::Lambda &lambda, - capnp::EdgeAtom::Lambda::Builder &builder) { + capnp::EdgeAtom::Lambda::Builder *builder, + std::vector *saved_uids) { if (lambda.inner_edge) { - auto ie_builder = builder.getInnerEdge(); - lambda.inner_edge->Save(ie_builder); + auto ie_builder = builder->getInnerEdge(); + lambda.inner_edge->Save(&ie_builder, saved_uids); } if (lambda.inner_node) { - auto in_builder = builder.getInnerNode(); - lambda.inner_node->Save(in_builder); + auto in_builder = builder->getInnerNode(); + lambda.inner_node->Save(&in_builder, saved_uids); } if (lambda.expression) { - auto expr_builder = builder.getExpression(); - lambda.expression->Save(expr_builder); + auto expr_builder = builder->getExpression(); + lambda.expression->Save(&expr_builder, saved_uids); } } -void EdgeAtom::Save(capnp::EdgeAtom::Builder &builder) { +void EdgeAtom::Save(capnp::EdgeAtom::Builder *builder, + std::vector *saved_uids) { switch (type_) { case Type::BREADTH_FIRST: - builder.setType(capnp::EdgeAtom::Type::BREADTH_FIRST); + builder->setType(capnp::EdgeAtom::Type::BREADTH_FIRST); break; case Type::DEPTH_FIRST: - builder.setType(capnp::EdgeAtom::Type::DEPTH_FIRST); + builder->setType(capnp::EdgeAtom::Type::DEPTH_FIRST); break; case Type::SINGLE: - builder.setType(capnp::EdgeAtom::Type::SINGLE); + builder->setType(capnp::EdgeAtom::Type::SINGLE); break; case Type::WEIGHTED_SHORTEST_PATH: - builder.setType(capnp::EdgeAtom::Type::WEIGHTED_SHORTEST_PATH); + builder->setType(capnp::EdgeAtom::Type::WEIGHTED_SHORTEST_PATH); break; } switch (direction_) { case Direction::BOTH: - builder.setDirection(capnp::EdgeAtom::Direction::BOTH); + builder->setDirection(capnp::EdgeAtom::Direction::BOTH); break; case Direction::IN: - builder.setDirection(capnp::EdgeAtom::Direction::IN); + builder->setDirection(capnp::EdgeAtom::Direction::IN); break; case Direction::OUT: - builder.setDirection(capnp::EdgeAtom::Direction::OUT); + builder->setDirection(capnp::EdgeAtom::Direction::OUT); break; } ::capnp::List::Builder common_builders = - builder.initEdgeTypes(edge_types_.size()); + builder->initEdgeTypes(edge_types_.size()); for (size_t i = 0; i < edge_types_.size(); ++i) { auto common_builder = common_builders[i]; edge_types_[i].Save(common_builder); } ::capnp::List::Builder map_builder = - builder.initProperties(properties_.size()); + builder->initProperties(properties_.size()); size_t i = 0; for (auto &entry : properties_) { auto entry_builder = map_builder[i]; @@ -1791,93 +2119,100 @@ void EdgeAtom::Save(capnp::EdgeAtom::Builder &builder) { auto storage_property_builder = key_builder.getSecond(); entry.first.second.Save(storage_property_builder); auto value_builder = entry_builder.getValue(); - if (entry.second) entry.second->Save(value_builder); + if (entry.second) entry.second->Save(&value_builder, saved_uids); ++i; } if (lower_bound_) { - auto lb_builder = builder.getLowerBound(); - lower_bound_->Save(lb_builder); + auto lb_builder = builder->getLowerBound(); + lower_bound_->Save(&lb_builder, saved_uids); } if (upper_bound_) { - auto ub_builder = builder.getUpperBound(); - upper_bound_->Save(ub_builder); + auto ub_builder = builder->getUpperBound(); + upper_bound_->Save(&ub_builder, saved_uids); } - auto filter_builder = builder.initFilterLambda(); - SaveLambda(filter_lambda_, filter_builder); - auto weight_builder = builder.initWeightLambda(); - SaveLambda(weight_lambda_, weight_builder); + auto filter_builder = builder->initFilterLambda(); + SaveLambda(filter_lambda_, &filter_builder, saved_uids); + auto weight_builder = builder->initWeightLambda(); + SaveLambda(weight_lambda_, &weight_builder, saved_uids); if (total_weight_) { - auto total_weight_builder = builder.getTotalWeight(); - total_weight_->Save(total_weight_builder); + auto total_weight_builder = builder->getTotalWeight(); + total_weight_->Save(&total_weight_builder, saved_uids); } } void LoadLambda(capnp::EdgeAtom::Lambda::Reader &reader, - query::EdgeAtom::Lambda &lambda, AstTreeStorage &storage) { + query::EdgeAtom::Lambda &lambda, AstTreeStorage *storage, + std::vector *loaded_uids) { if (reader.hasInnerEdge()) { - auto ie_reader = reader.getInnerEdge(); - lambda.inner_edge = dynamic_cast(storage.Load(ie_reader)); + const auto ie_reader = reader.getInnerEdge(); + lambda.inner_edge = + dynamic_cast(storage->Load(ie_reader, loaded_uids)); } if (reader.hasInnerNode()) { - auto in_reader = reader.getInnerNode(); - lambda.inner_node = dynamic_cast(storage.Load(in_reader)); + const auto in_reader = reader.getInnerNode(); + lambda.inner_node = + dynamic_cast(storage->Load(in_reader, loaded_uids)); } if (reader.hasExpression()) { - auto expr_reader = reader.getExpression(); - lambda.expression = dynamic_cast(storage.Load(expr_reader)); + const auto expr_reader = reader.getExpression(); + lambda.expression = + dynamic_cast(storage->Load(expr_reader, loaded_uids)); } } -EdgeAtom *EdgeAtom::Construct(capnp::EdgeAtom::Reader &reader, - AstTreeStorage &storage) { - auto *atom = storage.Create(); - +void EdgeAtom::Load(const capnp::Tree::Reader &base_reader, + AstTreeStorage *storage, std::vector *loaded_uids) { + PatternAtom::Load(base_reader, storage, loaded_uids); + auto reader = base_reader.getPatternAtom().getEdgeAtom(); switch (reader.getType()) { case capnp::EdgeAtom::Type::BREADTH_FIRST: - atom->type_ = Type::BREADTH_FIRST; + type_ = Type::BREADTH_FIRST; break; case capnp::EdgeAtom::Type::DEPTH_FIRST: - atom->type_ = Type::DEPTH_FIRST; + type_ = Type::DEPTH_FIRST; break; case capnp::EdgeAtom::Type::SINGLE: - atom->type_ = Type::SINGLE; + type_ = Type::SINGLE; break; case capnp::EdgeAtom::Type::WEIGHTED_SHORTEST_PATH: - atom->type_ = Type::WEIGHTED_SHORTEST_PATH; + type_ = Type::WEIGHTED_SHORTEST_PATH; break; } switch (reader.getDirection()) { case capnp::EdgeAtom::Direction::BOTH: - atom->direction_ = Direction::BOTH; + direction_ = Direction::BOTH; break; case capnp::EdgeAtom::Direction::IN: - atom->direction_ = Direction::IN; + direction_ = Direction::IN; break; case capnp::EdgeAtom::Direction::OUT: - atom->direction_ = Direction::OUT; + direction_ = Direction::OUT; break; } if (reader.hasTotalWeight()) { - auto id_reader = reader.getTotalWeight(); - atom->total_weight_ = dynamic_cast(storage.Load(id_reader)); + const auto id_reader = reader.getTotalWeight(); + total_weight_ = + dynamic_cast(storage->Load(id_reader, loaded_uids)); } if (reader.hasLowerBound()) { - auto lb_reader = reader.getLowerBound(); - atom->lower_bound_ = dynamic_cast(storage.Load(lb_reader)); + const auto lb_reader = reader.getLowerBound(); + lower_bound_ = + dynamic_cast(storage->Load(lb_reader, loaded_uids)); } if (reader.hasUpperBound()) { - auto ub_reader = reader.getUpperBound(); - atom->upper_bound_ = dynamic_cast(storage.Load(ub_reader)); + const auto ub_reader = reader.getUpperBound(); + upper_bound_ = + dynamic_cast(storage->Load(ub_reader, loaded_uids)); } auto filter_reader = reader.getFilterLambda(); - LoadLambda(filter_reader, atom->filter_lambda_, storage); + LoadLambda(filter_reader, filter_lambda_, storage, loaded_uids); auto weight_reader = reader.getWeightLambda(); - LoadLambda(weight_reader, atom->weight_lambda_, storage); + LoadLambda(weight_reader, weight_lambda_, storage, loaded_uids); for (auto entry_reader : reader.getProperties()) { auto key_pair_reader = entry_reader.getKey(); @@ -1885,78 +2220,100 @@ EdgeAtom *EdgeAtom::Construct(capnp::EdgeAtom::Reader &reader, auto storage_property_reader = key_pair_reader.getSecond(); storage::Property property; property.Load(storage_property_reader); - auto value_reader = entry_reader.getValue(); - auto value = storage.Load(value_reader); + const auto value_reader = entry_reader.getValue(); + auto value = storage->Load(value_reader, loaded_uids); auto key = std::make_pair(key_first, property); // TODO Check if expression is null? - atom->properties_.emplace(key, dynamic_cast(value)); + properties_.emplace(key, dynamic_cast(value)); } for (auto edge_type_reader : reader.getEdgeTypes()) { storage::EdgeType edge_type; edge_type.Load(edge_type_reader); - atom->edge_types_.push_back(edge_type); + edge_types_.push_back(edge_type); } - return atom; +} + +EdgeAtom *EdgeAtom::Construct(const capnp::EdgeAtom::Reader &reader, + AstTreeStorage *storage) { + return storage->Create(); } // Query -void Query::Save(capnp::Tree::Builder &tree_builder) { - Tree::Save(tree_builder); - auto builder = tree_builder.initQuery(); - Save(builder); +void Query::Save(capnp::Tree::Builder *tree_builder, + std::vector *saved_uids) { + Tree::Save(tree_builder, saved_uids); + if (IsSaved(*saved_uids)) { + return; + } + auto builder = tree_builder->initQuery(); + Save(&builder, saved_uids); + AddToSaved(saved_uids); } -void Query::Save(capnp::Query::Builder &builder) { +void Query::Save(capnp::Query::Builder *builder, std::vector *saved_uids) { if (single_query_) { - auto sq_builder = builder.initSingleQuery(); - single_query_->Save(sq_builder); + auto sq_builder = builder->initSingleQuery(); + single_query_->Save(&sq_builder, saved_uids); } ::capnp::List::Builder tree_builders = - builder.initCypherUnions(cypher_unions_.size()); + builder->initCypherUnions(cypher_unions_.size()); for (size_t i = 0; i < cypher_unions_.size(); ++i) { auto tree_builder = tree_builders[i]; - cypher_unions_[i]->Save(tree_builder); + cypher_unions_[i]->Save(&tree_builder, saved_uids); } } -Query *Query::Construct(capnp::Query::Reader &reader, AstTreeStorage &storage) { - auto query = storage.query(); - if (reader.hasSingleQuery()) { - auto sq_reader = reader.getSingleQuery(); - query->single_query_ = dynamic_cast(storage.Load(sq_reader)); +void Query::Load(const capnp::Tree::Reader &reader, AstTreeStorage *storage, + std::vector *loaded_uids) { + Tree::Load(reader, storage, loaded_uids); + auto query_reader = reader.getQuery(); + if (query_reader.hasSingleQuery()) { + const auto sq_reader = query_reader.getSingleQuery(); + single_query_ = + dynamic_cast(storage->Load(sq_reader, loaded_uids)); } - for (auto tree_reader : reader.getCypherUnions()) { - auto tree = storage.Load(tree_reader); - query->cypher_unions_.push_back(dynamic_cast(tree)); + for (const auto tree_reader : query_reader.getCypherUnions()) { + auto tree = storage->Load(tree_reader, loaded_uids); + cypher_unions_.push_back(dynamic_cast(tree)); } - return query; } // SingleQuery -void SingleQuery::Save(capnp::Tree::Builder &tree_builder) { - Tree::Save(tree_builder); - auto builder = tree_builder.initSingleQuery(); - Save(builder); +void SingleQuery::Save(capnp::Tree::Builder *tree_builder, + std::vector *saved_uids) { + Tree::Save(tree_builder, saved_uids); + if (IsSaved(*saved_uids)) { + return; + } + auto builder = tree_builder->initSingleQuery(); + Save(&builder, saved_uids); + AddToSaved(saved_uids); } -void SingleQuery::Save(capnp::SingleQuery::Builder &builder) { +void SingleQuery::Save(capnp::SingleQuery::Builder *builder, + std::vector *saved_uids) { ::capnp::List::Builder tree_builders = - builder.initClauses(clauses_.size()); + builder->initClauses(clauses_.size()); for (size_t i = 0; i < clauses_.size(); ++i) { auto tree_builder = tree_builders[i]; - clauses_[i]->Save(tree_builder); + clauses_[i]->Save(&tree_builder, saved_uids); } } -SingleQuery *SingleQuery::Construct(capnp::SingleQuery::Reader &reader, - AstTreeStorage &storage) { - auto query = storage.Create(); - for (auto tree_reader : reader.getClauses()) { - auto tree = storage.Load(tree_reader); - query->clauses_.push_back(dynamic_cast(tree)); +void SingleQuery::Load(const capnp::Tree::Reader &base_reader, + AstTreeStorage *storage, std::vector *loaded_uids) { + Tree::Load(base_reader, storage, loaded_uids); + auto reader = base_reader.getSingleQuery(); + for (const auto tree_reader : reader.getClauses()) { + auto tree = storage->Load(tree_reader, loaded_uids); + clauses_.push_back(dynamic_cast(tree)); } - return query; +} + +SingleQuery *SingleQuery::Construct(const capnp::SingleQuery::Reader &reader, + AstTreeStorage *storage) { + return storage->Create(); } } // namespace query diff --git a/src/query/frontend/ast/ast.hpp b/src/query/frontend/ast/ast.hpp index 9e9929d71..122dc50dc 100644 --- a/src/query/frontend/ast/ast.hpp +++ b/src/query/frontend/ast/ast.hpp @@ -103,7 +103,7 @@ class AstTreeStorage { Load(ar, *query()); } - Tree *Load(capnp::Tree::Reader &tree); + Tree *Load(const capnp::Tree::Reader &tree, std::vector *loaded_uids); private: int next_uid_ = 0; @@ -169,12 +169,16 @@ class Tree : public ::utils::Visitable, int uid() const { return uid_; } virtual Tree *Clone(AstTreeStorage &storage) const = 0; - virtual void Save(capnp::Tree::Builder &builder); + virtual void Save(capnp::Tree::Builder *builder, + std::vector *saved_uids); protected: explicit Tree(int uid) : uid_(uid) {} - virtual void Load(capnp::Tree::Reader &reader, AstTreeStorage &storage); + virtual void Load(const capnp::Tree::Reader &reader, AstTreeStorage *storage, + std::vector *loaded_uids); + bool IsSaved(const std::vector &saved_uids); + void AddToSaved(std::vector *saved_uids); private: int uid_; @@ -194,15 +198,16 @@ class Expression : public Tree { public: Expression *Clone(AstTreeStorage &storage) const override = 0; - static Expression *Construct(capnp::Expression::Reader &reader, - AstTreeStorage &storage); + static Expression *Construct(const capnp::Expression::Reader &reader, + AstTreeStorage *storage); - void Save(capnp::Tree::Builder &builder) override; + void Save(capnp::Tree::Builder *builder, + std::vector *saved_uids) override; protected: explicit Expression(int uid) : Tree(uid) {} - virtual void Save(capnp::Expression::Builder &) {} + virtual void Save(capnp::Expression::Builder *, std::vector *) {} private: friend class boost::serialization::access; @@ -225,10 +230,11 @@ class Where : public Tree { return storage.Create(expression_->Clone(storage)); } - static Where *Construct(capnp::Where::Reader &reader, - AstTreeStorage &storage); + static Where *Construct(const capnp::Where::Reader &reader, + AstTreeStorage *storage); - void Save(capnp::Tree::Builder &builder) override; + void Save(capnp::Tree::Builder *builder, + std::vector *saved_uids) override; Expression *expression_ = nullptr; @@ -236,7 +242,9 @@ class Where : public Tree { explicit Where(int uid) : Tree(uid) {} Where(int uid, Expression *expression) : Tree(uid), expression_(expression) {} - virtual void Save(capnp::Where::Builder &); + virtual void Save(capnp::Where::Builder *, std::vector *saved_uids); + void Load(const capnp::Tree::Reader &tree_reader, AstTreeStorage *storage, + std::vector *loaded_uids) override; private: friend class boost::serialization::access; @@ -268,18 +276,21 @@ class BinaryOperator : public Expression { Expression *expression2_ = nullptr; BinaryOperator *Clone(AstTreeStorage &storage) const override = 0; - static BinaryOperator *Construct(capnp::BinaryOperator::Reader &reader, - AstTreeStorage &storage); + static BinaryOperator *Construct(const capnp::BinaryOperator::Reader &reader, + AstTreeStorage *storage); protected: explicit BinaryOperator(int uid) : Expression(uid) {} BinaryOperator(int uid, Expression *expression1, Expression *expression2) : Expression(uid), expression1_(expression1), expression2_(expression2) {} - void Save(capnp::Expression::Builder &builder) override; + void Save(capnp::Expression::Builder *builder, + std::vector *saved_uids) override; using Expression::Save; - virtual void Save(capnp::BinaryOperator::Builder &builder); - void Load(capnp::Tree::Reader &reader, AstTreeStorage &storage) override; + virtual void Save(capnp::BinaryOperator::Builder *builder, + std::vector *saved_uids); + void Load(const capnp::Tree::Reader &reader, AstTreeStorage *storage, + std::vector *loaded_uids) override; private: friend class boost::serialization::access; @@ -308,18 +319,21 @@ class UnaryOperator : public Expression { Expression *expression_ = nullptr; UnaryOperator *Clone(AstTreeStorage &storage) const override = 0; - static UnaryOperator *Construct(capnp::UnaryOperator::Reader &reader, - AstTreeStorage &storage); + static UnaryOperator *Construct(const capnp::UnaryOperator::Reader &reader, + AstTreeStorage *storage); protected: explicit UnaryOperator(int uid) : Expression(uid) {} UnaryOperator(int uid, Expression *expression) : Expression(uid), expression_(expression) {} - void Save(capnp::Expression::Builder &) override; + void Save(capnp::Expression::Builder *, + std::vector *saved_uids) override; using Expression::Save; - virtual void Save(capnp::UnaryOperator::Builder &builder); - void Load(capnp::Tree::Reader &reader, AstTreeStorage &storage) override; + virtual void Save(capnp::UnaryOperator::Builder *builder, + std::vector *saved_uids); + void Load(const capnp::Tree::Reader &reader, AstTreeStorage *storage, + std::vector *loaded_uids) override; private: friend class boost::serialization::access; @@ -352,12 +366,13 @@ class OrOperator : public BinaryOperator { } CLONE_BINARY_EXPRESSION; - static OrOperator *Construct(capnp::OrOperator::Reader &reader, - AstTreeStorage &storage); + static OrOperator *Construct(const capnp::OrOperator::Reader &reader, + AstTreeStorage *storage); protected: using BinaryOperator::BinaryOperator; - void Save(capnp::BinaryOperator::Builder &builder) override; + void Save(capnp::BinaryOperator::Builder *builder, + std::vector *saved_uids) override; private: friend class boost::serialization::access; @@ -380,12 +395,13 @@ class XorOperator : public BinaryOperator { return visitor.PostVisit(*this); } CLONE_BINARY_EXPRESSION; - static XorOperator *Construct(capnp::XorOperator::Reader &reader, - AstTreeStorage &storage); + static XorOperator *Construct(const capnp::XorOperator::Reader &reader, + AstTreeStorage *storage); protected: using BinaryOperator::BinaryOperator; - void Save(capnp::BinaryOperator::Builder &builder) override; + void Save(capnp::BinaryOperator::Builder *builder, + std::vector *saved_uids) override; private: friend class boost::serialization::access; @@ -408,12 +424,13 @@ class AndOperator : public BinaryOperator { return visitor.PostVisit(*this); } CLONE_BINARY_EXPRESSION; - static AndOperator *Construct(capnp::AndOperator::Reader &reader, - AstTreeStorage &storage); + static AndOperator *Construct(const capnp::AndOperator::Reader &reader, + AstTreeStorage *storage); protected: using BinaryOperator::BinaryOperator; - void Save(capnp::BinaryOperator::Builder &builder) override; + void Save(capnp::BinaryOperator::Builder *builder, + std::vector *saved_uids) override; private: friend class boost::serialization::access; @@ -436,12 +453,13 @@ class AdditionOperator : public BinaryOperator { return visitor.PostVisit(*this); } CLONE_BINARY_EXPRESSION; - static AdditionOperator *Construct(capnp::AdditionOperator::Reader &reader, - AstTreeStorage &storage); + static AdditionOperator *Construct( + const capnp::AdditionOperator::Reader &reader, AstTreeStorage *storage); protected: using BinaryOperator::BinaryOperator; - void Save(capnp::BinaryOperator::Builder &builder) override; + void Save(capnp::BinaryOperator::Builder *builder, + std::vector *saved_uids) override; private: friend class boost::serialization::access; @@ -465,11 +483,12 @@ class SubtractionOperator : public BinaryOperator { } CLONE_BINARY_EXPRESSION; static SubtractionOperator *Construct( - capnp::SubtractionOperator::Reader &reader, AstTreeStorage &storage); + capnp::SubtractionOperator::Reader &reader, AstTreeStorage *storage); protected: using BinaryOperator::BinaryOperator; - void Save(capnp::BinaryOperator::Builder &builder) override; + void Save(capnp::BinaryOperator::Builder *builder, + std::vector *saved_uids) override; private: friend class boost::serialization::access; @@ -493,11 +512,12 @@ class MultiplicationOperator : public BinaryOperator { } CLONE_BINARY_EXPRESSION; static MultiplicationOperator *Construct( - capnp::MultiplicationOperator::Reader &reader, AstTreeStorage &storage); + capnp::MultiplicationOperator::Reader &reader, AstTreeStorage *storage); protected: using BinaryOperator::BinaryOperator; - void Save(capnp::BinaryOperator::Builder &builder) override; + void Save(capnp::BinaryOperator::Builder *builder, + std::vector *saved_uids) override; private: friend class boost::serialization::access; @@ -519,12 +539,13 @@ class DivisionOperator : public BinaryOperator { return visitor.PostVisit(*this); } CLONE_BINARY_EXPRESSION; - static DivisionOperator *Construct(capnp::DivisionOperator::Reader &reader, - AstTreeStorage &storage); + static DivisionOperator *Construct( + const capnp::DivisionOperator::Reader &reader, AstTreeStorage *storage); protected: using BinaryOperator::BinaryOperator; - void Save(capnp::BinaryOperator::Builder &builder) override; + void Save(capnp::BinaryOperator::Builder *builder, + std::vector *saved_uids) override; private: friend class boost::serialization::access; @@ -547,12 +568,13 @@ class ModOperator : public BinaryOperator { return visitor.PostVisit(*this); } CLONE_BINARY_EXPRESSION; - static ModOperator *Construct(capnp::ModOperator::Reader &reader, - AstTreeStorage &storage); + static ModOperator *Construct(const capnp::ModOperator::Reader &reader, + AstTreeStorage *storage); protected: using BinaryOperator::BinaryOperator; - void Save(capnp::BinaryOperator::Builder &builder) override; + void Save(capnp::BinaryOperator::Builder *builder, + std::vector *saved_uids) override; private: friend class boost::serialization::access; @@ -575,12 +597,13 @@ class NotEqualOperator : public BinaryOperator { return visitor.PostVisit(*this); } CLONE_BINARY_EXPRESSION; - static NotEqualOperator *Construct(capnp::NotEqualOperator::Reader &reader, - AstTreeStorage &storage); + static NotEqualOperator *Construct( + const capnp::NotEqualOperator::Reader &reader, AstTreeStorage *storage); protected: using BinaryOperator::BinaryOperator; - void Save(capnp::BinaryOperator::Builder &builder) override; + void Save(capnp::BinaryOperator::Builder *builder, + std::vector *saved_uids) override; private: friend class boost::serialization::access; @@ -603,12 +626,13 @@ class EqualOperator : public BinaryOperator { return visitor.PostVisit(*this); } CLONE_BINARY_EXPRESSION; - static EqualOperator *Construct(capnp::EqualOperator::Reader &reader, - AstTreeStorage &storage); + static EqualOperator *Construct(const capnp::EqualOperator::Reader &reader, + AstTreeStorage *storage); protected: using BinaryOperator::BinaryOperator; - void Save(capnp::BinaryOperator::Builder &builder) override; + void Save(capnp::BinaryOperator::Builder *builder, + std::vector *saved_uids) override; private: friend class boost::serialization::access; @@ -631,12 +655,13 @@ class LessOperator : public BinaryOperator { return visitor.PostVisit(*this); } CLONE_BINARY_EXPRESSION; - static LessOperator *Construct(capnp::LessOperator::Reader &reader, - AstTreeStorage &storage); + static LessOperator *Construct(const capnp::LessOperator::Reader &reader, + AstTreeStorage *storage); protected: using BinaryOperator::BinaryOperator; - void Save(capnp::BinaryOperator::Builder &builder) override; + void Save(capnp::BinaryOperator::Builder *builder, + std::vector *saved_uids) override; private: friend class boost::serialization::access; @@ -659,12 +684,13 @@ class GreaterOperator : public BinaryOperator { return visitor.PostVisit(*this); } CLONE_BINARY_EXPRESSION; - static GreaterOperator *Construct(capnp::GreaterOperator::Reader &reader, - AstTreeStorage &storage); + static GreaterOperator *Construct( + const capnp::GreaterOperator::Reader &reader, AstTreeStorage *storage); protected: using BinaryOperator::BinaryOperator; - void Save(capnp::BinaryOperator::Builder &builder) override; + void Save(capnp::BinaryOperator::Builder *builder, + std::vector *saved_uids) override; private: friend class boost::serialization::access; @@ -687,12 +713,13 @@ class LessEqualOperator : public BinaryOperator { return visitor.PostVisit(*this); } CLONE_BINARY_EXPRESSION; - static LessEqualOperator *Construct(capnp::LessEqualOperator::Reader &reader, - AstTreeStorage &storage); + static LessEqualOperator *Construct( + const capnp::LessEqualOperator::Reader &reader, AstTreeStorage *storage); protected: using BinaryOperator::BinaryOperator; - void Save(capnp::BinaryOperator::Builder &builder) override; + void Save(capnp::BinaryOperator::Builder *builder, + std::vector *saved_uids) override; private: friend class boost::serialization::access; @@ -716,11 +743,13 @@ class GreaterEqualOperator : public BinaryOperator { } CLONE_BINARY_EXPRESSION; static GreaterEqualOperator *Construct( - capnp::GreaterEqualOperator::Reader &reader, AstTreeStorage &storage); + const capnp::GreaterEqualOperator::Reader &reader, + AstTreeStorage *storage); protected: using BinaryOperator::BinaryOperator; - void Save(capnp::BinaryOperator::Builder &builder) override; + void Save(capnp::BinaryOperator::Builder *builder, + std::vector *saved_uids) override; private: friend class boost::serialization::access; @@ -743,12 +772,13 @@ class InListOperator : public BinaryOperator { return visitor.PostVisit(*this); } CLONE_BINARY_EXPRESSION; - static InListOperator *Construct(capnp::InListOperator::Reader &reader, - AstTreeStorage &storage); + static InListOperator *Construct(const capnp::InListOperator::Reader &reader, + AstTreeStorage *storage); protected: using BinaryOperator::BinaryOperator; - void Save(capnp::BinaryOperator::Builder &builder) override; + void Save(capnp::BinaryOperator::Builder *builder, + std::vector *saved_uids) override; private: friend class boost::serialization::access; @@ -772,11 +802,12 @@ class ListMapIndexingOperator : public BinaryOperator { } CLONE_BINARY_EXPRESSION; static ListMapIndexingOperator *Construct( - capnp::ListMapIndexingOperator::Reader &reader, AstTreeStorage &storage); + capnp::ListMapIndexingOperator::Reader &reader, AstTreeStorage *storage); protected: using BinaryOperator::BinaryOperator; - void Save(capnp::BinaryOperator::Builder &builder) override; + void Save(capnp::BinaryOperator::Builder *builder, + std::vector *saved_uids) override; private: friend class boost::serialization::access; @@ -812,7 +843,8 @@ class ListSlicingOperator : public Expression { } static ListSlicingOperator *Construct( - capnp::ListSlicingOperator::Reader &reader, AstTreeStorage &storage); + const capnp::ListSlicingOperator::Reader &reader, + AstTreeStorage *storage); Expression *list_ = nullptr; Expression *lower_bound_ = nullptr; @@ -826,9 +858,13 @@ class ListSlicingOperator : public Expression { lower_bound_(lower_bound), upper_bound_(upper_bound) {} - void Save(capnp::Expression::Builder &builder) override; + void Save(capnp::Expression::Builder *builder, + std::vector *saved_uids) override; using Expression::Save; - virtual void Save(capnp::ListSlicingOperator::Builder &builder); + virtual void Save(capnp::ListSlicingOperator::Builder *builder, + std::vector *saved_uids); + void Load(const capnp::Tree::Reader &reader, AstTreeStorage *storage, + std::vector *loaded_uids) override; private: friend class boost::serialization::access; @@ -876,8 +912,8 @@ class IfOperator : public Expression { else_expression_->Clone(storage)); } - static IfOperator *Construct(capnp::IfOperator::Reader &reader, - AstTreeStorage &storage); + static IfOperator *Construct(const capnp::IfOperator::Reader &reader, + AstTreeStorage *storage); // None of the expressions should be nullptrs. If there is no else_expression // you probably want to make it NULL PrimitiveLiteral. Expression *condition_; @@ -892,9 +928,13 @@ class IfOperator : public Expression { then_expression_(then_expression), else_expression_(else_expression) {} - void Save(capnp::Expression::Builder &builder) override; + void Save(capnp::Expression::Builder *builder, + std::vector *saved_uids) override; using Expression::Save; - virtual void Save(capnp::IfOperator::Builder &builder); + virtual void Save(capnp::IfOperator::Builder *builder, + std::vector *saved_uids); + void Load(const capnp::Tree::Reader &reader, AstTreeStorage *storage, + std::vector *loaded_uids) override; private: friend class boost::serialization::access; @@ -935,12 +975,13 @@ class NotOperator : public UnaryOperator { return visitor.PostVisit(*this); } CLONE_UNARY_EXPRESSION; - static NotOperator *Construct(capnp::NotOperator::Reader &reader, - AstTreeStorage &storage); + static NotOperator *Construct(const capnp::NotOperator::Reader &reader, + AstTreeStorage *storage); protected: using UnaryOperator::UnaryOperator; - void Save(capnp::UnaryOperator::Builder &builder) override; + void Save(capnp::UnaryOperator::Builder *builder, + std::vector *saved_uids) override; private: friend class boost::serialization::access; @@ -963,12 +1004,13 @@ class UnaryPlusOperator : public UnaryOperator { return visitor.PostVisit(*this); } CLONE_UNARY_EXPRESSION; - static UnaryPlusOperator *Construct(capnp::UnaryPlusOperator::Reader &reader, - AstTreeStorage &storage); + static UnaryPlusOperator *Construct( + const capnp::UnaryPlusOperator::Reader &reader, AstTreeStorage *storage); protected: using UnaryOperator::UnaryOperator; - void Save(capnp::UnaryOperator::Builder &builder) override; + void Save(capnp::UnaryOperator::Builder *builder, + std::vector *saved_uids) override; private: friend class boost::serialization::access; @@ -992,11 +1034,12 @@ class UnaryMinusOperator : public UnaryOperator { } CLONE_UNARY_EXPRESSION; static UnaryMinusOperator *Construct( - capnp::UnaryMinusOperator::Reader &reader, AstTreeStorage &storage); + capnp::UnaryMinusOperator::Reader &reader, AstTreeStorage *storage); protected: using UnaryOperator::UnaryOperator; - void Save(capnp::UnaryOperator::Builder &builder) override; + void Save(capnp::UnaryOperator::Builder *builder, + std::vector *saved_uids) override; private: friend class boost::serialization::access; @@ -1019,12 +1062,13 @@ class IsNullOperator : public UnaryOperator { return visitor.PostVisit(*this); } CLONE_UNARY_EXPRESSION; - static IsNullOperator *Construct(capnp::IsNullOperator::Reader &reader, - AstTreeStorage &storage); + static IsNullOperator *Construct(const capnp::IsNullOperator::Reader &reader, + AstTreeStorage *storage); protected: using UnaryOperator::UnaryOperator; - void Save(capnp::UnaryOperator::Builder &builder) override; + void Save(capnp::UnaryOperator::Builder *builder, + std::vector *saved_uids) override; private: friend class boost::serialization::access; @@ -1040,15 +1084,17 @@ class BaseLiteral : public Expression { public: BaseLiteral *Clone(AstTreeStorage &storage) const override = 0; - static BaseLiteral *Construct(capnp::BaseLiteral::Reader &reader, - AstTreeStorage &storage); + static BaseLiteral *Construct(const capnp::BaseLiteral::Reader &reader, + AstTreeStorage *storage); protected: explicit BaseLiteral(int uid) : Expression(uid) {} - void Save(capnp::Expression::Builder &builder) override; + void Save(capnp::Expression::Builder *builder, + std::vector *saved_uids) override; using Expression::Save; - virtual void Save(capnp::BaseLiteral::Builder &) {} + virtual void Save(capnp::BaseLiteral::Builder *, + std::vector *saved_uids) {} private: friend class boost::serialization::access; @@ -1066,8 +1112,8 @@ class PrimitiveLiteral : public BaseLiteral { return storage.Create(value_, token_position_); } - static PrimitiveLiteral *Construct(capnp::PrimitiveLiteral::Reader &reader, - AstTreeStorage &storage); + static PrimitiveLiteral *Construct( + const capnp::PrimitiveLiteral::Reader &reader, AstTreeStorage *storage); TypedValue value_; // This field contains token position of literal used to create @@ -1083,7 +1129,10 @@ class PrimitiveLiteral : public BaseLiteral { PrimitiveLiteral(int uid, T value, int token_position) : BaseLiteral(uid), value_(value), token_position_(token_position) {} - void Save(capnp::BaseLiteral::Builder &builder) override; + void Save(capnp::BaseLiteral::Builder *builder, + std::vector *saved_uids) override; + void Load(const capnp::Tree::Reader &reader, AstTreeStorage *storage, + std::vector *loaded_uids) override; private: friend class boost::serialization::access; @@ -1131,8 +1180,8 @@ class ListLiteral : public BaseLiteral { return list; } - static ListLiteral *Construct(capnp::ListLiteral::Reader &reader, - AstTreeStorage &storage); + static ListLiteral *Construct(const capnp::ListLiteral::Reader &reader, + AstTreeStorage *storage); std::vector elements_; @@ -1141,7 +1190,10 @@ class ListLiteral : public BaseLiteral { ListLiteral(int uid, const std::vector &elements) : BaseLiteral(uid), elements_(elements) {} - void Save(capnp::BaseLiteral::Builder &builder) override; + void Save(capnp::BaseLiteral::Builder *builder, + std::vector *saved_uids) override; + void Load(const capnp::Tree::Reader &reader, AstTreeStorage *storage, + std::vector *loaded_uids) override; private: friend class boost::serialization::access; @@ -1186,8 +1238,8 @@ class MapLiteral : public BaseLiteral { return map; } - static MapLiteral *Construct(capnp::MapLiteral::Reader &reader, - AstTreeStorage &storage); + static MapLiteral *Construct(const capnp::MapLiteral::Reader &reader, + AstTreeStorage *storage); // maps (property_name, property) to expressions std::unordered_map, Expression *> @@ -1200,7 +1252,10 @@ class MapLiteral : public BaseLiteral { Expression *> &elements) : BaseLiteral(uid), elements_(elements) {} - void Save(capnp::BaseLiteral::Builder &builder) override; + void Save(capnp::BaseLiteral::Builder *builder, + std::vector *saved_uids) override; + void Load(const capnp::Tree::Reader &reader, AstTreeStorage *storage, + std::vector *loaded_uids) override; private: friend class boost::serialization::access; @@ -1252,8 +1307,8 @@ class Identifier : public Expression { return storage.Create(name_, user_declared_); } - static Identifier *Construct(capnp::Identifier::Reader &reader, - AstTreeStorage &storage); + static Identifier *Construct(const capnp::Identifier::Reader &reader, + AstTreeStorage *storage); using Expression::Save; std::string name_; @@ -1264,8 +1319,10 @@ class Identifier : public Expression { Identifier(int uid, const std::string &name, bool user_declared) : Expression(uid), name_(name), user_declared_(user_declared) {} - void Save(capnp::Expression::Builder &builder) override; - virtual void Save(capnp::Identifier::Builder &builder); + void Save(capnp::Expression::Builder *builder, + std::vector *saved_uids) override; + virtual void Save(capnp::Identifier::Builder *builder, + std::vector *saved_uids); private: friend class boost::serialization::access; @@ -1300,8 +1357,8 @@ class PropertyLookup : public Expression { property_name_, property_); } - static PropertyLookup *Construct(capnp::PropertyLookup::Reader &reader, - AstTreeStorage &storage); + static PropertyLookup *Construct(const capnp::PropertyLookup::Reader &reader, + AstTreeStorage *storage); using Expression::Save; Expression *expression_ = nullptr; @@ -1322,8 +1379,12 @@ class PropertyLookup : public Expression { property_name_(property.first), property_(property.second) {} - void Save(capnp::Expression::Builder &builder) override; - virtual void Save(capnp::PropertyLookup::Builder &builder); + void Save(capnp::Expression::Builder *builder, + std::vector *saved_uids) override; + virtual void Save(capnp::PropertyLookup::Builder *builder, + std::vector *saved_uids); + void Load(const capnp::Tree::Reader &reader, AstTreeStorage *storage, + std::vector *loaded_uids) override; private: friend class boost::serialization::access; @@ -1368,8 +1429,8 @@ class LabelsTest : public Expression { return storage.Create(expression_->Clone(storage), labels_); } - static LabelsTest *Construct(capnp::LabelsTest::Reader &reader, - AstTreeStorage &storage); + static LabelsTest *Construct(const capnp::LabelsTest::Reader &reader, + AstTreeStorage *storage); using Expression::Save; Expression *expression_ = nullptr; @@ -1380,8 +1441,12 @@ class LabelsTest : public Expression { const std::vector &labels) : Expression(uid), expression_(expression), labels_(labels) {} - void Save(capnp::Expression::Builder &builder) override; - virtual void Save(capnp::LabelsTest::Builder &builder); + void Save(capnp::Expression::Builder *builder, + std::vector *saved_uids) override; + virtual void Save(capnp::LabelsTest::Builder *builder, + std::vector *saved_uids); + void Load(const capnp::Tree::Reader &tree_reader, AstTreeStorage *storage, + std::vector *loaded_uids) override; private: friend class boost::serialization::access; @@ -1430,8 +1495,8 @@ class Function : public Expression { return storage.Create(function_name_, arguments); } - static Function *Construct(capnp::Function::Reader &reader, - AstTreeStorage &storage); + static Function *Construct(const capnp::Function::Reader &reader, + AstTreeStorage *storage); const auto &function() const { return function_; } const auto &function_name() const { return function_name_; } @@ -1448,9 +1513,13 @@ class Function : public Expression { function_(NameToFunction(function_name_)) { DCHECK(function_) << "Unexpected missing function: " << function_name_; } - void Save(capnp::Expression::Builder &builder) override; + void Save(capnp::Expression::Builder *builder, + std::vector *saved_uids) override; using Expression::Save; - virtual void Save(capnp::Function::Builder &builder); + virtual void Save(capnp::Function::Builder *builder, + std::vector *saved_uids); + void Load(const capnp::Tree::Reader &tree_reader, AstTreeStorage *storage, + std::vector *loaded_uids) override; private: std::string function_name_; @@ -1517,8 +1586,8 @@ class Aggregation : public BinaryOperator { } Op op_; - static Aggregation *Construct(capnp::Aggregation::Reader &, - AstTreeStorage &storage); + static Aggregation *Construct(const capnp::Aggregation::Reader &, + AstTreeStorage *storage); protected: // Use only for serialization. @@ -1536,7 +1605,8 @@ class Aggregation : public BinaryOperator { "invalid otherwise"; } - void Save(capnp::BinaryOperator::Builder &builder) override; + void Save(capnp::BinaryOperator::Builder *builder, + std::vector *saved_uids) override; private: friend class boost::serialization::access; @@ -1574,8 +1644,8 @@ class Reduce : public Expression { expression_->Clone(storage)); } - static Reduce *Construct(capnp::Reduce::Reader &reader, - AstTreeStorage &storage); + static Reduce *Construct(const capnp::Reduce::Reader &reader, + AstTreeStorage *storage); using Expression::Save; // None of these should be nullptr after construction. @@ -1602,8 +1672,12 @@ class Reduce : public Expression { list_(list), expression_(expression) {} - void Save(capnp::Expression::Builder &builder) override; - virtual void Save(capnp::Reduce::Builder &builder); + void Save(capnp::Expression::Builder *builder, + std::vector *saved_uids) override; + virtual void Save(capnp::Reduce::Builder *builder, + std::vector *saved_uids); + void Load(const capnp::Tree::Reader &tree_reader, AstTreeStorage *storage, + std::vector *loaded_uids) override; private: friend class boost::serialization::access; @@ -1655,7 +1729,8 @@ class All : public Expression { where_->Clone(storage)); } - static All *Construct(capnp::All::Reader &reader, AstTreeStorage &storage); + static All *Construct(const capnp::All::Reader &reader, + AstTreeStorage *storage); // None of these should be nullptr after construction. Identifier *identifier_ = nullptr; @@ -1670,9 +1745,12 @@ class All : public Expression { list_expression_(list_expression), where_(where) {} - void Save(capnp::Expression::Builder &builder) override; + void Save(capnp::Expression::Builder *builder, + std::vector *saved_uids) override; using Expression::Save; - virtual void Save(capnp::All::Builder &builder); + virtual void Save(capnp::All::Builder *builder, std::vector *saved_uids); + void Load(const capnp::Tree::Reader &tree_reader, AstTreeStorage *storage, + std::vector *loaded_uids) override; private: friend class boost::serialization::access; @@ -1722,8 +1800,8 @@ class Single : public Expression { where_->Clone(storage)); } - static Single *Construct(capnp::Single::Reader &reader, - AstTreeStorage &storage); + static Single *Construct(const capnp::Single::Reader &reader, + AstTreeStorage *storage); using Expression::Save; // None of these should be nullptr after construction. @@ -1739,8 +1817,12 @@ class Single : public Expression { list_expression_(list_expression), where_(where) {} - void Save(capnp::Expression::Builder &builder) override; - virtual void Save(capnp::Single::Builder &builder); + void Save(capnp::Expression::Builder *builder, + std::vector *saved_uids) override; + virtual void Save(capnp::Single::Builder *builder, + std::vector *saved_uids); + void Load(const capnp::Tree::Reader &tree_reader, AstTreeStorage *storage, + std::vector *loaded_uids) override; private: friend class boost::serialization::access; @@ -1779,8 +1861,8 @@ class ParameterLookup : public Expression { return storage.Create(token_position_); } - static ParameterLookup *Construct(capnp::ParameterLookup::Reader &reader, - AstTreeStorage &storage); + static ParameterLookup *Construct( + const capnp::ParameterLookup::Reader &reader, AstTreeStorage *storage); using Expression::Save; // This field contains token position of *literal* used to create @@ -1793,8 +1875,10 @@ class ParameterLookup : public Expression { ParameterLookup(int uid, int token_position) : Expression(uid), token_position_(token_position) {} - void Save(capnp::Expression::Builder &builder) override; - virtual void Save(capnp::ParameterLookup::Builder &builder); + void Save(capnp::Expression::Builder *builder, + std::vector *saved_uids) override; + virtual void Save(capnp::ParameterLookup::Builder *builder, + std::vector *saved_uids); friend class boost::serialization::access; @@ -1827,9 +1911,10 @@ class NamedExpression : public Tree { token_position_); } - static NamedExpression *Construct(capnp::NamedExpression::Reader &reader, - AstTreeStorage &storage); - void Save(capnp::Tree::Builder &builder) override; + static NamedExpression *Construct( + const capnp::NamedExpression::Reader &reader, AstTreeStorage *storage); + void Save(capnp::Tree::Builder *builder, + std::vector *saved_uids) override; std::string name_; Expression *expression_ = nullptr; @@ -1850,7 +1935,10 @@ class NamedExpression : public Tree { expression_(expression), token_position_(token_position) {} - virtual void Save(capnp::NamedExpression::Builder &); + virtual void Save(capnp::NamedExpression::Builder *, + std::vector *saved_uids); + void Load(const capnp::Tree::Reader &base_reader, AstTreeStorage *storage, + std::vector *loaded_uids) override; private: friend class boost::serialization::access; @@ -1889,17 +1977,20 @@ class PatternAtom : public Tree { PatternAtom *Clone(AstTreeStorage &storage) const override = 0; - static PatternAtom *Construct(capnp::PatternAtom::Reader &reader, - AstTreeStorage &storage); - void Save(capnp::Tree::Builder &builder) override; + static PatternAtom *Construct(const capnp::PatternAtom::Reader &reader, + AstTreeStorage *storage); + void Save(capnp::Tree::Builder *builder, + std::vector *saved_uids) override; protected: explicit PatternAtom(int uid) : Tree(uid) {} PatternAtom(int uid, Identifier *identifier) : Tree(uid), identifier_(identifier) {} - virtual void Save(capnp::PatternAtom::Builder &); - void Load(capnp::Tree::Reader &reader, AstTreeStorage &storage) override; + virtual void Save(capnp::PatternAtom::Builder *, + std::vector *saved_uids); + void Load(const capnp::Tree::Reader &reader, AstTreeStorage *storage, + std::vector *loaded_uids) override; private: friend class boost::serialization::access; @@ -1945,8 +2036,8 @@ class NodeAtom : public PatternAtom { return node_atom; } - static NodeAtom *Construct(capnp::NodeAtom::Reader &reader, - AstTreeStorage &storage); + static NodeAtom *Construct(const capnp::NodeAtom::Reader &reader, + AstTreeStorage *storage); using PatternAtom::Save; std::vector labels_; @@ -1957,8 +2048,12 @@ class NodeAtom : public PatternAtom { protected: using PatternAtom::PatternAtom; - void Save(capnp::PatternAtom::Builder &builder) override; - virtual void Save(capnp::NodeAtom::Builder &builder); + void Save(capnp::PatternAtom::Builder *builder, + std::vector *saved_uids) override; + virtual void Save(capnp::NodeAtom::Builder *builder, + std::vector *saved_uids); + void Load(const capnp::Tree::Reader &base_reader, AstTreeStorage *storage, + std::vector *loaded_uids) override; private: friend class boost::serialization::access; @@ -2017,7 +2112,8 @@ class EdgeAtom : public PatternAtom { }; enum class Direction { IN, OUT, BOTH }; - /// Lambda for use in filtering or weight calculation during variable expands. + /// Lambda for use in filtering or weight calculation during variable + /// expands. struct Lambda { /// Argument identifier for the edge currently being traversed. Identifier *inner_edge = nullptr; @@ -2081,8 +2177,8 @@ class EdgeAtom : public PatternAtom { } } - static EdgeAtom *Construct(capnp::EdgeAtom::Reader &reader, - AstTreeStorage &storage); + static EdgeAtom *Construct(const capnp::EdgeAtom::Reader &reader, + AstTreeStorage *storage); using PatternAtom::Save; Type type_ = Type::SINGLE; @@ -2105,7 +2201,8 @@ class EdgeAtom : public PatternAtom { /// It must have valid expressions and identifiers. In all other expand /// types, it is empty. Lambda weight_lambda_; - /// Variable where the total weight for weighted shortest path will be stored. + /// Variable where the total weight for weighted shortest path will be + /// stored. Identifier *total_weight_ = nullptr; protected: @@ -2121,8 +2218,12 @@ class EdgeAtom : public PatternAtom { direction_(direction), edge_types_(edge_types) {} - void Save(capnp::PatternAtom::Builder &builder) override; - virtual void Save(capnp::EdgeAtom::Builder &builder); + void Save(capnp::PatternAtom::Builder *builder, + std::vector *saved_uids) override; + virtual void Save(capnp::EdgeAtom::Builder *builder, + std::vector *saved_uids); + void Load(const capnp::Tree::Reader &base_reader, AstTreeStorage *storage, + std::vector *loaded_uids) override; private: friend class boost::serialization::access; @@ -2214,9 +2315,10 @@ class Pattern : public Tree { return pattern; } - static Pattern *Construct(capnp::Pattern::Reader &reader, - AstTreeStorage &storage); - void Save(capnp::Tree::Builder &builder) override; + static Pattern *Construct(const capnp::Pattern::Reader &reader, + AstTreeStorage *storage); + void Save(capnp::Tree::Builder *builder, + std::vector *saved_uids) override; Identifier *identifier_ = nullptr; std::vector atoms_; @@ -2224,7 +2326,9 @@ class Pattern : public Tree { protected: explicit Pattern(int uid) : Tree(uid) {} - virtual void Save(capnp::Pattern::Builder &); + virtual void Save(capnp::Pattern::Builder *, std::vector *saved_uids); + void Load(const capnp::Tree::Reader &base_reader, AstTreeStorage *storage, + std::vector *loaded_uids) override; private: friend class boost::serialization::access; @@ -2260,13 +2364,14 @@ class Clause : public Tree { Clause *Clone(AstTreeStorage &storage) const override = 0; - static Clause *Construct(capnp::Clause::Reader &reader, - AstTreeStorage &storage); + static Clause *Construct(const capnp::Clause::Reader &reader, + AstTreeStorage *storage); - void Save(capnp::Tree::Builder &builder) override; + void Save(capnp::Tree::Builder *builder, + std::vector *saved_uids) override; protected: - virtual void Save(capnp::Clause::Builder &) {} + virtual void Save(capnp::Clause::Builder *, std::vector *saved_uids) {} private: friend class boost::serialization::access; @@ -2297,17 +2402,21 @@ class SingleQuery : public Tree { return single_query; } - static SingleQuery *Construct(capnp::SingleQuery::Reader &reader, - AstTreeStorage &storage); + static SingleQuery *Construct(const capnp::SingleQuery::Reader &reader, + AstTreeStorage *storage); - void Save(capnp::Tree::Builder &builder) override; + void Save(capnp::Tree::Builder *builder, + std::vector *saved_uids) override; std::vector clauses_; protected: explicit SingleQuery(int uid) : Tree(uid) {} - virtual void Save(capnp::SingleQuery::Builder &); + virtual void Save(capnp::SingleQuery::Builder *, + std::vector *saved_uids); + void Load(const capnp::Tree::Reader &base_reader, AstTreeStorage *storage, + std::vector *loaded_uids) override; private: friend class boost::serialization::access; @@ -2353,14 +2462,16 @@ class CypherUnion : public Tree { return cypher_union; } - static CypherUnion *Construct(capnp::CypherUnion::Reader &reader, - AstTreeStorage &storage); - void Save(capnp::Tree::Builder &builder) override; + static CypherUnion *Construct(const capnp::CypherUnion::Reader &reader, + AstTreeStorage *storage); + void Save(capnp::Tree::Builder *builder, + std::vector *saved_uids) override; SingleQuery *single_query_ = nullptr; bool distinct_ = false; /// Holds symbols that are created during symbol generation phase. - /// These symbols are used when UNION/UNION ALL combines single query results. + /// These symbols are used when UNION/UNION ALL combines single query + /// results. std::vector union_symbols_; protected: @@ -2373,7 +2484,10 @@ class CypherUnion : public Tree { distinct_(distinct), union_symbols_(union_symbols) {} - virtual void Save(capnp::CypherUnion::Builder &); + virtual void Save(capnp::CypherUnion::Builder *, + std::vector *saved_uids); + void Load(const capnp::Tree::Reader &base_reader, AstTreeStorage *storage, + std::vector *loaded_uids) override; private: friend class boost::serialization::access; @@ -2431,9 +2545,10 @@ class Query : public Tree { return query; } - static Query *Construct(capnp::Query::Reader &reader, - AstTreeStorage &storage); - void Save(capnp::Tree::Builder &builder) override; + void Load(const capnp::Tree::Reader &reader, AstTreeStorage *storage, + std::vector *loaded_uids) override; + void Save(capnp::Tree::Builder *builder, + std::vector *saved_uids) override; SingleQuery *single_query_ = nullptr; std::vector cypher_unions_; @@ -2441,7 +2556,7 @@ class Query : public Tree { protected: explicit Query(int uid) : Tree(uid) {} - virtual void Save(capnp::Query::Builder &); + virtual void Save(capnp::Query::Builder *, std::vector *saved_uids); private: friend class boost::serialization::access; @@ -2491,8 +2606,8 @@ class Create : public Clause { return create; } - static Create *Construct(capnp::Create::Reader &reader, - AstTreeStorage &storage); + static Create *Construct(const capnp::Create::Reader &reader, + AstTreeStorage *storage); using Clause::Save; std::vector patterns_; @@ -2502,8 +2617,12 @@ class Create : public Clause { Create(int uid, std::vector patterns) : Clause(uid), patterns_(patterns) {} - void Save(capnp::Clause::Builder &builder) override; - virtual void Save(capnp::Create::Builder &builder); + void Save(capnp::Clause::Builder *builder, + std::vector *saved_uids) override; + virtual void Save(capnp::Create::Builder *builder, + std::vector *saved_uids); + void Load(const capnp::Tree::Reader &tree_reader, AstTreeStorage *storage, + std::vector *loaded_uids) override; private: friend class boost::serialization::access; @@ -2558,8 +2677,8 @@ class Match : public Clause { } using Clause::Save; - static Match *Construct(capnp::Match::Reader &reader, - AstTreeStorage &storage); + static Match *Construct(const capnp::Match::Reader &reader, + AstTreeStorage *storage); std::vector patterns_; Where *where_ = nullptr; @@ -2571,8 +2690,12 @@ class Match : public Clause { Match(int uid, bool optional, Where *where, std::vector patterns) : Clause(uid), patterns_(patterns), where_(where), optional_(optional) {} - void Save(capnp::Clause::Builder &builder) override; - virtual void Save(capnp::Match::Builder &builder); + void Save(capnp::Clause::Builder *builder, + std::vector *saved_uids) override; + virtual void Save(capnp::Match::Builder *builder, + std::vector *saved_uids); + void Load(const capnp::Tree::Reader &base_reader, AstTreeStorage *storage, + std::vector *loaded_uids) override; private: friend class boost::serialization::access; @@ -2697,8 +2820,8 @@ class Return : public Clause { } using Clause::Save; - static Return *Construct(capnp::Return::Reader &reader, - AstTreeStorage &storage); + static Return *Construct(const capnp::Return::Reader &reader, + AstTreeStorage *storage); ReturnBody body_; @@ -2706,8 +2829,12 @@ class Return : public Clause { explicit Return(int uid) : Clause(uid) {} Return(int uid, ReturnBody &body) : Clause(uid), body_(body) {} - void Save(capnp::Clause::Builder &builder) override; - virtual void Save(capnp::Return::Builder &builder); + void Save(capnp::Clause::Builder *builder, + std::vector *saved_uids) override; + virtual void Save(capnp::Return::Builder *builder, + std::vector *saved_uids); + void Load(const capnp::Tree::Reader &base_reader, AstTreeStorage *storage, + std::vector *loaded_uids) override; private: friend class boost::serialization::access; @@ -2760,7 +2887,8 @@ class With : public Clause { } using Clause::Save; - static With *Construct(capnp::With::Reader &reader, AstTreeStorage &storage); + static With *Construct(const capnp::With::Reader &reader, + AstTreeStorage *storage); ReturnBody body_; Where *where_ = nullptr; @@ -2770,8 +2898,12 @@ class With : public Clause { With(int uid, ReturnBody &body, Where *where) : Clause(uid), body_(body), where_(where) {} - void Save(capnp::Clause::Builder &builder) override; - virtual void Save(capnp::With::Builder &builder); + void Save(capnp::Clause::Builder *builder, + std::vector *saved_uids) override; + virtual void Save(capnp::With::Builder *builder, + std::vector *saved_uids); + void Load(const capnp::Tree::Reader &base_reader, AstTreeStorage *storage, + std::vector *loaded_uids) override; private: friend class boost::serialization::access; @@ -2821,8 +2953,8 @@ class Delete : public Clause { } using Clause::Save; - static Delete *Construct(capnp::Delete::Reader &reader, - AstTreeStorage &storage); + static Delete *Construct(const capnp::Delete::Reader &reader, + AstTreeStorage *storage); std::vector expressions_; @@ -2833,8 +2965,12 @@ class Delete : public Clause { Delete(int uid, bool detach, std::vector expressions) : Clause(uid), expressions_(expressions), detach_(detach) {} - void Save(capnp::Clause::Builder &builder) override; - virtual void Save(capnp::Delete::Builder &builder); + void Save(capnp::Clause::Builder *builder, + std::vector *saved_uids) override; + virtual void Save(capnp::Delete::Builder *builder, + std::vector *saved_uids); + void Load(const capnp::Tree::Reader &base_reader, AstTreeStorage *storage, + std::vector *loaded_uids) override; private: friend class boost::serialization::access; @@ -2878,8 +3014,8 @@ class SetProperty : public Clause { } using Clause::Save; - static SetProperty *Construct(capnp::SetProperty::Reader &reader, - AstTreeStorage &storage); + static SetProperty *Construct(const capnp::SetProperty::Reader &reader, + AstTreeStorage *storage); PropertyLookup *property_lookup_ = nullptr; Expression *expression_ = nullptr; @@ -2891,8 +3027,12 @@ class SetProperty : public Clause { property_lookup_(property_lookup), expression_(expression) {} - void Save(capnp::Clause::Builder &builder) override; - virtual void Save(capnp::SetProperty::Builder &builder); + void Save(capnp::Clause::Builder *builder, + std::vector *saved_uids) override; + virtual void Save(capnp::SetProperty::Builder *builder, + std::vector *saved_uids); + void Load(const capnp::Tree::Reader &base_reader, AstTreeStorage *storage, + std::vector *loaded_uids) override; private: friend class boost::serialization::access; @@ -2937,8 +3077,8 @@ class SetProperties : public Clause { } using Clause::Save; - static SetProperties *Construct(capnp::SetProperties::Reader &reader, - AstTreeStorage &storage); + static SetProperties *Construct(const capnp::SetProperties::Reader &reader, + AstTreeStorage *storage); Identifier *identifier_ = nullptr; Expression *expression_ = nullptr; @@ -2953,8 +3093,12 @@ class SetProperties : public Clause { expression_(expression), update_(update) {} - void Save(capnp::Clause::Builder &builder) override; - virtual void Save(capnp::SetProperties::Builder &builder); + void Save(capnp::Clause::Builder *builder, + std::vector *saved_uids) override; + virtual void Save(capnp::SetProperties::Builder *builder, + std::vector *saved_uids); + void Load(const capnp::Tree::Reader &base_reader, AstTreeStorage *storage, + std::vector *loaded_uids) override; private: friend class boost::serialization::access; @@ -3000,8 +3144,8 @@ class SetLabels : public Clause { } using Clause::Save; - static SetLabels *Construct(capnp::SetLabels::Reader &reader, - AstTreeStorage &storage); + static SetLabels *Construct(const capnp::SetLabels::Reader &reader, + AstTreeStorage *storage); Identifier *identifier_ = nullptr; std::vector labels_; @@ -3012,8 +3156,12 @@ class SetLabels : public Clause { const std::vector &labels) : Clause(uid), identifier_(identifier), labels_(labels) {} - void Save(capnp::Clause::Builder &builder) override; - virtual void Save(capnp::SetLabels::Builder &builder); + void Save(capnp::Clause::Builder *builder, + std::vector *saved_uids) override; + virtual void Save(capnp::SetLabels::Builder *builder, + std::vector *saved_uids); + void Load(const capnp::Tree::Reader &base_reader, AstTreeStorage *storage, + std::vector *loaded_uids) override; private: friend class boost::serialization::access; @@ -3056,8 +3204,8 @@ class RemoveProperty : public Clause { } using Clause::Save; - static RemoveProperty *Construct(capnp::RemoveProperty::Reader &reader, - AstTreeStorage &storage); + static RemoveProperty *Construct(const capnp::RemoveProperty::Reader &reader, + AstTreeStorage *storage); PropertyLookup *property_lookup_ = nullptr; @@ -3066,8 +3214,12 @@ class RemoveProperty : public Clause { RemoveProperty(int uid, PropertyLookup *property_lookup) : Clause(uid), property_lookup_(property_lookup) {} - void Save(capnp::Clause::Builder &builder) override; - virtual void Save(capnp::RemoveProperty::Builder &builder); + void Save(capnp::Clause::Builder *builder, + std::vector *saved_uids) override; + virtual void Save(capnp::RemoveProperty::Builder *builder, + std::vector *saved_uids); + void Load(const capnp::Tree::Reader &base_reader, AstTreeStorage *storage, + std::vector *loaded_uids) override; private: friend class boost::serialization::access; @@ -3109,8 +3261,8 @@ class RemoveLabels : public Clause { } using Clause::Save; - static RemoveLabels *Construct(capnp::RemoveLabels::Reader &reader, - AstTreeStorage &storage); + static RemoveLabels *Construct(const capnp::RemoveLabels::Reader &reader, + AstTreeStorage *storage); Identifier *identifier_ = nullptr; std::vector labels_; @@ -3121,8 +3273,12 @@ class RemoveLabels : public Clause { const std::vector &labels) : Clause(uid), identifier_(identifier), labels_(labels) {} - void Save(capnp::Clause::Builder &builder) override; - virtual void Save(capnp::RemoveLabels::Builder &builder); + void Save(capnp::Clause::Builder *builder, + std::vector *saved_uids) override; + virtual void Save(capnp::RemoveLabels::Builder *builder, + std::vector *saved_uids); + void Load(const capnp::Tree::Reader &base_reader, AstTreeStorage *storage, + std::vector *loaded_uids) override; private: friend class boost::serialization::access; @@ -3190,8 +3346,8 @@ class Merge : public Clause { } using Clause::Save; - static Merge *Construct(capnp::Merge::Reader &reader, - AstTreeStorage &storage); + static Merge *Construct(const capnp::Merge::Reader &reader, + AstTreeStorage *storage); Pattern *pattern_ = nullptr; std::vector on_match_; @@ -3206,8 +3362,12 @@ class Merge : public Clause { on_match_(on_match), on_create_(on_create) {} - void Save(capnp::Clause::Builder &builder) override; - virtual void Save(capnp::Merge::Builder &builder); + void Save(capnp::Clause::Builder *builder, + std::vector *saved_uids) override; + virtual void Save(capnp::Merge::Builder *builder, + std::vector *saved_uids); + void Load(const capnp::Tree::Reader &base_reader, AstTreeStorage *storage, + std::vector *loaded_uids) override; private: friend class boost::serialization::access; @@ -3252,8 +3412,8 @@ class Unwind : public Clause { } using Clause::Save; - static Unwind *Construct(capnp::Unwind::Reader &reader, - AstTreeStorage &storage); + static Unwind *Construct(const capnp::Unwind::Reader &reader, + AstTreeStorage *storage); NamedExpression *named_expression_ = nullptr; @@ -3266,8 +3426,12 @@ class Unwind : public Clause { << "Unwind cannot take nullptr for named_expression"; } - void Save(capnp::Clause::Builder &builder) override; - virtual void Save(capnp::Unwind::Builder &builder); + void Save(capnp::Clause::Builder *builder, + std::vector *saved_uids) override; + virtual void Save(capnp::Unwind::Builder *builder, + std::vector *saved_uids); + void Load(const capnp::Tree::Reader &base_reader, AstTreeStorage *storage, + std::vector *loaded_uids) override; private: friend class boost::serialization::access; @@ -3302,8 +3466,8 @@ class CreateIndex : public Clause { return storage.Create(label_, property_); } - static CreateIndex *Construct(capnp::CreateIndex::Reader &reader, - AstTreeStorage &storage); + static CreateIndex *Construct(const capnp::CreateIndex::Reader &reader, + AstTreeStorage *storage); using Clause::Save; storage::Label label_; @@ -3314,8 +3478,10 @@ class CreateIndex : public Clause { CreateIndex(int uid, storage::Label label, storage::Property property) : Clause(uid), label_(label), property_(property) {} - void Save(capnp::Clause::Builder &builder) override; - virtual void Save(capnp::CreateIndex::Builder &builder); + void Save(capnp::Clause::Builder *builder, + std::vector *saved_uids) override; + virtual void Save(capnp::CreateIndex::Builder *builder, + std::vector *saved_uids); private: friend class boost::serialization::access; diff --git a/tests/unit/cypher_main_visitor.cpp b/tests/unit/cypher_main_visitor.cpp index 333aac2a4..26dd1d9a8 100644 --- a/tests/unit/cypher_main_visitor.cpp +++ b/tests/unit/cypher_main_visitor.cpp @@ -154,14 +154,16 @@ class CapnpAstGenerator : public Base { { query::capnp::Tree::Builder builder = message.initRoot(); - visitor.query()->Save(builder); + std::vector saved_uids; + visitor.query()->Save(&builder, &saved_uids); } AstTreeStorage new_ast; { - query::capnp::Tree::Reader reader = + const query::capnp::Tree::Reader reader = message.getRoot(); - new_ast.Load(reader); + std::vector loaded_uids; + new_ast.Load(reader, &loaded_uids); } return new_ast; }()),