From 6c81f630a3d0066364836e5bda4a6fbfa8e8cc53 Mon Sep 17 00:00:00 2001 From: Willi Goesgens Date: Thu, 25 Sep 2014 17:08:20 +0200 Subject: [PATCH] Add filter rule which moves Filters & Calculations into the parts of a Plan that is distributed to clusters. --- arangod/Aql/Optimizer.cpp | 8 ++++ arangod/Aql/Optimizer.h | 8 +++- arangod/Aql/OptimizerRules.cpp | 82 ++++++++++++++++++++++++++++++++++ arangod/Aql/OptimizerRules.h | 1 + 4 files changed, 97 insertions(+), 2 deletions(-) diff --git a/arangod/Aql/Optimizer.cpp b/arangod/Aql/Optimizer.cpp index 339f495606..9ac3660c44 100644 --- a/arangod/Aql/Optimizer.cpp +++ b/arangod/Aql/Optimizer.cpp @@ -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: diff --git a/arangod/Aql/Optimizer.h b/arangod/Aql/Optimizer.h index 7b11723774..8b7eb89c3d 100644 --- a/arangod/Aql/Optimizer.h +++ b/arangod/Aql/Optimizer.h @@ -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: diff --git a/arangod/Aql/OptimizerRules.cpp b/arangod/Aql/OptimizerRules.cpp index 74eb5638e2..c861a5b3b7 100644 --- a/arangod/Aql/OptimizerRules.cpp +++ b/arangod/Aql/OptimizerRules.cpp @@ -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 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--\\|/// @\\}\\)" diff --git a/arangod/Aql/OptimizerRules.h b/arangod/Aql/OptimizerRules.h index 4aa86d284e..68334896d1 100644 --- a/arangod/Aql/OptimizerRules.h +++ b/arangod/Aql/OptimizerRules.h @@ -112,6 +112,7 @@ namespace triagens { int distributeInCluster (Optimizer*, ExecutionPlan*, Optimizer::Rule const*); + int distributeFilternCalcToCluster (Optimizer*, ExecutionPlan*, Optimizer::Rule const*); } // namespace aql } // namespace triagens