1
0
Fork 0

cppcheck fixes and dead code cleanup.

This commit is contained in:
Michael Hackstein 2016-08-11 11:15:38 +02:00
parent f4eeb1dbf0
commit e8ff84c8da
19 changed files with 102 additions and 445 deletions

View File

@ -3657,54 +3657,6 @@ void arangodb::aql::optimizeTraversalsRule(Optimizer* opt,
n->walk(&finder);
}
}
// now check if we can use an optimized version of the neighbors search...
if (!arangodb::ServerState::instance()->isRunningInCluster()) {
for (auto const& n : tNodes) {
TraversalNode* traversal = static_cast<TraversalNode*>(n);
if (traversal->edgeOutVariable() != nullptr ||
traversal->pathOutVariable() != nullptr) {
// traversal produces edges or paths
continue;
}
/*
if (!traversal->expressions()->empty()) {
// traversal has filter expressions
continue;
}
*/
if (!traversal->allDirectionsEqual()) {
// not all directions are equal
continue;
}
traverser::TraverserOptions const* options = traversal->options();
TRI_ASSERT(options != nullptr);
if (options->maxDepth > 100) {
// neighbors search is recursive... do not use recursive version if
// depth is potentially high
continue;
}
if (options->uniqueVertices != traverser::TraverserOptions::GLOBAL ||
options->uniqueEdges != traverser::TraverserOptions::NONE) {
// neighbors search is hard-coded to global vertex uniqueness
continue;
}
if (!options->useBreadthFirst) {
continue;
}
traversal->specializeToNeighborsSearch();
modified = true;
}
}
opt->addPlan(plan, rule, modified);
}

View File

