summaryrefslogtreecommitdiff
path: root/src/mongo/db/pipeline/document_source_skip.cpp
diff options
context:
space:
mode:
authorJames Wahlin <james.wahlin@10gen.com>2016-12-14 16:20:26 -0500
committerJames Wahlin <james.wahlin@10gen.com>2016-12-19 10:07:09 -0500
commita916d0398ac10489e9b382c6ad6f066999310254 (patch)
treeaad5ab3e038cb71a9f1d6e7d3601d10a3f38c174 /src/mongo/db/pipeline/document_source_skip.cpp
parent6c900f92522959ed584d0f6a52c837f9f296efcc (diff)
downloadmongo-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.cpp15
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 {