1
0
Fork 0

Removed superflous aql::ShortestPathOptions and replaced it by traverser::ShortestPathOptions. Api is not fixed yet.

This commit is contained in:
Michael Hackstein 2017-04-10 11:02:01 +02:00
parent e2813114ea
commit 052c4942fc
9 changed files with 84 additions and 166 deletions

View File

@ -22,10 +22,10 @@
////////////////////////////////////////////////////////////////////////////////
#include "ExecutionPlan.h"
#include "Aql/CollectOptions.h"
#include "Aql/Ast.h"
#include "Aql/AstNode.h"
#include "Aql/CollectNode.h"
#include "Aql/CollectOptions.h"
#include "Aql/Collection.h"
#include "Aql/ExecutionNode.h"
#include "Aql/Expression.h"
@ -35,7 +35,6 @@
#include "Aql/OptimizerRulesFeature.h"
#include "Aql/Query.h"
#include "Aql/ShortestPathNode.h"
#include "Aql/ShortestPathOptions.h"
#include "Aql/SortNode.h"
#include "Aql/TraversalNode.h"
#include "Aql/Variable.h"
@ -44,6 +43,7 @@
#include "Basics/SmallVector.h"
#include "Basics/StaticStrings.h"
#include "Basics/VelocyPackHelper.h"
#include "V8Server/V8Traverser.h"
#include "VocBase/AccessMode.h"
#include <velocypack/Iterator.h>
@ -69,8 +69,8 @@ static uint64_t checkTraversalDepthValue(AstNode const* node) {
}
static std::unique_ptr<traverser::TraverserOptions> CreateTraversalOptions(
transaction::Methods* trx, AstNode const* direction, AstNode const* optionsNode) {
transaction::Methods* trx, AstNode const* direction,
AstNode const* optionsNode) {
auto options = std::make_unique<traverser::TraverserOptions>(trx);
TRI_ASSERT(direction != nullptr);
@ -145,8 +145,9 @@ static std::unique_ptr<traverser::TraverserOptions> CreateTraversalOptions(
return options;
}
static ShortestPathOptions CreateShortestPathOptions(AstNode const* node) {
ShortestPathOptions options;
static std::unique_ptr<traverser::ShortestPathOptions> CreateShortestPathOptions(
arangodb::transaction::Methods* trx, AstNode const* node) {
auto options = std::make_unique<traverser::ShortestPathOptions>(trx);
if (node != nullptr && node->type == NODE_TYPE_OBJECT) {
size_t n = node->numMembers();
@ -161,10 +162,10 @@ static ShortestPathOptions CreateShortestPathOptions(AstNode const* node) {
TRI_ASSERT(value->isConstant());
if (name == "weightAttribute" && value->isStringValue()) {
options.weightAttribute =
options->weightAttribute =
std::string(value->getStringValue(), value->getStringLength());
} else if (name == "defaultWeight" && value->isNumericValue()) {
options.defaultWeight = value->getDoubleValue();
options->defaultWeight = value->getDoubleValue();
}
}
}
@ -181,8 +182,7 @@ ExecutionPlan::ExecutionPlan(Ast* ast)
_nextId(0),
_ast(ast),
_lastLimitNode(nullptr),
_subqueries() {
}
_subqueries() {}
/// @brief destroy the plan, frees all assigned nodes
ExecutionPlan::~ExecutionPlan() {
@ -296,9 +296,7 @@ ExecutionPlan* ExecutionPlan::clone(Ast* ast) {
}
/// @brief clone an existing execution plan
ExecutionPlan* ExecutionPlan::clone() {
return clone(_ast);
}
ExecutionPlan* ExecutionPlan::clone() { return clone(_ast); }
/// @brief create an execution plan identical to this one
/// keep the memory of the plan on the query object specified.
@ -314,7 +312,8 @@ ExecutionPlan* ExecutionPlan::clone(Query const& query) {
}
/// @brief export to VelocyPack
std::shared_ptr<VPackBuilder> ExecutionPlan::toVelocyPack(Ast* ast, bool verbose) const {
std::shared_ptr<VPackBuilder> ExecutionPlan::toVelocyPack(Ast* ast,
bool verbose) const {
auto builder = std::make_shared<VPackBuilder>();
toVelocyPack(*builder, ast, verbose);
@ -322,7 +321,8 @@ std::shared_ptr<VPackBuilder> ExecutionPlan::toVelocyPack(Ast* ast, bool verbose
}
/// @brief export to VelocyPack
void ExecutionPlan::toVelocyPack(VPackBuilder& builder, Ast* ast, bool verbose) const {
void ExecutionPlan::toVelocyPack(VPackBuilder& builder, Ast* ast,
bool verbose) const {
// keeps top level of built object open
_root->toVelocyPack(builder, verbose, true);
@ -335,7 +335,7 @@ void ExecutionPlan::toVelocyPack(VPackBuilder& builder, Ast* ast, bool verbose)
builder.add(VPackValue(r));
}
builder.close();
// set up collections
builder.add(VPackValue("collections"));
builder.openArray();
@ -792,11 +792,11 @@ ExecutionNode* ExecutionPlan::fromNodeShortestPath(ExecutionNode* previous,
AstNode const* direction = node->getMember(0);
TRI_ASSERT(direction->isIntValue());
AstNode const* start = parseTraversalVertexNode(previous, node->getMember(1));
AstNode const* target = parseTraversalVertexNode(previous, node->getMember(2));
AstNode const* target =
parseTraversalVertexNode(previous, node->getMember(2));
AstNode const* graph = node->getMember(3);
ShortestPathOptions options = CreateShortestPathOptions(node->getMember(4));
auto options = CreateShortestPathOptions(getAst()->query()->trx(), node->getMember(4));
// First create the node
auto spNode = new ShortestPathNode(this, nextId(), _ast->query()->vocbase(),
@ -1652,9 +1652,9 @@ void ExecutionPlan::findNodesOfType(SmallVector<ExecutionNode*>& result,
root()->walk(&finder);
}
/// @brief find nodes of a certain types
void ExecutionPlan::findNodesOfType(SmallVector<ExecutionNode*>& result,
void ExecutionPlan::findNodesOfType(
SmallVector<ExecutionNode*>& result,
std::vector<ExecutionNode::NodeType> const& types, bool enterSubqueries) {
NodeFinder<std::vector<ExecutionNode::NodeType>> finder(types, result,
enterSubqueries);
@ -1663,7 +1663,7 @@ void ExecutionPlan::findNodesOfType(SmallVector<ExecutionNode*>& result,
/// @brief find all end nodes in a plan
void ExecutionPlan::findEndNodes(SmallVector<ExecutionNode*>& result,
bool enterSubqueries) const {
bool enterSubqueries) const {
EndNodeFinder finder(result, enterSubqueries);
root()->walk(&finder);
}
@ -1891,20 +1891,23 @@ void ExecutionPlan::insertDependency(ExecutionNode* oldNode,
/// @brief create a plan from VPack
ExecutionNode* ExecutionPlan::fromSlice(VPackSlice const& slice) {
if (!slice.isObject()) {
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "plan slice is not an object");
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL,
"plan slice is not an object");
}
if (slice.hasKey("initialize")) {
// whether or not this plan (or fragment) is responsible for calling initialize
// whether or not this plan (or fragment) is responsible for calling
// initialize
_isResponsibleForInitialize = slice.get("initialize").getBoolean();
}
VPackSlice nodes = slice.get("nodes");
if (!nodes.isArray()) {
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "plan \"nodes\" attribute is not an array");
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL,
"plan \"nodes\" attribute is not an array");
}
ExecutionNode* ret = nullptr;
// first, re-create all nodes from the Slice, using the node ids

View File

@ -84,7 +84,7 @@ ShortestPathNode::ShortestPathNode(ExecutionPlan* plan, size_t id,
TRI_vocbase_t* vocbase, uint64_t direction,
AstNode const* start, AstNode const* target,
AstNode const* graph,
ShortestPathOptions const& options)
std::unique_ptr<traverser::ShortestPathOptions>& options)
: ExecutionNode(plan, id),
_vocbase(vocbase),
_vertexOutVariable(nullptr),
@ -92,12 +92,13 @@ ShortestPathNode::ShortestPathNode(ExecutionPlan* plan, size_t id,
_inStartVariable(nullptr),
_inTargetVariable(nullptr),
_graphObj(nullptr),
_options(options) {
_options(nullptr) {
_options.swap(options);
TRI_ASSERT(_vocbase != nullptr);
TRI_ASSERT(start != nullptr);
TRI_ASSERT(target != nullptr);
TRI_ASSERT(graph != nullptr);
TRI_ASSERT(_options != nullptr);
TRI_edge_direction_e baseDirection = parseDirection(direction);
@ -239,7 +240,7 @@ ShortestPathNode::ShortestPathNode(ExecutionPlan* plan, size_t id,
std::string const& startVertexId,
Variable const* inTargetVariable,
std::string const& targetVertexId,
ShortestPathOptions const& options)
std::unique_ptr<traverser::ShortestPathOptions>& options)
: ExecutionNode(plan, id),
_vocbase(vocbase),
_vertexOutVariable(nullptr),
@ -250,8 +251,8 @@ ShortestPathNode::ShortestPathNode(ExecutionPlan* plan, size_t id,
_targetVertexId(targetVertexId),
_directions(directions),
_graphObj(nullptr),
_options(options) {
_options(nullptr) {
_options.swap(options);
_graphInfo.openArray();
for (auto const& it : edgeColls) {
_edgeColls.emplace_back(it);
@ -260,11 +261,13 @@ ShortestPathNode::ShortestPathNode(ExecutionPlan* plan, size_t id,
_graphInfo.close();
}
ShortestPathNode::~ShortestPathNode() {}
void ShortestPathNode::fillOptions(arangodb::traverser::ShortestPathOptions& opts) const {
if (!_options.weightAttribute.empty()) {
if (!_options->weightAttribute.empty()) {
opts.useWeight = true;
opts.weightAttribute = _options.weightAttribute;
opts.defaultWeight = _options.defaultWeight;
opts.weightAttribute = _options->weightAttribute;
opts.defaultWeight = _options->defaultWeight;
} else {
opts.useWeight = false;
}
@ -392,7 +395,8 @@ ShortestPathNode::ShortestPathNode(ExecutionPlan* plan,
// Flags
if (base.hasKey("shortestPathFlags")) {
_options = ShortestPathOptions(base);
_options = std::make_unique<traverser::ShortestPathOptions>(
_plan->getAst()->query()->trx(), base);
}
}
@ -441,7 +445,7 @@ void ShortestPathNode::toVelocyPackHelper(VPackBuilder& nodes,
}
nodes.add(VPackValue("shortestPathFlags"));
_options.toVelocyPack(nodes);
_options->toVelocyPack(nodes);
// And close it:
nodes.close();
@ -450,9 +454,12 @@ void ShortestPathNode::toVelocyPackHelper(VPackBuilder& nodes,
ExecutionNode* ShortestPathNode::clone(ExecutionPlan* plan,
bool withDependencies,
bool withProperties) const {
auto tmp =
std::make_unique<arangodb::traverser::ShortestPathOptions>(*_options.get());
auto c = new ShortestPathNode(plan, _id, _vocbase, _edgeColls, _directions,
_inStartVariable, _startVertexId,
_inTargetVariable, _targetVertexId, _options);
_inTargetVariable, _targetVertexId, tmp);
if (usesVertexOutVariable()) {
auto vertexOutVariable = _vertexOutVariable;
if (withProperties) {

View File

@ -26,7 +26,6 @@
#include "Aql/ExecutionNode.h"
#include "Aql/Graphs.h"
#include "Aql/ShortestPathOptions.h"
#include <velocypack/Builder.h>
@ -47,11 +46,11 @@ class ShortestPathNode : public ExecutionNode {
public:
ShortestPathNode(ExecutionPlan* plan, size_t id, TRI_vocbase_t* vocbase,
uint64_t direction, AstNode const* start, AstNode const* target,
AstNode const* graph, ShortestPathOptions const& options);
AstNode const* graph, std::unique_ptr<traverser::ShortestPathOptions>& options);
ShortestPathNode(ExecutionPlan* plan, arangodb::velocypack::Slice const& base);
~ShortestPathNode() {}
~ShortestPathNode();
/// @brief Internal constructor to clone the node.
private:
@ -62,7 +61,7 @@ class ShortestPathNode : public ExecutionNode {
std::string const& startVertexId,
Variable const* inTargetVariable,
std::string const& targetVertexId,
ShortestPathOptions const& options);
std::unique_ptr<traverser::ShortestPathOptions>& options);
public:
/// @brief return the type of the node
@ -190,7 +189,7 @@ class ShortestPathNode : public ExecutionNode {
Graph const* _graphObj;
/// @brief Options for traversals
ShortestPathOptions _options;
std::unique_ptr<traverser::ShortestPathOptions> _options;
};
} // namespace arangodb::aql

View File

@ -1,54 +0,0 @@
////////////////////////////////////////////////////////////////////////////////
/// DISCLAIMER
///
/// Copyright 2016-2016 ArangoDB GmbH, Cologne, Germany
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
///
/// @author Michael Hackstein
////////////////////////////////////////////////////////////////////////////////
#include "Aql/ShortestPathOptions.h"
#include <velocypack/velocypack-aliases.h>
using namespace arangodb::aql;
ShortestPathOptions::ShortestPathOptions(VPackSlice const& slice)
: weightAttribute(), defaultWeight(1) {
VPackSlice obj = slice.get("shortestPathFlags");
if (obj.isObject()) {
if (obj.hasKey("weightAttribute")) {
VPackSlice v = obj.get("weightAttribute");
if (v.isString()) {
weightAttribute = v.copyString();
}
}
if (obj.hasKey("defaultWeight")) {
VPackSlice v = obj.get("defaultWeight");
if (v.isNumber()) {
defaultWeight = v.getNumericValue<double>();
}
}
}
}
void ShortestPathOptions::toVelocyPack(VPackBuilder& builder) const {
VPackObjectBuilder guard(&builder);
builder.add("weightAttribute", VPackValue(weightAttribute));
builder.add("defaultWeight", VPackValue(defaultWeight));
}

View File

@ -1,54 +0,0 @@
////////////////////////////////////////////////////////////////////////////////
/// DISCLAIMER
///
/// Copyright 2016-2016 ArangoDB GmbH, Cologne, Germany
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
///
/// @author Michael Hackstein
////////////////////////////////////////////////////////////////////////////////
#ifndef ARANGOD_AQL_SHORTEST_PATH_OPTIONS_H
#define ARANGOD_AQL_SHORTEST_PATH_OPTIONS_H 1
#include "Basics/Common.h"
#include <velocypack/Builder.h>
#include <velocypack/Slice.h>
namespace arangodb {
namespace aql {
/// @brief TraversalOptions
struct ShortestPathOptions {
/// @brief constructor
explicit ShortestPathOptions(arangodb::velocypack::Slice const&);
/// @brief constructor, using default values
ShortestPathOptions()
: weightAttribute(),
defaultWeight(1) {}
void toVelocyPack(arangodb::velocypack::Builder&) const;
std::string weightAttribute;
double defaultWeight;
};
} // namespace arangodb::aql
} // namespace arangodb
#endif

View File

@ -123,7 +123,7 @@ TraversalNode::TraversalNode(ExecutionPlan* plan, size_t id,
TRI_ASSERT(direction != nullptr);
TRI_ASSERT(start != nullptr);
TRI_ASSERT(graph != nullptr);
_options.reset(options.release());
_options.swap(options);
auto ast = _plan->getAst();
// Let us build the conditions on _from and _to. Just in case we need them.
@ -409,7 +409,7 @@ TraversalNode::TraversalNode(
_toCondition(nullptr),
_optionsBuild(false),
_isSmart(false) {
_options.reset(options.release());
_options.swap(options);
_graphInfo.openArray();
for (auto& it : edgeColls) {

View File

@ -159,7 +159,6 @@ SET(ARANGOD_SOURCES
Aql/ShortStringStorage.cpp
Aql/ShortestPathBlock.cpp
Aql/ShortestPathNode.cpp
Aql/ShortestPathOptions.cpp
Aql/SortBlock.cpp
Aql/SortCondition.cpp
Aql/SortNode.cpp

View File

@ -33,6 +33,16 @@ using namespace arangodb::basics;
using namespace arangodb::traverser;
ShortestPathOptions::ShortestPathOptions(transaction::Methods* trx)
: BasicOptions(trx),
direction("outbound"),
useWeight(false),
weightAttribute(""),
defaultWeight(1),
bidirectional(true),
multiThreaded(true) {}
ShortestPathOptions::ShortestPathOptions(transaction::Methods* trx,
VPackSlice const& info)
: BasicOptions(trx),
direction("outbound"),
useWeight(false),
@ -40,6 +50,14 @@ ShortestPathOptions::ShortestPathOptions(transaction::Methods* trx)
defaultWeight(1),
bidirectional(true),
multiThreaded(true) {
VPackSlice obj = info.get("shortestPathFlags");
if (obj.isObject()) {
weightAttribute =
VelocyPackHelper::getStringValue(obj, "weightAttribute", "");
defaultWeight =
VelocyPackHelper::getNumericValue<double>(obj, "defaultWeight", 1);
}
}
void ShortestPathOptions::setStart(std::string const& id) {
@ -58,6 +76,10 @@ VPackSlice ShortestPathOptions::getStart() const {
return startBuilder.slice();
}
VPackSlice ShortestPathOptions::getEnd() const {
return endBuilder.slice();
VPackSlice ShortestPathOptions::getEnd() const { return endBuilder.slice(); }
void ShortestPathOptions::toVelocyPack(VPackBuilder& builder) const {
VPackObjectBuilder guard(&builder);
builder.add("weightAttribute", VPackValue(weightAttribute));
builder.add("defaultWeight", VPackValue(defaultWeight));
}

View File

@ -40,25 +40,18 @@ namespace traverser {
// A collection of shared options used in several functions.
// Should not be used directly, use specialization instead.
struct BasicOptions {
transaction::Methods* _trx;
protected:
explicit BasicOptions(transaction::Methods* trx) : _trx(trx) {}
explicit BasicOptions(transaction::Methods* trx)
: _trx(trx) {}
virtual ~BasicOptions() {
}
virtual ~BasicOptions() {}
public:
std::string start;
public:
transaction::Methods* trx() { return _trx; }
};
struct ShortestPathOptions : BasicOptions {
@ -75,14 +68,17 @@ struct ShortestPathOptions : BasicOptions {
explicit ShortestPathOptions(transaction::Methods* trx);
ShortestPathOptions(transaction::Methods* trx,
arangodb::velocypack::Slice const& info);
void setStart(std::string const&);
void setEnd(std::string const&);
arangodb::velocypack::Slice getStart() const;
arangodb::velocypack::Slice getEnd() const;
void toVelocyPack(arangodb::velocypack::Builder&) const;
};
}
}