1
0
Fork 0

Make WalkerWorker a template class.

Implement findNodesOfType for ExecutionPlans.
This commit is contained in:
Max Neunhoeffer 2014-08-14 15:04:59 +02:00
parent 50851bfcba
commit f248792865
8 changed files with 58 additions and 48 deletions

View File

@ -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;

View File

@ -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:

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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
// -----------------------------------------------------------------------------

View 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
// -----------------------------------------------------------------------------

View File

@ -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;
};
}