本文整理汇总了C++中WorkingSetMember类的典型用法代码示例。如果您正苦于以下问题:C++ WorkingSetMember类的具体用法?C++ WorkingSetMember怎么用?C++ WorkingSetMember使用的例子?那么恭喜您, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了WorkingSetMember类的20个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于我们的系统推荐出更棒的C++代码示例。
示例1: if
bool MultiPlanRunner::workAllPlans() {
for (size_t i = 0; i < _candidates.size(); ++i) {
CandidatePlan& candidate = _candidates[i];
WorkingSetID id;
PlanStage::StageState state = candidate.root->work(&id);
if (PlanStage::ADVANCED == state) {
// Save result for later.
candidate.results.push(id);
}
else if (PlanStage::NEED_TIME == state) {
// Nothing to do here.
}
else if (PlanStage::NEED_FETCH == state) {
// XXX: We can yield to do this. We have to deal with synchronization issues with
// regards to the working set and invalidation. What if another thread invalidates
// the thing we're fetching? The loc could vanish between hasLoc() and the actual
// fetch...
// id has a loc and refers to an obj we need to fetch.
WorkingSetMember* member = candidate.ws->get(id);
// This must be true for somebody to request a fetch and can only change when an
// invalidation happens, which is when we give up a lock. Don't give up the
// lock between receiving the NEED_FETCH and actually fetching(?).
verify(member->hasLoc());
// Actually bring record into memory.
Record* record = member->loc.rec();
record->touch();
// Record should be in memory now. Log if it's not.
if (!Record::likelyInPhysicalMemory(record->dataNoThrowing())) {
OCCASIONALLY {
warning() << "Record wasn't in memory immediately after fetch: "
<< member->loc.toString() << endl;
}
}
// Note that we're not freeing id. Fetch semantics say that we shouldn't.
}
开发者ID:ekpyrosis,项目名称:mongo,代码行数:41,代码来源:multi_plan_runner.cpp
示例2: getSortKey
Status SortStageKeyGenerator::getSortKey(const WorkingSetMember& member,
BSONObj* objOut) const {
BSONObj btreeKeyToUse;
Status btreeStatus = getBtreeKey(member.obj, &btreeKeyToUse);
if (!btreeStatus.isOK()) {
return btreeStatus;
}
if (!_sortHasMeta) {
*objOut = btreeKeyToUse;
return Status::OK();
}
BSONObjBuilder mergedKeyBob;
// Merge metadata into the key.
BSONObjIterator it(_rawSortSpec);
BSONObjIterator btreeIt(btreeKeyToUse);
while (it.more()) {
BSONElement elt = it.next();
if (elt.isNumber()) {
// Merge btree key elt.
mergedKeyBob.append(btreeIt.next());
}
else if (LiteParsedQuery::isTextScoreMeta(elt)) {
// Add text score metadata
double score = 0.0;
if (member.hasComputed(WSM_COMPUTED_TEXT_SCORE)) {
const TextScoreComputedData* scoreData
= static_cast<const TextScoreComputedData*>(
member.getComputed(WSM_COMPUTED_TEXT_SCORE));
score = scoreData->getScore();
}
mergedKeyBob.append("$metaTextScore", score);
}
}
*objOut = mergedKeyBob.obj();
return Status::OK();
}
开发者ID:Albert-B-P,项目名称:mongo,代码行数:41,代码来源:sort.cpp
示例3: prepareForSnapshotChange
void WorkingSetCommon::prepareForSnapshotChange(WorkingSet* workingSet) {
if (!supportsDocLocking()) {
// Non doc-locking storage engines use invalidations, so we don't need to examine the
// buffered working set ids. But we do need to clear the set of ids in order to keep our
// memory utilization in check.
workingSet->getAndClearYieldSensitiveIds();
return;
}
for (auto id : workingSet->getAndClearYieldSensitiveIds()) {
if (workingSet->isFree(id)) {
continue;
}
// We may see the same member twice, so anything we do here should be idempotent.
WorkingSetMember* member = workingSet->get(id);
if (member->getState() == WorkingSetMember::RID_AND_IDX) {
member->isSuspicious = true;
}
}
}
开发者ID:AnkyrinRepeat,项目名称:mongo,代码行数:21,代码来源:working_set_common.cpp
示例4: getRecordIds
void getRecordIds(Collection* collection,
CollectionScanParams::Direction direction,
vector<RecordId>* out) {
WorkingSet ws;
CollectionScanParams params;
params.collection = collection;
params.direction = direction;
params.tailable = false;
unique_ptr<CollectionScan> scan(new CollectionScan(&_txn, params, &ws, NULL));
while (!scan->isEOF()) {
WorkingSetID id = WorkingSet::INVALID_ID;
PlanStage::StageState state = scan->work(&id);
if (PlanStage::ADVANCED == state) {
WorkingSetMember* member = ws.get(id);
verify(member->hasRecordId());
out->push_back(member->recordId);
}
}
}
开发者ID:CeperaCPP,项目名称:mongo,代码行数:21,代码来源:query_stage_collscan.cpp
示例5: invalidate
void MergeSortStage::invalidate(const DiskLoc& dl, InvalidationType type) {
++_commonStats.invalidates;
for (size_t i = 0; i < _children.size(); ++i) {
_children[i]->invalidate(dl, type);
}
// Go through our data and see if we're holding on to the invalidated loc.
for (list<StageWithValue>::iterator valueIt = _mergingData.begin(); valueIt != _mergingData.end(); valueIt++) {
WorkingSetMember* member = _ws->get(valueIt->id);
if (member->hasLoc() && (dl == member->loc)) {
// Force a fetch and flag. We could possibly merge this result back in later.
WorkingSetCommon::fetchAndInvalidateLoc(member, _collection);
_ws->flagForReview(valueIt->id);
++_specificStats.forcedFetches;
}
}
// If we see DL again it is not the same record as it once was so we still want to
// return it.
if (_dedup) { _seen.erase(dl); }
}
开发者ID:Albert-B-P,项目名称:mongo,代码行数:21,代码来源:merge_sort.cpp
示例6: doInvalidate
void MergeSortStage::doInvalidate(OperationContext* txn,
const RecordId& dl,
InvalidationType type) {
// Go through our data and see if we're holding on to the invalidated RecordId.
for (list<StageWithValue>::iterator valueIt = _mergingData.begin();
valueIt != _mergingData.end();
valueIt++) {
WorkingSetMember* member = _ws->get(valueIt->id);
if (member->hasRecordId() && (dl == member->recordId)) {
// Fetch the about-to-be mutated result.
WorkingSetCommon::fetchAndInvalidateRecordId(txn, member, _collection);
++_specificStats.forcedFetches;
}
}
// If we see the deleted RecordId again it is not the same record as it once was so we still
// want to return it.
if (_dedup && INVALIDATION_DELETION == type) {
_seen.erase(dl);
}
}
开发者ID:AlexOreshkevich,项目名称:mongo,代码行数:21,代码来源:merge_sort.cpp
示例7: invalidate
void MultiPlanRunner::invalidate(const DiskLoc& dl, InvalidationType type) {
if (_failure || _killed) { return; }
if (NULL != _bestPlan) {
_bestPlan->invalidate(dl, type);
for (list<WorkingSetID>::iterator it = _alreadyProduced.begin();
it != _alreadyProduced.end();) {
WorkingSetMember* member = _bestPlan->getWorkingSet()->get(*it);
if (member->hasLoc() && member->loc == dl) {
list<WorkingSetID>::iterator next = it;
next++;
WorkingSetCommon::fetchAndInvalidateLoc(member);
_bestPlan->getWorkingSet()->flagForReview(*it);
_alreadyProduced.erase(it);
it = next;
}
else {
it++;
}
}
if (NULL != _backupPlan) {
_backupPlan->invalidate(dl, type);
for (list<WorkingSetID>::iterator it = _backupAlreadyProduced.begin();
it != _backupAlreadyProduced.end();) {
WorkingSetMember* member = _backupPlan->getWorkingSet()->get(*it);
if (member->hasLoc() && member->loc == dl) {
list<WorkingSetID>::iterator next = it;
next++;
WorkingSetCommon::fetchAndInvalidateLoc(member);
_backupPlan->getWorkingSet()->flagForReview(*it);
_backupAlreadyProduced.erase(it);
it = next;
}
else {
it++;
}
}
}
}
else {
for (size_t i = 0; i < _candidates.size(); ++i) {
_candidates[i].root->invalidate(dl, type);
for (list<WorkingSetID>::iterator it = _candidates[i].results.begin();
it != _candidates[i].results.end();) {
WorkingSetMember* member = _candidates[i].ws->get(*it);
if (member->hasLoc() && member->loc == dl) {
list<WorkingSetID>::iterator next = it;
next++;
WorkingSetCommon::fetchAndInvalidateLoc(member);
_candidates[i].ws->flagForReview(*it);
_candidates[i].results.erase(it);
it = next;
}
else {
it++;
}
}
}
}
}
开发者ID:AlanLiu-AI,项目名称:mongo,代码行数:60,代码来源:multi_plan_runner.cpp
示例8: status
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;
}
开发者ID:YanliSai,项目名称:mongo,代码行数:40,代码来源:multi_iterator.cpp
示例9: run
void run() {
// Various variables we'll need.
OldClientWriteContext ctx(&_txn, nss.ns());
Collection* coll = ctx.getCollection();
const BSONObj query = BSONObj();
const auto ws = make_unique<WorkingSet>();
const unique_ptr<CanonicalQuery> cq(canonicalize(query));
// Configure a QueuedDataStage to pass an OWNED_OBJ to the delete stage.
auto qds = make_unique<QueuedDataStage>(&_txn, ws.get());
{
WorkingSetID id = ws->allocate();
WorkingSetMember* member = ws->get(id);
member->obj = Snapshotted<BSONObj>(SnapshotId(), fromjson("{x: 1}"));
member->transitionToOwnedObj();
qds->pushBack(id);
}
// Configure the delete.
DeleteStageParams deleteParams;
deleteParams.isMulti = false;
deleteParams.canonicalQuery = cq.get();
const auto deleteStage =
make_unique<DeleteStage>(&_txn, deleteParams, ws.get(), coll, qds.release());
const DeleteStats* stats = static_cast<const DeleteStats*>(deleteStage->getSpecificStats());
// Call work, passing the set up member to the delete stage.
WorkingSetID id = WorkingSet::INVALID_ID;
PlanStage::StageState state = deleteStage->work(&id);
// Should return NEED_TIME, not deleting anything.
ASSERT_EQUALS(PlanStage::NEED_TIME, state);
ASSERT_EQUALS(stats->docsDeleted, 0U);
id = WorkingSet::INVALID_ID;
state = deleteStage->work(&id);
ASSERT_EQUALS(PlanStage::IS_EOF, state);
}
开发者ID:tmnsur,项目名称:mongo,代码行数:39,代码来源:query_stage_delete.cpp
示例10: timer
PlanStage::StageState SortKeyGeneratorStage::work(WorkingSetID* out) {
++_commonStats.works;
// Adds the amount of time taken by work() to executionTimeMillis.
ScopedTimer timer(&_commonStats.executionTimeMillis);
if (!_sortKeyGen) {
_sortKeyGen = stdx::make_unique<SortKeyGenerator>(_collection, _sortSpec, _query);
++_commonStats.needTime;
return PlanStage::NEED_TIME;
}
auto stageState = child()->work(out);
if (stageState == PlanStage::ADVANCED) {
WorkingSetMember* member = _ws->get(*out);
BSONObj sortKey;
Status sortKeyStatus = _sortKeyGen->getSortKey(*member, &sortKey);
if (!sortKeyStatus.isOK()) {
*out = WorkingSetCommon::allocateStatusMember(_ws, sortKeyStatus);
return PlanStage::FAILURE;
}
// Add the sort key to the WSM as computed data.
member->addComputed(new SortKeyComputedData(sortKey));
return PlanStage::ADVANCED;
}
if (stageState == PlanStage::IS_EOF) {
_commonStats.isEOF = true;
} else if (stageState == PlanStage::NEED_TIME) {
++_commonStats.needTime;
} else if (stageState == PlanStage::NEED_YIELD) {
++_commonStats.needYield;
}
return stageState;
}
开发者ID:kangic,项目名称:mongo,代码行数:39,代码来源:sort_key_generator.cpp
示例11: invalidate
void NearStage::invalidate(OperationContext* txn, const RecordId& dl, InvalidationType type) {
++_stats->common.invalidates;
for (size_t i = 0; i < _childrenIntervals.size(); i++) {
_childrenIntervals[i]->covering->invalidate(txn, dl, type);
}
// If a result is in _resultBuffer and has a RecordId it will be in _nextIntervalSeen as
// well. It's safe to return the result w/o the RecordId, so just fetch the result.
unordered_map<RecordId, WorkingSetID, RecordId::Hasher>::iterator seenIt = _nextIntervalSeen
.find(dl);
if (seenIt != _nextIntervalSeen.end()) {
WorkingSetMember* member = _workingSet->get(seenIt->second);
verify(member->hasLoc());
WorkingSetCommon::fetchAndInvalidateLoc(txn, member, _collection);
verify(!member->hasLoc());
// Don't keep it around in the seen map since there's no valid RecordId anymore
_nextIntervalSeen.erase(seenIt);
}
}
开发者ID:3rf,项目名称:mongo,代码行数:22,代码来源:near.cpp
示例12: invalidate
void NearStage::invalidate(const DiskLoc& dl, InvalidationType type) {
++_stats->common.invalidates;
if (_nextInterval) {
_nextInterval->covering->invalidate(dl, type);
}
// If a result is in _resultBuffer and has a DiskLoc it will be in _nextIntervalSeen as
// well. It's safe to return the result w/o the DiskLoc, so just fetch the result.
unordered_map<DiskLoc, WorkingSetID, DiskLoc::Hasher>::iterator seenIt = _nextIntervalSeen
.find(dl);
if (seenIt != _nextIntervalSeen.end()) {
WorkingSetMember* member = _workingSet->get(seenIt->second);
verify(member->hasLoc());
WorkingSetCommon::fetchAndInvalidateLoc(member, _collection);
verify(!member->hasLoc());
// Don't keep it around in the seen map since there's no valid DiskLoc anymore
_nextIntervalSeen.erase(seenIt);
}
}
开发者ID:Benguang,项目名称:mongo,代码行数:22,代码来源:near.cpp
示例13: invariant
PlanStage::StageState TextOrStage::returnResults(WorkingSetID* out) {
if (_scoreIterator == _scores.end()) {
_internalState = State::kDone;
return PlanStage::IS_EOF;
}
// Retrieve the record that contains the text score.
TextRecordData textRecordData = _scoreIterator->second;
++_scoreIterator;
// Ignore non-matched documents.
if (textRecordData.score < 0) {
invariant(textRecordData.wsid == WorkingSet::INVALID_ID);
return PlanStage::NEED_TIME;
}
WorkingSetMember* wsm = _ws->get(textRecordData.wsid);
// Populate the working set member with the text score and return it.
wsm->addComputed(new TextScoreComputedData(textRecordData.score));
*out = textRecordData.wsid;
return PlanStage::ADVANCED;
}
开发者ID:christkv,项目名称:mongo,代码行数:23,代码来源:text_or.cpp
示例14: doWork
PlanStage::StageState PipelineProxyStage::doWork(WorkingSetID* out) {
if (!out) {
return PlanStage::FAILURE;
}
if (!_stash.empty()) {
*out = _ws->allocate();
WorkingSetMember* member = _ws->get(*out);
member->obj = Snapshotted<BSONObj>(SnapshotId(), _stash.back());
_stash.pop_back();
member->transitionToOwnedObj();
return PlanStage::ADVANCED;
}
if (boost::optional<BSONObj> next = getNextBson()) {
*out = _ws->allocate();
WorkingSetMember* member = _ws->get(*out);
member->obj = Snapshotted<BSONObj>(SnapshotId(), *next);
member->transitionToOwnedObj();
return PlanStage::ADVANCED;
}
return PlanStage::IS_EOF;
}
开发者ID:ShaneHarvey,项目名称:mongo,代码行数:24,代码来源:pipeline_proxy.cpp
示例15: run
bool run(OperationContext* txn,
const string& dbname,
BSONObj& cmdObj,
int,
string& errmsg,
BSONObjBuilder& result) {
BSONElement first = cmdObj.firstElement();
uassert(28528,
str::stream() << "Argument to listIndexes must be of type String, not "
<< typeName(first.type()),
first.type() == String);
StringData collectionName = first.valueStringData();
uassert(28529,
str::stream() << "Argument to listIndexes must be a collection name, "
<< "not the empty string",
!collectionName.empty());
const NamespaceString ns(dbname, collectionName);
const long long defaultBatchSize = std::numeric_limits<long long>::max();
long long batchSize;
Status parseCursorStatus = parseCommandCursorOptions(cmdObj, defaultBatchSize, &batchSize);
if (!parseCursorStatus.isOK()) {
return appendCommandStatus(result, parseCursorStatus);
}
AutoGetCollectionForRead autoColl(txn, ns);
if (!autoColl.getDb()) {
return appendCommandStatus(result,
Status(ErrorCodes::NamespaceNotFound, "no database"));
}
const Collection* collection = autoColl.getCollection();
if (!collection) {
return appendCommandStatus(result,
Status(ErrorCodes::NamespaceNotFound, "no collection"));
}
const CollectionCatalogEntry* cce = collection->getCatalogEntry();
invariant(cce);
vector<string> indexNames;
MONGO_WRITE_CONFLICT_RETRY_LOOP_BEGIN {
indexNames.clear();
cce->getAllIndexes(txn, &indexNames);
}
MONGO_WRITE_CONFLICT_RETRY_LOOP_END(txn, "listIndexes", ns.ns());
std::unique_ptr<WorkingSet> ws(new WorkingSet());
std::unique_ptr<QueuedDataStage> root(new QueuedDataStage(ws.get()));
for (size_t i = 0; i < indexNames.size(); i++) {
BSONObj indexSpec;
MONGO_WRITE_CONFLICT_RETRY_LOOP_BEGIN {
indexSpec = cce->getIndexSpec(txn, indexNames[i]);
}
MONGO_WRITE_CONFLICT_RETRY_LOOP_END(txn, "listIndexes", ns.ns());
WorkingSetID id = ws->allocate();
WorkingSetMember* member = ws->get(id);
member->keyData.clear();
member->loc = RecordId();
member->obj = Snapshotted<BSONObj>(SnapshotId(), indexSpec.getOwned());
member->transitionToOwnedObj();
root->pushBack(id);
}
std::string cursorNamespace = str::stream() << dbname << ".$cmd." << name << "."
<< ns.coll();
dassert(NamespaceString(cursorNamespace).isValid());
dassert(NamespaceString(cursorNamespace).isListIndexesCursorNS());
dassert(ns == NamespaceString(cursorNamespace).getTargetNSForListIndexes());
auto statusWithPlanExecutor = PlanExecutor::make(
txn, std::move(ws), std::move(root), cursorNamespace, PlanExecutor::YIELD_MANUAL);
if (!statusWithPlanExecutor.isOK()) {
return appendCommandStatus(result, statusWithPlanExecutor.getStatus());
}
std::unique_ptr<PlanExecutor> exec = std::move(statusWithPlanExecutor.getValue());
BSONArrayBuilder firstBatch;
const int byteLimit = MaxBytesToReturnToClientAtOnce;
for (long long objCount = 0; objCount < batchSize && firstBatch.len() < byteLimit;
objCount++) {
BSONObj next;
PlanExecutor::ExecState state = exec->getNext(&next, NULL);
if (state == PlanExecutor::IS_EOF) {
break;
}
invariant(state == PlanExecutor::ADVANCED);
firstBatch.append(next);
}
CursorId cursorId = 0LL;
if (!exec->isEOF()) {
exec->saveState();
ClientCursor* cursor = new ClientCursor(
CursorManager::getGlobalCursorManager(), exec.release(), cursorNamespace);
cursorId = cursor->cursorid();
}
//.........这里部分代码省略.........
开发者ID:Andiry,项目名称:mongo,代码行数:101,代码来源:list_indexes.cpp
示例16: run
void run() {
Client::WriteContext ctx(&_txn, ns());
Database* db = ctx.ctx().db();
Collection* coll = db->getCollection(&_txn, ns());
if (!coll) {
coll = db->createCollection(&_txn, ns());
}
WorkingSet ws;
// Sort by foo:1
MergeSortStageParams msparams;
msparams.pattern = BSON("foo" << 1);
auto_ptr<MergeSortStage> ms(new MergeSortStage(msparams, &ws, coll));
IndexScanParams params;
params.bounds.isSimpleRange = true;
params.bounds.startKey = objWithMinKey(1);
params.bounds.endKey = objWithMaxKey(1);
params.bounds.endKeyInclusive = true;
params.direction = 1;
// Index 'a'+i has foo equal to 'i'.
int numIndices = 20;
for (int i = 0; i < numIndices; ++i) {
// 'a', 'b', ...
string index(1, 'a' + i);
insert(BSON(index << 1 << "foo" << i));
BSONObj indexSpec = BSON(index << 1 << "foo" << 1);
addIndex(indexSpec);
params.descriptor = getIndex(indexSpec, coll);
ms->addChild(new IndexScan(&_txn, params, &ws, NULL));
}
set<DiskLoc> locs;
getLocs(&locs, coll);
set<DiskLoc>::iterator it = locs.begin();
ctx.commit();
// Get 10 results. Should be getting results in order of 'locs'.
int count = 0;
while (!ms->isEOF() && count < 10) {
WorkingSetID id = WorkingSet::INVALID_ID;
PlanStage::StageState status = ms->work(&id);
if (PlanStage::ADVANCED != status) { continue; }
WorkingSetMember* member = ws.get(id);
ASSERT_EQUALS(member->loc, *it);
BSONElement elt;
string index(1, 'a' + count);
ASSERT(member->getFieldDotted(index, &elt));
ASSERT_EQUALS(1, elt.numberInt());
ASSERT(member->getFieldDotted("foo", &elt));
ASSERT_EQUALS(count, elt.numberInt());
++count;
++it;
}
// Invalidate locs[11]. Should force a fetch. We don't get it back.
ms->prepareToYield();
ms->invalidate(*it, INVALIDATION_DELETION);
ms->recoverFromYield(&_txn);
// Make sure locs[11] was fetched for us.
{
// TODO: If we have "return upon invalidation" ever triggerable, do the following test.
/*
WorkingSetID id = WorkingSet::INVALID_ID;
PlanStage::StageState status;
do {
status = ms->work(&id);
} while (PlanStage::ADVANCED != status);
WorkingSetMember* member = ws.get(id);
ASSERT(!member->hasLoc());
ASSERT(member->hasObj());
string index(1, 'a' + count);
BSONElement elt;
ASSERT_TRUE(member->getFieldDotted(index, &elt));
ASSERT_EQUALS(1, elt.numberInt());
ASSERT(member->getFieldDotted("foo", &elt));
ASSERT_EQUALS(count, elt.numberInt());
*/
++it;
++count;
}
// And get the rest.
while (!ms->isEOF()) {
WorkingSetID id = WorkingSet::INVALID_ID;
PlanStage::StageState status = ms->work(&id);
if (PlanStage::ADVANCED != status) { continue; }
WorkingSetMember* member = ws.get(id);
ASSERT_EQUALS(member->loc, *it);
BSONElement elt;
string index(1, 'a' + count);
//.........这里部分代码省略.........
开发者ID:glenlray,项目名称:mongo,代码行数:101,代码来源:query_stage_merge_sort.cpp
示例17: run
void run() {
// Populate the collection.
for (int i = 0; i < 50; ++i) {
insert(BSON("_id" << i << "foo" << i));
}
ASSERT_EQUALS(50U, count(BSONObj()));
// Various variables we'll need.
dbtests::WriteContextForTests ctx(&_opCtx, nss.ns());
OpDebug* opDebug = &CurOp::get(_opCtx)->debug();
Collection* coll = ctx.getCollection();
ASSERT(coll);
UpdateRequest request(nss);
const CollatorInterface* collator = nullptr;
UpdateDriver driver(new ExpressionContext(&_opCtx, collator));
const int targetDocIndex = 10;
const BSONObj query = BSON("foo" << BSON("$gte" << targetDocIndex));
const auto ws = make_unique<WorkingSet>();
const unique_ptr<CanonicalQuery> cq(canonicalize(query));
// Get the RecordIds that would be returned by an in-order scan.
vector<RecordId> recordIds;
getRecordIds(coll, CollectionScanParams::FORWARD, &recordIds);
// Populate the request.
request.setQuery(query);
request.setUpdates(fromjson("{$set: {x: 0}}"));
request.setSort(BSONObj());
request.setMulti(false);
request.setReturnDocs(UpdateRequest::RETURN_NEW);
const std::map<StringData, std::unique_ptr<ExpressionWithPlaceholder>> arrayFilters;
ASSERT_DOES_NOT_THROW(driver.parse(request.getUpdates(), arrayFilters, request.isMulti()));
// Configure a QueuedDataStage to pass the first object in the collection back in a
// RID_AND_OBJ state.
auto qds = make_unique<QueuedDataStage>(&_opCtx, ws.get());
WorkingSetID id = ws->allocate();
WorkingSetMember* member = ws->get(id);
member->recordId = recordIds[targetDocIndex];
const BSONObj oldDoc = BSON("_id" << targetDocIndex << "foo" << targetDocIndex);
member->obj = Snapshotted<BSONObj>(SnapshotId(), oldDoc);
ws->transitionToRecordIdAndObj(id);
qds->pushBack(id);
// Configure the update.
UpdateStageParams updateParams(&request, &driver, opDebug);
updateParams.canonicalQuery = cq.get();
auto updateStage =
make_unique<UpdateStage>(&_opCtx, updateParams, ws.get(), coll, qds.release());
// Should return advanced.
id = WorkingSet::INVALID_ID;
PlanStage::StageState state = updateStage->work(&id);
ASSERT_EQUALS(PlanStage::ADVANCED, state);
// Make sure the returned value is what we expect it to be.
// Should give us back a valid id.
ASSERT_TRUE(WorkingSet::INVALID_ID != id);
WorkingSetMember* resultMember = ws->get(id);
// With an owned copy of the object, with no RecordId.
ASSERT_TRUE(resultMember->hasOwnedObj());
ASSERT_FALSE(resultMember->hasRecordId());
ASSERT_EQUALS(resultMember->getState(), WorkingSetMember::OWNED_OBJ);
ASSERT_TRUE(resultMember->obj.value().isOwned());
// Should be the new value.
BSONObj newDoc = BSON("_id" << targetDocIndex << "foo" << targetDocIndex << "x" << 0);
ASSERT_BSONOBJ_EQ(resultMember->obj.value(), newDoc);
// Should have done the update.
vector<BSONObj> objs;
getCollContents(coll, &objs);
ASSERT_BSONOBJ_EQ(objs[targetDocIndex], newDoc);
// That should be it.
id = WorkingSet::INVALID_ID;
ASSERT_EQUALS(PlanStage::IS_EOF, updateStage->work(&id));
}
开发者ID:ShaneHarvey,项目名称:mongo,代码行数:82,代码来源:query_stage_update.cpp
示例18: if
PlanStage::StageState S2NearStage::addResultToQueue(WorkingSetID* out) {
PlanStage::StageState state = _child->work(out);
// All done reading from _child.
if (PlanStage::IS_EOF == state) {
_child.reset();
_keyGeoFilter.reset();
// Adjust the annulus size depending on how many results we got.
if (_results.empty()) {
_radiusIncrement *= 2;
} else if (_results.size() < 300) {
_radiusIncrement *= 2;
} else if (_results.size() > 600) {
_radiusIncrement /= 2;
}
// Make a new ixscan next time.
return PlanStage::NEED_TIME;
}
// Nothing to do unless we advance.
if (PlanStage::ADVANCED != state) { return state; }
WorkingSetMember* member = _ws->get(*out);
// Must have an object in order to get geometry out of it.
verify(member->hasObj());
// The scans we use don't dedup so we must dedup them ourselves. We only put locs into here
// if we know for sure whether or not we'll return them in this annulus.
if (member->hasLoc()) {
if (_seenInScan.end() != _seenInScan.find(member->loc)) {
return PlanStage::NEED_TIME;
}
}
// Get all the fields with that name from the document.
BSONElementSet geom;
member->obj.getFieldsDotted(_params.nearQuery.field, geom, false);
if (geom.empty()) {
return PlanStage::NEED_TIME;
}
// Some value that any distance we can calculate will be less than.
double minDistance = numeric_limits<double>::max();
BSONObj minDistanceObj;
for (BSONElementSet::iterator git = geom.begin(); git != geom.end(); ++git) {
if (!git->isABSONObj()) {
mongoutils::str::stream ss;
ss << "s2near stage read invalid geometry element " << *git << " from child";
Status status(ErrorCodes::InternalError, ss);
*out = WorkingSetCommon::allocateStatusMember( _ws, status);
return PlanStage::FAILURE;
}
BSONObj obj = git->Obj();
double distToObj;
if (S2SearchUtil::distanceBetween(_params.nearQuery.centroid.point, obj, &distToObj)) {
if (distToObj < minDistance) {
minDistance = distToObj;
minDistanceObj = obj;
}
}
else {
warning() << "unknown geometry: " << obj.toString();
}
}
// If we're here we'll either include the doc in this annulus or reject it. It's safe to
// ignore it if it pops up again in this annulus.
if (member->hasLoc()) {
_seenInScan.insert(member->loc);
}
// If the distance to the doc satisfies our distance criteria, add it to our buffered
// results.
if (minDistance >= _innerRadius &&
(_outerRadiusInclusive ? minDistance <= _outerRadius : minDistance < _outerRadius)) {
_results.push(Result(*out, minDistance));
if (_params.addDistMeta) {
// FLAT implies the output distances are in radians. Convert to meters.
if (FLAT == _params.nearQuery.centroid.crs) {
member->addComputed(new GeoDistanceComputedData(minDistance
/ kRadiusOfEarthInMeters));
}
else {
member->addComputed(new GeoDistanceComputedData(minDistance));
}
}
if (_params.addPointMeta) {
member->addComputed(new GeoNearPointComputedData(minDistanceObj));
}
if (member->hasLoc()) {
_invalidationMap[member->loc] = *out;
}
}
return PlanStage::NEED_TIME;
}
开发者ID:AshishThakur,项目名称:mongo,代码行数:99,代码来源:s2near.cpp
示例19: status
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.taila
|
请发表评论