From b285cd26a32d53c091486cbb99a78cdac8d06dfa Mon Sep 17 00:00:00 2001 From: Michael Hackstein Date: Wed, 6 Jul 2016 22:42:46 +0200 Subject: [PATCH] Internal cleanup of TraversalOptions. Now the options know the the expressions not the traverser any more. Preparation to use other indexes --- arangod/Aql/TraversalBlock.cpp | 6 +- arangod/Cluster/ClusterTraverser.cpp | 24 ++++---- arangod/Cluster/ClusterTraverser.h | 6 +- arangod/VocBase/SingleServerTraverser.cpp | 31 +++++------ arangod/VocBase/SingleServerTraverser.h | 8 +-- arangod/VocBase/Traverser.h | 67 ++++++++++++----------- 6 files changed, 68 insertions(+), 74 deletions(-) diff --git a/arangod/Aql/TraversalBlock.cpp b/arangod/Aql/TraversalBlock.cpp index d0877d5042..c44a0c18a8 100644 --- a/arangod/Aql/TraversalBlock.cpp +++ b/arangod/Aql/TraversalBlock.cpp @@ -53,7 +53,7 @@ TraversalBlock::TraversalBlock(ExecutionEngine* engine, TraversalNode const* ep) _pathReg(0), _expressions(ep->expressions()), _hasV8Expression(false) { - arangodb::traverser::TraverserOptions opts(_trx); + arangodb::traverser::TraverserOptions opts(_trx, _expressions); ep->fillTraversalOptions(opts); auto ast = ep->_plan->getAst(); @@ -91,10 +91,10 @@ TraversalBlock::TraversalBlock(ExecutionEngine* engine, TraversalNode const* ep) _traverser.reset(new arangodb::traverser::ClusterTraverser( ep->edgeColls(), opts, std::string(_trx->vocbase()->_name, strlen(_trx->vocbase()->_name)), - _trx, _expressions)); + _trx)); } else { _traverser.reset( - new arangodb::traverser::SingleServerTraverser(opts, _trx, _expressions)); + new arangodb::traverser::SingleServerTraverser(opts, _trx)); } if (!ep->usesInVariable()) { _vertexId = ep->getStartVertex(); diff --git a/arangod/Cluster/ClusterTraverser.cpp b/arangod/Cluster/ClusterTraverser.cpp index 9726fc4a5b..78f326589a 100644 --- a/arangod/Cluster/ClusterTraverser.cpp +++ b/arangod/Cluster/ClusterTraverser.cpp @@ -47,8 +47,8 @@ bool ClusterTraverser::VertexGetter::getVertex(std::string const& edgeId, std::string to = slice.get(StaticStrings::ToString).copyString(); result = std::move(to); } - auto exp = _traverser->_expressions->find(depth); - if (exp != _traverser->_expressions->end()) { + auto exp = _traverser->_opts.expressions->find(depth); + if (exp != _traverser->_opts.expressions->end()) { auto v = _traverser->_vertices.find(result); if (v == _traverser->_vertices.end()) { // If the vertex ist not in list it means it has not passed any @@ -95,8 +95,8 @@ bool ClusterTraverser::UniqueVertexGetter::getVertex( return false; } - auto exp = _traverser->_expressions->find(depth); - if (exp != _traverser->_expressions->end()) { + auto exp = _traverser->_opts.expressions->find(depth); + if (exp != _traverser->_opts.expressions->end()) { auto v = _traverser->_vertices.find(result); if (v == _traverser->_vertices.end()) { // If the vertex ist not in list it means it has not passed any @@ -137,8 +137,8 @@ void ClusterTraverser::ClusterEdgeGetter::getEdge( // We have to request the next level arangodb::GeneralResponse::ResponseCode responseCode; std::vector expEdges; - auto found = _traverser->_expressions->find(depth); - if (found != _traverser->_expressions->end()) { + auto found = _traverser->_opts.expressions->find(depth); + if (found != _traverser->_opts.expressions->end()) { expEdges = found->second; } @@ -254,8 +254,8 @@ void ClusterTraverser::ClusterEdgeGetter::getAllEdges( TRI_edge_direction_e dir; size_t eColIdx = 0; std::vector expEdges; - auto found = _traverser->_expressions->find(depth); - if (found != _traverser->_expressions->end()) { + auto found = _traverser->_opts.expressions->find(depth); + if (found != _traverser->_opts.expressions->end()) { expEdges = found->second; } @@ -348,8 +348,8 @@ void ClusterTraverser::setStartVertex(std::string const& id) { } } - auto exp = _expressions->find(0); - if (exp != _expressions->end() && + auto exp = _opts.expressions->find(0); + if (exp != _opts.expressions->end() && !vertexMatchesCondition(VPackSlice(it->second->data()), exp->second)) { // We can stop here. The start vertex does not match condition _done = true; @@ -378,8 +378,8 @@ void ClusterTraverser::fetchVertices(std::unordered_set& verticesTo _readDocuments += verticesToFetch.size(); std::vector expVertices; - auto found = _expressions->find(depth); - if (found != _expressions->end()) { + auto found = _opts.expressions->find(depth); + if (found != _opts.expressions->end()) { expVertices = found->second; } diff --git a/arangod/Cluster/ClusterTraverser.h b/arangod/Cluster/ClusterTraverser.h index c4dbfcec0a..e2cf495f21 100644 --- a/arangod/Cluster/ClusterTraverser.h +++ b/arangod/Cluster/ClusterTraverser.h @@ -40,10 +40,8 @@ class ClusterTraverser final : public Traverser { public: ClusterTraverser( std::vector edgeCollections, TraverserOptions& opts, - std::string const& dbname, Transaction* trx, - std::unordered_map> const* - expressions) - : Traverser(opts, expressions), + std::string const& dbname, Transaction* trx) + : Traverser(opts), _edgeCols(edgeCollections), _dbname(dbname), _trx(trx) { diff --git a/arangod/VocBase/SingleServerTraverser.cpp b/arangod/VocBase/SingleServerTraverser.cpp index 2cdd2e3bbd..14c6f177cc 100644 --- a/arangod/VocBase/SingleServerTraverser.cpp +++ b/arangod/VocBase/SingleServerTraverser.cpp @@ -56,12 +56,9 @@ static int FetchDocumentById(arangodb::Transaction* trx, return res; } -SingleServerTraverser::SingleServerTraverser( - TraverserOptions& opts, arangodb::Transaction* trx, - std::unordered_map> const* - expressions) - : Traverser(opts, expressions), _trx(trx) { - +SingleServerTraverser::SingleServerTraverser(TraverserOptions& opts, + arangodb::Transaction* trx) + : Traverser(opts), _trx(trx) { _edgeGetter = std::make_unique(this, opts, trx); if (opts.uniqueVertices == TraverserOptions::UniquenessLevel::GLOBAL) { _vertexGetter = std::make_unique(this); @@ -73,11 +70,11 @@ SingleServerTraverser::SingleServerTraverser( SingleServerTraverser::~SingleServerTraverser() {} bool SingleServerTraverser::edgeMatchesConditions(VPackSlice e, size_t depth) { - if (_hasEdgeConditions) { - TRI_ASSERT(_expressions != nullptr); - auto it = _expressions->find(depth); + if (_opts.hasEdgeConditions) { + TRI_ASSERT(_opts.expressions != nullptr); + auto it = _opts.expressions->find(depth); - if (it != _expressions->end()) { + if (it != _opts.expressions->end()) { for (auto const& exp : it->second) { TRI_ASSERT(exp != nullptr); @@ -93,11 +90,11 @@ bool SingleServerTraverser::edgeMatchesConditions(VPackSlice e, size_t depth) { bool SingleServerTraverser::vertexMatchesConditions(std::string const& v, size_t depth) { - if (_hasVertexConditions) { - TRI_ASSERT(_expressions != nullptr); - auto it = _expressions->find(depth); + if (_opts.hasVertexConditions) { + TRI_ASSERT(_opts.expressions != nullptr); + auto it = _opts.expressions->find(depth); - if (it != _expressions->end()) { + if (it != _opts.expressions->end()) { bool fetchVertex = true; aql::AqlValue vertex; for (auto const& exp : it->second) { @@ -229,11 +226,11 @@ void SingleServerTraverser::UniqueVertexGetter::reset(std::string const& startVe void SingleServerTraverser::setStartVertex(std::string const& v) { _pruneNext = false; - TRI_ASSERT(_expressions != nullptr); + TRI_ASSERT(_opts.expressions != nullptr); - auto it = _expressions->find(0); + auto it = _opts.expressions->find(0); - if (it != _expressions->end()) { + if (it != _opts.expressions->end()) { if (!it->second.empty()) { TRI_doc_mptr_t vertex; bool fetchVertex = true; diff --git a/arangod/VocBase/SingleServerTraverser.h b/arangod/VocBase/SingleServerTraverser.h index d378663b57..42dfb93e13 100644 --- a/arangod/VocBase/SingleServerTraverser.h +++ b/arangod/VocBase/SingleServerTraverser.h @@ -171,11 +171,9 @@ class SingleServerTraverser final : public Traverser { ////////////////////////////////////////////////////////////////////////////// public: - SingleServerTraverser( - TraverserOptions&, Transaction*, - std::unordered_map> const*); - - ~SingleServerTraverser(); + SingleServerTraverser(TraverserOptions&, Transaction*); + + ~SingleServerTraverser(); ////////////////////////////////////////////////////////////////////////////// /// @brief Reset the traverser to use another start vertex diff --git a/arangod/VocBase/Traverser.h b/arangod/VocBase/Traverser.h index 5bf94be98c..28bdfcba89 100644 --- a/arangod/VocBase/Traverser.h +++ b/arangod/VocBase/Traverser.h @@ -216,13 +216,43 @@ struct TraverserOptions { UniquenessLevel uniqueEdges; - explicit TraverserOptions(arangodb::Transaction* trx) + ////////////////////////////////////////////////////////////////////////////// + /// @brief a vector containing all information for early pruning + ////////////////////////////////////////////////////////////////////////////// + + std::unordered_map> const* expressions; + + ////////////////////////////////////////////////////////////////////////////// + /// @brief whether or not we have valid expressions + ////////////////////////////////////////////////////////////////////////////// + + bool hasEdgeConditions; + + bool hasVertexConditions; + + explicit TraverserOptions( + arangodb::Transaction* trx, + std::unordered_map> const* expr) : _trx(trx), minDepth(1), maxDepth(1), useBreadthFirst(false), uniqueVertices(UniquenessLevel::NONE), - uniqueEdges(UniquenessLevel::PATH) {} + uniqueEdges(UniquenessLevel::PATH), + expressions(expr), + hasEdgeConditions(false), + hasVertexConditions(false) { + TRI_ASSERT(expressions != nullptr); + for (auto& it : *expressions) { + for (auto& it2 : it.second) { + if (it2->isEdgeAccess) { + hasEdgeConditions = true; + } else { + hasVertexConditions = true; + } + } + } + } void setCollections(std::vector const&, TRI_edge_direction_e); void setCollections(std::vector const&, @@ -246,28 +276,13 @@ class Traverser { /// @brief Constructor. This is an abstract only class. ////////////////////////////////////////////////////////////////////////////// - Traverser(TraverserOptions& opts, - std::unordered_map> const* - expressions) + Traverser(TraverserOptions& opts) : _readDocuments(0), _filteredPaths(0), _pruneNext(false), _done(true), - _hasVertexConditions(false), - _hasEdgeConditions(false), - _opts(opts), - _expressions(expressions) { + _opts(opts) { - TRI_ASSERT(_expressions != nullptr); - for (auto& it : *_expressions) { - for (auto& it2 : it.second) { - if (it2->isEdgeAccess) { - _hasEdgeConditions = true; - } else { - _hasVertexConditions = true; - } - } - } } ////////////////////////////////////////////////////////////////////////////// @@ -411,26 +426,12 @@ class Traverser { bool _done; - ////////////////////////////////////////////////////////////////////////////// - /// @brief whether or not we have valid expressions - ////////////////////////////////////////////////////////////////////////////// - - bool _hasVertexConditions; - bool _hasEdgeConditions; - ////////////////////////////////////////////////////////////////////////////// /// @brief options for traversal ////////////////////////////////////////////////////////////////////////////// TraverserOptions _opts; - ////////////////////////////////////////////////////////////////////////////// - /// @brief a vector containing all information for early pruning - ////////////////////////////////////////////////////////////////////////////// - - std::unordered_map> const* - _expressions; - ////////////////////////////////////////////////////////////////////////////// /// @brief Function to fetch the real data of a vertex into an AQLValue //////////////////////////////////////////////////////////////////////////////