diff options
author | James Wahlin <james.wahlin@10gen.com> | 2016-12-14 16:20:26 -0500 |
---|---|---|
committer | James Wahlin <james.wahlin@10gen.com> | 2016-12-19 10:07:09 -0500 |
commit | a916d0398ac10489e9b382c6ad6f066999310254 (patch) | |
tree | aad5ab3e038cb71a9f1d6e7d3601d10a3f38c174 /src/mongo/db/pipeline/document_source_skip.cpp | |
parent | 6c900f92522959ed584d0f6a52c837f9f296efcc (diff) | |
download | mongo-a916d0398ac10489e9b382c6ad6f066999310254.tar.gz |
SERVER-27288 Release Document ref in DocumentSourceSkip and DocumentSourceMatch getNext()
Diffstat (limited to 'src/mongo/db/pipeline/document_source_skip.cpp')
-rw-r--r-- | src/mongo/db/pipeline/document_source_skip.cpp | 15 |
1 files changed, 12 insertions, 3 deletions
diff --git a/src/mongo/db/pipeline/document_source_skip.cpp b/src/mongo/db/pipeline/document_source_skip.cpp index ff528f0634e..114a2f7d1b4 100644 --- a/src/mongo/db/pipeline/document_source_skip.cpp +++ b/src/mongo/db/pipeline/document_source_skip.cpp @@ -57,11 +57,20 @@ const char* DocumentSourceSkip::getSourceName() const { DocumentSource::GetNextResult DocumentSourceSkip::getNext() { pExpCtx->checkForInterrupt(); - auto nextInput = pSource->getNext(); - for (; _nSkippedSoFar < _nToSkip && nextInput.isAdvanced(); nextInput = pSource->getNext()) { + while (_nSkippedSoFar < _nToSkip) { + // For performance reasons, a streaming stage must not keep references to documents across + // calls to getNext(). Such stages must retrieve a result from their child and then release + // it (or return it) before asking for another result. Failing to do so can result in extra + // work, since the Document/Value library must copy data on write when that data has a + // refcount above one. + auto nextInput = pSource->getNext(); + if (!nextInput.isAdvanced()) { + return nextInput; + } ++_nSkippedSoFar; } - return nextInput; + + return pSource->getNext(); } Value DocumentSourceSkip::serialize(bool explain) const { |