mirror of https://gitee.com/bigwinds/arangodb
remove-redundant-sorts
This commit is contained in:
parent
2eb38c9657
commit
ca814c9733
|
@ -1425,6 +1425,38 @@ namespace triagens {
|
||||||
std::vector<std::tuple<ExecutionNode const*, std::string, bool>> criteria;
|
std::vector<std::tuple<ExecutionNode const*, std::string, bool>> criteria;
|
||||||
bool isValid = true;
|
bool isValid = true;
|
||||||
bool isComplex = false;
|
bool isComplex = false;
|
||||||
|
|
||||||
|
bool isCoveredBy (SortInformation const& other) {
|
||||||
|
if (! isValid || ! other.isValid) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isComplex) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t const n = criteria.size();
|
||||||
|
for (size_t i = 0; i < n; ++i) {
|
||||||
|
if (other.criteria.size() < i) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto ours = criteria[i];
|
||||||
|
auto theirs = other.criteria[i];
|
||||||
|
|
||||||
|
if (std::get<2>(ours) != std::get<2>(theirs)) {
|
||||||
|
// sort order is different
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (std::get<1>(ours) != std::get<1>(theirs)) {
|
||||||
|
// sort criterion is different
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
|
@ -59,23 +59,55 @@ int triagens::aql::removeRedundantSorts (Optimizer* opt,
|
||||||
ExecutionPlan* plan,
|
ExecutionPlan* plan,
|
||||||
int level,
|
int level,
|
||||||
Optimizer::PlanList& out) {
|
Optimizer::PlanList& out) {
|
||||||
// should we enter subqueries??
|
|
||||||
std::vector<ExecutionNode*> nodes = plan->findNodesOfType(triagens::aql::ExecutionNode::SORT, true);
|
std::vector<ExecutionNode*> nodes = plan->findNodesOfType(triagens::aql::ExecutionNode::SORT, true);
|
||||||
|
std::unordered_set<ExecutionNode*> toUnlink;
|
||||||
|
|
||||||
for (auto n : nodes) {
|
for (auto n : nodes) {
|
||||||
auto sortInfo = static_cast<SortNode*>(n)->getSortInformation(plan);
|
auto sortInfo = static_cast<SortNode*>(n)->getSortInformation(plan);
|
||||||
|
|
||||||
if (sortInfo.isValid) {
|
if (sortInfo.isValid && ! sortInfo.criteria.empty()) {
|
||||||
/*
|
// we found a sort that we can understand
|
||||||
TODO: finalize
|
|
||||||
std::cout << "FOUND SORT:\n";
|
std::vector<ExecutionNode*> stack;
|
||||||
for (auto it = sortInfo.criteria.begin(); it != sortInfo.criteria.end(); ++it) {
|
for (auto dep : n->getDependencies()) {
|
||||||
std::cout << "- " << std::get<1>(*it) << ", " << std::get<2>(*it) << "\n";
|
stack.push_back(dep);
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
while (! stack.empty()) {
|
||||||
|
auto current = stack.back();
|
||||||
|
stack.pop_back();
|
||||||
|
|
||||||
|
if (current->getType() == triagens::aql::ExecutionNode::SORT) {
|
||||||
|
// we found another sort. now check if they are compatible!
|
||||||
|
auto other = static_cast<SortNode*>(current)->getSortInformation(plan);
|
||||||
|
|
||||||
|
if (sortInfo.isCoveredBy(other)) {
|
||||||
|
// the sort at the start of the pipeline makes the sort at the end
|
||||||
|
// superfluous, so we'll remove it
|
||||||
|
toUnlink.insert(n);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto deps = current->getDependencies();
|
||||||
|
if (deps.size() != 1) {
|
||||||
|
// node either has no or more than one dependency. we don't know what to do and must abort
|
||||||
|
// note: this will also handle Singleton nodes
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto dep : deps) {
|
||||||
|
stack.push_back(dep);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! toUnlink.empty()) {
|
||||||
|
plan->unlinkNodes(toUnlink);
|
||||||
|
plan->findVarUsage();
|
||||||
|
}
|
||||||
|
|
||||||
out.push_back(plan, level);
|
out.push_back(plan, level);
|
||||||
|
|
||||||
return TRI_ERROR_NO_ERROR;
|
return TRI_ERROR_NO_ERROR;
|
||||||
|
|
Loading…
Reference in New Issue