mirror of https://gitee.com/bigwinds/arangodb
Adapted traverser implementations to new Path Enumerator for improved pruning
This commit is contained in:
parent
d0021131b5
commit
a7b7d1ec18
|
@ -68,19 +68,26 @@ triagens::basics::Json* ClusterTraversalPath::lastVertexToJson (Transaction*,
|
|||
// --SECTION-- class ClusterTraverser
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
std::string ClusterTraverser::VertexGetter::operator() (std::string const& edgeId,
|
||||
std::string const& vertexId) {
|
||||
auto it = _edges->find(edgeId);
|
||||
bool ClusterTraverser::VertexGetter::operator() (std::string const& edgeId,
|
||||
std::string const& vertexId,
|
||||
size_t depth,
|
||||
std::string& result) {
|
||||
auto it = _traverser->_edges.find(edgeId);
|
||||
std::string def = "";
|
||||
if (it != _edges->end()) {
|
||||
if (it != _traverser->_edges.end()) {
|
||||
std::string from = triagens::basics::JsonHelper::getStringValue(it->second, "_from", def);
|
||||
if (from != vertexId) {
|
||||
return from;
|
||||
result = from;
|
||||
}
|
||||
std::string to = triagens::basics::JsonHelper::getStringValue(it->second, "_to", def);
|
||||
return to;
|
||||
else {
|
||||
std::string to = triagens::basics::JsonHelper::getStringValue(it->second, "_to", def);
|
||||
result = to;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return def;
|
||||
TRI_ASSERT(false);
|
||||
result = def;
|
||||
return false;
|
||||
}
|
||||
|
||||
void ClusterTraverser::EdgeGetter::operator() (std::string const& startVertex,
|
||||
|
@ -157,6 +164,10 @@ void ClusterTraverser::EdgeGetter::operator() (std::string const& startVertex,
|
|||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
THROW_ARANGO_EXCEPTION(res);
|
||||
}
|
||||
if (! expVertices.empty() && ! verticesToFetch.empty()) {
|
||||
// There are some vertices that either do not exist or do not match the filter.
|
||||
// We have to exclude these from the traversal
|
||||
}
|
||||
std::string next = stack.top();
|
||||
stack.pop();
|
||||
last = &_continueConst;
|
||||
|
@ -188,6 +199,50 @@ void ClusterTraverser::setStartVertex (VertexId& v) {
|
|||
std::string id = v.toString(_resolver);
|
||||
_enumerator.reset(new triagens::basics::PathEnumerator<std::string, std::string, size_t> (_edgeGetter, _vertexGetter, id));
|
||||
_done = false;
|
||||
auto it = _vertices.find(id);
|
||||
if (it == _vertices.end()) {
|
||||
triagens::rest::HttpResponse::HttpResponseCode responseCode;
|
||||
std::map<std::string, std::string> headers;
|
||||
std::map<std::string, std::string> resultHeaders;
|
||||
std::vector<std::string> splitId = triagens::basics::StringUtils::split(id, '/');
|
||||
TRI_ASSERT(splitId.size() == 2);
|
||||
std::string vertexResult;
|
||||
int res = getDocumentOnCoordinator(_dbname,
|
||||
splitId[0],
|
||||
splitId[1],
|
||||
0,
|
||||
headers,
|
||||
true,
|
||||
responseCode,
|
||||
resultHeaders,
|
||||
vertexResult);
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
THROW_ARANGO_EXCEPTION(res);
|
||||
}
|
||||
if (responseCode == triagens::rest::HttpResponse::HttpResponseCode::NOT_FOUND) {
|
||||
_vertices.emplace(id, nullptr);
|
||||
}
|
||||
else {
|
||||
_vertices.emplace(id, triagens::basics::JsonHelper::fromString(vertexResult));
|
||||
}
|
||||
it = _vertices.find(id);
|
||||
}
|
||||
auto exp = _expressions->find(0);
|
||||
if (exp != _expressions->end() && ! vertexMatchesCondition(it->second, exp->second)) {
|
||||
// We can stop here. The start vertex does not match condition
|
||||
_done = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool ClusterTraverser::vertexMatchesCondition (TRI_json_t* v, std::vector<TraverserExpression*> const& exp) {
|
||||
for (auto const& e : exp) {
|
||||
if (! e->isEdgeAccess) {
|
||||
if (v == nullptr || ! e->matchesCheck(v)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
const triagens::arango::traverser::TraversalPath* ClusterTraverser::next () {
|
||||
|
|
|
@ -54,7 +54,7 @@ namespace triagens {
|
|||
) : Traverser(opts, expressions),
|
||||
_edgeCols(edgeCollections),
|
||||
_dbname(dbname),
|
||||
_vertexGetter(&_edges),
|
||||
_vertexGetter(this),
|
||||
_edgeGetter(this),
|
||||
_resolver(resolver) {
|
||||
}
|
||||
|
@ -72,6 +72,12 @@ namespace triagens {
|
|||
|
||||
private:
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- private methods
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
bool vertexMatchesCondition (TRI_json_t*, std::vector<TraverserExpression*> const&);
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- private classes
|
||||
// -----------------------------------------------------------------------------
|
||||
|
@ -80,15 +86,15 @@ namespace triagens {
|
|||
|
||||
public:
|
||||
|
||||
VertexGetter (std::unordered_map<std::string, TRI_json_t*> const* edges)
|
||||
: _edges(edges) {
|
||||
VertexGetter (ClusterTraverser* traverser)
|
||||
: _traverser(traverser) {
|
||||
}
|
||||
|
||||
std::string operator() (std::string const&, std::string const&);
|
||||
bool operator() (std::string const&, std::string const&, size_t, std::string&);
|
||||
|
||||
private:
|
||||
|
||||
std::unordered_map<std::string, TRI_json_t*> const* _edges;
|
||||
ClusterTraverser* _traverser;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -789,18 +789,21 @@ DepthFirstTraverser::DepthFirstTraverser (
|
|||
}
|
||||
|
||||
void DepthFirstTraverser::_defInternalFunctions () {
|
||||
_getVertex = [] (EdgeInfo& edge, VertexId& vertex) -> VertexId {
|
||||
_getVertex = [] (EdgeInfo const& edge, VertexId const& vertex, size_t depth, VertexId& result) -> bool {
|
||||
auto mptr = edge.mptr;
|
||||
// TODO fill Statistics
|
||||
if (strcmp(TRI_EXTRACT_MARKER_FROM_KEY(&mptr), vertex.key) == 0 &&
|
||||
TRI_EXTRACT_MARKER_FROM_CID(&mptr) == vertex.cid) {
|
||||
return VertexId(TRI_EXTRACT_MARKER_TO_CID(&mptr), TRI_EXTRACT_MARKER_TO_KEY(&mptr));
|
||||
result = VertexId(TRI_EXTRACT_MARKER_TO_CID(&mptr), TRI_EXTRACT_MARKER_TO_KEY(&mptr));
|
||||
}
|
||||
return VertexId(TRI_EXTRACT_MARKER_FROM_CID(&mptr), TRI_EXTRACT_MARKER_FROM_KEY(&mptr));
|
||||
else {
|
||||
result = VertexId(TRI_EXTRACT_MARKER_FROM_CID(&mptr), TRI_EXTRACT_MARKER_FROM_KEY(&mptr));
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
if (_opts.direction == TRI_EDGE_ANY) {
|
||||
_getEdge = [&] (VertexId& startVertex, std::vector<EdgeInfo>& edges, TRI_doc_mptr_copy_t*& last, size_t& eColIdx, bool& dir) {
|
||||
_getEdge = [&] (VertexId const& startVertex, std::vector<EdgeInfo>& edges, TRI_doc_mptr_copy_t*& last, size_t& eColIdx, bool& dir) {
|
||||
std::vector<TRI_doc_mptr_copy_t> tmp;
|
||||
TRI_ASSERT(eColIdx < _edgeCols.size());
|
||||
// TODO fill Statistics
|
||||
|
@ -864,7 +867,9 @@ void DepthFirstTraverser::_defInternalFunctions () {
|
|||
return;
|
||||
}
|
||||
if (! exp->isEdgeAccess) {
|
||||
VertexId other = _getVertex(e, startVertex);
|
||||
VertexId other;
|
||||
// This always returns true and third parameter is ignored
|
||||
_getVertex(e, startVertex, 0, other);
|
||||
auto collection = _trx->trxCollection(other.cid);
|
||||
if (collection == nullptr) {
|
||||
int res = TRI_AddCollectionTransaction(_trx->getInternals(),
|
||||
|
@ -902,7 +907,7 @@ void DepthFirstTraverser::_defInternalFunctions () {
|
|||
}
|
||||
};
|
||||
} else {
|
||||
_getEdge = [&] (VertexId& startVertex, std::vector<EdgeInfo>& edges, TRI_doc_mptr_copy_t*& last, size_t& eColIdx, bool& dir) {
|
||||
_getEdge = [&] (VertexId const& startVertex, std::vector<EdgeInfo>& edges, TRI_doc_mptr_copy_t*& last, size_t& eColIdx, bool& dir) {
|
||||
std::vector<TRI_doc_mptr_copy_t> tmp;
|
||||
TRI_ASSERT(eColIdx < _edgeCols.size());
|
||||
// Do not touch the bool parameter, as long as it is default the first encountered nullptr is final
|
||||
|
@ -936,7 +941,9 @@ void DepthFirstTraverser::_defInternalFunctions () {
|
|||
return;
|
||||
}
|
||||
if (! exp->isEdgeAccess) {
|
||||
VertexId other = _getVertex(e, startVertex);
|
||||
VertexId other;
|
||||
// This always returns true, third parameter is ignored
|
||||
_getVertex(e, startVertex, 0, other);
|
||||
auto collection = _trx->trxCollection(other.cid);
|
||||
if (collection == nullptr) {
|
||||
int res = TRI_AddCollectionTransaction(_trx->getInternals(),
|
||||
|
|
|
@ -261,15 +261,17 @@ namespace triagens {
|
|||
/// @brief internal function to extract an edge
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::function<void(VertexId&, std::vector<EdgeInfo>&,
|
||||
std::function<void(VertexId const&,
|
||||
std::vector<EdgeInfo>&,
|
||||
TRI_doc_mptr_copy_t*&,
|
||||
size_t&, bool&)> _getEdge;
|
||||
size_t&,
|
||||
bool&)> _getEdge;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief internal function to extract vertex information
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::function<VertexId (EdgeInfo&, VertexId&)> _getVertex;
|
||||
std::function<bool (EdgeInfo const&, VertexId const&, size_t, VertexId&)> _getVertex;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief a vector containing all required edge collection structures
|
||||
|
|
|
@ -145,10 +145,7 @@ bool TraverserExpression::recursiveCheck (triagens::aql::AstNode const* node,
|
|||
/// @brief evalutes if an element matches the given expression
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool TraverserExpression::matchesCheck (TRI_doc_mptr_t& element,
|
||||
TRI_document_collection_t* collection,
|
||||
CollectionNameResolver const* resolver) const {
|
||||
DocumentAccessor accessor(resolver, collection, &element);
|
||||
bool TraverserExpression::matchesCheck (DocumentAccessor& accessor) const {
|
||||
recursiveCheck(varAccess, accessor);
|
||||
triagens::basics::Json result = accessor.toJson();
|
||||
switch (comparisonType) {
|
||||
|
@ -167,4 +164,26 @@ bool TraverserExpression::matchesCheck (TRI_doc_mptr_t& element,
|
|||
default:
|
||||
TRI_ASSERT(false);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief evalutes if an element matches the given expression
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool TraverserExpression::matchesCheck (TRI_json_t* element) const {
|
||||
DocumentAccessor accessor(element);
|
||||
return matchesCheck(accessor);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief evalutes if an element matches the given expression
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool TraverserExpression::matchesCheck (TRI_doc_mptr_t& element,
|
||||
TRI_document_collection_t* collection,
|
||||
CollectionNameResolver const* resolver) const {
|
||||
DocumentAccessor accessor(resolver, collection, &element);
|
||||
return matchesCheck(accessor);
|
||||
}
|
||||
|
|
|
@ -132,6 +132,10 @@ namespace triagens {
|
|||
TRI_document_collection_t* collection,
|
||||
CollectionNameResolver const* resolver) const;
|
||||
|
||||
bool matchesCheck (TRI_json_t* element) const;
|
||||
|
||||
bool matchesCheck (DocumentAccessor& accessor) const;
|
||||
|
||||
private:
|
||||
|
||||
bool recursiveCheck (triagens::aql::AstNode const*,
|
||||
|
|
Loading…
Reference in New Issue