diff options
author | David Storch <david.storch@mongodb.com> | 2019-10-22 21:32:40 +0000 |
---|---|---|
committer | evergreen <evergreen@mongodb.com> | 2019-10-22 21:32:40 +0000 |
commit | 8d048a3bb2f0f2f81cf99ce76ff21112bf3963d6 (patch) | |
tree | 8ac057129946e378c53730914e15d366ca0b0c92 /src/mongo/db/exec | |
parent | 0a5b8a92ed440f9dbc35d8e3d22cde43fab164f6 (diff) | |
download | mongo-8d048a3bb2f0f2f81cf99ce76ff21112bf3963d6.tar.gz |
SERVER-7568 Push $sort into PlanStage layer even for blocking SORT plans.
This change results in the multi-planning mechanism
evaluating both non-blocking and blocking plans for the
$sort when possible. The system should no longer select a
non-blocking plan when a plan with a SORT stage is superior.
Diffstat (limited to 'src/mongo/db/exec')
-rw-r--r-- | src/mongo/db/exec/sort.cpp | 2 | ||||
-rw-r--r-- | src/mongo/db/exec/sort.h | 8 | ||||
-rw-r--r-- | src/mongo/db/exec/sort_executor.cpp | 30 | ||||
-rw-r--r-- | src/mongo/db/exec/sort_executor.h | 29 |
4 files changed, 30 insertions, 39 deletions
diff --git a/src/mongo/db/exec/sort.cpp b/src/mongo/db/exec/sort.cpp index eb5486b61ee..a7c4c045234 100644 --- a/src/mongo/db/exec/sort.cpp +++ b/src/mongo/db/exec/sort.cpp @@ -111,7 +111,7 @@ std::unique_ptr<PlanStageStats> SortStage::getStats() { _commonStats.isEOF = isEOF(); std::unique_ptr<PlanStageStats> ret = std::make_unique<PlanStageStats>(_commonStats, STAGE_SORT); - ret->specific = _sortExecutor.stats(); + ret->specific = _sortExecutor.cloneStats(); ret->children.emplace_back(child()->getStats()); return ret; } diff --git a/src/mongo/db/exec/sort.h b/src/mongo/db/exec/sort.h index f437ce0b719..b727771c8bb 100644 --- a/src/mongo/db/exec/sort.h +++ b/src/mongo/db/exec/sort.h @@ -72,12 +72,8 @@ public: std::unique_ptr<PlanStageStats> getStats(); - /** - * Returns nullptr. Stats related to sort execution must be extracted with 'getStats()', since - * they are retrieved on demand from the underlying sort execution machinery. - */ const SpecificStats* getSpecificStats() const final { - return nullptr; + return &_sortExecutor.stats(); } private: @@ -86,8 +82,6 @@ private: SortExecutor _sortExecutor; - SortStats _specificStats; - // Whether or not we have finished loading data into '_sortExecutor'. bool _populated = false; }; diff --git a/src/mongo/db/exec/sort_executor.cpp b/src/mongo/db/exec/sort_executor.cpp index 51e0255a01d..bf2d02a465d 100644 --- a/src/mongo/db/exec/sort_executor.cpp +++ b/src/mongo/db/exec/sort_executor.cpp @@ -55,10 +55,13 @@ SortExecutor::SortExecutor(SortPattern sortPattern, std::string tempDir, bool allowDiskUse) : _sortPattern(std::move(sortPattern)), - _limit(limit), - _maxMemoryUsageBytes(maxMemoryUsageBytes), _tempDir(std::move(tempDir)), - _diskUseAllowed(allowDiskUse) {} + _diskUseAllowed(allowDiskUse) { + _stats.sortPattern = + _sortPattern.serialize(SortPattern::SortKeySerialization::kForExplain).toBson(); + _stats.limit = limit; + _stats.maxMemoryUsageBytes = maxMemoryUsageBytes; +} boost::optional<Document> SortExecutor::getNextDoc() { auto wsm = getNextWsm(); @@ -114,7 +117,7 @@ void SortExecutor::add(Value sortKey, WorkingSetMember data) { } _sorter->add(std::move(sortKey), std::move(data)); - _totalDataSizeBytes += data.getMemUsage(); + _stats.totalDataSizeBytes += data.getMemUsage(); } void SortExecutor::loadingDone() { @@ -123,17 +126,17 @@ void SortExecutor::loadingDone() { _sorter.reset(DocumentSorter::make(makeSortOptions(), Comparator(_sortPattern))); } _output.reset(_sorter->done()); - _wasDiskUsed = _wasDiskUsed || _sorter->usedDisk(); + _stats.wasDiskUsed = _stats.wasDiskUsed || _sorter->usedDisk(); _sorter.reset(); } SortOptions SortExecutor::makeSortOptions() const { SortOptions opts; - if (_limit) { - opts.limit = _limit; + if (_stats.limit) { + opts.limit = _stats.limit; } - opts.maxMemoryUsageBytes = _maxMemoryUsageBytes; + opts.maxMemoryUsageBytes = _stats.maxMemoryUsageBytes; if (_diskUseAllowed) { opts.extSortAllowed = true; opts.tempDir = _tempDir; @@ -142,15 +145,8 @@ SortOptions SortExecutor::makeSortOptions() const { return opts; } -std::unique_ptr<SortStats> SortExecutor::stats() const { - auto stats = std::make_unique<SortStats>(); - stats->sortPattern = - _sortPattern.serialize(SortPattern::SortKeySerialization::kForExplain).toBson(); - stats->limit = _limit; - stats->maxMemoryUsageBytes = _maxMemoryUsageBytes; - stats->totalDataSizeBytes = _totalDataSizeBytes; - stats->wasDiskUsed = _wasDiskUsed; - return stats; +std::unique_ptr<SortStats> SortExecutor::cloneStats() const { + return std::unique_ptr<SortStats>{static_cast<SortStats*>(_stats.clone())}; } } // namespace mongo diff --git a/src/mongo/db/exec/sort_executor.h b/src/mongo/db/exec/sort_executor.h index c0945fe1fd4..085311e19da 100644 --- a/src/mongo/db/exec/sort_executor.h +++ b/src/mongo/db/exec/sort_executor.h @@ -68,20 +68,20 @@ public: * the smallest limit. */ void setLimit(uint64_t limit) { - if (!_limit || limit < _limit) - _limit = limit; + if (!_stats.limit || limit < _stats.limit) + _stats.limit = limit; } uint64_t getLimit() const { - return _limit; + return _stats.limit; } bool hasLimit() const { - return _limit > 0; + return _stats.limit > 0; } bool wasDiskUsed() const { - return _wasDiskUsed; + return _stats.wasDiskUsed; } /** @@ -107,7 +107,11 @@ public: return _isEOF; } - std::unique_ptr<SortStats> stats() const; + const SortStats& stats() const { + return _stats; + } + + std::unique_ptr<SortStats> cloneStats() const; private: using DocumentSorter = Sorter<Value, WorkingSetMember>; @@ -124,18 +128,15 @@ private: SortOptions makeSortOptions() const; - SortPattern _sortPattern; - // A limit of zero is defined as no limit. - uint64_t _limit; - uint64_t _maxMemoryUsageBytes; - std::string _tempDir; - bool _diskUseAllowed = false; + const SortPattern _sortPattern; + const std::string _tempDir; + const bool _diskUseAllowed; std::unique_ptr<DocumentSorter> _sorter; std::unique_ptr<DocumentSorter::Iterator> _output; + SortStats _stats; + bool _isEOF = false; - bool _wasDiskUsed = false; - uint64_t _totalDataSizeBytes = 0u; }; } // namespace mongo |