From 1003e52cf74222aae66e65c201281bc4ca13afd2 Mon Sep 17 00:00:00 2001 From: Jan Steemann Date: Sun, 18 Jan 2015 16:41:48 +0100 Subject: [PATCH] some cleanup --- arangod/Aql/ExecutionBlock.cpp | 81 ++++++++++++++++++---------------- arangod/Aql/ExecutionBlock.h | 12 ++--- arangod/Aql/ExecutionNode.cpp | 2 +- arangod/Aql/ExecutionNode.h | 2 +- arangod/Aql/OptimizerRules.cpp | 6 ++- 5 files changed, 56 insertions(+), 47 deletions(-) diff --git a/arangod/Aql/ExecutionBlock.cpp b/arangod/Aql/ExecutionBlock.cpp index 3c63f10bce..dd646195e9 100644 --- a/arangod/Aql/ExecutionBlock.cpp +++ b/arangod/Aql/ExecutionBlock.cpp @@ -1245,43 +1245,7 @@ bool IndexRangeBlock::initRanges () { return false; } - // sort the conditions! - - // TODO this should also be done for hash indexes when - // they are lazy too, but only if they should be used to produce a sorted result - - size_t const n = _condition->size(); - // first sort by the prefix of the index - std::vector> prefix; - prefix.reserve(n); - - if (! _sortCoords.empty()) { - _sortCoords.clear(); - _sortCoords.reserve(n); - } - - for (size_t s = 0; s < n; s++) { - _sortCoords.push_back(s); - std::vector next; - next.reserve(en->_index->fields.size()); - prefix.emplace_back(next); - // prefix[s][t] = position in _condition[s] corresponding to the th index - // field - for (size_t t = 0; t < en->_index->fields.size(); t++) { - for (size_t u = 0; u < _condition->at(s).size(); u++) { - auto ri = _condition->at(s)[u]; - if (en->_index->fields[t].compare(ri._attr) == 0) { - prefix.at(s).insert(prefix.at(s).begin() + t, u); - break; - } - } - } - } - - SortFunc sortFunc(prefix, _condition, en->_reverse); - - // then sort by the values of the bounds - std::sort(_sortCoords.begin(), _sortCoords.end(), sortFunc); + sortConditions(); _posInRanges = 0; getSkiplistIterator(_condition->at(_sortCoords[_posInRanges])); @@ -1292,6 +1256,49 @@ bool IndexRangeBlock::initRanges () { LEAVE_BLOCK; } +//////////////////////////////////////////////////////////////////////////////// +// @brief: sorts the index range conditions and resets _posInRanges to 0 +//////////////////////////////////////////////////////////////////////////////// + +void IndexRangeBlock::sortConditions () { + auto en = static_cast(getPlanNode()); + + size_t const n = _condition->size(); + // first sort by the prefix of the index + std::vector> prefix; + prefix.reserve(n); + + if (! _sortCoords.empty()) { + _sortCoords.clear(); + _sortCoords.reserve(n); + } + + for (size_t s = 0; s < n; s++) { + _sortCoords.push_back(s); + std::vector next; + next.reserve(en->_index->fields.size()); + prefix.emplace_back(next); + // prefix[s][t] = position in _condition[s] corresponding to the th index + // field + for (size_t t = 0; t < en->_index->fields.size(); t++) { + for (size_t u = 0; u < _condition->at(s).size(); u++) { + auto ri = _condition->at(s)[u]; + if (en->_index->fields[t].compare(ri._attr) == 0) { + prefix.at(s).insert(prefix.at(s).begin() + t, u); + break; + } + } + } + } + + SortFunc sortFunc(prefix, _condition, en->_reverse); + + // then sort by the values of the bounds + std::sort(_sortCoords.begin(), _sortCoords.end(), sortFunc); + + _posInRanges = 0; +} + //////////////////////////////////////////////////////////////////////////////// // @brief: is _condition[i] < _condition[j]? these are IndexAndConditions. //////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/Aql/ExecutionBlock.h b/arangod/Aql/ExecutionBlock.h index 3f61523f9c..6442b1195d 100644 --- a/arangod/Aql/ExecutionBlock.h +++ b/arangod/Aql/ExecutionBlock.h @@ -569,12 +569,6 @@ namespace triagens { private: -//////////////////////////////////////////////////////////////////////////////// -/// @brief free all dynamic bounds expressions -//////////////////////////////////////////////////////////////////////////////// - - void freeDynamicBoundsExpressions (); - //////////////////////////////////////////////////////////////////////////////// /// @brief free _condition if it belongs to us //////////////////////////////////////////////////////////////////////////////// @@ -642,6 +636,12 @@ namespace triagens { void readSkiplistIndex (size_t atMost); +//////////////////////////////////////////////////////////////////////////////// +// @brief: sorts the index range conditions and resets _posInRanges to 0 +//////////////////////////////////////////////////////////////////////////////// + + void sortConditions (); + //////////////////////////////////////////////////////////////////////////////// /// @brief andCombineRangeInfoVecs: combine the arguments into a single vector, /// by intersecting every pair of range infos and inserting them in the returned diff --git a/arangod/Aql/ExecutionNode.cpp b/arangod/Aql/ExecutionNode.cpp index 8dc76a598b..04a82d6b63 100644 --- a/arangod/Aql/ExecutionNode.cpp +++ b/arangod/Aql/ExecutionNode.cpp @@ -1383,7 +1383,7 @@ IndexRangeNode::IndexRangeNode (ExecutionPlan* plan, } } -ExecutionNode::IndexMatch IndexRangeNode::MatchesIndex (IndexMatchVec const& pattern) const { +ExecutionNode::IndexMatch IndexRangeNode::matchesIndex (IndexMatchVec const& pattern) const { return CompareIndex(_index, pattern); } diff --git a/arangod/Aql/ExecutionNode.h b/arangod/Aql/ExecutionNode.h index 735d4e3436..6b1ee5eefb 100644 --- a/arangod/Aql/ExecutionNode.h +++ b/arangod/Aql/ExecutionNode.h @@ -1202,7 +1202,7 @@ namespace triagens { /// @brief check whether the pattern matches this node's index //////////////////////////////////////////////////////////////////////////////// - IndexMatch MatchesIndex (IndexMatchVec const& pattern) const; + IndexMatch matchesIndex (IndexMatchVec const& pattern) const; //////////////////////////////////////////////////////////////////////////////// /// @brief whether or not a reverse index traversal is used diff --git a/arangod/Aql/OptimizerRules.cpp b/arangod/Aql/OptimizerRules.cpp index 45d2bdc2a3..454f867561 100644 --- a/arangod/Aql/OptimizerRules.cpp +++ b/arangod/Aql/OptimizerRules.cpp @@ -2072,7 +2072,9 @@ public: return std::make_pair(v, rangeInfo); // for now, no mixed support. } } + // Collect the right data for the sorting: + v.reserve(_sortNodeData.size()); for (size_t j = 0; j < _sortNodeData.size(); j ++) { v.push_back(std::make_pair(_sortNodeData[j]->attributevec, _sortNodeData[j]->ASC)); @@ -2105,7 +2107,6 @@ class SortToIndexNode : public WalkerWorker { Optimizer::RuleLevel _level; bool _modified; - public: SortToIndexNode (ExecutionPlan* plan, @@ -2168,7 +2169,8 @@ class SortToIndexNode : public WalkerWorker { auto variableName = node->getVariablesSetHere()[0]->name; auto result = _sortNode->getAttrsForVariableName(variableName); - auto const& match = node->MatchesIndex(result.first); + auto const& match = node->matchesIndex(result.first); + if (match.doesMatch) { if (match.reverse) { node->reverse(true);