mirror of https://gitee.com/bigwinds/arangodb
Now the Traverser Node figures out the correct index handle. Next Up: SingleServerTraverser needs to use indexScan for this condition. Traversal Still out of function.
This commit is contained in:
parent
36d579e20e
commit
5b1e1b7496
|
@ -568,6 +568,10 @@ struct AstNode {
|
|||
}
|
||||
members.erase(members.begin() + i, members.end());
|
||||
}
|
||||
|
||||
inline void clearMembers() {
|
||||
members.clear();
|
||||
}
|
||||
|
||||
/// @brief set the node's value type
|
||||
inline void setValueType(AstNodeValueType type) { value.type = type; }
|
||||
|
|
|
@ -612,7 +612,6 @@ arangodb::OperationCursor* IndexBlock::orderCursor(size_t currentIndex) {
|
|||
// yet no cursor for index, so create it
|
||||
IndexNode const* node = static_cast<IndexNode const*>(getPlanNode());
|
||||
_cursors[currentIndex].reset(_trx->indexScanForCondition(
|
||||
_collection->getName(),
|
||||
_indexes[currentIndex],
|
||||
conditionNode,
|
||||
node->outVariable(),
|
||||
|
|
|
@ -410,6 +410,8 @@ size_t TraversalBlock::skipSome(size_t atLeast, size_t atMost) {
|
|||
|
||||
/// @brief optimized version of neighbors search, must properly implement this
|
||||
void TraversalBlock::neighbors(std::string const& startVertex) {
|
||||
#warning Needs to be rebuild
|
||||
/*
|
||||
std::unordered_set<VPackSlice, arangodb::basics::VelocyPackHelper::VPackStringHash, arangodb::basics::VelocyPackHelper::VPackStringEqual> visited;
|
||||
|
||||
std::vector<VPackSlice> result;
|
||||
|
@ -451,6 +453,7 @@ void TraversalBlock::neighbors(std::string const& startVertex) {
|
|||
|
||||
_vertices.emplace_back(AqlValue(mptr.vpack(), AqlValueFromMasterPointer()));
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
/// @brief worker for neighbors() function
|
||||
|
@ -459,6 +462,7 @@ void TraversalBlock::runNeighbors(std::vector<VPackSlice> const& startVertices,
|
|||
std::vector<VPackSlice>& distinct,
|
||||
TRI_edge_direction_e direction,
|
||||
uint64_t depth) {
|
||||
/*
|
||||
std::vector<VPackSlice> nextDepth;
|
||||
bool initialized = false;
|
||||
TraversalNode const* node = static_cast<TraversalNode const*>(getPlanNode());
|
||||
|
@ -538,4 +542,5 @@ void TraversalBlock::runNeighbors(std::vector<VPackSlice> const& startVertices,
|
|||
if (!nextDepth.empty()) {
|
||||
runNeighbors(nextDepth, visited, distinct, direction, depth + 1);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
|
|
@ -170,22 +170,10 @@ static void transformCondition(AstNode const* node, Variable const* pvar,
|
|||
|
||||
AstNode* result = node->clone(ast);
|
||||
|
||||
auto tmpVar = ast->variables()->createTemporaryVariable();
|
||||
AstNode* varRefNode = tn->getTemporaryRefNode();
|
||||
|
||||
size_t const n = result->numMembers();
|
||||
|
||||
// replace the path variable access by a variable access to edge/vertex
|
||||
// (then current to the iteration)
|
||||
auto varRefNode = new AstNode(NODE_TYPE_REFERENCE);
|
||||
try {
|
||||
ast->query()->addNode(varRefNode);
|
||||
} catch (...) {
|
||||
// prevent leak
|
||||
delete varRefNode;
|
||||
throw;
|
||||
}
|
||||
varRefNode->setData(tmpVar);
|
||||
|
||||
for (size_t i = 0; i < n; ++i) {
|
||||
AstNode* baseCondition = result->getMemberUnchecked(i);
|
||||
#ifdef ARANGODB_ENABLE_MAINTAINER_MODE
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "Aql/TraversalNode.h"
|
||||
#include "Aql/ExecutionPlan.h"
|
||||
#include "Aql/Ast.h"
|
||||
#include "Aql/SortCondition.h"
|
||||
#include "Aql/TraversalOptions.h"
|
||||
#include "Indexes/Index.h"
|
||||
|
||||
|
@ -49,14 +50,17 @@ static uint64_t checkTraversalDepthValue(AstNode const* node) {
|
|||
return static_cast<uint64_t>(v);
|
||||
}
|
||||
|
||||
TraversalNode::EdgeConditionBuilder::EdgeConditionBuilder(TraversalNode const* tn,
|
||||
AstNode* modCondition)
|
||||
TraversalNode::EdgeConditionBuilder::EdgeConditionBuilder(
|
||||
TraversalNode const* tn)
|
||||
: _tn(tn), _containsCondition(false) {
|
||||
_modCondition = _tn->_ast->createNodeNaryOperator(NODE_TYPE_OPERATOR_NARY_AND);
|
||||
_modCondition->addMember(modCondition);
|
||||
}
|
||||
|
||||
AstNode const* TraversalNode::EdgeConditionBuilder::getOutboundCondition() {
|
||||
void TraversalNode::EdgeConditionBuilder::addConditionPart(AstNode const* part) {
|
||||
_modCondition->addMember(part);
|
||||
}
|
||||
|
||||
AstNode* TraversalNode::EdgeConditionBuilder::getOutboundCondition() {
|
||||
if (_containsCondition) {
|
||||
_modCondition->changeMember(_modCondition->numMembers() - 1, _tn->_fromCondition);
|
||||
} else {
|
||||
|
@ -69,7 +73,7 @@ AstNode const* TraversalNode::EdgeConditionBuilder::getOutboundCondition() {
|
|||
return _modCondition;
|
||||
};
|
||||
|
||||
AstNode const* TraversalNode::EdgeConditionBuilder::getInboundCondition() {
|
||||
AstNode* TraversalNode::EdgeConditionBuilder::getInboundCondition() {
|
||||
if (_containsCondition) {
|
||||
_modCondition->changeMember(_modCondition->numMembers() - 1, _tn->_toCondition);
|
||||
} else {
|
||||
|
@ -616,7 +620,101 @@ void TraversalNode::fillTraversalOptions(
|
|||
arangodb::traverser::TraverserOptions& opts) const {
|
||||
opts.minDepth = _minDepth;
|
||||
opts.maxDepth = _maxDepth;
|
||||
opts.setCollections(_edgeColls, _directions);
|
||||
|
||||
// This is required by trx api.
|
||||
// But we do not use it here.
|
||||
SortCondition sort;
|
||||
|
||||
size_t numEdgeColls = _edgeColls.size();
|
||||
AstNode* condition = nullptr;
|
||||
Transaction* trx = _ast->query()->trx();
|
||||
bool res = false;
|
||||
EdgeConditionBuilder globalEdgeConditionBuilder(this);
|
||||
|
||||
opts._baseIndexHandles.reserve(numEdgeColls);
|
||||
// Compute Edge Indexes. First default indexes:
|
||||
for (size_t i = 0; i < numEdgeColls; ++i) {
|
||||
auto dir = _directions[i];
|
||||
switch (dir) {
|
||||
case TRI_EDGE_IN:
|
||||
condition = globalEdgeConditionBuilder.getInboundCondition();
|
||||
break;
|
||||
case TRI_EDGE_OUT:
|
||||
condition = globalEdgeConditionBuilder.getOutboundCondition();
|
||||
break;
|
||||
case TRI_EDGE_ANY:
|
||||
condition = globalEdgeConditionBuilder.getInboundCondition();
|
||||
res = trx->getBestIndexHandleForFilterCondition(
|
||||
_edgeColls[i], condition, _tmpObjVariable, &sort, 1000,
|
||||
opts._baseIndexHandles);
|
||||
TRI_ASSERT(res); // Right now we have an enforced edge index which wil
|
||||
// always fit.
|
||||
condition = globalEdgeConditionBuilder.getOutboundCondition();
|
||||
break;
|
||||
}
|
||||
#warning hard-coded nrItems.
|
||||
res = trx->getBestIndexHandleForFilterCondition(
|
||||
_edgeColls[i], condition, _tmpObjVariable, &sort, 1000,
|
||||
opts._baseIndexHandles);
|
||||
TRI_ASSERT(res); // We have an enforced edge index which wil always fit.
|
||||
}
|
||||
|
||||
for (std::pair<size_t, EdgeConditionBuilder> it : _edgeConditions) {
|
||||
auto ins = opts._depthIndexHandles.emplace(
|
||||
it.first, std::vector<Transaction::IndexHandle>());
|
||||
TRI_ASSERT(ins.second);
|
||||
|
||||
auto& idxList = ins.first->second;
|
||||
idxList.reserve(numEdgeColls);
|
||||
// Compute Edge Indexes. First default indexes:
|
||||
for (size_t i = 0; i < numEdgeColls; ++i) {
|
||||
auto dir = _directions[i];
|
||||
switch (dir) {
|
||||
case TRI_EDGE_IN:
|
||||
condition = it.second.getInboundCondition();
|
||||
break;
|
||||
case TRI_EDGE_OUT:
|
||||
condition = it.second.getOutboundCondition();
|
||||
break;
|
||||
case TRI_EDGE_ANY:
|
||||
condition = it.second.getInboundCondition();
|
||||
res = trx->getBestIndexHandleForFilterCondition(
|
||||
_edgeColls[i], condition, _tmpObjVariable, &sort, 1000, idxList);
|
||||
TRI_ASSERT(res); // Right now we have an enforced edge index which wil
|
||||
// always fit.
|
||||
condition = it.second.getOutboundCondition();
|
||||
break;
|
||||
}
|
||||
#warning hard-coded nrItems.
|
||||
res = trx->getBestIndexHandleForFilterCondition(
|
||||
_edgeColls[i], condition, _tmpObjVariable, &sort, 1000, idxList);
|
||||
TRI_ASSERT(res); // We have an enforced edge index which wil always fit.
|
||||
}
|
||||
}
|
||||
|
||||
VPackBuilder ulf;
|
||||
ulf.openObject();
|
||||
ulf.add(VPackValue("base"));
|
||||
ulf.openArray();
|
||||
for (auto const& idx : opts._baseIndexHandles) {
|
||||
ulf.openObject();
|
||||
idx.toVelocyPack(ulf, false);
|
||||
ulf.close();
|
||||
}
|
||||
ulf.close();
|
||||
for (auto const& it : opts._depthIndexHandles) {
|
||||
ulf.add(VPackValue(std::to_string(it.first)));
|
||||
ulf.openArray();
|
||||
for (auto const& idx : it.second) {
|
||||
ulf.openObject();
|
||||
idx.toVelocyPack(ulf, false);
|
||||
ulf.close();
|
||||
}
|
||||
ulf.close();
|
||||
}
|
||||
ulf.close();
|
||||
LOG(ERR) << ulf.toJson();
|
||||
|
||||
opts.useBreadthFirst = _options.useBreadthFirst;
|
||||
opts.uniqueVertices = _options.uniqueVertices;
|
||||
opts.uniqueEdges = _options.uniqueEdges;
|
||||
|
@ -643,11 +741,17 @@ void TraversalNode::setCondition(arangodb::aql::Condition* condition) {
|
|||
|
||||
void TraversalNode::registerCondition(bool isConditionOnEdge,
|
||||
size_t conditionLevel,
|
||||
AstNode* condition) {
|
||||
AstNode const* condition) {
|
||||
|
||||
if (isConditionOnEdge) {
|
||||
TRI_ASSERT(_edgeConditions.find(conditionLevel) == _edgeConditions.end());
|
||||
_edgeConditions.emplace(conditionLevel, EdgeConditionBuilder(this, condition));
|
||||
auto const& it = _edgeConditions.find(conditionLevel);
|
||||
if (it == _edgeConditions.end()) {
|
||||
EdgeConditionBuilder builder(this);
|
||||
builder.addConditionPart(condition);
|
||||
_edgeConditions.emplace(conditionLevel, builder);
|
||||
} else {
|
||||
it->second.addConditionPart(condition);
|
||||
}
|
||||
} else {
|
||||
auto const& it = _vertexConditions.find(conditionLevel);
|
||||
if (it == _vertexConditions.end()) {
|
||||
|
@ -664,7 +768,7 @@ void TraversalNode::registerCondition(bool isConditionOnEdge,
|
|||
}
|
||||
|
||||
void TraversalNode::registerGlobalCondition(bool isConditionOnEdge,
|
||||
AstNode* condition) {
|
||||
AstNode const* condition) {
|
||||
std::cout << "Registering global condition for edges: " << isConditionOnEdge << std::endl;
|
||||
if (isConditionOnEdge) {
|
||||
_globalEdgeCondition = condition;
|
||||
|
@ -674,3 +778,7 @@ void TraversalNode::registerGlobalCondition(bool isConditionOnEdge,
|
|||
|
||||
condition->dump(0);
|
||||
}
|
||||
|
||||
AstNode* TraversalNode::getTemporaryRefNode() const {
|
||||
return _tmpObjVarNode;
|
||||
}
|
||||
|
|
|
@ -49,13 +49,15 @@ class TraversalNode : public ExecutionNode {
|
|||
bool _containsCondition;
|
||||
|
||||
public:
|
||||
EdgeConditionBuilder(TraversalNode const*, AstNode*);
|
||||
EdgeConditionBuilder(TraversalNode const*);
|
||||
|
||||
~EdgeConditionBuilder() {}
|
||||
|
||||
AstNode const* getOutboundCondition();
|
||||
void addConditionPart(AstNode const*);
|
||||
|
||||
AstNode const* getInboundCondition();
|
||||
AstNode* getOutboundCondition();
|
||||
|
||||
AstNode* getInboundCondition();
|
||||
};
|
||||
|
||||
|
||||
|
@ -211,12 +213,12 @@ class TraversalNode : public ExecutionNode {
|
|||
/// @brief register a filter condition on a given search depth.
|
||||
/// If this condition is not fulfilled a traversal will abort.
|
||||
/// The condition will contain the local variable for it's accesses.
|
||||
void registerCondition(bool, size_t, AstNode*);
|
||||
void registerCondition(bool, size_t, AstNode const*);
|
||||
|
||||
/// @brief register a filter condition for all search depths
|
||||
/// If this condition is not fulfilled a traversal will abort.
|
||||
/// The condition will contain the local variable for it's accesses.
|
||||
void registerGlobalCondition(bool, AstNode*);
|
||||
void registerGlobalCondition(bool, AstNode const*);
|
||||
|
||||
bool allDirectionsEqual() const;
|
||||
|
||||
|
@ -227,6 +229,8 @@ class TraversalNode : public ExecutionNode {
|
|||
|
||||
TraversalOptions const* options() const { return &_options; }
|
||||
|
||||
AstNode* getTemporaryRefNode() const;
|
||||
|
||||
private:
|
||||
/// @brief the database
|
||||
TRI_vocbase_t* _vocbase;
|
||||
|
@ -299,10 +303,10 @@ class TraversalNode : public ExecutionNode {
|
|||
|
||||
/// @brief The global edge condition. Does not contain
|
||||
/// _from and _to checks
|
||||
AstNode* _globalEdgeCondition;
|
||||
AstNode const* _globalEdgeCondition;
|
||||
|
||||
/// @brief The global vertex condition
|
||||
AstNode* _globalVertexCondition;
|
||||
AstNode const* _globalVertexCondition;
|
||||
|
||||
/// @brief List of all depth specific conditions for edges
|
||||
std::unordered_map<size_t, EdgeConditionBuilder> _edgeConditions;
|
||||
|
|
|
@ -101,6 +101,8 @@ void ClusterTraverser::UniqueVertexGetter::reset() {
|
|||
void ClusterTraverser::ClusterEdgeGetter::getEdge(
|
||||
std::string const& startVertex, std::vector<std::string>& result,
|
||||
size_t*& last, size_t& eColIdx) {
|
||||
#warning This path fetches Edges from DBServer, honoring conditions. Has to be rewritten.
|
||||
/*
|
||||
std::string collName;
|
||||
TRI_edge_direction_e dir;
|
||||
if (!_traverser->_opts.getCollection(eColIdx, collName, dir)) {
|
||||
|
@ -116,8 +118,6 @@ void ClusterTraverser::ClusterEdgeGetter::getEdge(
|
|||
|
||||
VPackBuilder resultEdges;
|
||||
resultEdges.openObject();
|
||||
#warning This path fetches Edges from DBServer, honoring conditions. Has to be rewritten.
|
||||
/*
|
||||
auto found = _traverser->_opts.expressions->find(depth);
|
||||
if (found != _traverser->_opts.expressions->end()) {
|
||||
expEdges = found->second;
|
||||
|
@ -129,7 +129,6 @@ void ClusterTraverser::ClusterEdgeGetter::getEdge(
|
|||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
THROW_ARANGO_EXCEPTION(res);
|
||||
}
|
||||
*/
|
||||
resultEdges.close();
|
||||
VPackSlice resSlice = resultEdges.slice();
|
||||
VPackSlice edgesSlice = resSlice.get("edges");
|
||||
|
@ -225,6 +224,7 @@ void ClusterTraverser::ClusterEdgeGetter::getEdge(
|
|||
result.push_back(std::move(next));
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
void ClusterTraverser::ClusterEdgeGetter::getAllEdges(
|
||||
|
|
|
@ -380,10 +380,9 @@ bool Transaction::sortOrs(arangodb::aql::Ast* ast,
|
|||
std::pair<bool, bool> Transaction::findIndexHandleForAndNode(
|
||||
std::vector<std::shared_ptr<Index>> indexes, arangodb::aql::AstNode* node,
|
||||
arangodb::aql::Variable const* reference,
|
||||
arangodb::aql::SortCondition const* sortCondition,
|
||||
size_t itemsInCollection,
|
||||
arangodb::aql::SortCondition const* sortCondition, size_t itemsInCollection,
|
||||
std::vector<Transaction::IndexHandle>& usedIndexes,
|
||||
arangodb::aql::AstNode*& specializedCondition,
|
||||
bool computeSpecialisation, arangodb::aql::AstNode*& specializedCondition,
|
||||
bool& isSparse) const {
|
||||
std::shared_ptr<Index> bestIndex;
|
||||
double bestCost = 0.0;
|
||||
|
@ -461,7 +460,9 @@ std::pair<bool, bool> Transaction::findIndexHandleForAndNode(
|
|||
return std::make_pair(false, false);
|
||||
}
|
||||
|
||||
specializedCondition = bestIndex->specializeCondition(node, reference);
|
||||
if (computeSpecialisation) {
|
||||
specializedCondition = bestIndex->specializeCondition(node, reference);
|
||||
}
|
||||
|
||||
usedIndexes.emplace_back(bestIndex);
|
||||
isSparse = bestIndex->sparse();
|
||||
|
@ -2694,7 +2695,7 @@ std::pair<bool, bool> Transaction::getBestIndexHandlesForFilterCondition(
|
|||
arangodb::aql::AstNode* specializedCondition = nullptr;
|
||||
auto canUseIndex = findIndexHandleForAndNode(
|
||||
indexes, node, reference, sortCondition, itemsInCollection, usedIndexes,
|
||||
specializedCondition, isSparse);
|
||||
true, specializedCondition, isSparse);
|
||||
|
||||
if (canUseIndex.second && !canUseIndex.first) {
|
||||
// index can be used for sorting only
|
||||
|
@ -2731,6 +2732,41 @@ std::pair<bool, bool> Transaction::getBestIndexHandlesForFilterCondition(
|
|||
return std::make_pair(canUseForFilter, canUseForSort);
|
||||
}
|
||||
|
||||
|
||||
/// @brief Gets the best fitting index for one specific condition.
|
||||
/// Difference to IndexHandles: Condition is only one NARY_AND
|
||||
/// and the Condition stays unmodified. Also does not care for sorting
|
||||
/// Returns false if no index could be found.
|
||||
|
||||
bool Transaction::getBestIndexHandleForFilterCondition(
|
||||
std::string const& collectionName,
|
||||
arangodb::aql::AstNode const* node,
|
||||
arangodb::aql::Variable const* reference,
|
||||
arangodb::aql::SortCondition const* sortCondition,
|
||||
size_t itemsInCollection,
|
||||
std::vector<IndexHandle>& usedIndexes) {
|
||||
// We can only start after DNF transformation and only a single AND
|
||||
TRI_ASSERT(node->type ==
|
||||
arangodb::aql::AstNodeType::NODE_TYPE_OPERATOR_NARY_AND);
|
||||
if (node->numMembers() == 0) {
|
||||
// Well no index can serve no condition.
|
||||
return false;
|
||||
}
|
||||
|
||||
auto indexes = indexesForCollection(collectionName);
|
||||
bool isSparse = false;
|
||||
|
||||
arangodb::aql::AstNode* specializedCondition = nullptr;
|
||||
// Const cast is save here. Giving computeSpecialisation == false
|
||||
// Makes sure node is NOT modified.
|
||||
auto canUseIndex = findIndexHandleForAndNode(
|
||||
indexes, const_cast<aql::AstNode*>(node), reference, sortCondition,
|
||||
itemsInCollection, usedIndexes, false, specializedCondition, isSparse);
|
||||
|
||||
return canUseIndex.first;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Checks if the index supports the filter condition.
|
||||
/// note: the caller must have read-locked the underlying collection when
|
||||
|
@ -2832,7 +2868,7 @@ std::pair<bool, bool> Transaction::getIndexForSortCondition(
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
OperationCursor* Transaction::indexScanForCondition(
|
||||
std::string const& collectionName, IndexHandle const& indexId,
|
||||
IndexHandle const& indexId,
|
||||
arangodb::aql::AstNode const* condition, arangodb::aql::Variable const* var,
|
||||
uint64_t limit, uint64_t batchSize, bool reverse) {
|
||||
if (ServerState::isCoordinator(_serverRole)) {
|
||||
|
|
|
@ -546,6 +546,17 @@ class Transaction {
|
|||
arangodb::aql::Variable const*, arangodb::aql::SortCondition const*,
|
||||
size_t, std::vector<IndexHandle>&, bool&);
|
||||
|
||||
/// @brief Gets the best fitting index for one specific condition.
|
||||
/// Difference to IndexHandles: Condition is only one NARY_AND
|
||||
/// and the Condition stays unmodified. Also does not care for sorting
|
||||
/// Returns false if no index could be found.
|
||||
|
||||
bool getBestIndexHandleForFilterCondition(std::string const&,
|
||||
arangodb::aql::AstNode const*,
|
||||
arangodb::aql::Variable const*,
|
||||
arangodb::aql::SortCondition const*,
|
||||
size_t, std::vector<IndexHandle>&);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Checks if the index supports the filter condition.
|
||||
/// note: the caller must have read-locked the underlying collection when
|
||||
|
@ -584,10 +595,10 @@ class Transaction {
|
|||
/// calling this method
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
OperationCursor* indexScanForCondition(
|
||||
std::string const& collectionName, IndexHandle const& indexId,
|
||||
arangodb::aql::AstNode const*, arangodb::aql::Variable const*, uint64_t,
|
||||
uint64_t, bool);
|
||||
OperationCursor* indexScanForCondition(IndexHandle const&,
|
||||
arangodb::aql::AstNode const*,
|
||||
arangodb::aql::Variable const*,
|
||||
uint64_t, uint64_t, bool);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief factory for OperationCursor objects
|
||||
|
@ -810,7 +821,7 @@ class Transaction {
|
|||
arangodb::aql::SortCondition const* sortCondition,
|
||||
size_t itemsInCollection,
|
||||
std::vector<Transaction::IndexHandle>& usedIndexes,
|
||||
arangodb::aql::AstNode*& specializedCondition,
|
||||
bool computeSpecialisation, arangodb::aql::AstNode*& specializedCondition,
|
||||
bool& isSparse) const;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -294,6 +294,9 @@ aql::AqlValue SingleServerTraverser::pathToAqlValue(VPackBuilder& builder) {
|
|||
bool SingleServerTraverser::EdgeGetter::nextCursor(std::string const& startVertex,
|
||||
size_t& eColIdx,
|
||||
size_t*& last) {
|
||||
#warning Reimplement
|
||||
return false;
|
||||
/*
|
||||
std::string eColName;
|
||||
|
||||
while (true) {
|
||||
|
@ -327,6 +330,7 @@ bool SingleServerTraverser::EdgeGetter::nextCursor(std::string const& startVerte
|
|||
_results.emplace();
|
||||
return true;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
void SingleServerTraverser::EdgeGetter::nextEdge(
|
||||
|
@ -424,6 +428,8 @@ void SingleServerTraverser::EdgeGetter::getAllEdges(
|
|||
std::string const& startVertex, std::unordered_set<std::string>& edges,
|
||||
size_t depth) {
|
||||
|
||||
#warning reimplement
|
||||
/*
|
||||
size_t idxId = 0;
|
||||
std::string eColName;
|
||||
arangodb::Transaction::IndexHandle indexHandle;
|
||||
|
@ -476,5 +482,6 @@ void SingleServerTraverser::EdgeGetter::getAllEdges(
|
|||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
|
|
|
@ -71,34 +71,8 @@ void arangodb::traverser::ShortestPath::vertexToVelocyPack(Transaction* trx, siz
|
|||
}
|
||||
}
|
||||
|
||||
void arangodb::traverser::TraverserOptions::setCollections(
|
||||
std::vector<std::string> const& colls, TRI_edge_direction_e dir) {
|
||||
// We do not allow to reset the collections.
|
||||
TRI_ASSERT(_collections.empty());
|
||||
TRI_ASSERT(_directions.empty());
|
||||
TRI_ASSERT(!colls.empty());
|
||||
_collections = colls;
|
||||
_directions.emplace_back(dir);
|
||||
for (auto const& it : colls) {
|
||||
_indexHandles.emplace_back(_trx->edgeIndexHandle(it));
|
||||
}
|
||||
}
|
||||
|
||||
void arangodb::traverser::TraverserOptions::setCollections(
|
||||
std::vector<std::string> const& colls,
|
||||
std::vector<TRI_edge_direction_e> const& dirs) {
|
||||
// We do not allow to reset the collections.
|
||||
TRI_ASSERT(_collections.empty());
|
||||
TRI_ASSERT(_directions.empty());
|
||||
TRI_ASSERT(!colls.empty());
|
||||
TRI_ASSERT(colls.size() == dirs.size());
|
||||
_collections = colls;
|
||||
_directions = dirs;
|
||||
for (auto const& it : colls) {
|
||||
_indexHandles.emplace_back(_trx->edgeIndexHandle(it));
|
||||
}
|
||||
}
|
||||
|
||||
#warning TODO remove
|
||||
/*
|
||||
size_t arangodb::traverser::TraverserOptions::collectionCount () const {
|
||||
return _collections.size();
|
||||
}
|
||||
|
@ -144,6 +118,7 @@ bool arangodb::traverser::TraverserOptions::getCollectionAndSearchValue(
|
|||
arangodb::EdgeIndex::buildSearchValue(dir, vertexId, builder);
|
||||
return true;
|
||||
}
|
||||
*/
|
||||
|
||||
bool arangodb::traverser::TraverserOptions::evaluateEdgeExpression(arangodb::velocypack::Slice edge, size_t depth) const {
|
||||
#warning This has to be implemented.
|
||||
|
|
|
@ -39,6 +39,10 @@ namespace velocypack {
|
|||
class Builder;
|
||||
class Slice;
|
||||
}
|
||||
|
||||
namespace aql {
|
||||
class TraversalNode;
|
||||
}
|
||||
namespace traverser {
|
||||
|
||||
class TraverserExpression {
|
||||
|
@ -197,13 +201,17 @@ class TraversalPath {
|
|||
};
|
||||
|
||||
struct TraverserOptions {
|
||||
friend class arangodb::aql::TraversalNode;
|
||||
|
||||
enum UniquenessLevel { NONE, PATH, GLOBAL };
|
||||
|
||||
private:
|
||||
arangodb::Transaction* _trx;
|
||||
std::vector<std::string> _collections;
|
||||
std::vector<TRI_edge_direction_e> _directions;
|
||||
std::vector<arangodb::Transaction::IndexHandle> _indexHandles;
|
||||
std::vector<arangodb::Transaction::IndexHandle> _baseIndexHandles;
|
||||
std::unordered_map<size_t, std::vector<arangodb::Transaction::IndexHandle>>
|
||||
_depthIndexHandles;
|
||||
|
||||
public:
|
||||
uint64_t minDepth;
|
||||
|
@ -227,10 +235,7 @@ struct TraverserOptions {
|
|||
uniqueEdges(UniquenessLevel::PATH) {
|
||||
}
|
||||
|
||||
void setCollections(std::vector<std::string> const&, TRI_edge_direction_e);
|
||||
void setCollections(std::vector<std::string> const&,
|
||||
std::vector<TRI_edge_direction_e> const&);
|
||||
|
||||
/*
|
||||
size_t collectionCount() const;
|
||||
|
||||
bool getCollection(size_t, std::string&, TRI_edge_direction_e&) const;
|
||||
|
@ -238,7 +243,8 @@ struct TraverserOptions {
|
|||
bool getCollectionAndSearchValue(size_t, std::string const&, std::string&,
|
||||
arangodb::Transaction::IndexHandle&,
|
||||
arangodb::velocypack::Builder&) const;
|
||||
|
||||
*/
|
||||
|
||||
bool evaluateEdgeExpression(arangodb::velocypack::Slice, size_t) const;
|
||||
|
||||
bool evaluateVertexExpression(arangodb::velocypack::Slice, size_t) const;
|
||||
|
|
Loading…
Reference in New Issue