1
0
Fork 0

Internal cleanup of TraversalOptions. Now the options know the the expressions not the traverser any more. Preparation to use other indexes

This commit is contained in:
Michael Hackstein 2016-07-06 22:42:46 +02:00
parent 617a833040
commit b285cd26a3
6 changed files with 68 additions and 74 deletions

View File

@ -53,7 +53,7 @@ TraversalBlock::TraversalBlock(ExecutionEngine* engine, TraversalNode const* ep)
_pathReg(0), _pathReg(0),
_expressions(ep->expressions()), _expressions(ep->expressions()),
_hasV8Expression(false) { _hasV8Expression(false) {
arangodb::traverser::TraverserOptions opts(_trx); arangodb::traverser::TraverserOptions opts(_trx, _expressions);
ep->fillTraversalOptions(opts); ep->fillTraversalOptions(opts);
auto ast = ep->_plan->getAst(); auto ast = ep->_plan->getAst();
@ -91,10 +91,10 @@ TraversalBlock::TraversalBlock(ExecutionEngine* engine, TraversalNode const* ep)
_traverser.reset(new arangodb::traverser::ClusterTraverser( _traverser.reset(new arangodb::traverser::ClusterTraverser(
ep->edgeColls(), opts, ep->edgeColls(), opts,
std::string(_trx->vocbase()->_name, strlen(_trx->vocbase()->_name)), std::string(_trx->vocbase()->_name, strlen(_trx->vocbase()->_name)),
_trx, _expressions)); _trx));
} else { } else {
_traverser.reset( _traverser.reset(
new arangodb::traverser::SingleServerTraverser(opts, _trx, _expressions)); new arangodb::traverser::SingleServerTraverser(opts, _trx));
} }
if (!ep->usesInVariable()) { if (!ep->usesInVariable()) {
_vertexId = ep->getStartVertex(); _vertexId = ep->getStartVertex();

View File

@ -47,8 +47,8 @@ bool ClusterTraverser::VertexGetter::getVertex(std::string const& edgeId,
std::string to = slice.get(StaticStrings::ToString).copyString(); std::string to = slice.get(StaticStrings::ToString).copyString();
result = std::move(to); result = std::move(to);
} }
auto exp = _traverser->_expressions->find(depth); auto exp = _traverser->_opts.expressions->find(depth);
if (exp != _traverser->_expressions->end()) { if (exp != _traverser->_opts.expressions->end()) {
auto v = _traverser->_vertices.find(result); auto v = _traverser->_vertices.find(result);
if (v == _traverser->_vertices.end()) { if (v == _traverser->_vertices.end()) {
// If the vertex ist not in list it means it has not passed any // If the vertex ist not in list it means it has not passed any
@ -95,8 +95,8 @@ bool ClusterTraverser::UniqueVertexGetter::getVertex(
return false; return false;
} }
auto exp = _traverser->_expressions->find(depth); auto exp = _traverser->_opts.expressions->find(depth);
if (exp != _traverser->_expressions->end()) { if (exp != _traverser->_opts.expressions->end()) {
auto v = _traverser->_vertices.find(result); auto v = _traverser->_vertices.find(result);
if (v == _traverser->_vertices.end()) { if (v == _traverser->_vertices.end()) {
// If the vertex ist not in list it means it has not passed any // 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 // We have to request the next level
arangodb::GeneralResponse::ResponseCode responseCode; arangodb::GeneralResponse::ResponseCode responseCode;
std::vector<TraverserExpression*> expEdges; std::vector<TraverserExpression*> expEdges;
auto found = _traverser->_expressions->find(depth); auto found = _traverser->_opts.expressions->find(depth);
if (found != _traverser->_expressions->end()) { if (found != _traverser->_opts.expressions->end()) {
expEdges = found->second; expEdges = found->second;
} }
@ -254,8 +254,8 @@ void ClusterTraverser::ClusterEdgeGetter::getAllEdges(
TRI_edge_direction_e dir; TRI_edge_direction_e dir;
size_t eColIdx = 0; size_t eColIdx = 0;
std::vector<TraverserExpression*> expEdges; std::vector<TraverserExpression*> expEdges;
auto found = _traverser->_expressions->find(depth); auto found = _traverser->_opts.expressions->find(depth);
if (found != _traverser->_expressions->end()) { if (found != _traverser->_opts.expressions->end()) {
expEdges = found->second; expEdges = found->second;
} }
@ -348,8 +348,8 @@ void ClusterTraverser::setStartVertex(std::string const& id) {
} }
} }
auto exp = _expressions->find(0); auto exp = _opts.expressions->find(0);
if (exp != _expressions->end() && if (exp != _opts.expressions->end() &&
!vertexMatchesCondition(VPackSlice(it->second->data()), exp->second)) { !vertexMatchesCondition(VPackSlice(it->second->data()), exp->second)) {
// We can stop here. The start vertex does not match condition // We can stop here. The start vertex does not match condition
_done = true; _done = true;
@ -378,8 +378,8 @@ void ClusterTraverser::fetchVertices(std::unordered_set<std::string>& verticesTo
_readDocuments += verticesToFetch.size(); _readDocuments += verticesToFetch.size();
std::vector<TraverserExpression*> expVertices; std::vector<TraverserExpression*> expVertices;
auto found = _expressions->find(depth); auto found = _opts.expressions->find(depth);
if (found != _expressions->end()) { if (found != _opts.expressions->end()) {
expVertices = found->second; expVertices = found->second;
} }

View File

@ -40,10 +40,8 @@ class ClusterTraverser final : public Traverser {
public: public:
ClusterTraverser( ClusterTraverser(
std::vector<std::string> edgeCollections, TraverserOptions& opts, std::vector<std::string> edgeCollections, TraverserOptions& opts,
std::string const& dbname, Transaction* trx, std::string const& dbname, Transaction* trx)
std::unordered_map<size_t, std::vector<TraverserExpression*>> const* : Traverser(opts),
expressions)
: Traverser(opts, expressions),
_edgeCols(edgeCollections), _edgeCols(edgeCollections),
_dbname(dbname), _dbname(dbname),
_trx(trx) { _trx(trx) {

View File

@ -56,12 +56,9 @@ static int FetchDocumentById(arangodb::Transaction* trx,
return res; return res;
} }
SingleServerTraverser::SingleServerTraverser( SingleServerTraverser::SingleServerTraverser(TraverserOptions& opts,
TraverserOptions& opts, arangodb::Transaction* trx, arangodb::Transaction* trx)
std::unordered_map<size_t, std::vector<TraverserExpression*>> const* : Traverser(opts), _trx(trx) {
expressions)
: Traverser(opts, expressions), _trx(trx) {
_edgeGetter = std::make_unique<EdgeGetter>(this, opts, trx); _edgeGetter = std::make_unique<EdgeGetter>(this, opts, trx);
if (opts.uniqueVertices == TraverserOptions::UniquenessLevel::GLOBAL) { if (opts.uniqueVertices == TraverserOptions::UniquenessLevel::GLOBAL) {
_vertexGetter = std::make_unique<UniqueVertexGetter>(this); _vertexGetter = std::make_unique<UniqueVertexGetter>(this);
@ -73,11 +70,11 @@ SingleServerTraverser::SingleServerTraverser(
SingleServerTraverser::~SingleServerTraverser() {} SingleServerTraverser::~SingleServerTraverser() {}
bool SingleServerTraverser::edgeMatchesConditions(VPackSlice e, size_t depth) { bool SingleServerTraverser::edgeMatchesConditions(VPackSlice e, size_t depth) {
if (_hasEdgeConditions) { if (_opts.hasEdgeConditions) {
TRI_ASSERT(_expressions != nullptr); TRI_ASSERT(_opts.expressions != nullptr);
auto it = _expressions->find(depth); auto it = _opts.expressions->find(depth);
if (it != _expressions->end()) { if (it != _opts.expressions->end()) {
for (auto const& exp : it->second) { for (auto const& exp : it->second) {
TRI_ASSERT(exp != nullptr); TRI_ASSERT(exp != nullptr);
@ -93,11 +90,11 @@ bool SingleServerTraverser::edgeMatchesConditions(VPackSlice e, size_t depth) {
bool SingleServerTraverser::vertexMatchesConditions(std::string const& v, bool SingleServerTraverser::vertexMatchesConditions(std::string const& v,
size_t depth) { size_t depth) {
if (_hasVertexConditions) { if (_opts.hasVertexConditions) {
TRI_ASSERT(_expressions != nullptr); TRI_ASSERT(_opts.expressions != nullptr);
auto it = _expressions->find(depth); auto it = _opts.expressions->find(depth);
if (it != _expressions->end()) { if (it != _opts.expressions->end()) {
bool fetchVertex = true; bool fetchVertex = true;
aql::AqlValue vertex; aql::AqlValue vertex;
for (auto const& exp : it->second) { 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) { void SingleServerTraverser::setStartVertex(std::string const& v) {
_pruneNext = false; _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()) { if (!it->second.empty()) {
TRI_doc_mptr_t vertex; TRI_doc_mptr_t vertex;
bool fetchVertex = true; bool fetchVertex = true;

View File

@ -171,11 +171,9 @@ class SingleServerTraverser final : public Traverser {
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
public: public:
SingleServerTraverser( SingleServerTraverser(TraverserOptions&, Transaction*);
TraverserOptions&, Transaction*,
std::unordered_map<size_t, std::vector<TraverserExpression*>> const*); ~SingleServerTraverser();
~SingleServerTraverser();
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
/// @brief Reset the traverser to use another start vertex /// @brief Reset the traverser to use another start vertex

View File

@ -216,13 +216,43 @@ struct TraverserOptions {
UniquenessLevel uniqueEdges; UniquenessLevel uniqueEdges;
explicit TraverserOptions(arangodb::Transaction* trx) //////////////////////////////////////////////////////////////////////////////
/// @brief a vector containing all information for early pruning
//////////////////////////////////////////////////////////////////////////////
std::unordered_map<size_t, std::vector<TraverserExpression*>> const* expressions;
//////////////////////////////////////////////////////////////////////////////
/// @brief whether or not we have valid expressions
//////////////////////////////////////////////////////////////////////////////
bool hasEdgeConditions;
bool hasVertexConditions;
explicit TraverserOptions(
arangodb::Transaction* trx,
std::unordered_map<size_t, std::vector<TraverserExpression*>> const* expr)
: _trx(trx), : _trx(trx),
minDepth(1), minDepth(1),
maxDepth(1), maxDepth(1),
useBreadthFirst(false), useBreadthFirst(false),
uniqueVertices(UniquenessLevel::NONE), 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<std::string> const&, TRI_edge_direction_e); void setCollections(std::vector<std::string> const&, TRI_edge_direction_e);
void setCollections(std::vector<std::string> const&, void setCollections(std::vector<std::string> const&,
@ -246,28 +276,13 @@ class Traverser {
/// @brief Constructor. This is an abstract only class. /// @brief Constructor. This is an abstract only class.
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
Traverser(TraverserOptions& opts, Traverser(TraverserOptions& opts)
std::unordered_map<size_t, std::vector<TraverserExpression*>> const*
expressions)
: _readDocuments(0), : _readDocuments(0),
_filteredPaths(0), _filteredPaths(0),
_pruneNext(false), _pruneNext(false),
_done(true), _done(true),
_hasVertexConditions(false), _opts(opts) {
_hasEdgeConditions(false),
_opts(opts),
_expressions(expressions) {
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; bool _done;
//////////////////////////////////////////////////////////////////////////////
/// @brief whether or not we have valid expressions
//////////////////////////////////////////////////////////////////////////////
bool _hasVertexConditions;
bool _hasEdgeConditions;
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
/// @brief options for traversal /// @brief options for traversal
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
TraverserOptions _opts; TraverserOptions _opts;
//////////////////////////////////////////////////////////////////////////////
/// @brief a vector containing all information for early pruning
//////////////////////////////////////////////////////////////////////////////
std::unordered_map<size_t, std::vector<TraverserExpression*>> const*
_expressions;
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
/// @brief Function to fetch the real data of a vertex into an AQLValue /// @brief Function to fetch the real data of a vertex into an AQLValue
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////