1
0
Fork 0

Add filter rule which moves Filters & Calculations into the parts of a Plan that is distributed to clusters.

This commit is contained in:
Willi Goesgens 2014-09-25 17:08:20 +02:00
parent f0e6356695
commit 6c81f630a3
4 changed files with 97 additions and 2 deletions

View File

@ -454,6 +454,14 @@ void Optimizer::setupRules () {
distributeInCluster_pass10,
false);
}
if (triagens::arango::ServerState::instance()->isCoordinator()) {
// distribute operations in cluster
registerRule("distribute-filtercalc-to-cluster",
distributeFilternCalcToCluster,
distributeFilternCalcToCluster_pass10,
false);
}
}
// Local Variables:

View File

@ -136,8 +136,12 @@ namespace triagens {
//////////////////////////////////////////////////////////////////////////////
// make operations on sharded collections use scatter / gather / remote
distributeInCluster_pass10 = 1000
distributeInCluster_pass10 = 1000,
// move FilterNodes & Calculation nodes inbetween
// scatter(remote) <-> gather(remote) so they're
// distributed to the cluster nodes.
distributeFilternCalcToCluster_pass10 = 1010
};
public:

View File

@ -1681,6 +1681,88 @@ int triagens::aql::distributeInCluster (Optimizer* opt,
return TRI_ERROR_NO_ERROR;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief move filters up in the plan
/// this rule modifies the plan in place
/// filters are moved as far up in the plan as possible to make result sets
/// as small as possible as early as possible
/// filters are not pushed beyond limits
////////////////////////////////////////////////////////////////////////////////
int triagens::aql::distributeFilternCalcToCluster (Optimizer* opt,
ExecutionPlan* plan,
Optimizer::Rule const* rule) {
bool modified = false;
std::vector<ExecutionNode*> nodes
= plan->findNodesOfType(triagens::aql::ExecutionNode::GATHER, true);
for (auto n : nodes) {
auto remoteNodeList = n->getDependencies();
TRI_ASSERT(remoteNodeList.size() > 0);
auto rn = remoteNodeList[0];
auto parents = n->getParents();
if (parents.size() < 1) {
continue;
}
while (1) {
bool stopSearching = false;
auto inspectNode = parents[0];
switch (inspectNode->getType()) {
case EN::ENUMERATE_LIST:
case EN::SINGLETON:
case EN::AGGREGATE:
case EN::INSERT:
case EN::REMOVE:
case EN::REPLACE:
case EN::UPDATE:
parents = inspectNode->getParents();
continue;
case EN::SUBQUERY:
case EN::RETURN:
case EN::NORESULTS:
case EN::SCATTER:
case EN::GATHER:
case EN::ILLEGAL:
//do break
case EN::REMOTE:
case EN::LIMIT:
case EN::SORT:
case EN::INDEX_RANGE:
case EN::ENUMERATE_COLLECTION:
stopSearching = true;
break;
case EN::CALCULATION:
case EN::FILTER:
// remember our cursor...
parents = inspectNode->getParents();
// then unlink the filter/calculator from the plan
plan->unlinkNode(inspectNode);
// and re-insert into plan in front of the remoteNode
plan->insertDependency(rn, inspectNode);
modified = true;
//ready to rumble!
};
if (stopSearching) {
break;
}
}
}
if (modified) {
plan->findVarUsage();
}
opt->addPlan(plan, rule->level, modified);
return TRI_ERROR_NO_ERROR;
}
// Local Variables:
// mode: outline-minor
// outline-regexp: "^\\(/// @brief\\|/// {@inheritDoc}\\|/// @addtogroup\\|// --SECTION--\\|/// @\\}\\)"

View File

@ -112,6 +112,7 @@ namespace triagens {
int distributeInCluster (Optimizer*, ExecutionPlan*, Optimizer::Rule const*);
int distributeFilternCalcToCluster (Optimizer*, ExecutionPlan*, Optimizer::Rule const*);
} // namespace aql
} // namespace triagens