2
* Copyright (C) 2014 MongoDB Inc.
4
* This program is free software: you can redistribute it and/or modify
5
* it under the terms of the GNU Affero General Public License, version 3,
6
* as published by the Free Software Foundation.
8
* This program is distributed in the hope that it will be useful,
9
* but WITHOUT ANY WARRANTY; without even the implied warranty of
10
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
* GNU Affero General Public License for more details.
13
* You should have received a copy of the GNU Affero General Public License
14
* along with this program. If not, see <http://www.gnu.org/licenses/>.
16
* As a special exception, the copyright holders give permission to link the
17
* code of portions of this program with the OpenSSL library under certain
18
* conditions as described in each individual source file and distribute
19
* linked combinations including the program with the OpenSSL library. You
20
* must comply with the GNU Affero General Public License in all respects for
21
* all of the code used other than as permitted herein. If you modify file(s)
22
* with this exception, you may extend this exception to your version of the
23
* file(s), but you are not obligated to do so. If you do not wish to do so,
24
* delete this exception statement from your version. If you delete this
25
* exception statement from all source files in the program, then also delete
26
* it in the license file.
29
#include "mongo/db/exec/keep_mutations.h"
30
#include "mongo/db/exec/filter.h"
34
KeepMutationsStage::KeepMutationsStage(const MatchExpression* filter,
40
_doneReadingChild(false),
41
_doneReturningFlagged(false) { }
43
KeepMutationsStage::~KeepMutationsStage() { }
45
bool KeepMutationsStage::isEOF() {
46
return _doneReadingChild && _doneReturningFlagged;
49
PlanStage::StageState KeepMutationsStage::work(WorkingSetID* out) {
52
// If we've returned as many results as we're limited to, isEOF will be true.
53
if (isEOF()) { return PlanStage::IS_EOF; }
55
// Stream child results until the child is all done.
56
if (!_doneReadingChild) {
57
StageState status = _child->work(out);
59
// Child is still returning results. Pass them through.
60
if (PlanStage::IS_EOF != status) {
61
if (PlanStage::ADVANCED == status) {
62
++_commonStats.advanced;
64
else if (PlanStage::NEED_TIME == status) {
65
++_commonStats.needTime;
67
else if (PlanStage::NEED_FETCH == status) {
68
++_commonStats.needFetch;
74
// Child is EOF. We want to stream flagged results if there are any.
75
_doneReadingChild = true;
76
_flaggedIterator = _workingSet->getFlagged().begin();
79
// We're streaming flagged results.
80
invariant(!_doneReturningFlagged);
81
if (_flaggedIterator == _workingSet->getFlagged().end()) {
82
_doneReturningFlagged = true;
83
return PlanStage::IS_EOF;
86
WorkingSetID idToTest = *_flaggedIterator;
89
WorkingSetMember* member = _workingSet->get(idToTest);
90
if (Filter::passes(member, _filter)) {
92
++_commonStats.advanced;
93
return PlanStage::ADVANCED;
96
_workingSet->free(idToTest);
97
++_commonStats.needTime;
98
return PlanStage::NEED_TIME;
102
void KeepMutationsStage::prepareToYield() {
103
++_commonStats.yields;
104
_child->prepareToYield();
107
void KeepMutationsStage::recoverFromYield() {
108
++_commonStats.unyields;
109
_child->recoverFromYield();
112
void KeepMutationsStage::invalidate(const DiskLoc& dl, InvalidationType type) {
113
++_commonStats.invalidates;
114
_child->invalidate(dl, type);
117
PlanStageStats* KeepMutationsStage::getStats() {
118
_commonStats.isEOF = isEOF();
119
auto_ptr<PlanStageStats> ret(new PlanStageStats(_commonStats, STAGE_KEEP_MUTATIONS));
120
// Takes ownership of the object returned from _child->getStats().
121
ret->children.push_back(_child->getStats());
122
return ret.release();