1
0
Fork 0

Used the TraverserExpression in Local case for Edges. Right now it fails hardcoded.

This commit is contained in:
Michael Hackstein 2015-11-18 11:26:55 +01:00
parent a656182145
commit f880592025
5 changed files with 108 additions and 34 deletions

View File

@ -256,6 +256,7 @@ add_executable(
VocBase/shaped-json.cpp VocBase/shaped-json.cpp
VocBase/Shaper.cpp VocBase/Shaper.cpp
VocBase/transaction.cpp VocBase/transaction.cpp
VocBase/Traverser.cpp
VocBase/vocbase.cpp VocBase/vocbase.cpp
VocBase/vocbase-defaults.cpp VocBase/vocbase-defaults.cpp
VocBase/VocShaper.cpp VocBase/VocShaper.cpp

View File

@ -218,6 +218,7 @@ arangod_libarangod_a_SOURCES = \
arangod/VocBase/shaped-json.cpp \ arangod/VocBase/shaped-json.cpp \
arangod/VocBase/Shaper.cpp \ arangod/VocBase/Shaper.cpp \
arangod/VocBase/transaction.cpp \ arangod/VocBase/transaction.cpp \
arangod/VocBase/Traverser.cpp \
arangod/VocBase/vocbase.cpp \ arangod/VocBase/vocbase.cpp \
arangod/VocBase/vocbase-defaults.cpp \ arangod/VocBase/vocbase-defaults.cpp \
arangod/VocBase/VocShaper.cpp \ arangod/VocBase/VocShaper.cpp \

View File

@ -843,15 +843,13 @@ void DepthFirstTraverser::_defInternalFunctions () {
return VertexId(TRI_EXTRACT_MARKER_FROM_CID(&mptr), TRI_EXTRACT_MARKER_FROM_KEY(&mptr)); return VertexId(TRI_EXTRACT_MARKER_FROM_CID(&mptr), TRI_EXTRACT_MARKER_FROM_KEY(&mptr));
}; };
auto direction = _opts.direction; if (_opts.direction == TRI_EDGE_ANY) {
auto edgeCols = _edgeCols; _getEdge = [&] (VertexId& startVertex, std::vector<EdgeInfo>& edges, TRI_doc_mptr_copy_t*& last, size_t& eColIdx, bool& dir) {
if (direction == TRI_EDGE_ANY) {
_getEdge = [edgeCols] (VertexId& startVertex, std::vector<EdgeInfo>& edges, TRI_doc_mptr_copy_t*& last, size_t& eColIdx, bool& dir) {
std::vector<TRI_doc_mptr_copy_t> tmp; std::vector<TRI_doc_mptr_copy_t> tmp;
TRI_ASSERT(eColIdx < edgeCols.size()); TRI_ASSERT(eColIdx < _edgeCols.size());
// TODO fill Statistics // TODO fill Statistics
// TODO Self referencing edges // TODO Self referencing edges
triagens::arango::EdgeIndex* edgeIndex = edgeCols.at(eColIdx)->edgeIndex(); triagens::arango::EdgeIndex* edgeIndex = _edgeCols.at(eColIdx)->edgeIndex();
if (dir) { if (dir) {
TRI_edge_index_iterator_t it(TRI_EDGE_OUT, startVertex.cid, startVertex.key); TRI_edge_index_iterator_t it(TRI_EDGE_OUT, startVertex.cid, startVertex.key);
edgeIndex->lookup(&it, tmp, last, 1); edgeIndex->lookup(&it, tmp, last, 1);
@ -859,12 +857,12 @@ void DepthFirstTraverser::_defInternalFunctions () {
// Switch back direction // Switch back direction
dir = false; dir = false;
++eColIdx; ++eColIdx;
if (edgeCols.size() == eColIdx) { if (_edgeCols.size() == eColIdx) {
// No more to do, stop here // No more to do, stop here
return; return;
} }
TRI_edge_index_iterator_t it(TRI_EDGE_IN, startVertex.cid, startVertex.key); TRI_edge_index_iterator_t it(TRI_EDGE_IN, startVertex.cid, startVertex.key);
edgeIndex = edgeCols.at(eColIdx)->edgeIndex(); edgeIndex = _edgeCols.at(eColIdx)->edgeIndex();
edgeIndex->lookup(&it, tmp, last, 1); edgeIndex->lookup(&it, tmp, last, 1);
if (last == nullptr) { if (last == nullptr) {
dir = true; dir = true;
@ -884,12 +882,12 @@ void DepthFirstTraverser::_defInternalFunctions () {
// The other direction also has no further edges // The other direction also has no further edges
dir = false; dir = false;
++eColIdx; ++eColIdx;
if (edgeCols.size() == eColIdx) { if (_edgeCols.size() == eColIdx) {
// No more to do, stop here // No more to do, stop here
return; return;
} }
TRI_edge_index_iterator_t it(TRI_EDGE_IN, startVertex.cid, startVertex.key); TRI_edge_index_iterator_t it(TRI_EDGE_IN, startVertex.cid, startVertex.key);
edgeIndex = edgeCols.at(eColIdx)->edgeIndex(); edgeIndex = _edgeCols.at(eColIdx)->edgeIndex();
edgeIndex->lookup(&it, tmp, last, 1); edgeIndex->lookup(&it, tmp, last, 1);
} }
} }
@ -897,39 +895,62 @@ void DepthFirstTraverser::_defInternalFunctions () {
if (last != nullptr) { if (last != nullptr) {
// sth is stored in tmp. Now push it on edges // sth is stored in tmp. Now push it on edges
TRI_ASSERT(tmp.size() == 1); TRI_ASSERT(tmp.size() == 1);
auto it = _expressions->find(edges.size());
if (it != _expressions->end()) {
auto shaper = _edgeCols.at(eColIdx)->getShaper();
for (auto const& exp : it->second) {
if (exp->isEdgeAccess && ! exp->matchesCheck(tmp.back(), shaper)) {
// Retry with the next element
_getEdge(startVertex, edges, last, eColIdx, dir);
return;
}
}
}
EdgeInfo e( EdgeInfo e(
edgeCols.at(eColIdx)->_info._cid, _edgeCols.at(eColIdx)->_info._cid,
tmp.back() tmp.back()
); );
edges.push_back(e); edges.push_back(e);
} }
}; };
} else { } else {
_getEdge = [edgeCols, direction] (VertexId& startVertex, std::vector<EdgeInfo>& edges, TRI_doc_mptr_copy_t*& last, size_t& eColIdx, bool&) { _getEdge = [&] (VertexId& startVertex, std::vector<EdgeInfo>& edges, TRI_doc_mptr_copy_t*& last, size_t& eColIdx, bool& dir) {
std::vector<TRI_doc_mptr_copy_t> tmp; std::vector<TRI_doc_mptr_copy_t> tmp;
TRI_ASSERT(eColIdx < edgeCols.size()); TRI_ASSERT(eColIdx < _edgeCols.size());
// Do not touch the bool parameter, as long as it is default the first encountered nullptr is final // Do not touch the bool parameter, as long as it is default the first encountered nullptr is final
// TODO fill Statistics // TODO fill Statistics
TRI_edge_index_iterator_t it(direction, startVertex.cid, startVertex.key); TRI_edge_index_iterator_t it(_opts.direction, startVertex.cid, startVertex.key);
triagens::arango::EdgeIndex* edgeIndex = edgeCols.at(eColIdx)->edgeIndex(); triagens::arango::EdgeIndex* edgeIndex = _edgeCols.at(eColIdx)->edgeIndex();
edgeIndex->lookup(&it, tmp, last, 1); edgeIndex->lookup(&it, tmp, last, 1);
while (last == nullptr) { while (last == nullptr) {
// This edge collection does not have any more edges for this vertex. Check the next one // This edge collection does not have any more edges for this vertex. Check the next one
++eColIdx; ++eColIdx;
if (edgeCols.size() == eColIdx) { if (_edgeCols.size() == eColIdx) {
// No more to do, stop here // No more to do, stop here
return; return;
} }
edgeIndex = edgeCols.at(eColIdx)->edgeIndex(); edgeIndex = _edgeCols.at(eColIdx)->edgeIndex();
edgeIndex->lookup(&it, tmp, last, 1); edgeIndex->lookup(&it, tmp, last, 1);
} }
if (last != nullptr) { if (last != nullptr) {
// sth is stored in tmp. Now push it on edges // sth is stored in tmp. Now push it on edges
TRI_ASSERT(tmp.size() == 1); TRI_ASSERT(tmp.size() == 1);
edges.push_back(EdgeInfo( auto it = _expressions->find(edges.size());
edgeCols.at(eColIdx)->_info._cid, if (it != _expressions->end()) {
auto shaper = _edgeCols.at(eColIdx)->getShaper();
for (auto const& exp : it->second) {
if (exp->isEdgeAccess && ! exp->matchesCheck(tmp.back(), shaper)) {
// Retry with the next element
_getEdge(startVertex, edges, last, eColIdx, dir);
return;
}
}
}
EdgeInfo e(
_edgeCols.at(eColIdx)->_info._cid,
tmp.back() tmp.back()
)); );
edges.push_back(e);
} }
}; };
} }

View File

@ -0,0 +1,62 @@
////////////////////////////////////////////////////////////////////////////////
/// @brief Traverser
///
/// @file
///
/// DISCLAIMER
///
/// Copyright 2014-2015 ArangoDB GmbH, Cologne, Germany
/// Copyright 2004-2014 triAGENS 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
/// @author Copyright 2014-2015, ArangoDB GmbH, Cologne, Germany
/// @author Copyright 2012-2013, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////
#include "Traverser.h"
using TraverserExpression = triagens::arango::traverser::TraverserExpression;
////////////////////////////////////////////////////////////////////////////////
/// @brief transforms the expression into json
////////////////////////////////////////////////////////////////////////////////
void TraverserExpression::toJson (triagens::basics::Json& json,
TRI_memory_zone_t* zone) const {
auto op = triagens::aql::AstNode::Operators.find(comparisonType);
if (op == triagens::aql::AstNode::Operators.end()) {
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_QUERY_PARSE, "invalid operator for TraverserExpression");
}
std::string const operatorStr = op->second;
json("isEdgeAccess", triagens::basics::Json(isEdgeAccess))
("comparisonType", triagens::basics::Json(operatorStr))
("varAccess", varAccess->toJson(zone, true));
if (compareTo != nullptr) {
json("compareTo", *compareTo);
}
}
////////////////////////////////////////////////////////////////////////////////
/// @brief evalutes if an element matches the given expression
////////////////////////////////////////////////////////////////////////////////
bool TraverserExpression::matchesCheck (TRI_doc_mptr_t& element,
VocShaper* shaper) const {
return false;
}

View File

@ -70,21 +70,10 @@ namespace triagens {
} }
void toJson (triagens::basics::Json& json, void toJson (triagens::basics::Json& json,
TRI_memory_zone_t* zone) const { TRI_memory_zone_t* zone) const;
auto op = triagens::aql::AstNode::Operators.find(comparisonType);
if (op == triagens::aql::AstNode::Operators.end()) { bool matchesCheck (TRI_doc_mptr_t& element,
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_QUERY_PARSE, "invalid operator for TraverserExpression"); VocShaper* shaper) const;
}
std::string const operatorStr = op->second;
json("isEdgeAccess", triagens::basics::Json(isEdgeAccess))
("comparisonType", triagens::basics::Json(operatorStr))
("varAccess", varAccess->toJson(zone, true));
if (compareTo != nullptr) {
json("compareTo", *compareTo);
}
}
}; };