8000 Bug fix/non recursive plan handling by mpoeter · Pull Request #14475 · arangodb/arangodb · GitHub
[go: up one dir, main page]

Skip to content
Merged
Prev Previous commit
Next Next commit
Make cost estimation and invalidation non-recursive.
  • Loading branch information
mpoeter committed Jul 7, 2021
commit af8977d9dd4053371fc370b3eafd0e024f159303
C6DF
23 changes: 17 additions & 6 deletions arangod/Aql/ExecutionNode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -652,18 +652,29 @@ bool ExecutionNode::isEqualTo(ExecutionNode const& other) const {

/// @brief invalidate the cost estimation for the node and its dependencies
void ExecutionNode::invalidateCost() {
_costEstimate.invalidate();

for (auto& dep : _dependencies) {
dep->invalidateCost();
}
struct CostInvalidator : WalkerWorkerBase<ExecutionNode> {
void after(ExecutionNode* n) override {
n->_costEstimate.invalidate();
}
} invalidator;
this->walk(invalidator);
}

/// @brief estimate the cost of the node . . .
/// does not recalculate the estimate if already calculated
CostEstimate ExecutionNode::getCost() const {
if (!_costEstimate.isValid()) {
_costEstimate = estimateCost();
// Use a walker to estimate cost of all direct and indirect dependencies.
// This is necessary to avoid deeply nested recursive calls in estimateCosts
// which could result in a stack overflow.
struct CostEstimator : WalkerWorkerBase<ExecutionNode> {
void after(ExecutionNode* n) override {
if (!n->_costEstimate.isValid()) {
n->_costEstimate = n->estimateCost();
}
}
} estimator;
const_cast<ExecutionNode*>(this)->walk(estimator);
}
TRI_ASSERT(_costEstimate.estimatedCost >= 0.0);
TRI_ASSERT(_costEstimate.isValid());
Expand Down
0