mirror of https://gitee.com/bigwinds/arangodb
prelim version of undistributeRemoveAfterEnumColl
This commit is contained in:
parent
96cb6e3550
commit
2fd8c2b185
|
@ -1875,17 +1875,17 @@ int triagens::aql::distributeSortToCluster (Optimizer* opt,
|
||||||
return TRI_ERROR_NO_ERROR;
|
return TRI_ERROR_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
class RemoveToSingletonViaCalcOnlyFinder: public WalkerWorker<ExecutionNode> {
|
class RemoteToSingletonViaCalcOnlyFinder: public WalkerWorker<ExecutionNode> {
|
||||||
ExecutionNode* _scatter;
|
ExecutionNode* _scatter;
|
||||||
std::unordered_set<ExecutionNode*>& _toUnlink;
|
std::unordered_set<ExecutionNode*>& _toUnlink;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RemoveToSingletonViaCalcOnlyFinder (std::unordered_set<ExecutionNode*>& toUnlink)
|
RemoteToSingletonViaCalcOnlyFinder (std::unordered_set<ExecutionNode*>& toUnlink)
|
||||||
: _scatter(nullptr),
|
: _scatter(nullptr),
|
||||||
_toUnlink(toUnlink){
|
_toUnlink(toUnlink){
|
||||||
};
|
};
|
||||||
|
|
||||||
~RemoveToSingletonViaCalcOnlyFinder () {
|
~RemoteToSingletonViaCalcOnlyFinder () {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool before (ExecutionNode* en) {
|
bool before (ExecutionNode* en) {
|
||||||
|
@ -1944,19 +1944,156 @@ class RemoveToSingletonViaCalcOnlyFinder: public WalkerWorker<ExecutionNode> {
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
int triagens::aql::removeUnnecessaryRemoteScatter (Optimizer* opt,
|
int triagens::aql::removeUnnecessaryRemoteScatter (Optimizer* opt,
|
||||||
ExecutionPlan* plan,
|
ExecutionPlan* plan,
|
||||||
Optimizer::Rule const* rule) {
|
Optimizer::Rule const* rule) {
|
||||||
std::vector<ExecutionNode*> nodes
|
std::vector<ExecutionNode*> nodes
|
||||||
= plan->findNodesOfType(triagens::aql::ExecutionNode::REMOTE, true);
|
= plan->findNodesOfType(triagens::aql::ExecutionNode::REMOTE, true);
|
||||||
std::unordered_set<ExecutionNode*> toUnlink;
|
std::unordered_set<ExecutionNode*> toUnlink;
|
||||||
|
|
||||||
for (auto n : nodes) {
|
for (auto n : nodes) {
|
||||||
RemoveToSingletonViaCalcOnlyFinder finder(toUnlink);
|
RemoteToSingletonViaCalcOnlyFinder finder(toUnlink);
|
||||||
n->walk(&finder);
|
n->walk(&finder);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool modified = false;
|
bool modified = false;
|
||||||
if (! toUnlink.empty()) {
|
if (!toUnlink.empty()) {
|
||||||
|
plan->unlinkNodes(toUnlink);
|
||||||
|
plan->findVarUsage();
|
||||||
|
modified = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
opt->addPlan(plan, rule->level, modified);
|
||||||
|
|
||||||
|
return TRI_ERROR_NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
class RemoveToEnumCollFinder: public WalkerWorker<ExecutionNode> {
|
||||||
|
ExecutionPlan* _plan;
|
||||||
|
std::unordered_set<ExecutionNode*>& _toUnlink;
|
||||||
|
bool _remove;
|
||||||
|
bool _scatter;
|
||||||
|
bool _gather;
|
||||||
|
EnumerateCollectionNode* _enumColl;
|
||||||
|
const Variable* _variable;
|
||||||
|
|
||||||
|
public:
|
||||||
|
RemoveToEnumCollFinder (ExecutionPlan* plan,
|
||||||
|
std::unordered_set<ExecutionNode*>& toUnlink)
|
||||||
|
: _plan(plan),
|
||||||
|
_toUnlink(toUnlink),
|
||||||
|
_remove(false),
|
||||||
|
_scatter(false),
|
||||||
|
_gather(false),
|
||||||
|
_enumColl(nullptr){
|
||||||
|
};
|
||||||
|
|
||||||
|
~RemoveToEnumCollFinder () {
|
||||||
|
}
|
||||||
|
|
||||||
|
bool before (ExecutionNode* en) {
|
||||||
|
switch (en->getType()) {
|
||||||
|
case EN::REMOVE:{
|
||||||
|
TRI_ASSERT(_remove == false);
|
||||||
|
_remove = en;
|
||||||
|
_toUnlink.insert(en);
|
||||||
|
|
||||||
|
// find the variable we are removing . . .
|
||||||
|
auto rn = static_cast<RemoveNode*>(en);
|
||||||
|
auto varsToRemove = rn->getVariablesUsedHere();
|
||||||
|
|
||||||
|
// remove nodes always have one input variable
|
||||||
|
TRI_ASSERT(varsToRemove.size() == 1);
|
||||||
|
_variable = varsToRemove[0]; // the variable we'll remove
|
||||||
|
|
||||||
|
auto _enumColl = static_cast<EnumerateCollectionNode*>(_plan->getVarSetBy(_variable->id));
|
||||||
|
|
||||||
|
if (_enumColl == nullptr
|
||||||
|
|| _enumColl->getType() != triagens::aql::ExecutionNode::ENUMERATE_COLLECTION
|
||||||
|
|| _enumColl->collection()->cid() != rn->collection()->cid() ) {
|
||||||
|
// remove variable was not introduced by an enumerate collection or
|
||||||
|
// it was but the collections differ
|
||||||
|
break; // abort . . .
|
||||||
|
}
|
||||||
|
return false; // continue . . .
|
||||||
|
}
|
||||||
|
case EN::REMOTE:{
|
||||||
|
_toUnlink.insert(en);
|
||||||
|
return false; // continue . . .
|
||||||
|
}
|
||||||
|
case EN::SCATTER:{
|
||||||
|
if (_scatter) { // met more than one scatter node
|
||||||
|
break; // abort . . .
|
||||||
|
}
|
||||||
|
_scatter = en;
|
||||||
|
_toUnlink.insert(en);
|
||||||
|
return false; // continue . . .
|
||||||
|
}
|
||||||
|
case EN::GATHER:{
|
||||||
|
if (_gather) { // met more than one gather node
|
||||||
|
break; // abort . . .
|
||||||
|
}
|
||||||
|
_gather = en;
|
||||||
|
_toUnlink.insert(en);
|
||||||
|
return false; // continue . . .
|
||||||
|
}
|
||||||
|
case EN::FILTER:{
|
||||||
|
// check that we are filtering something with the variable we are to remove
|
||||||
|
auto fn = static_cast<FilterNode*>(en);
|
||||||
|
auto varsUsedHere = fn->getVariablesUsedHere();
|
||||||
|
|
||||||
|
// filter nodes always have one input variable
|
||||||
|
TRI_ASSERT(varsUsedHere.size() == 1);
|
||||||
|
|
||||||
|
if (varsUsedHere[0]->id != _variable->id) {
|
||||||
|
break; // abort . . . FIXME is this the desired behaviour??
|
||||||
|
}
|
||||||
|
_toUnlink.insert(en);
|
||||||
|
return false; // continue . . .
|
||||||
|
}
|
||||||
|
case EN::ENUMERATE_COLLECTION: {
|
||||||
|
// check that we are enumerating the variable we are to remove
|
||||||
|
if (en->id() != _enumColl->id()) {
|
||||||
|
break; // abort . . . FIXME is this the desired behaviour??
|
||||||
|
}
|
||||||
|
_toUnlink.insert(en);
|
||||||
|
return true; // stop
|
||||||
|
}
|
||||||
|
|
||||||
|
case EN::SINGLETON:
|
||||||
|
case EN::CALCULATION:
|
||||||
|
case EN::ENUMERATE_LIST:
|
||||||
|
case EN::SUBQUERY:
|
||||||
|
case EN::AGGREGATE:
|
||||||
|
case EN::INSERT:
|
||||||
|
case EN::REPLACE:
|
||||||
|
case EN::UPDATE:
|
||||||
|
case EN::RETURN:
|
||||||
|
case EN::NORESULTS:
|
||||||
|
case EN::ILLEGAL:
|
||||||
|
case EN::LIMIT:
|
||||||
|
case EN::SORT:
|
||||||
|
case EN::INDEX_RANGE:{}
|
||||||
|
// if we meet any of the above, then we abort . . .
|
||||||
|
}
|
||||||
|
_toUnlink.clear();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
int triagens::aql::undistributeRemoveAfterEnumColl (Optimizer* opt,
|
||||||
|
ExecutionPlan* plan,
|
||||||
|
Optimizer::Rule const* rule) {
|
||||||
|
std::vector<ExecutionNode*> nodes
|
||||||
|
= plan->findNodesOfType(triagens::aql::ExecutionNode::REMOVE, true);
|
||||||
|
std::unordered_set<ExecutionNode*> toUnlink;
|
||||||
|
|
||||||
|
for (auto n : nodes) {
|
||||||
|
RemoveToEnumCollFinder finder(plan, toUnlink);
|
||||||
|
n->walk(&finder);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool modified = false;
|
||||||
|
if (!toUnlink.empty()) {
|
||||||
plan->unlinkNodes(toUnlink);
|
plan->unlinkNodes(toUnlink);
|
||||||
plan->findVarUsage();
|
plan->findVarUsage();
|
||||||
modified = true;
|
modified = true;
|
||||||
|
|
|
@ -123,6 +123,12 @@ namespace triagens {
|
||||||
|
|
||||||
int removeUnnecessaryRemoteScatter (Optimizer*, ExecutionPlan*, Optimizer::Rule const*);
|
int removeUnnecessaryRemoteScatter (Optimizer*, ExecutionPlan*, Optimizer::Rule const*);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief recognises that a RemoveNode can be moved to the shards.
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
int undistributeRemoveAfterEnumColl (Optimizer*, ExecutionPlan*, Optimizer::Rule const*);
|
||||||
|
|
||||||
} // namespace aql
|
} // namespace aql
|
||||||
} // namespace triagens
|
} // namespace triagens
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue