mirror of https://gitee.com/bigwinds/arangodb
Finish first optimization rule: remove unnecessary calcs.
So far not activated, because test suite crashes. Need to look into details.
This commit is contained in:
parent
f8cf5dc26d
commit
9e91d9bba3
|
@ -709,6 +709,16 @@ namespace triagens {
|
|||
//FIXME improve this estimate . . .
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief getVariablesSetHere
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
virtual std::vector<Variable const*> getVariablesSetHere () {
|
||||
std::vector<Variable const*> v;
|
||||
v.push_back(_outVariable);
|
||||
return v;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- private variables
|
||||
// -----------------------------------------------------------------------------
|
||||
|
@ -1548,6 +1558,28 @@ namespace triagens {
|
|||
// TODO: improve this estimate!
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief getVariablesUsedHere
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
virtual std::vector<Variable const*> getVariablesUsedHere () {
|
||||
std::vector<Variable const*> v;
|
||||
v.push_back(_inVariable);
|
||||
return v;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief getVariablesSetHere
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
virtual std::vector<Variable const*> getVariablesSetHere () {
|
||||
std::vector<Variable const*> v;
|
||||
if (_outVariable != nullptr) {
|
||||
v.push_back(_outVariable);
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- private variables
|
||||
// -----------------------------------------------------------------------------
|
||||
|
@ -1635,6 +1667,28 @@ namespace triagens {
|
|||
return 1000 * _dependencies.at(0)->getCost(); //FIXME change this!
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief getVariablesUsedHere
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
virtual std::vector<Variable const*> getVariablesUsedHere () {
|
||||
std::vector<Variable const*> v;
|
||||
v.push_back(_inVariable);
|
||||
return v;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief getVariablesSetHere
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
virtual std::vector<Variable const*> getVariablesSetHere () {
|
||||
std::vector<Variable const*> v;
|
||||
if (_outVariable != nullptr) {
|
||||
v.push_back(_outVariable);
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- private variables
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
|
@ -832,6 +832,56 @@ void ExecutionPlan::findVarUsage () {
|
|||
root()->walk(&finder);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief removeNodes
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct NodeRemover : public WalkerWorker<ExecutionNode> {
|
||||
|
||||
ExecutionPlan* _plan;
|
||||
std::unordered_set<ExecutionNode*>& _toRemove;
|
||||
std::vector<ExecutionNode*> parents;
|
||||
|
||||
NodeRemover (ExecutionPlan* plan,
|
||||
std::unordered_set<ExecutionNode*>& toRemove)
|
||||
: _plan(plan), _toRemove(toRemove) {
|
||||
}
|
||||
|
||||
~NodeRemover () {
|
||||
};
|
||||
|
||||
void before (ExecutionNode* en) {
|
||||
if (_toRemove.find(en) != _toRemove.end()) {
|
||||
// Remove this node:
|
||||
if (parents.size() == 0) {
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL,
|
||||
"Cannot remove root node of plan.");
|
||||
}
|
||||
else {
|
||||
auto dep = en->getDependencies();
|
||||
parents.back()->removeDependency(en);
|
||||
if (dep.size() == 1) {
|
||||
parents.back()->addDependency(dep[0]);
|
||||
}
|
||||
else if (dep.size() > 1) {
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL,
|
||||
"Cannot remove node with more than one dependency.");
|
||||
}
|
||||
}
|
||||
}
|
||||
parents.push_back(en);
|
||||
}
|
||||
|
||||
void after (ExecutionNode* en) {
|
||||
parents.pop_back();
|
||||
}
|
||||
};
|
||||
|
||||
void ExecutionPlan::removeNodes (std::unordered_set<ExecutionNode*>& toRemove) {
|
||||
NodeRemover remover(this, toRemove);
|
||||
root()->walk(&remover);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- END-OF-FILE
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
|
@ -110,6 +110,13 @@ namespace triagens {
|
|||
|
||||
void findVarUsage ();
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief removeNodes, note that this does not delete the removed
|
||||
/// nodes and that one cannot remove the root node of the plan.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void removeNodes (std::unordered_set<ExecutionNode*>& toRemove);
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- private methods
|
||||
// -----------------------------------------------------------------------------
|
||||
|
@ -251,7 +258,7 @@ namespace triagens {
|
|||
std::vector<ExecutionNode*> _nodes;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief root node of the engine
|
||||
/// @brief root node of the plan
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ExecutionNode* _root;
|
||||
|
|
|
@ -41,7 +41,8 @@ using namespace triagens::aql;
|
|||
Optimizer::Optimizer () {
|
||||
// List all the rules in the system here:
|
||||
registerRule (relaxRule, 1000);
|
||||
registerRule (removeUnnecessaryCalc, 999);
|
||||
// registerRule (removeUnnecessaryCalc, 999);
|
||||
// deactivated because a test crashes
|
||||
|
||||
// Now sort them by pass:
|
||||
std::stable_sort(_rules.begin(), _rules.end());
|
||||
|
@ -65,6 +66,9 @@ int Optimizer::createPlans (ExecutionPlan* plan) {
|
|||
_plans.clear();
|
||||
|
||||
for (int pass = 1; pass <= numberOfPasses; pass++) {
|
||||
std::cout << "Entering pass " << pass << " of query optimization..."
|
||||
<< std::endl;
|
||||
|
||||
// This vector holds the plans we have created in this pass:
|
||||
PlanList newPlans;
|
||||
|
||||
|
|
|
@ -55,7 +55,32 @@ int triagens::aql::removeUnnecessaryCalc (Optimizer* opt,
|
|||
bool& keep) {
|
||||
std::vector<ExecutionNode*> nodes
|
||||
= plan->findNodesOfType(triagens::aql::ExecutionNode::CALCULATION);
|
||||
keep = true;
|
||||
std::unordered_set<ExecutionNode*> toRemove;
|
||||
for (auto n : nodes) {
|
||||
auto nn = static_cast<CalculationNode*>(n);
|
||||
if (! nn->expression()->canThrow()) {
|
||||
// If this node can throw, we must not optimize it away!
|
||||
auto outvar = n->getVariablesSetHere();
|
||||
TRI_ASSERT(outvar.size() == 1);
|
||||
auto varsUsedLater = n->getVarsUsedLater();
|
||||
if (varsUsedLater.find(outvar[0]) == varsUsedLater.end()) {
|
||||
// The variable whose value is calculated here is not used at
|
||||
// all further down the pipeline! We remove the whole
|
||||
// calculation node,
|
||||
toRemove.insert(n);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (toRemove.size() > 0) {
|
||||
std::cout << "Removing " << toRemove.size() << " unnecessary "
|
||||
"CalculationNodes..." << std::endl;
|
||||
plan->removeNodes(toRemove);
|
||||
out.push_back(plan);
|
||||
keep = false;
|
||||
}
|
||||
else {
|
||||
keep = true;
|
||||
}
|
||||
return TRI_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue