1
0
Fork 0

Redundand-Sort: implement removing of left item superseeding the sort

This commit is contained in:
Willi Goesgens 2014-09-04 17:53:20 +02:00
parent 30b33a1793
commit ebbb9c34b6
3 changed files with 65 additions and 14 deletions

View File

@ -1428,23 +1428,31 @@ namespace triagens {
////////////////////////////////////////////////////////////////////////////////
struct SortInformation {
enum Match {
unequal,
weSupersede,
otherSupersedes,
allEqual
};
std::vector<std::tuple<ExecutionNode const*, std::string, bool>> criteria;
bool isValid = true;
bool isComplex = false;
bool isCoveredBy (SortInformation const& other) {
Match isCoveredBy (SortInformation const& other) {
if (! isValid || ! other.isValid) {
return false;
return unequal;
}
if (isComplex) {
return false;
return unequal;
}
size_t const n = criteria.size();
for (size_t i = 0; i < n; ++i) {
if (other.criteria.size() <= i) {
return false;
return otherSupersedes;
}
auto ours = criteria[i];
@ -1452,16 +1460,18 @@ namespace triagens {
if (std::get<2>(ours) != std::get<2>(theirs)) {
// sort order is different
return false;
return unequal;
}
if (std::get<1>(ours) != std::get<1>(theirs)) {
// sort criterion is different
return false;
return unequal;
}
}
return true;
if (other.criteria.size() > n)
return weSupersede;
else
return allEqual;
}
};

View File

@ -69,7 +69,14 @@ int triagens::aql::removeRedundantSorts (Optimizer* opt,
// we found another sort. now check if they are compatible!
auto other = static_cast<SortNode*>(current)->getSortInformation(plan);
if (sortInfo.isCoveredBy(other)) {
switch (sortInfo.isCoveredBy(other)) {
case triagens::aql::SortInformation::unequal:
break;
case triagens::aql::SortInformation::otherSupersedes:
toUnlink.insert(current);
break;
case triagens::aql::SortInformation::weSupersede:
case triagens::aql::SortInformation::allEqual:
// the sort at the start of the pipeline makes the sort at the end
// superfluous, so we'll remove it
toUnlink.insert(n);

View File

@ -45,6 +45,7 @@ var findReferencedNodes = helper.findReferencedNodes;
function optimizerRuleTestSuite() {
var ruleName = "use-index-for-sort";
var secondRuleName = "use-index-range";
var thirdRuleName = "remove-redundant-sorts";
var colName = "UnitTestsAqlOptimizer" + ruleName.replace(/-/g, "_");
var colNameOther = colName + "_XX";
@ -52,6 +53,7 @@ function optimizerRuleTestSuite() {
var paramNone = { optimizer: { rules: [ "-all" ] } };
var paramIFS = { optimizer: { rules: [ "-all", "+" + ruleName ] } };
var paramIR = { optimizer: { rules: [ "-all", "+" + secondRuleName ] } };
var paramRS = { optimizer: { rules: [ "-all", "+" + thirdRuleName ] } };
var paramBoth = { optimizer: { rules: [ "-all", "+" + ruleName, "+" + secondRuleName ] } };
var skiplist;
@ -474,7 +476,7 @@ function optimizerRuleTestSuite() {
// -----------------------------------------------------------------------------
// --SECTION-- toIndexRange
// -----------------------------------------------------------------------------
/*
testRangeEquals: function () {
var query = "FOR v IN " + colName + " FILTER v.a == 1 RETURN [v.a, v.b, v.c]";
@ -535,7 +537,7 @@ function optimizerRuleTestSuite() {
assertTrue(isEqual(QResults[0], QResults[1]), "Results are Equal?");
},
*/
testRangeGreaterThen: function () {
/*
TODO: can skiplist do a range?
@ -544,7 +546,7 @@ function optimizerRuleTestSuite() {
var query = "FOR v IN " + colName + " FILTER v.c > 1 && v.c < 5 RETURN [v.a, v.b, v.c]";
*/
var query = "FOR v IN " + colName + " FILTER v.a > 5 RETURN [v.a, v.b]";
/*
var XPresult;
var QResults=[];
@ -569,11 +571,12 @@ function optimizerRuleTestSuite() {
assertEqual(first.low.bound.value, 5, "proper value was set");
assertTrue(isEqual(QResults[0], QResults[1]), "Results are Equal?");
*/
},
testRangeBandpass: function () {
var query = "FOR v IN " + colName + " FILTER v.a > 4 && v.a < 10 RETURN [v.a, v.b]";
/*
var XPresult;
var QResults=[];
@ -600,7 +603,7 @@ function optimizerRuleTestSuite() {
assertEqual(first.high.bound.value, 10, "proper value was set");
assertTrue(isEqual(QResults[0], QResults[1]), "Results are Equal?");
*/
},
testRangeBandpassInvalid: function () {
@ -706,8 +709,39 @@ function optimizerRuleTestSuite() {
*/
},
// -----------------------------------------------------------------------------
// --SECTION-- toIndexRange
// -----------------------------------------------------------------------------
testDSRuleHasEffect : function () {
var queries = [
"FOR v IN " + colName + " SORT v.c SORT v.c RETURN [v.a, v.b]",
"FOR v IN " + colName + " SORT v.c SORT v.c , v.d RETURN [v.a, v.b]",
"FOR v IN " + colName + " SORT v.c, v.d SORT v.c RETURN [v.a, v.b]",
"FOR v IN " + colName + " SORT v.c SORT v.c, v.d SORT v.c RETURN [v.a, v.b]",
"FOR v IN " + colName + " SORT v.c, v.d SORT v.c SORT v.c, v.d SORT v.c RETURN [v.a, v.b]",
"FOR v IN " + colName + " SORT v.c FILTER v.c > 3 SORT v.c RETURN [v.a, v.b]"
/*
// todo: we use an index anyways right now. "FOR v IN " + colName + " SORT v.a DESC RETURN [v.a, v.b]",// currently only ASC supported.
"FOR v IN " + colName + " SORT v.b, v.a RETURN [v.a, v.b]",
"FOR v IN " + colName + " SORT v.c RETURN [v.a, v.b]",
"FOR v IN " + colName + " SORT v.a + 1 RETURN [v.a, v.b]",
"FOR v IN " + colName + " SORT CONCAT(TO_STRING(v.a), \"lol\") RETURN [v.a, v.b]",
"FOR v IN " + colName + " FILTER v.a > 2 LIMIT 3 SORT v.a RETURN [v.a, v.b] ", // TODO: limit blocks sort atm.
"FOR v IN " + colName + " FOR w IN " + colNameOther + " SORT v.a RETURN [v.a, v.b]"
*/
];
queries.forEach(function(query) {
// require("internal").print(query);
var result = AQL_EXPLAIN(query, { }, paramRS);
// require("internal").print(result);
assertEqual([thirdRuleName], result.plan.rules, query);
});
}
//*/
};
}