@ -160,7 +160,7 @@ ShortestPathNode::ShortestPathNode(ExecutionPlan* plan, size_t id,
ShortestPathNode::ShortestPathNode(ExecutionPlan* plan, size_t id,
TRI_vocbase_t* vocbase,
std::vector<std::string> const& edgeColls,
std::vector<TRI_edge_direction_e> directions,
std::vector<TRI_edge_direction_e> const& directions,
Variable const* inStartVariable,
std::string const& startVertexId,
Variable const* inTargetVariable,

View File

@ -54,7 +54,7 @@ class ShortestPathNode : public ExecutionNode {
private:
ShortestPathNode(ExecutionPlan* plan, size_t id, TRI_vocbase_t* vocbase,
std::vector<std::string> const& edgeColls,
std::vector<TRI_edge_direction_e> directions,
std::vector<TRI_edge_direction_e> const& directions,
Variable const* inStartVariable,
std::string const& startVertexId,
Variable const* inTargetVariable,

View File

@ -155,11 +155,6 @@ int TraversalBlock::initializeCursor(AqlItemBlock* items, size_t pos) {
bool TraversalBlock::morePaths(size_t hint) {
DEBUG_BEGIN_BLOCK();
TraversalNode const* planNode = static_cast<TraversalNode const*>(getPlanNode());
if (planNode->_specializedNeighborsSearch) {
return false;
}
freeCaches();
_posInPaths = 0;
if (!_traverser->hasMore()) {
@ -207,8 +202,6 @@ bool TraversalBlock::morePaths(size_t hint) {
/// @brief skip the next paths
size_t TraversalBlock::skipPaths(size_t hint) {
DEBUG_BEGIN_BLOCK();
TRI_ASSERT(!static_cast<TraversalNode const*>(getPlanNode())->_specializedNeighborsSearch);
freeCaches();
_posInPaths = 0;
if (!_traverser->hasMore()) {
@ -237,8 +230,6 @@ void TraversalBlock::initializePaths(AqlItemBlock const* items, size_t pos) {
return;
}
TraversalNode const* planNode = static_cast<TraversalNode const*>(getPlanNode());
if (!_useRegister) {
if (!_usedConstant) {
_usedConstant = true;
@ -249,36 +240,21 @@ void TraversalBlock::initializePaths(AqlItemBlock const* items, size_t pos) {
"Only id strings or objects with "
"_id are allowed");
} else {
if (planNode->_specializedNeighborsSearch) {
// fetch neighbor nodes
neighbors(_vertexId);
} else {
_traverser->setStartVertex(_vertexId);
}
_traverser->setStartVertex(_vertexId);
}
}
} else {
AqlValue const& in = items->getValueReference(_pos, _reg);
if (in.isObject()) {
try {
if (planNode->_specializedNeighborsSearch) {
// fetch neighbor nodes
neighbors(_trx->extractIdString(in.slice()));
} else {
_traverser->setStartVertex(_trx->extractIdString(in.slice()));
}
_traverser->setStartVertex(_trx->extractIdString(in.slice()));
}
catch (...) {
// _id or _key not present... ignore this error and fall through
}
} else if (in.isString()) {
_vertexId = in.slice().copyString();
if (planNode->_specializedNeighborsSearch) {
// fetch neighbor nodes
neighbors(_vertexId);
} else {
_traverser->setStartVertex(_vertexId);
}
_traverser->setStartVertex(_vertexId);
} else {
_engine->getQuery()->registerWarning(
TRI_ERROR_BAD_PARAMETER, "Invalid input for traversal: Only "
@ -428,140 +404,3 @@ size_t TraversalBlock::skipSome(size_t atLeast, size_t atMost) {
return atMost;
DEBUG_END_BLOCK();
}
/// @brief optimized version of neighbors search, must properly implement this
void TraversalBlock::neighbors(std::string const& startVertex) {
#warning Needs to be rebuild
/*
std::unordered_set<VPackSlice, arangodb::basics::VelocyPackHelper::VPackStringHash, arangodb::basics::VelocyPackHelper::VPackStringEqual> visited;
std::vector<VPackSlice> result;
result.reserve(1000);
TransactionBuilderLeaser builder(_trx);
builder->add(VPackValue(startVertex));
std::vector<VPackSlice> startVertices;
startVertices.emplace_back(builder->slice());
visited.emplace(builder->slice());
TRI_edge_direction_e direction = TRI_EDGE_ANY;
std::string collectionName;
traverser::TraverserOptions const* options = _traverser->options();
if (options->getCollection(0, collectionName, direction)) {
runNeighbors(startVertices, visited, result, direction, 1);
}
TRI_doc_mptr_t mptr;
_vertices.clear();
_vertices.reserve(result.size());
for (auto const& it : result) {
VPackValueLength l;
char const* p = it.getString(l);
StringRef ref(p, l);
size_t pos = ref.find('/');
if (pos == std::string::npos) {
// invalid id
continue;
}
int res = _trx->documentFastPathLocal(ref.substr(0, pos).toString(), ref.substr(pos + 1).toString(), &mptr);
if (res != TRI_ERROR_NO_ERROR) {
continue;
}
_vertices.emplace_back(AqlValue(mptr.vpack(), AqlValueFromMasterPointer()));
}
*/
}
/// @brief worker for neighbors() function
void TraversalBlock::runNeighbors(std::vector<VPackSlice> const& startVertices,
std::unordered_set<VPackSlice, arangodb::basics::VelocyPackHelper::VPackStringHash, arangodb::basics::VelocyPackHelper::VPackStringEqual>& visited,
std::vector<VPackSlice>& distinct,
TRI_edge_direction_e direction,
uint64_t depth) {
/*
std::vector<VPackSlice> nextDepth;
bool initialized = false;
TraversalNode const* node = static_cast<TraversalNode const*>(getPlanNode());
traverser::TraverserOptions const* options = _traverser->options();
TransactionBuilderLeaser builder(_trx);
size_t const n = options->collectionCount();
std::string collectionName;
Transaction::IndexHandle indexHandle;
std::vector<TRI_doc_mptr_t*> edges;
for (auto const& startVertex : startVertices) {
for (size_t i = 0; i < n; ++i) {
builder->clear();
if (!options->getCollectionAndSearchValue(i, startVertex.copyString(), collectionName, indexHandle, *builder.builder())) {
TRI_ASSERT(false);
}
std::unique_ptr<OperationCursor> cursor = _trx->indexScan(collectionName,
arangodb::Transaction::CursorType::INDEX, indexHandle,
builder->slice(), 0, UINT64_MAX, 1000, false);
if (cursor->failed()) {
continue;
}
edges.clear();
while (cursor->hasMore()) {
cursor->getMoreMptr(edges, 1000);
for (auto const& it : edges) {
VPackSlice edge(it->vpack());
VPackSlice v;
if (direction == TRI_EDGE_IN) {
v = Transaction::extractFromFromDocument(edge);
} else {
v = Transaction::extractToFromDocument(edge);
}
if (visited.emplace(v).second) {
// we have not yet visited this vertex
if (depth >= node->minDepth()) {
distinct.emplace_back(v);
}
if (depth < node->maxDepth()) {
if (!initialized) {
nextDepth.reserve(64);
initialized = true;
}
nextDepth.emplace_back(v);
}
continue;
} else if (direction == TRI_EDGE_ANY) {
v = Transaction::extractToFromDocument(edge);
if (visited.emplace(v).second) {
// we have not yet visited this vertex
if (depth >= node->minDepth()) {
distinct.emplace_back(v);
}
if (depth < node->maxDepth()) {
if (!initialized) {
nextDepth.reserve(64);
initialized = true;
}
nextDepth.emplace_back(v);
}
}
}
}
}
}
}
if (!nextDepth.empty()) {
runNeighbors(nextDepth, visited, distinct, direction, depth + 1);
}
*/
}

View File

@ -142,16 +142,6 @@ class TraversalBlock : public ExecutionBlock {
/// @brief Checks if we output the path
bool usesPathOutput() { return _pathVar != nullptr; }
/// @brief optimized version of neighbors search, must properly implement this
void neighbors(std::string const& startVertex);
/// @brief worker for neighbors() function
void runNeighbors(std::vector<VPackSlice> const& startVertices,
std::unordered_set<VPackSlice, arangodb::basics::VelocyPackHelper::VPackStringHash, arangodb::basics::VelocyPackHelper::VPackStringEqual>& visited,
std::vector<VPackSlice>& distinct,
TRI_edge_direction_e direction,
uint64_t depth);
};
} // namespace arangodb::aql
} // namespace arangodb

View File

@ -168,9 +168,6 @@ static bool checkPathVariableAccessFeasible(CalculationNode const* cn,
for (auto const & node : onePath) {
if (node->type == NODE_TYPE_FCALL) {
//
// we currently don't know how to execute functions in the
// traversal (-> TraverserExpression::recursiveCheck
return false;
}
if (node->type == NODE_TYPE_OPERATOR_BINARY_IN ||

View File

@ -41,24 +41,33 @@ using namespace arangodb::aql;
TraversalNode::EdgeConditionBuilder::EdgeConditionBuilder(
TraversalNode const* tn)
: _tn(tn), _containsCondition(false) {
_modCondition = _tn->_plan->getAst()->createNodeNaryOperator(NODE_TYPE_OPERATOR_NARY_AND);
}
_modCondition =
_tn->_plan->getAst()->createNodeNaryOperator(NODE_TYPE_OPERATOR_NARY_AND);
}
TraversalNode::EdgeConditionBuilder::EdgeConditionBuilder(
TraversalNode const* tn, arangodb::basics::Json const& condition)
: _tn(tn), _containsCondition(false) {
_modCondition = new AstNode(_tn->_plan->getAst(), condition);
TRI_ASSERT(_modCondition != nullptr);
TRI_ASSERT(_modCondition->type == NODE_TYPE_OPERATOR_NARY_AND);
}
_modCondition = new AstNode(_tn->_plan->getAst(), condition);
TRI_ASSERT(_modCondition != nullptr);
TRI_ASSERT(_modCondition->type == NODE_TYPE_OPERATOR_NARY_AND);
}
void TraversalNode::EdgeConditionBuilder::addConditionPart(AstNode const* part) {
TraversalNode::EdgeConditionBuilder::EdgeConditionBuilder(
TraversalNode const* tn, EdgeConditionBuilder const* other)
: _tn(tn),
_modCondition(other->_modCondition),
_containsCondition(other->_containsCondition) {}
void TraversalNode::EdgeConditionBuilder::addConditionPart(
AstNode const* part) {
_modCondition->addMember(part);
}
AstNode* TraversalNode::EdgeConditionBuilder::getOutboundCondition() {
if (_containsCondition) {
_modCondition->changeMember(_modCondition->numMembers() - 1, _tn->_fromCondition);
_modCondition->changeMember(_modCondition->numMembers() - 1,
_tn->_fromCondition);
} else {
for (auto& it : _tn->_globalEdgeConditions) {
_modCondition->addMember(it);
@ -125,7 +134,6 @@ TraversalNode::TraversalNode(ExecutionPlan* plan, size_t id,
_inVariable(nullptr),
_graphObj(nullptr),
_condition(nullptr),
_specializedNeighborsSearch(false),
_tmpObjVariable(_plan->getAst()->variables()->createTemporaryVariable()),
_tmpObjVarNode(_plan->getAst()->createNodeReference(_tmpObjVariable)),
_tmpIdNode(_plan->getAst()->createNodeValueString("", 0)),
@ -318,7 +326,7 @@ TraversalNode::TraversalNode(
std::vector<std::unique_ptr<aql::Collection>> const& edgeColls,
std::vector<std::unique_ptr<aql::Collection>> const& vertexColls,
Variable const* inVariable, std::string const& vertexId,
std::vector<TRI_edge_direction_e> directions,
std::vector<TRI_edge_direction_e> const& directions,
std::unique_ptr<traverser::TraverserOptions>& options)
: ExecutionNode(plan, id),
_vocbase(vocbase),
@ -330,7 +338,6 @@ TraversalNode::TraversalNode(
_directions(directions),
_graphObj(nullptr),
_condition(nullptr),
_specializedNeighborsSearch(false),
_fromCondition(nullptr),
_toCondition(nullptr),
_optionsBuild(false) {
@ -361,15 +368,14 @@ TraversalNode::TraversalNode(ExecutionPlan* plan,
_inVariable(nullptr),
_graphObj(nullptr),
_condition(nullptr),
_specializedNeighborsSearch(false),
_options(std::make_unique<traverser::TraverserOptions>(
_plan->getAst()->query()->trx(), base)),
_tmpObjVariable(nullptr),
_tmpObjVarNode(nullptr),
_tmpIdNode(nullptr),
_fromCondition(nullptr),
_toCondition(nullptr),
_optionsBuild(false) {
_options = std::make_unique<arangodb::traverser::TraverserOptions>(
_plan->getAst()->query()->trx(), base);
auto dirList = base.get("directions");
TRI_ASSERT(dirList.json() != nullptr);
for (size_t i = 0; i < dirList.size(); ++i) {
@ -569,12 +575,10 @@ TraversalNode::TraversalNode(ExecutionPlan* plan,
auto value = Json(TRI_UNKNOWN_MEM_ZONE,
static_cast<TRI_json_t const*>(
TRI_AtVector(&list->_value._objects, i + 1)));
_edgeConditions.emplace(std::make_pair(
StringUtils::uint64(key), EdgeConditionBuilder(this, value)));
auto ecbuilder = std::make_unique<EdgeConditionBuilder>(this, value);
_edgeConditions.emplace(StringUtils::uint64(key), std::move(ecbuilder));
}
}
_specializedNeighborsSearch = arangodb::basics::JsonHelper::getBooleanValue(base.json(), "specializedNeighborsSearch", false);
#ifdef TRI_ENABLE_MAINTAINER_MODE
checkConditionsDefined();
@ -647,14 +651,6 @@ bool TraversalNode::allDirectionsEqual() const {
return true;
}
void TraversalNode::specializeToNeighborsSearch() {
TRI_ASSERT(allDirectionsEqual());
TRI_ASSERT(!_directions.empty());
_specializedNeighborsSearch = true;
}
/// @brief toVelocyPack, for TraversalNode
void TraversalNode::toVelocyPackHelper(arangodb::velocypack::Builder& nodes,
bool verbose) const {
ExecutionNode::toVelocyPackHelperGeneric(nodes,
@ -791,7 +787,7 @@ void TraversalNode::toVelocyPackHelper(arangodb::velocypack::Builder& nodes,
nodes.openObject();
for (auto const& it : _edgeConditions) {
nodes.add(VPackValue(basics::StringUtils::itoa(it.first)));
it.second.toVelocyPack(nodes, verbose);
it.second->toVelocyPack(nodes, verbose);
}
nodes.close();
}
@ -840,10 +836,6 @@ ExecutionNode* TraversalNode::clone(ExecutionPlan* plan, bool withDependencies,
c->setPathOutput(pathOutVariable);
}
if (_specializedNeighborsSearch) {
c->specializeToNeighborsSearch();
}
c->_conditionVariables.reserve(_conditionVariables.size());
for (auto const& it: _conditionVariables) {
c->_conditionVariables.emplace(it->clone());
@ -869,7 +861,9 @@ ExecutionNode* TraversalNode::clone(ExecutionPlan* plan, bool withDependencies,
_globalVertexConditions.end());
for (auto const& it : _edgeConditions) {
c->_edgeConditions.emplace(it.first, it.second);
// Copy the builder
auto ecBuilder = std::make_unique<EdgeConditionBuilder>(this, it.second.get());
c->_edgeConditions.emplace(it.first, std::move(ecBuilder));
}
for (auto const& it : _vertexConditions) {
@ -934,7 +928,6 @@ void TraversalNode::prepareOptions() {
_options->_tmpVar = _tmpObjVariable;
size_t numEdgeColls = _edgeColls.size();
AstNode* condition = nullptr;
bool res = false;
EdgeConditionBuilder globalEdgeConditionBuilder(this);
Ast* ast = _plan->getAst();
@ -969,7 +962,7 @@ void TraversalNode::prepareOptions() {
_options->_baseLookupInfos.emplace_back(std::move(info));
}
for (std::pair<size_t, EdgeConditionBuilder> it : _edgeConditions) {
for (auto& it : _edgeConditions) {
auto ins = _options->_depthLookupInfo.emplace(
it.first, std::vector<traverser::TraverserOptions::LookupInfo>());
// We probably have to adopt minDepth. We cannot fulfill a condition of larger depth anyway
@ -988,10 +981,10 @@ void TraversalNode::prepareOptions() {
traverser::TraverserOptions::LookupInfo info;
switch (dir) {
case TRI_EDGE_IN:
info.indexCondition = builder.getInboundCondition()->clone(ast);
info.indexCondition = builder->getInboundCondition()->clone(ast);
break;
case TRI_EDGE_OUT:
info.indexCondition = builder.getOutboundCondition()->clone(ast);
info.indexCondition = builder->getOutboundCondition()->clone(ast);
break;
case TRI_EDGE_ANY:
TRI_ASSERT(false);
@ -1063,11 +1056,11 @@ void TraversalNode::registerCondition(bool isConditionOnEdge,
if (isConditionOnEdge) {
auto const& it = _edgeConditions.find(conditionLevel);
if (it == _edgeConditions.end()) {
EdgeConditionBuilder builder(this);
builder.addConditionPart(condition);
_edgeConditions.emplace(conditionLevel, builder);
auto builder = std::make_unique<EdgeConditionBuilder>(this);
builder->addConditionPart(condition);
_edgeConditions.emplace(conditionLevel, std::move(builder));
} else {
it->second.addConditionPart(condition);
it->second->addConditionPart(condition);
}
} else {
auto const& it = _vertexConditions.find(conditionLevel);

View File

@ -50,13 +50,19 @@ class TraversalNode : public ExecutionNode {
bool _containsCondition;
public:
EdgeConditionBuilder(TraversalNode const*);
explicit EdgeConditionBuilder(TraversalNode const*);
EdgeConditionBuilder(TraversalNode const*, arangodb::basics::Json const&);
EdgeConditionBuilder(TraversalNode const*, arangodb::basics::Json const&);
~EdgeConditionBuilder() {}
EdgeConditionBuilder(TraversalNode const*, EdgeConditionBuilder const*);
void addConditionPart(AstNode const*);
~EdgeConditionBuilder() {}
EdgeConditionBuilder(EdgeConditionBuilder const&) = delete;
EdgeConditionBuilder(EdgeConditionBuilder&&) = delete;
void addConditionPart(AstNode const*);
AstNode* getOutboundCondition();
@ -87,7 +93,7 @@ class TraversalNode : public ExecutionNode {
std::vector<std::unique_ptr<aql::Collection>> const& edgeColls,
std::vector<std::unique_ptr<aql::Collection>> const& vertexColls,
Variable const* inVariable, std::string const& vertexId,
std::vector<TRI_edge_direction_e> directions,
std::vector<TRI_edge_direction_e> const& directions,
std::unique_ptr<traverser::TraverserOptions>& options);
public:
@ -225,8 +231,6 @@ class TraversalNode : public ExecutionNode {
bool allDirectionsEqual() const;
void specializeToNeighborsSearch();
traverser::TraverserOptions* options() const;
AstNode* getTemporaryRefNode() const;
@ -303,10 +307,6 @@ class TraversalNode : public ExecutionNode {
/// @brief Options for traversals
std::unique_ptr<traverser::TraverserOptions> _options;
/// @brief Defines if you use a specialized neighbors search instead of general purpose
/// traversal
bool _specializedNeighborsSearch;
/// @brief Temporary pseudo variable for the currently traversed object.
Variable const* _tmpObjVariable;
@ -330,7 +330,7 @@ class TraversalNode : public ExecutionNode {
std::vector<AstNode const*> _globalVertexConditions;
/// @brief List of all depth specific conditions for edges
std::unordered_map<size_t, EdgeConditionBuilder> _edgeConditions;
std::unordered_map<size_t, std::unique_ptr<EdgeConditionBuilder>> _edgeConditions;
/// @brief List of all depth specific conditions for vertices
std::unordered_map<size_t, AstNode*> _vertexConditions;

View File

@ -106,49 +106,6 @@ void ClusterTraverser::fetchVertices() {
fetchVerticesFromEngines(_dbname, _engines, _verticesToFetch, _vertices,
*(lease.get()));
_verticesToFetch.clear();
#warning Reimplement this. Fetching Documents Coordinator-Case
/*
std::vector<TraverserExpression*> expVertices;
auto found = _opts.expressions->find(depth);
if (found != _opts.expressions->end()) {
expVertices = found->second;
}
int res = getFilteredDocumentsOnCoordinator(_dbname, expVertices,
verticesToFetch, _vertices);
if (res != TRI_ERROR_NO_ERROR &&
res != TRI_ERROR_ARANGO_COLLECTION_NOT_FOUND) {
THROW_ARANGO_EXCEPTION(res);
}
// By convention verticesToFetch now contains all _ids of vertices that
// could not be found.
// Store them as NULL
for (auto const& it : verticesToFetch) {
VPackBuilder builder;
builder.add(VPackValue(VPackValueType::Null));
_vertices.emplace(it, builder.steal());
}
*/
}
bool ClusterTraverser::vertexMatchesCondition(
VPackSlice const& v,
std::vector<arangodb::traverser::TraverserExpression*> const& exp) {
for (auto const& e : exp) {
if (!e->isEdgeAccess) {
if (v.isNone() || !e->matchesCheck(_trx, v)) {
++_filteredPaths;
return false;
}
}
}
return true;
}
bool ClusterTraverser::next() {
TRI_ASSERT(!_done);
return _enumerator->next();
}
aql::AqlValue ClusterTraverser::fetchVertexData(VPackSlice idString) {
@ -196,15 +153,3 @@ void ClusterTraverser::addEdgeToVelocyPack(arangodb::velocypack::Slice edge,
arangodb::velocypack::Builder& result) {
result.add(edge);
}
aql::AqlValue ClusterTraverser::lastVertexToAqlValue() {
return _enumerator->lastVertexToAqlValue();
}
aql::AqlValue ClusterTraverser::lastEdgeToAqlValue() {
return _enumerator->lastEdgeToAqlValue();
}
aql::AqlValue ClusterTraverser::pathToAqlValue(VPackBuilder& builder) {
return _enumerator->pathToAqlValue(builder);
}

View File

@ -64,32 +64,6 @@ class ClusterTraverser final : public Traverser {
bool getSingleVertex(arangodb::velocypack::Slice, arangodb::velocypack::Slice,
size_t, arangodb::velocypack::Slice&) override;
bool next() override;
//////////////////////////////////////////////////////////////////////////////
/// @brief Builds only the last vertex as AQLValue
//////////////////////////////////////////////////////////////////////////////
aql::AqlValue lastVertexToAqlValue() override;
//////////////////////////////////////////////////////////////////////////////
/// @brief Builds only the last edge as AQLValue
//////////////////////////////////////////////////////////////////////////////
aql::AqlValue lastEdgeToAqlValue() override;
//////////////////////////////////////////////////////////////////////////////
/// @brief Builds the complete path as AQLValue
/// Has the format:
/// {
/// vertices: [<vertex-as-velocypack>],
/// edges: [<edge-as-velocypack>]
/// }
/// NOTE: Will clear the given buffer and will leave the path in it.
//////////////////////////////////////////////////////////////////////////////
aql::AqlValue pathToAqlValue(arangodb::velocypack::Builder&) override;
protected:
//////////////////////////////////////////////////////////////////////////////
/// @brief Function to fetch the real data of a vertex into an AQLValue
@ -121,9 +95,6 @@ class ClusterTraverser final : public Traverser {
void fetchVertices();
bool vertexMatchesCondition(arangodb::velocypack::Slice const&,
std::vector<TraverserExpression*> const&);
std::unordered_map<arangodb::velocypack::Slice, arangodb::velocypack::Slice>
_edges;
@ -131,12 +102,8 @@ class ClusterTraverser final : public Traverser {
std::shared_ptr<arangodb::velocypack::Buffer<uint8_t>>>
_vertices;
std::stack<std::stack<std::string>> _iteratorCache;
std::string _dbname;
arangodb::velocypack::Builder _builder;
std::unordered_map<ServerID, traverser::TraverserEngineID> const* _engines;
std::unordered_set<arangodb::velocypack::Slice> _verticesToFetch;

View File

@ -183,7 +183,6 @@ void TraverserEngine::getVertexData(VPackSlice vertex, VPackBuilder& builder) {
TRI_ASSERT(vertex.isString() || vertex.isArray());
builder.openObject();
bool found;
int res = TRI_ERROR_NO_ERROR;
auto workOnOneDocument = [&](VPackSlice v) {
found = false;
StringRef id(v);
@ -199,7 +198,7 @@ void TraverserEngine::getVertexData(VPackSlice vertex, VPackBuilder& builder) {
}
builder.add(v);
for (std::string const& shard : shards->second) {
res = _trx->documentFastPath(shard, v, builder, false);
int res = _trx->documentFastPath(shard, v, builder, false);
if (res == TRI_ERROR_NO_ERROR) {
found = true;
// FOUND short circuit.
@ -233,7 +232,6 @@ void TraverserEngine::getVertexData(VPackSlice vertex, size_t depth,
TRI_ASSERT(vertex.isString() || vertex.isArray());
size_t read = 0;
size_t filtered = 0;
int res = TRI_ERROR_NO_ERROR;
bool found = false;
builder.openObject();
builder.add(VPackValue("vertices"));
@ -251,7 +249,7 @@ void TraverserEngine::getVertexData(VPackSlice vertex, size_t depth,
}
builder.add(v);
for (std::string const& shard : shards->second) {
res = _trx->documentFastPath(shard, v, builder, false);
int res = _trx->documentFastPath(shard, v, builder, false);
if (res == TRI_ERROR_NO_ERROR) {
read++;
found = true;

View File

@ -60,6 +60,9 @@ class TraverserEngine {
~TraverserEngine();
public:
// The engine is NOT copyable.
TraverserEngine(TraverserEngine const&) = delete;
void getEdges(arangodb::velocypack::Slice, size_t,
arangodb::velocypack::Builder&);

View File

@ -476,7 +476,6 @@ bool Transaction::findIndexHandleForAndNode(
Transaction::IndexHandle& usedIndex) const {
std::shared_ptr<Index> bestIndex;
double bestCost = 0.0;
size_t coveredAttributes = 0;
for (auto const& idx : indexes) {
double filterCost = 0.0;

View File

@ -22,6 +22,7 @@
////////////////////////////////////////////////////////////////////////////////
#include "SingleServerTraverser.h"
#include "Basics/StringRef.h"
#include "Utils/Transaction.h"
#include "VocBase/MasterPointer.h"
@ -36,19 +37,16 @@ using namespace arangodb::traverser;
////////////////////////////////////////////////////////////////////////////////
static int FetchDocumentById(arangodb::Transaction* trx,
std::string const& id,
StringRef const& id,
TRI_doc_mptr_t* mptr) {
size_t pos = id.find('/');
if (pos == std::string::npos) {
TRI_ASSERT(false);
return TRI_ERROR_INTERNAL;
}
if (id.find('/', pos + 1) != std::string::npos) {
TRI_ASSERT(false);
return TRI_ERROR_INTERNAL;
}
int res = trx->documentFastPathLocal(id.substr(0, pos), id.substr(pos + 1), mptr);
int res = trx->documentFastPathLocal(id.substr(0, pos).toString(),
id.substr(pos + 1).toString(), mptr);
if (res != TRI_ERROR_NO_ERROR && res != TRI_ERROR_ARANGO_DOCUMENT_NOT_FOUND) {
THROW_ARANGO_EXCEPTION(res);
@ -147,8 +145,8 @@ aql::AqlValue SingleServerTraverser::fetchVertexData(VPackSlice id) {
if (it == _vertices.end()) {
TRI_doc_mptr_t mptr;
#warning Do we need the copy here?
int res = FetchDocumentById(_trx, id.copyString(), &mptr);
StringRef ref(id);
int res = FetchDocumentById(_trx, ref, &mptr);
++_readDocuments;
if (res != TRI_ERROR_NO_ERROR) {
return aql::AqlValue(basics::VelocyPackHelper::NullValue());
@ -173,8 +171,8 @@ void SingleServerTraverser::addVertexToVelocyPack(VPackSlice id,
if (it == _vertices.end()) {
TRI_doc_mptr_t mptr;
#warning Do we need the copy here?
int res = FetchDocumentById(_trx, id.copyString(), &mptr);
StringRef ref(id);
int res = FetchDocumentById(_trx, ref, &mptr);
++_readDocuments;
if (res != TRI_ERROR_NO_ERROR) {
result.add(basics::VelocyPackHelper::NullValue());
@ -223,24 +221,3 @@ bool SingleServerTraverser::getSingleVertex(VPackSlice edge, VPackSlice vertex,
size_t depth, VPackSlice& result) {
return _vertexGetter->getSingleVertex(edge, vertex, depth, result);
}
bool SingleServerTraverser::next() {
TRI_ASSERT(!_done);
bool res = _enumerator->next();
if (!res) {
_done = true;
}
return res;
}
aql::AqlValue SingleServerTraverser::lastVertexToAqlValue() {
return _enumerator->lastVertexToAqlValue();
}
aql::AqlValue SingleServerTraverser::lastEdgeToAqlValue() {
return _enumerator->lastEdgeToAqlValue();
}
aql::AqlValue SingleServerTraverser::pathToAqlValue(VPackBuilder& builder) {
return _enumerator->pathToAqlValue(builder);
}

View File

@ -88,36 +88,6 @@ class SingleServerTraverser final : public Traverser {
bool getSingleVertex(arangodb::velocypack::Slice, arangodb::velocypack::Slice,
size_t depth, arangodb::velocypack::Slice&) override;
//////////////////////////////////////////////////////////////////////////////
/// @brief Get the next possible path in the graph.
//////////////////////////////////////////////////////////////////////////////
bool next() override;
//////////////////////////////////////////////////////////////////////////////
/// @brief Builds only the last vertex as AQLValue
//////////////////////////////////////////////////////////////////////////////
aql::AqlValue lastVertexToAqlValue() override;
//////////////////////////////////////////////////////////////////////////////
/// @brief Builds only the last edge as AQLValue
//////////////////////////////////////////////////////////////////////////////
aql::AqlValue lastEdgeToAqlValue() override;
//////////////////////////////////////////////////////////////////////////////
/// @brief Builds the complete path as AQLValue
/// Has the format:
/// {
/// vertices: [<vertex-as-velocypack>],
/// edges: [<edge-as-velocypack>]
/// }
/// NOTE: Will clear the given buffer and will leave the path in it.
//////////////////////////////////////////////////////////////////////////////
aql::AqlValue pathToAqlValue(arangodb::velocypack::Builder&) override;
protected:
//////////////////////////////////////////////////////////////////////////////
/// @brief Function to fetch the real data of a vertex into an AQLValue

View File

@ -376,3 +376,24 @@ bool arangodb::traverser::Traverser::vertexMatchesConditions(VPackSlice v, size_
return true;
}
bool arangodb::traverser::Traverser::next() {
TRI_ASSERT(!_done);
bool res = _enumerator->next();
if (!res) {
_done = true;
}
return res;
}
arangodb::aql::AqlValue arangodb::traverser::Traverser::lastVertexToAqlValue() {
return _enumerator->lastVertexToAqlValue();
}
arangodb::aql::AqlValue arangodb::traverser::Traverser::lastEdgeToAqlValue() {
return _enumerator->lastEdgeToAqlValue();
}
arangodb::aql::AqlValue arangodb::traverser::Traverser::pathToAqlValue(
VPackBuilder& builder) {
return _enumerator->pathToAqlValue(builder);
}

View File

@ -50,7 +50,7 @@ namespace traverser {
struct TraverserOptions;
#warning Deprecated
//TODO Deprecated
class TraverserExpression {
public:
bool isEdgeAccess;
@ -298,11 +298,8 @@ class Traverser {
return skipped;
}
//////////////////////////////////////////////////////////////////////////////
/// @brief Get the next possible path in the graph.
//////////////////////////////////////////////////////////////////////////////
virtual bool next() = 0;
bool next();
/// @brief Function to load the other sides vertex of an edge
/// Returns true if the vertex passes filtering conditions
@ -322,13 +319,13 @@ class Traverser {
/// @brief Builds only the last vertex as AQLValue
//////////////////////////////////////////////////////////////////////////////
virtual aql::AqlValue lastVertexToAqlValue() = 0;
aql::AqlValue lastVertexToAqlValue();
//////////////////////////////////////////////////////////////////////////////
/// @brief Builds only the last edge as AQLValue
//////////////////////////////////////////////////////////////////////////////
virtual aql::AqlValue lastEdgeToAqlValue() = 0;
aql::AqlValue lastEdgeToAqlValue();
//////////////////////////////////////////////////////////////////////////////
/// @brief Builds the complete path as AQLValue
@ -340,7 +337,7 @@ class Traverser {
/// NOTE: Will clear the given buffer and will leave the path in it.
//////////////////////////////////////////////////////////////////////////////
virtual aql::AqlValue pathToAqlValue(arangodb::velocypack::Builder&) = 0;
aql::AqlValue pathToAqlValue(arangodb::velocypack::Builder&);
//////////////////////////////////////////////////////////////////////////////
/// @brief Get the number of filtered paths

View File

@ -472,7 +472,6 @@ bool arangodb::traverser::TraverserOptions::evaluateEdgeExpression(
// The Coordinator never checks conditions. The DBServer is responsible!
return true;
}
bool mustDestroy = false;
auto specific = _depthLookupInfo.find(depth);
arangodb::aql::Expression* expression = nullptr;
@ -506,17 +505,21 @@ bool arangodb::traverser::TraverserOptions::evaluateEdgeExpression(
idNode->stealComputedValue();
idNode->setStringValue(vid, vidLength);
bool mustDestroy = false;
aql::AqlValue res = expression->execute(_trx, _ctx, mustDestroy);
TRI_ASSERT(res.isBoolean());
expression->clearVariable(_tmpVar);
return res.toBoolean();
bool result = res.toBoolean();
if (mustDestroy) {
res.destroy();
}
return result;
}
return true;
}
bool arangodb::traverser::TraverserOptions::evaluateVertexExpression(
arangodb::velocypack::Slice vertex, size_t depth) const {
bool mustDestroy = false;
arangodb::aql::Expression* expression = nullptr;
auto specific = _vertexExpressions.find(depth);
@ -532,10 +535,15 @@ bool arangodb::traverser::TraverserOptions::evaluateVertexExpression(
TRI_ASSERT(!expression->isV8());
expression->setVariable(_tmpVar, vertex);
bool mustDestroy = false;
aql::AqlValue res = expression->execute(_trx, _ctx, mustDestroy);
TRI_ASSERT(res.isBoolean());
bool result = res.toBoolean();
expression->clearVariable(_tmpVar);
return res.toBoolean();
if (mustDestroy) {
res.destroy();
}
return result;
}
arangodb::traverser::EdgeCursor*

View File

@ -115,6 +115,7 @@ struct TraverserOptions {
_baseVertexExpression(nullptr),
_tmpVar(nullptr),
_ctx(new aql::FixedVarExpressionContext()),
_traverser(nullptr),
minDepth(1),
maxDepth(1),
useBreadthFirst(false),