mirror of https://gitee.com/bigwinds/arangodb
Simplified AqlTraverser Setup code by moving shared logic into the TraverserOptions.
This commit is contained in:
parent
b09dfaa323
commit
212de2b0d1
|
@ -900,7 +900,6 @@ void TraversalNode::prepareOptions() {
|
||||||
_options->_tmpVar = _tmpObjVariable;
|
_options->_tmpVar = _tmpObjVariable;
|
||||||
|
|
||||||
size_t numEdgeColls = _edgeColls.size();
|
size_t numEdgeColls = _edgeColls.size();
|
||||||
bool res = false;
|
|
||||||
TraversalEdgeConditionBuilder globalEdgeConditionBuilder(this);
|
TraversalEdgeConditionBuilder globalEdgeConditionBuilder(this);
|
||||||
|
|
||||||
for (auto& it : _globalEdgeConditions) {
|
for (auto& it : _globalEdgeConditions) {
|
||||||
|
@ -908,78 +907,30 @@ void TraversalNode::prepareOptions() {
|
||||||
}
|
}
|
||||||
|
|
||||||
Ast* ast = _plan->getAst();
|
Ast* ast = _plan->getAst();
|
||||||
auto trx = ast->query()->trx();
|
|
||||||
|
|
||||||
_options->_baseLookupInfos.reserve(numEdgeColls);
|
|
||||||
// Compute Edge Indexes. First default indexes:
|
// Compute Edge Indexes. First default indexes:
|
||||||
for (size_t i = 0; i < numEdgeColls; ++i) {
|
for (size_t i = 0; i < numEdgeColls; ++i) {
|
||||||
std::string usedField;
|
|
||||||
auto dir = _directions[i];
|
auto dir = _directions[i];
|
||||||
// TODO we can optimize here. indexCondition and Expression could be
|
|
||||||
// made non-overlapping.
|
|
||||||
traverser::TraverserOptions::LookupInfo info;
|
|
||||||
switch (dir) {
|
switch (dir) {
|
||||||
case TRI_EDGE_IN:
|
case TRI_EDGE_IN:
|
||||||
usedField = StaticStrings::ToString;
|
_options->addLookupInfo(
|
||||||
info.indexCondition =
|
ast, _edgeColls[i]->getName(), StaticStrings::ToString,
|
||||||
globalEdgeConditionBuilder.getInboundCondition()->clone(ast);
|
globalEdgeConditionBuilder.getInboundCondition()->clone(ast));
|
||||||
break;
|
break;
|
||||||
case TRI_EDGE_OUT:
|
case TRI_EDGE_OUT:
|
||||||
usedField = StaticStrings::FromString;
|
_options->addLookupInfo(
|
||||||
info.indexCondition =
|
ast, _edgeColls[i]->getName(), StaticStrings::FromString,
|
||||||
globalEdgeConditionBuilder.getOutboundCondition()->clone(ast);
|
globalEdgeConditionBuilder.getOutboundCondition()->clone(ast));
|
||||||
break;
|
break;
|
||||||
case TRI_EDGE_ANY:
|
case TRI_EDGE_ANY:
|
||||||
TRI_ASSERT(false);
|
TRI_ASSERT(false);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
info.expression = new Expression(ast, info.indexCondition->clone(ast));
|
|
||||||
res = trx->getBestIndexHandleForFilterCondition(
|
|
||||||
_edgeColls[i]->getName(), info.indexCondition, _tmpObjVariable, 1000,
|
|
||||||
info.idxHandles[0]);
|
|
||||||
TRI_ASSERT(res); // Right now we have an enforced edge index which will
|
|
||||||
// always fit.
|
|
||||||
if (!res) {
|
|
||||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "expected edge index not found");
|
|
||||||
}
|
|
||||||
|
|
||||||
// We now have to check if we need _from / _to inside the index lookup and which position
|
|
||||||
// it is used in. Such that the traverser can update the respective string value
|
|
||||||
// in-place
|
|
||||||
std::pair<Variable const*, std::vector<basics::AttributeName>> pathCmp;
|
|
||||||
for (size_t i = 0; i < info.indexCondition->numMembers(); ++i) {
|
|
||||||
// We search through the nary-and and look for EQ - _from/_to
|
|
||||||
auto eq = info.indexCondition->getMemberUnchecked(i);
|
|
||||||
if (eq->type != NODE_TYPE_OPERATOR_BINARY_EQ) {
|
|
||||||
// No equality. Skip
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
TRI_ASSERT(eq->numMembers() == 2);
|
|
||||||
// It is sufficient to only check member one.
|
|
||||||
// We build the condition this way.
|
|
||||||
auto mem = eq->getMemberUnchecked(0);
|
|
||||||
if (mem->isAttributeAccessForVariable(pathCmp)) {
|
|
||||||
if (pathCmp.first != _tmpObjVariable) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (pathCmp.second.size() == 1 && pathCmp.second[0].name == usedField) {
|
|
||||||
info.conditionNeedUpdate = true;
|
|
||||||
info.conditionMemberToUpdate = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_options->_baseLookupInfos.emplace_back(std::move(info));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& it : _edgeConditions) {
|
for (auto& it : _edgeConditions) {
|
||||||
auto ins = _options->_depthLookupInfo.emplace(
|
uint64_t depth = it.first;
|
||||||
it.first, std::vector<traverser::TraverserOptions::LookupInfo>());
|
|
||||||
// We probably have to adopt minDepth. We cannot fulfill a condition of larger depth anyway
|
// We probably have to adopt minDepth. We cannot fulfill a condition of larger depth anyway
|
||||||
TRI_ASSERT(ins.second);
|
|
||||||
auto& infos = ins.first->second;
|
|
||||||
infos.reserve(numEdgeColls);
|
|
||||||
auto& builder = it.second;
|
auto& builder = it.second;
|
||||||
|
|
||||||
for (auto& it : _globalEdgeConditions) {
|
for (auto& it : _globalEdgeConditions) {
|
||||||
|
@ -987,64 +938,24 @@ void TraversalNode::prepareOptions() {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < numEdgeColls; ++i) {
|
for (size_t i = 0; i < numEdgeColls; ++i) {
|
||||||
std::string usedField;
|
|
||||||
auto dir = _directions[i];
|
auto dir = _directions[i];
|
||||||
// TODO we can optimize here. indexCondition and Expression could be
|
// TODO we can optimize here. indexCondition and Expression could be
|
||||||
// made non-overlapping.
|
// made non-overlapping.
|
||||||
traverser::TraverserOptions::LookupInfo info;
|
|
||||||
switch (dir) {
|
switch (dir) {
|
||||||
case TRI_EDGE_IN:
|
case TRI_EDGE_IN:
|
||||||
usedField = StaticStrings::ToString;
|
_options->addDepthLookupInfo(
|
||||||
info.indexCondition = builder->getInboundCondition()->clone(ast);
|
ast, _edgeColls[i]->getName(), StaticStrings::ToString,
|
||||||
|
builder->getInboundCondition()->clone(ast), depth);
|
||||||
break;
|
break;
|
||||||
case TRI_EDGE_OUT:
|
case TRI_EDGE_OUT:
|
||||||
usedField = StaticStrings::FromString;
|
_options->addDepthLookupInfo(
|
||||||
info.indexCondition = builder->getOutboundCondition()->clone(ast);
|
ast, _edgeColls[i]->getName(), StaticStrings::FromString,
|
||||||
|
builder->getOutboundCondition()->clone(ast), depth);
|
||||||
break;
|
break;
|
||||||
case TRI_EDGE_ANY:
|
case TRI_EDGE_ANY:
|
||||||
TRI_ASSERT(false);
|
TRI_ASSERT(false);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
info.expression = new Expression(ast, info.indexCondition->clone(ast));
|
|
||||||
res = trx->getBestIndexHandleForFilterCondition(
|
|
||||||
_edgeColls[i]->getName(), info.indexCondition, _tmpObjVariable, 1000,
|
|
||||||
info.idxHandles[0]);
|
|
||||||
TRI_ASSERT(res); // Right now we have an enforced edge index which will
|
|
||||||
// always fit.
|
|
||||||
if (!res) {
|
|
||||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "expected edge index not found");
|
|
||||||
}
|
|
||||||
|
|
||||||
// We now have to check if we need _from / _to inside the index lookup and which position
|
|
||||||
// it is used in. Such that the traverser can update the respective string value
|
|
||||||
// in-place
|
|
||||||
|
|
||||||
std::pair<Variable const*, std::vector<basics::AttributeName>> pathCmp;
|
|
||||||
for (size_t i = 0; i < info.indexCondition->numMembers(); ++i) {
|
|
||||||
// We search through the nary-and and look for EQ - _from/_to
|
|
||||||
auto eq = info.indexCondition->getMemberUnchecked(i);
|
|
||||||
if (eq->type != NODE_TYPE_OPERATOR_BINARY_EQ) {
|
|
||||||
// No equality. Skip
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
TRI_ASSERT(eq->numMembers() == 2);
|
|
||||||
// It is sufficient to only check member one.
|
|
||||||
// We build the condition this way.
|
|
||||||
auto mem = eq->getMemberUnchecked(0);
|
|
||||||
if (mem->isAttributeAccessForVariable(pathCmp)) {
|
|
||||||
if (pathCmp.first != _tmpObjVariable) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (pathCmp.second.size() == 1 && pathCmp.second[0].name == usedField) {
|
|
||||||
info.conditionNeedUpdate = true;
|
|
||||||
info.conditionMemberToUpdate = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
infos.emplace_back(std::move(info));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -52,8 +52,8 @@ TraverserOptions::TraverserOptions(transaction::Methods* trx)
|
||||||
uniqueVertices(UniquenessLevel::NONE),
|
uniqueVertices(UniquenessLevel::NONE),
|
||||||
uniqueEdges(UniquenessLevel::PATH) {}
|
uniqueEdges(UniquenessLevel::PATH) {}
|
||||||
|
|
||||||
TraverserOptions::TraverserOptions(
|
TraverserOptions::TraverserOptions(transaction::Methods* trx,
|
||||||
transaction::Methods* trx, VPackSlice const& slice)
|
VPackSlice const& slice)
|
||||||
: BaseOptions(trx),
|
: BaseOptions(trx),
|
||||||
_baseVertexExpression(nullptr),
|
_baseVertexExpression(nullptr),
|
||||||
_traverser(nullptr),
|
_traverser(nullptr),
|
||||||
|
@ -89,16 +89,14 @@ TraverserOptions::TraverserOptions(
|
||||||
|
|
||||||
tmp = VPackHelper::getStringValue(obj, "uniqueEdges", "");
|
tmp = VPackHelper::getStringValue(obj, "uniqueEdges", "");
|
||||||
if (tmp == "none") {
|
if (tmp == "none") {
|
||||||
uniqueEdges =
|
uniqueEdges = arangodb::traverser::TraverserOptions::UniquenessLevel::NONE;
|
||||||
arangodb::traverser::TraverserOptions::UniquenessLevel::NONE;
|
|
||||||
} else if (tmp == "global") {
|
} else if (tmp == "global") {
|
||||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_BAD_PARAMETER,
|
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_BAD_PARAMETER,
|
||||||
"uniqueEdges: 'global' is not supported, "
|
"uniqueEdges: 'global' is not supported, "
|
||||||
"due to unpredictable results. Use 'path' "
|
"due to unpredictable results. Use 'path' "
|
||||||
"or 'none' instead");
|
"or 'none' instead");
|
||||||
} else {
|
} else {
|
||||||
uniqueEdges =
|
uniqueEdges = arangodb::traverser::TraverserOptions::UniquenessLevel::PATH;
|
||||||
arangodb::traverser::TraverserOptions::UniquenessLevel::PATH;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -233,8 +231,8 @@ arangodb::traverser::TraverserOptions::TraverserOptions(
|
||||||
d, new aql::Expression(query->ast(), info.value));
|
d, new aql::Expression(query->ast(), info.value));
|
||||||
TRI_ASSERT(it.second);
|
TRI_ASSERT(it.second);
|
||||||
#else
|
#else
|
||||||
_vertexExpressions.emplace(
|
_vertexExpressions.emplace(d,
|
||||||
d, new aql::Expression(query->ast(), info.value));
|
new aql::Expression(query->ast(), info.value));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -289,7 +287,8 @@ arangodb::traverser::TraverserOptions::~TraverserOptions() {
|
||||||
delete _baseVertexExpression;
|
delete _baseVertexExpression;
|
||||||
}
|
}
|
||||||
|
|
||||||
void arangodb::traverser::TraverserOptions::toVelocyPack(VPackBuilder& builder) const {
|
void arangodb::traverser::TraverserOptions::toVelocyPack(
|
||||||
|
VPackBuilder& builder) const {
|
||||||
VPackObjectBuilder guard(&builder);
|
VPackObjectBuilder guard(&builder);
|
||||||
|
|
||||||
builder.add("minDepth", VPackValue(minDepth));
|
builder.add("minDepth", VPackValue(minDepth));
|
||||||
|
@ -321,7 +320,8 @@ void arangodb::traverser::TraverserOptions::toVelocyPack(VPackBuilder& builder)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void arangodb::traverser::TraverserOptions::toVelocyPackIndexes(VPackBuilder& builder) const {
|
void arangodb::traverser::TraverserOptions::toVelocyPackIndexes(
|
||||||
|
VPackBuilder& builder) const {
|
||||||
VPackObjectBuilder guard(&builder);
|
VPackObjectBuilder guard(&builder);
|
||||||
|
|
||||||
// base indexes
|
// base indexes
|
||||||
|
@ -352,7 +352,8 @@ void arangodb::traverser::TraverserOptions::toVelocyPackIndexes(VPackBuilder& bu
|
||||||
builder.close();
|
builder.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
void arangodb::traverser::TraverserOptions::buildEngineInfo(VPackBuilder& result) const {
|
void arangodb::traverser::TraverserOptions::buildEngineInfo(
|
||||||
|
VPackBuilder& result) const {
|
||||||
result.openObject();
|
result.openObject();
|
||||||
result.add("minDepth", VPackValue(minDepth));
|
result.add("minDepth", VPackValue(minDepth));
|
||||||
result.add("maxDepth", VPackValue(maxDepth));
|
result.add("maxDepth", VPackValue(maxDepth));
|
||||||
|
@ -386,7 +387,7 @@ void arangodb::traverser::TraverserOptions::buildEngineInfo(VPackBuilder& result
|
||||||
|
|
||||||
result.add(VPackValue("baseLookupInfos"));
|
result.add(VPackValue("baseLookupInfos"));
|
||||||
result.openArray();
|
result.openArray();
|
||||||
for (auto const& it: _baseLookupInfos) {
|
for (auto const& it : _baseLookupInfos) {
|
||||||
it.buildEngineInfo(result);
|
it.buildEngineInfo(result);
|
||||||
}
|
}
|
||||||
result.close();
|
result.close();
|
||||||
|
@ -432,6 +433,18 @@ void arangodb::traverser::TraverserOptions::buildEngineInfo(VPackBuilder& result
|
||||||
result.close();
|
result.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TraverserOptions::addDepthLookupInfo(aql::Ast* ast,
|
||||||
|
std::string const& collectionName,
|
||||||
|
std::string const& attributeName,
|
||||||
|
aql::AstNode* condition,
|
||||||
|
uint64_t depth) {
|
||||||
|
TRI_ASSERT(_depthLookupInfo.find(depth) == _depthLookupInfo.end());
|
||||||
|
auto ins = _depthLookupInfo.emplace(depth, std::vector<LookupInfo>());
|
||||||
|
TRI_ASSERT(ins.second); // The insert should always work
|
||||||
|
injectLookupInfoInList(ins.first->second, ast, collectionName,
|
||||||
|
attributeName, condition);
|
||||||
|
}
|
||||||
|
|
||||||
bool arangodb::traverser::TraverserOptions::vertexHasFilter(
|
bool arangodb::traverser::TraverserOptions::vertexHasFilter(
|
||||||
uint64_t depth) const {
|
uint64_t depth) const {
|
||||||
if (_baseVertexExpression != nullptr) {
|
if (_baseVertexExpression != nullptr) {
|
||||||
|
@ -441,8 +454,8 @@ bool arangodb::traverser::TraverserOptions::vertexHasFilter(
|
||||||
}
|
}
|
||||||
|
|
||||||
bool arangodb::traverser::TraverserOptions::evaluateEdgeExpression(
|
bool arangodb::traverser::TraverserOptions::evaluateEdgeExpression(
|
||||||
arangodb::velocypack::Slice edge, StringRef vertexId,
|
arangodb::velocypack::Slice edge, StringRef vertexId, uint64_t depth,
|
||||||
uint64_t depth, size_t cursorId) const {
|
size_t cursorId) const {
|
||||||
if (_isCoordinator) {
|
if (_isCoordinator) {
|
||||||
// The Coordinator never checks conditions. The DBServer is responsible!
|
// The Coordinator never checks conditions. The DBServer is responsible!
|
||||||
return true;
|
return true;
|
||||||
|
@ -513,10 +526,12 @@ arangodb::traverser::TraverserOptions::nextCursor(ManagedDocumentResult* mmdr,
|
||||||
}
|
}
|
||||||
|
|
||||||
arangodb::traverser::EdgeCursor*
|
arangodb::traverser::EdgeCursor*
|
||||||
arangodb::traverser::TraverserOptions::nextCursorLocal(ManagedDocumentResult* mmdr,
|
arangodb::traverser::TraverserOptions::nextCursorLocal(
|
||||||
StringRef vid, uint64_t depth, std::vector<LookupInfo>& list) {
|
ManagedDocumentResult* mmdr, StringRef vid, uint64_t depth,
|
||||||
|
std::vector<LookupInfo>& list) {
|
||||||
TRI_ASSERT(mmdr != nullptr);
|
TRI_ASSERT(mmdr != nullptr);
|
||||||
auto allCursor = std::make_unique<SingleServerEdgeCursor>(mmdr, this, list.size());
|
auto allCursor =
|
||||||
|
std::make_unique<SingleServerEdgeCursor>(mmdr, this, list.size());
|
||||||
auto& opCursors = allCursor->getCursors();
|
auto& opCursors = allCursor->getCursors();
|
||||||
for (auto& info : list) {
|
for (auto& info : list) {
|
||||||
auto& node = info.indexCondition;
|
auto& node = info.indexCondition;
|
||||||
|
@ -535,8 +550,8 @@ arangodb::traverser::TraverserOptions::nextCursorLocal(ManagedDocumentResult* mm
|
||||||
std::vector<OperationCursor*> csrs;
|
std::vector<OperationCursor*> csrs;
|
||||||
csrs.reserve(info.idxHandles.size());
|
csrs.reserve(info.idxHandles.size());
|
||||||
for (auto const& it : info.idxHandles) {
|
for (auto const& it : info.idxHandles) {
|
||||||
csrs.emplace_back(_trx->indexScanForCondition(
|
csrs.emplace_back(_trx->indexScanForCondition(it, node, _tmpVar, mmdr,
|
||||||
it, node, _tmpVar, mmdr, UINT64_MAX, 1000, false));
|
UINT64_MAX, 1000, false));
|
||||||
}
|
}
|
||||||
opCursors.emplace_back(std::move(csrs));
|
opCursors.emplace_back(std::move(csrs));
|
||||||
}
|
}
|
||||||
|
@ -544,8 +559,8 @@ arangodb::traverser::TraverserOptions::nextCursorLocal(ManagedDocumentResult* mm
|
||||||
}
|
}
|
||||||
|
|
||||||
arangodb::traverser::EdgeCursor*
|
arangodb::traverser::EdgeCursor*
|
||||||
arangodb::traverser::TraverserOptions::nextCursorCoordinator(
|
arangodb::traverser::TraverserOptions::nextCursorCoordinator(StringRef vid,
|
||||||
StringRef vid, uint64_t depth) {
|
uint64_t depth) {
|
||||||
TRI_ASSERT(_traverser != nullptr);
|
TRI_ASSERT(_traverser != nullptr);
|
||||||
auto cursor = std::make_unique<ClusterEdgeCursor>(vid, depth, _traverser);
|
auto cursor = std::make_unique<ClusterEdgeCursor>(vid, depth, _traverser);
|
||||||
return cursor.release();
|
return cursor.release();
|
||||||
|
@ -556,7 +571,8 @@ void arangodb::traverser::TraverserOptions::linkTraverser(
|
||||||
_traverser = trav;
|
_traverser = trav;
|
||||||
}
|
}
|
||||||
|
|
||||||
double arangodb::traverser::TraverserOptions::estimateCost(size_t& nrItems) const {
|
double arangodb::traverser::TraverserOptions::estimateCost(
|
||||||
|
size_t& nrItems) const {
|
||||||
size_t count = 1;
|
size_t count = 1;
|
||||||
double cost = 0;
|
double cost = 0;
|
||||||
size_t baseCreateItems = 0;
|
size_t baseCreateItems = 0;
|
||||||
|
|
|
@ -24,9 +24,9 @@
|
||||||
#ifndef ARANGOD_VOC_BASE_TRAVERSER_OPTIONS_H
|
#ifndef ARANGOD_VOC_BASE_TRAVERSER_OPTIONS_H
|
||||||
#define ARANGOD_VOC_BASE_TRAVERSER_OPTIONS_H 1
|
#define ARANGOD_VOC_BASE_TRAVERSER_OPTIONS_H 1
|
||||||
|
|
||||||
|
#include "Aql/FixedVarExpressionContext.h"
|
||||||
#include "Basics/Common.h"
|
#include "Basics/Common.h"
|
||||||
#include "Basics/StringRef.h"
|
#include "Basics/StringRef.h"
|
||||||
#include "Aql/FixedVarExpressionContext.h"
|
|
||||||
#include "Graph/BaseOptions.h"
|
#include "Graph/BaseOptions.h"
|
||||||
#include "StorageEngine/TransactionState.h"
|
#include "StorageEngine/TransactionState.h"
|
||||||
#include "Transaction/Methods.h"
|
#include "Transaction/Methods.h"
|
||||||
|
@ -60,9 +60,13 @@ class EdgeCursor {
|
||||||
EdgeCursor() {}
|
EdgeCursor() {}
|
||||||
virtual ~EdgeCursor() {}
|
virtual ~EdgeCursor() {}
|
||||||
|
|
||||||
virtual bool next(std::function<void(arangodb::StringRef const&, VPackSlice, size_t)> callback) = 0;
|
virtual bool next(
|
||||||
|
std::function<void(arangodb::StringRef const&, VPackSlice, size_t)>
|
||||||
|
callback) = 0;
|
||||||
|
|
||||||
virtual void readAll(std::function<void(arangodb::StringRef const&, arangodb::velocypack::Slice, size_t&)>) = 0;
|
virtual void readAll(
|
||||||
|
std::function<void(arangodb::StringRef const&,
|
||||||
|
arangodb::velocypack::Slice, size_t&)>) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TraverserOptions : public graph::BaseOptions {
|
struct TraverserOptions : public graph::BaseOptions {
|
||||||
|
@ -111,11 +115,15 @@ struct TraverserOptions : public graph::BaseOptions {
|
||||||
/// for DBServer traverser engines.
|
/// for DBServer traverser engines.
|
||||||
void buildEngineInfo(arangodb::velocypack::Builder&) const;
|
void buildEngineInfo(arangodb::velocypack::Builder&) const;
|
||||||
|
|
||||||
|
/// @brief Add a lookup info for specific depth
|
||||||
|
void addDepthLookupInfo(aql::Ast* ast, std::string const& collectionName,
|
||||||
|
std::string const& attributeName,
|
||||||
|
aql::AstNode* condition, uint64_t depth);
|
||||||
|
|
||||||
bool vertexHasFilter(uint64_t) const;
|
bool vertexHasFilter(uint64_t) const;
|
||||||
|
|
||||||
bool evaluateEdgeExpression(arangodb::velocypack::Slice,
|
bool evaluateEdgeExpression(arangodb::velocypack::Slice, StringRef vertexId,
|
||||||
StringRef vertexId, uint64_t,
|
uint64_t, size_t) const;
|
||||||
size_t) const;
|
|
||||||
|
|
||||||
bool evaluateVertexExpression(arangodb::velocypack::Slice, uint64_t) const;
|
bool evaluateVertexExpression(arangodb::velocypack::Slice, uint64_t) const;
|
||||||
|
|
||||||
|
@ -126,14 +134,11 @@ struct TraverserOptions : public graph::BaseOptions {
|
||||||
double estimateCost(size_t& nrItems) const;
|
double estimateCost(size_t& nrItems) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
EdgeCursor* nextCursorLocal(ManagedDocumentResult*, StringRef vid, uint64_t,
|
||||||
EdgeCursor* nextCursorLocal(ManagedDocumentResult*,
|
|
||||||
StringRef vid, uint64_t,
|
|
||||||
std::vector<LookupInfo>&);
|
std::vector<LookupInfo>&);
|
||||||
|
|
||||||
EdgeCursor* nextCursorCoordinator(StringRef vid, uint64_t);
|
EdgeCursor* nextCursorCoordinator(StringRef vid, uint64_t);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue