mirror of https://gitee.com/bigwinds/arangodb
Make WalkerWorker a template class.
Implement findNodesOfType for ExecutionPlans.
This commit is contained in:
parent
50851bfcba
commit
f248792865
|
@ -141,7 +141,7 @@ int ExecutionBlock::initCursor (AqlItemBlock* items, size_t pos) {
|
|||
/// @brief functionality to walk an execution block recursively
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void ExecutionBlock::walk (WalkerWorker* worker) {
|
||||
void ExecutionBlock::walk (WalkerWorker<ExecutionBlock>* worker) {
|
||||
// Only do every node exactly once:
|
||||
if (worker->done(this)) {
|
||||
return;
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include "Aql/AqlItemBlock.h"
|
||||
#include "Aql/Collection.h"
|
||||
#include "Aql/ExecutionNode.h"
|
||||
#include "Aql/WalkerWorker.h"
|
||||
#include "Utils/AqlTransaction.h"
|
||||
#include "Utils/transactions.h"
|
||||
#include "Utils/V8TransactionContext.h"
|
||||
|
@ -97,35 +98,7 @@ namespace triagens {
|
|||
/// @brief functionality to walk an execution block recursively
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class WalkerWorker {
|
||||
public:
|
||||
WalkerWorker () {};
|
||||
virtual ~WalkerWorker () {};
|
||||
virtual void before (ExecutionBlock* eb) {};
|
||||
virtual void after (ExecutionBlock* eb) {};
|
||||
virtual bool enterSubquery (ExecutionBlock* super,
|
||||
ExecutionBlock* sub) {
|
||||
return true; // indicates that we enter the subquery
|
||||
};
|
||||
virtual void leaveSubquery (ExecutionBlock* super,
|
||||
ExecutionBlock* sub) {};
|
||||
bool done (ExecutionBlock* eb) {
|
||||
if (_done.find(eb) == _done.end()) {
|
||||
_done.insert(eb);
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
void reset () {
|
||||
_done.clear();
|
||||
}
|
||||
private:
|
||||
std::unordered_set<ExecutionBlock*> _done;
|
||||
};
|
||||
|
||||
void walk (WalkerWorker* worker);
|
||||
void walk (WalkerWorker<ExecutionBlock>* worker);
|
||||
|
||||
public:
|
||||
|
||||
|
@ -194,7 +167,7 @@ namespace triagens {
|
|||
}
|
||||
};
|
||||
|
||||
struct VarOverview : public WalkerWorker {
|
||||
struct VarOverview : public WalkerWorker<ExecutionBlock> {
|
||||
// The following are collected for global usage in the ExecutionBlock:
|
||||
|
||||
// map VariableIds to their depth and registerId:
|
||||
|
|
|
@ -70,7 +70,7 @@ ExecutionEngine::~ExecutionEngine () {
|
|||
// --SECTION-- walker class for ExecutionNode to instanciate
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
struct Instanciator : public WalkerWorker {
|
||||
struct Instanciator : public WalkerWorker<ExecutionNode> {
|
||||
ExecutionBlock* root;
|
||||
ExecutionEngine* engine;
|
||||
std::unordered_map<ExecutionNode*, ExecutionBlock*> cache;
|
||||
|
|
|
@ -27,7 +27,6 @@
|
|||
|
||||
#include "Aql/ExecutionNode.h"
|
||||
#include "Aql/Collection.h"
|
||||
#include "Aql/WalkerWorker.h"
|
||||
|
||||
using namespace triagens::basics;
|
||||
using namespace triagens::aql;
|
||||
|
@ -126,7 +125,7 @@ void ExecutionNode::appendAsString (std::string& st, int indent) {
|
|||
/// @brief functionality to walk an execution plan recursively
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void ExecutionNode::walk (WalkerWorker* worker) {
|
||||
void ExecutionNode::walk (WalkerWorker<ExecutionNode>* worker) {
|
||||
// Only do every node exactly once:
|
||||
if (worker->done(this)) {
|
||||
return;
|
||||
|
|
|
@ -37,12 +37,12 @@
|
|||
#include "Aql/Expression.h"
|
||||
#include "Aql/Variable.h"
|
||||
#include "Aql/Types.h"
|
||||
#include "Aql/WalkerWorker.h"
|
||||
|
||||
namespace triagens {
|
||||
namespace aql {
|
||||
|
||||
class ExecutionBlock;
|
||||
class WalkerWorker;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief class ExecutionNode, abstract base class of all execution Nodes
|
||||
|
@ -204,10 +204,10 @@ namespace triagens {
|
|||
//of performing the operation of the node . . .
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief FIXME what?
|
||||
/// @brief walk a complete execution plan recursively
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void walk (WalkerWorker* worker);
|
||||
void walk (WalkerWorker<ExecutionNode>* worker);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief export to JSON, returns an AUTOFREE Json object
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include "Aql/Expression.h"
|
||||
#include "Aql/Query.h"
|
||||
#include "Aql/Variable.h"
|
||||
#include "Aql/WalkerWorker.h"
|
||||
#include "Utils/Exception.h"
|
||||
|
||||
using namespace triagens::aql;
|
||||
|
@ -698,6 +699,39 @@ ExecutionNode* ExecutionPlan::fromNode (Ast const* ast,
|
|||
return en;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief find nodes of a certain type
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class NodeFinder : public WalkerWorker<ExecutionNode> {
|
||||
|
||||
ExecutionNode::NodeType _lookingFor;
|
||||
|
||||
std::vector<ExecutionNode*>& _out;
|
||||
|
||||
public:
|
||||
NodeFinder (ExecutionNode::NodeType lookingFor,
|
||||
std::vector<ExecutionNode*>& out)
|
||||
: _lookingFor(lookingFor), _out(out) {
|
||||
};
|
||||
|
||||
void before (ExecutionNode* en) {
|
||||
if (en->getType() == _lookingFor) {
|
||||
_out.push_back(en);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
std::vector<ExecutionNode*> ExecutionPlan::findNodesOfType (
|
||||
ExecutionNode::NodeType type) {
|
||||
|
||||
std::vector<ExecutionNode*> result;
|
||||
NodeFinder finder(type, result);
|
||||
root()->walk(&finder);
|
||||
return result;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- END-OF-FILE
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
|
@ -97,6 +97,12 @@ namespace triagens {
|
|||
return _root->getCost();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief find nodes of a certain type
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::vector<ExecutionNode*> findNodesOfType (ExecutionNode::NodeType);
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- private methods
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
|
@ -33,13 +33,11 @@
|
|||
namespace triagens {
|
||||
namespace aql {
|
||||
|
||||
class ExecutionNode;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief functionality to walk an execution plan recursively
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class WalkerWorker {
|
||||
template<class T> class WalkerWorker {
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- constructors / destructors
|
||||
|
@ -57,22 +55,22 @@ namespace triagens {
|
|||
// --SECTION-- public functions
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
virtual void before (ExecutionNode* en) {
|
||||
virtual void before (T* en) {
|
||||
}
|
||||
|
||||
virtual void after (ExecutionNode* en) {
|
||||
virtual void after (T* en) {
|
||||
}
|
||||
|
||||
virtual bool enterSubquery (ExecutionNode* super,
|
||||
ExecutionNode* sub) {
|
||||
virtual bool enterSubquery (T* super,
|
||||
T* sub) {
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual void leaveSubquery (ExecutionNode* super,
|
||||
ExecutionNode* sub) {
|
||||
virtual void leaveSubquery (T* super,
|
||||
T* sub) {
|
||||
}
|
||||
|
||||
bool done (ExecutionNode* en) {
|
||||
bool done (T* en) {
|
||||
if (_done.find(en) == _done.end()) {
|
||||
_done.insert(en);
|
||||
return false;
|
||||
|
@ -91,7 +89,7 @@ namespace triagens {
|
|||
|
||||
private:
|
||||
|
||||
std::unordered_set<ExecutionNode*> _done;
|
||||
std::unordered_set<T*> _done;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue