本文整理汇总了C++中WorkingSetMember::setFetcher方法的典型用法代码示例。如果您正苦于以下问题:C++ WorkingSetMember::setFetcher方法的具体用法?C++ WorkingSetMember::setFetcher怎么用?C++ WorkingSetMember::setFetcher使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类WorkingSetMember
的用法示例。
在下文中一共展示了WorkingSetMember::setFetcher方法的11个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: work
PlanStage::StageState MultiIteratorStage::work(WorkingSetID* out) {
if (_collection == NULL)
return PlanStage::DEAD;
// The RecordId we're about to look at it might not be in memory. In this case
// we request a yield while we fetch the document.
if (!_iterators.empty()) {
RecordId curr = _iterators.back()->curr();
if (!curr.isNull()) {
std::auto_ptr<RecordFetcher> fetcher(_collection->documentNeedsFetch(_txn, curr));
if (NULL != fetcher.get()) {
WorkingSetMember* member = _ws->get(_wsidForFetch);
member->loc = curr;
// Pass the RecordFetcher off to the WSM on which we're performing the fetch.
member->setFetcher(fetcher.release());
*out = _wsidForFetch;
return NEED_FETCH;
}
}
}
RecordId next = _advance();
if (next.isNull())
return PlanStage::IS_EOF;
*out = _ws->allocate();
WorkingSetMember* member = _ws->get(*out);
member->loc = next;
member->obj = _collection->docFor(_txn, next);
member->state = WorkingSetMember::LOC_AND_OBJ;
return PlanStage::ADVANCED;
}
示例2: work
PlanStage::StageState MultiIteratorStage::work(WorkingSetID* out) {
if (_collection == NULL) {
Status status(ErrorCodes::InternalError, "MultiIteratorStage died on null collection");
*out = WorkingSetCommon::allocateStatusMember(_ws, status);
return PlanStage::DEAD;
}
boost::optional<Record> record;
try {
while (!_iterators.empty()) {
if (auto fetcher = _iterators.back()->fetcherForNext()) {
// Pass the RecordFetcher off up.
WorkingSetMember* member = _ws->get(_wsidForFetch);
member->setFetcher(fetcher.release());
*out = _wsidForFetch;
return NEED_YIELD;
}
record = _iterators.back()->next();
if (record)
break;
_iterators.pop_back();
}
} catch (const WriteConflictException& wce) {
// If _advance throws a WCE we shouldn't have moved.
invariant(!_iterators.empty());
*out = WorkingSet::INVALID_ID;
return NEED_YIELD;
}
if (!record)
return IS_EOF;
*out = _ws->allocate();
WorkingSetMember* member = _ws->get(*out);
member->loc = record->id;
member->obj = {_txn->recoveryUnit()->getSnapshotId(), record->data.releaseToBson()};
member->state = WorkingSetMember::LOC_AND_UNOWNED_OBJ;
return PlanStage::ADVANCED;
}
示例3: doWork
PlanStage::StageState CollectionScan::doWork(WorkingSetID* out) {
if (_isDead) {
Status status(
ErrorCodes::CappedPositionLost,
str::stream()
<< "CollectionScan died due to position in capped collection being deleted. "
<< "Last seen record id: "
<< _lastSeenId);
*out = WorkingSetCommon::allocateStatusMember(_workingSet, status);
return PlanStage::DEAD;
}
if ((0 != _params.maxScan) && (_specificStats.docsTested >= _params.maxScan)) {
_commonStats.isEOF = true;
}
if (_commonStats.isEOF) {
return PlanStage::IS_EOF;
}
boost::optional<Record> record;
const bool needToMakeCursor = !_cursor;
try {
if (needToMakeCursor) {
const bool forward = _params.direction == CollectionScanParams::FORWARD;
_cursor = _params.collection->getCursor(getOpCtx(), forward);
if (!_lastSeenId.isNull()) {
invariant(_params.tailable);
// Seek to where we were last time. If it no longer exists, mark us as dead
// since we want to signal an error rather than silently dropping data from the
// stream. This is related to the _lastSeenId handling in invalidate. Note that
// we want to return the record *after* this one since we have already returned
// this one. This is only possible in the tailing case because that is the only
// time we'd need to create a cursor after already getting a record out of it.
if (!_cursor->seekExact(_lastSeenId)) {
_isDead = true;
Status status(ErrorCodes::CappedPositionLost,
str::stream() << "CollectionScan died due to failure to restore "
<< "tailable cursor position. "
<< "Last seen record id: "
<< _lastSeenId);
*out = WorkingSetCommon::allocateStatusMember(_workingSet, status);
return PlanStage::DEAD;
}
}
return PlanStage::NEED_TIME;
}
if (_lastSeenId.isNull() && !_params.start.isNull()) {
record = _cursor->seekExact(_params.start);
} else {
// See if the record we're about to access is in memory. If not, pass a fetch
// request up.
if (auto fetcher = _cursor->fetcherForNext()) {
// Pass the RecordFetcher up.
WorkingSetMember* member = _workingSet->get(_wsidForFetch);
member->setFetcher(fetcher.release());
*out = _wsidForFetch;
return PlanStage::NEED_YIELD;
}
record = _cursor->next();
}
} catch (const WriteConflictException& wce) {
// Leave us in a state to try again next time.
if (needToMakeCursor)
_cursor.reset();
*out = WorkingSet::INVALID_ID;
return PlanStage::NEED_YIELD;
}
if (!record) {
// We just hit EOF. If we are tailable and have already returned data, leave us in a
// state to pick up where we left off on the next call to work(). Otherwise EOF is
// permanent.
if (_params.tailable && !_lastSeenId.isNull()) {
_cursor.reset();
} else {
_commonStats.isEOF = true;
}
return PlanStage::IS_EOF;
}
_lastSeenId = record->id;
WorkingSetID id = _workingSet->allocate();
WorkingSetMember* member = _workingSet->get(id);
member->recordId = record->id;
member->obj = {getOpCtx()->recoveryUnit()->getSnapshotId(), record->data.releaseToBson()};
_workingSet->transitionToRecordIdAndObj(id);
return returnIfMatches(member, id, out);
}
示例4: work
PlanStage::StageState FetchStage::work(WorkingSetID* out) {
++_commonStats.works;
// Adds the amount of time taken by work() to executionTimeMillis.
ScopedTimer timer(&_commonStats.executionTimeMillis);
if (isEOF()) {
return PlanStage::IS_EOF;
}
// Either retry the last WSM we worked on or get a new one from our child.
WorkingSetID id;
StageState status;
if (_idRetrying == WorkingSet::INVALID_ID) {
status = child()->work(&id);
} else {
status = ADVANCED;
id = _idRetrying;
_idRetrying = WorkingSet::INVALID_ID;
}
if (PlanStage::ADVANCED == status) {
WorkingSetMember* member = _ws->get(id);
// If there's an obj there, there is no fetching to perform.
if (member->hasObj()) {
++_specificStats.alreadyHasObj;
} else {
// We need a valid loc to fetch from and this is the only state that has one.
verify(WorkingSetMember::LOC_AND_IDX == member->getState());
verify(member->hasLoc());
try {
if (!_cursor)
_cursor = _collection->getCursor(getOpCtx());
if (auto fetcher = _cursor->fetcherForId(member->loc)) {
// There's something to fetch. Hand the fetcher off to the WSM, and pass up
// a fetch request.
_idRetrying = id;
member->setFetcher(fetcher.release());
*out = id;
_commonStats.needYield++;
return NEED_YIELD;
}
// The doc is already in memory, so go ahead and grab it. Now we have a RecordId
// as well as an unowned object
if (!WorkingSetCommon::fetch(getOpCtx(), _ws, id, _cursor)) {
_ws->free(id);
_commonStats.needTime++;
return NEED_TIME;
}
} catch (const WriteConflictException& wce) {
_idRetrying = id;
*out = WorkingSet::INVALID_ID;
_commonStats.needYield++;
return NEED_YIELD;
}
}
return returnIfMatches(member, id, out);
} else if (PlanStage::FAILURE == status || PlanStage::DEAD == status) {
*out = id;
// If a stage fails, it may create a status WSM to indicate why it
// failed, in which case 'id' is valid. If ID is invalid, we
// create our own error message.
if (WorkingSet::INVALID_ID == id) {
mongoutils::str::stream ss;
ss << "fetch stage failed to read in results from child";
Status status(ErrorCodes::InternalError, ss);
*out = WorkingSetCommon::allocateStatusMember(_ws, status);
}
return status;
} else if (PlanStage::NEED_TIME == status) {
++_commonStats.needTime;
} else if (PlanStage::NEED_YIELD == status) {
++_commonStats.needYield;
*out = id;
}
return status;
}
示例5: work
PlanStage::StageState IDHackStage::work(WorkingSetID* out) {
++_commonStats.works;
// Adds the amount of time taken by work() to executionTimeMillis.
ScopedTimer timer(&_commonStats.executionTimeMillis);
if (_killed) { return PlanStage::DEAD; }
if (_done) { return PlanStage::IS_EOF; }
if (WorkingSet::INVALID_ID != _idBeingPagedIn) {
WorkingSetID id = _idBeingPagedIn;
_idBeingPagedIn = WorkingSet::INVALID_ID;
WorkingSetMember* member = _workingSet->get(id);
WorkingSetCommon::completeFetch(_txn, member, _collection);
return advance(id, member, out);
}
// Use the index catalog to get the id index.
const IndexCatalog* catalog = _collection->getIndexCatalog();
// Find the index we use.
IndexDescriptor* idDesc = catalog->findIdIndex(_txn);
if (NULL == idDesc) {
_done = true;
return PlanStage::IS_EOF;
}
// This may not be valid always. See SERVER-12397.
const BtreeBasedAccessMethod* accessMethod =
static_cast<const BtreeBasedAccessMethod*>(catalog->getIndex(idDesc));
// Look up the key by going directly to the Btree.
DiskLoc loc = accessMethod->findSingle(_txn, _key);
// Key not found.
if (loc.isNull()) {
_done = true;
return PlanStage::IS_EOF;
}
++_specificStats.keysExamined;
++_specificStats.docsExamined;
// Create a new WSM for the result document.
WorkingSetID id = _workingSet->allocate();
WorkingSetMember* member = _workingSet->get(id);
member->loc = loc;
member->state = WorkingSetMember::LOC_AND_UNOWNED_OBJ;
// We may need to request a yield while we fetch the document.
std::auto_ptr<RecordFetcher> fetcher(_collection->documentNeedsFetch(_txn, loc));
if (NULL != fetcher.get()) {
// There's something to fetch. Hand the fetcher off to the WSM, and pass up a
// fetch request.
_idBeingPagedIn = id;
member->setFetcher(fetcher.release());
*out = id;
_commonStats.needFetch++;
return NEED_FETCH;
}
// The doc was already in memory, so we go ahead and return it.
member->obj = _collection->docFor(_txn, member->loc);
return advance(id, member, out);
}
示例6: work
PlanStage::StageState IDHackStage::work(WorkingSetID* out) {
++_commonStats.works;
// Adds the amount of time taken by work() to executionTimeMillis.
ScopedTimer timer(&_commonStats.executionTimeMillis);
if (_done) {
return PlanStage::IS_EOF;
}
if (WorkingSet::INVALID_ID != _idBeingPagedIn) {
invariant(_recordCursor);
WorkingSetID id = _idBeingPagedIn;
_idBeingPagedIn = WorkingSet::INVALID_ID;
WorkingSetMember* member = _workingSet->get(id);
invariant(WorkingSetCommon::fetchIfUnfetched(_txn, member, _recordCursor));
return advance(id, member, out);
}
WorkingSetID id = WorkingSet::INVALID_ID;
try {
// Use the index catalog to get the id index.
const IndexCatalog* catalog = _collection->getIndexCatalog();
// Find the index we use.
IndexDescriptor* idDesc = catalog->findIdIndex(_txn);
if (NULL == idDesc) {
_done = true;
return PlanStage::IS_EOF;
}
// Look up the key by going directly to the index.
RecordId loc = catalog->getIndex(idDesc)->findSingle(_txn, _key);
// Key not found.
if (loc.isNull()) {
_done = true;
return PlanStage::IS_EOF;
}
++_specificStats.keysExamined;
++_specificStats.docsExamined;
// Create a new WSM for the result document.
id = _workingSet->allocate();
WorkingSetMember* member = _workingSet->get(id);
member->state = WorkingSetMember::LOC_AND_IDX;
member->loc = loc;
if (!_recordCursor)
_recordCursor = _collection->getCursor(_txn);
// We may need to request a yield while we fetch the document.
if (auto fetcher = _recordCursor->fetcherForId(loc)) {
// There's something to fetch. Hand the fetcher off to the WSM, and pass up a
// fetch request.
_idBeingPagedIn = id;
member->setFetcher(fetcher.release());
*out = id;
_commonStats.needYield++;
return NEED_YIELD;
}
// The doc was already in memory, so we go ahead and return it.
if (!WorkingSetCommon::fetch(_txn, member, _recordCursor)) {
// _id is immutable so the index would return the only record that could
// possibly match the query.
_workingSet->free(id);
_commonStats.isEOF = true;
_done = true;
return IS_EOF;
}
return advance(id, member, out);
} catch (const WriteConflictException& wce) {
// Restart at the beginning on retry.
_recordCursor.reset();
if (id != WorkingSet::INVALID_ID)
_workingSet->free(id);
*out = WorkingSet::INVALID_ID;
_commonStats.needYield++;
return NEED_YIELD;
}
}
示例7: doWork
PlanStage::StageState IDHackStage::doWork(WorkingSetID* out) {
if (_done) {
return PlanStage::IS_EOF;
}
if (WorkingSet::INVALID_ID != _idBeingPagedIn) {
invariant(_recordCursor);
WorkingSetID id = _idBeingPagedIn;
_idBeingPagedIn = WorkingSet::INVALID_ID;
invariant(WorkingSetCommon::fetchIfUnfetched(getOpCtx(), _workingSet, id, _recordCursor));
WorkingSetMember* member = _workingSet->get(id);
return advance(id, member, out);
}
WorkingSetID id = WorkingSet::INVALID_ID;
try {
// Look up the key by going directly to the index.
RecordId recordId = _accessMethod->findSingle(getOpCtx(), _key);
// Key not found.
if (recordId.isNull()) {
_done = true;
return PlanStage::IS_EOF;
}
++_specificStats.keysExamined;
++_specificStats.docsExamined;
// Create a new WSM for the result document.
id = _workingSet->allocate();
WorkingSetMember* member = _workingSet->get(id);
member->recordId = recordId;
_workingSet->transitionToRecordIdAndIdx(id);
if (!_recordCursor)
_recordCursor = _collection->getCursor(getOpCtx());
// We may need to request a yield while we fetch the document.
if (auto fetcher = _recordCursor->fetcherForId(recordId)) {
// There's something to fetch. Hand the fetcher off to the WSM, and pass up a
// fetch request.
_idBeingPagedIn = id;
member->setFetcher(fetcher.release());
*out = id;
return NEED_YIELD;
}
// The doc was already in memory, so we go ahead and return it.
if (!WorkingSetCommon::fetch(getOpCtx(), _workingSet, id, _recordCursor)) {
// _id is immutable so the index would return the only record that could
// possibly match the query.
_workingSet->free(id);
_commonStats.isEOF = true;
_done = true;
return IS_EOF;
}
return advance(id, member, out);
} catch (const WriteConflictException& wce) {
// Restart at the beginning on retry.
_recordCursor.reset();
if (id != WorkingSet::INVALID_ID)
_workingSet->free(id);
*out = WorkingSet::INVALID_ID;
return NEED_YIELD;
}
}
示例8: work
PlanStage::StageState CollectionScan::work(WorkingSetID* out) {
++_commonStats.works;
// Adds the amount of time taken by work() to executionTimeMillis.
ScopedTimer timer(&_commonStats.executionTimeMillis);
if (_isDead) { return PlanStage::DEAD; }
// Do some init if we haven't already.
if (NULL == _iter) {
if ( _params.collection == NULL ) {
_isDead = true;
return PlanStage::DEAD;
}
try {
if (_lastSeenLoc.isNull()) {
_iter.reset( _params.collection->getIterator( _txn,
_params.start,
_params.direction ) );
}
else {
invariant(_params.tailable);
_iter.reset( _params.collection->getIterator( _txn,
_lastSeenLoc,
_params.direction ) );
// Advance _iter past where we were last time. If it returns something else,
// mark us as dead since we want to signal an error rather than silently
// dropping data from the stream. This is related to the _lastSeenLock handling
// in invalidate.
if (_iter->getNext() != _lastSeenLoc) {
_isDead = true;
return PlanStage::DEAD;
}
}
}
catch (const WriteConflictException& wce) {
// Leave us in a state to try again next time.
_iter.reset();
*out = WorkingSet::INVALID_ID;
return PlanStage::NEED_YIELD;
}
++_commonStats.needTime;
return PlanStage::NEED_TIME;
}
// Should we try getNext() on the underlying _iter?
if (isEOF())
return PlanStage::IS_EOF;
const RecordId curr = _iter->curr();
if (curr.isNull()) {
// We just hit EOF
if (_params.tailable)
_iter.reset(); // pick up where we left off on the next call to work()
return PlanStage::IS_EOF;
}
_lastSeenLoc = curr;
// See if the record we're about to access is in memory. If not, pass a fetch request up.
// Note that curr() does not touch the record. This way, we are able to yield before
// fetching the record.
{
std::auto_ptr<RecordFetcher> fetcher(
_params.collection->documentNeedsFetch(_txn, curr));
if (NULL != fetcher.get()) {
WorkingSetMember* member = _workingSet->get(_wsidForFetch);
member->loc = curr;
// Pass the RecordFetcher off to the WSM.
member->setFetcher(fetcher.release());
*out = _wsidForFetch;
_commonStats.needYield++;
return NEED_YIELD;
}
}
// Do this before advancing because it is more efficient while the iterator is still on this
// document.
const Snapshotted<BSONObj> obj = Snapshotted<BSONObj>(_txn->recoveryUnit()->getSnapshotId(),
_iter->dataFor(curr).releaseToBson());
// Advance the iterator.
try {
invariant(_iter->getNext() == curr);
}
catch (const WriteConflictException& wce) {
// If getNext thows, it leaves us on the original document.
invariant(_iter->curr() == curr);
*out = WorkingSet::INVALID_ID;
return PlanStage::NEED_YIELD;
}
WorkingSetID id = _workingSet->allocate();
WorkingSetMember* member = _workingSet->get(id);
member->loc = curr;
member->obj = obj;
//.........这里部分代码省略.........
示例9: doWork
PlanStage::StageState FetchStage::doWork(WorkingSetID* out) {
if (isEOF()) {
return PlanStage::IS_EOF;
}
// Either retry the last WSM we worked on or get a new one from our child.
WorkingSetID id;
StageState status;
if (_idRetrying == WorkingSet::INVALID_ID) {
status = child()->work(&id);
} else {
status = ADVANCED;
id = _idRetrying;
_idRetrying = WorkingSet::INVALID_ID;
}
if (PlanStage::ADVANCED == status) {
WorkingSetMember* member = _ws->get(id);
// If there's an obj there, there is no fetching to perform.
if (member->hasObj()) {
++_specificStats.alreadyHasObj;
} else {
// We need a valid RecordId to fetch from and this is the only state that has one.
verify(WorkingSetMember::RID_AND_IDX == member->getState());
verify(member->hasRecordId());
try {
if (!_cursor)
_cursor = _collection->getCursor(getOpCtx());
if (auto fetcher = _cursor->fetcherForId(member->recordId)) {
// There's something to fetch. Hand the fetcher off to the WSM, and pass up
// a fetch request.
_idRetrying = id;
member->setFetcher(fetcher.release());
*out = id;
return NEED_YIELD;
}
// The doc is already in memory, so go ahead and grab it. Now we have a RecordId
// as well as an unowned object
if (!WorkingSetCommon::fetch(getOpCtx(), _ws, id, _cursor)) {
_ws->free(id);
return NEED_TIME;
}
} catch (const WriteConflictException&) {
// Ensure that the BSONObj underlying the WorkingSetMember is owned because it may
// be freed when we yield.
member->makeObjOwnedIfNeeded();
_idRetrying = id;
*out = WorkingSet::INVALID_ID;
return NEED_YIELD;
}
}
return returnIfMatches(member, id, out);
} else if (PlanStage::FAILURE == status || PlanStage::DEAD == status) {
// The stage which produces a failure is responsible for allocating a working set member
// with error details.
invariant(WorkingSet::INVALID_ID != id);
*out = id;
return status;
} else if (PlanStage::NEED_YIELD == status) {
*out = id;
}
return status;
}
示例10: work
PlanStage::StageState CollectionScan::work(WorkingSetID* out) {
++_commonStats.works;
// Adds the amount of time taken by work() to executionTimeMillis.
ScopedTimer timer(&_commonStats.executionTimeMillis);
if (_isDead) { return PlanStage::DEAD; }
// Do some init if we haven't already.
if (NULL == _iter) {
if ( _params.collection == NULL ) {
_isDead = true;
return PlanStage::DEAD;
}
if (_lastSeenLoc.isNull()) {
_iter.reset( _params.collection->getIterator( _txn,
_params.start,
_params.direction ) );
}
else {
invariant(_params.tailable);
_iter.reset( _params.collection->getIterator( _txn,
_lastSeenLoc,
_params.direction ) );
// Advance _iter past where we were last time. If it returns something else, mark us
// as dead since we want to signal an error rather than silently dropping data from
// the stream. This is related to the _lastSeenLock handling in invalidate.
if (_iter->getNext() != _lastSeenLoc) {
_isDead = true;
return PlanStage::DEAD;
}
}
++_commonStats.needTime;
return PlanStage::NEED_TIME;
}
// Should we try getNext() on the underlying _iter?
if (isEOF())
return PlanStage::IS_EOF;
const DiskLoc curr = _iter->curr();
if (curr.isNull()) {
// We just hit EOF
if (_params.tailable)
_iter.reset(); // pick up where we left off on the next call to work()
return PlanStage::IS_EOF;
}
_lastSeenLoc = curr;
// See if the record we're about to access is in memory. If not, pass a fetch request up.
// Note that curr() does not touch the record (on MMAPv1 which is the only place we use
// NEED_FETCH) so we are able to yield before touching the record, as long as we do so
// before calling getNext().
{
std::auto_ptr<RecordFetcher> fetcher(
_params.collection->documentNeedsFetch(_txn, curr));
if (NULL != fetcher.get()) {
WorkingSetMember* member = _workingSet->get(_wsidForFetch);
member->loc = curr;
// Pass the RecordFetcher off to the WSM.
member->setFetcher(fetcher.release());
*out = _wsidForFetch;
_commonStats.needFetch++;
return NEED_FETCH;
}
}
WorkingSetID id = _workingSet->allocate();
WorkingSetMember* member = _workingSet->get(id);
member->loc = curr;
member->obj = _iter->dataFor(member->loc).releaseToBson();
member->state = WorkingSetMember::LOC_AND_UNOWNED_OBJ;
// Advance the iterator.
invariant(_iter->getNext() == curr);
return returnIfMatches(member, id, out);
}
示例11: work
PlanStage::StageState CollectionScan::work(WorkingSetID* out) {
++_commonStats.works;
// Adds the amount of time taken by work() to executionTimeMillis.
ScopedTimer timer(&_commonStats.executionTimeMillis);
if (_isDead) { return PlanStage::DEAD; }
// Do some init if we haven't already.
if (NULL == _iter) {
if ( _params.collection == NULL ) {
_isDead = true;
return PlanStage::DEAD;
}
if (_lastSeenLoc.isNull()) {
_iter.reset( _params.collection->getIterator( _txn,
_params.start,
_params.direction ) );
}
else {
invariant(_params.tailable);
_iter.reset( _params.collection->getIterator( _txn,
_lastSeenLoc,
_params.direction ) );
// Advance _iter past where we were last time. If it returns something else, mark us
// as dead since we want to signal an error rather than silently dropping data from
// the stream. This is related to the _lastSeenLock handling in invalidate.
if (_iter->getNext() != _lastSeenLoc) {
_isDead = true;
return PlanStage::DEAD;
}
}
++_commonStats.needTime;
return PlanStage::NEED_TIME;
}
// Should we try getNext() on the underlying _iter?
if (isEOF())
return PlanStage::IS_EOF;
// See if the record we're about to access is in memory. If not, pass a fetch request up.
// Note that curr() returns the same thing as getNext() will, except without advancing the
// iterator or touching the DiskLoc. This means that we can use curr() to check whether we
// need to fetch on the DiskLoc prior to touching it with getNext().
DiskLoc curr = _iter->curr();
if (!curr.isNull()) {
std::auto_ptr<RecordFetcher> fetcher(
_params.collection->documentNeedsFetch(_txn, curr));
if (NULL != fetcher.get()) {
WorkingSetMember* member = _workingSet->get(_wsidForFetch);
member->loc = curr;
// Pass the RecordFetcher off to the WSM.
member->setFetcher(fetcher.release());
*out = _wsidForFetch;
_commonStats.needFetch++;
return NEED_FETCH;
}
}
// What we'll return to the user.
DiskLoc nextLoc;
// See if _iter gives us anything new.
nextLoc = _iter->getNext();
if (nextLoc.isNull()) {
if (_params.tailable)
_iter.reset(); // pick up where we left off on the next call to work()
return PlanStage::IS_EOF;
}
_lastSeenLoc = nextLoc;
WorkingSetID id = _workingSet->allocate();
WorkingSetMember* member = _workingSet->get(id);
member->loc = nextLoc;
member->obj = _iter->dataFor(member->loc).releaseToBson();
member->state = WorkingSetMember::LOC_AND_UNOWNED_OBJ;
return returnIfMatches(member, id, out);
}