本文整理汇总了C++中PlanExecutor::enqueue方法的典型用法代码示例。如果您正苦于以下问题:C++ PlanExecutor::enqueue方法的具体用法?C++ PlanExecutor::enqueue怎么用?C++ PlanExecutor::enqueue使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类PlanExecutor
的用法示例。
在下文中一共展示了PlanExecutor::enqueue方法的2个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: generateBatch
/**
* Uses 'cursor' and 'request' to fill out 'nextBatch' with the batch of result documents to
* be returned by this getMore.
*
* Returns the number of documents in the batch in *numResults, which must be initialized to
* zero by the caller. Returns the final ExecState returned by the cursor in *state.
*
* Returns an OK status if the batch was successfully generated, and a non-OK status if the
* PlanExecutor encounters a failure.
*/
Status generateBatch(ClientCursor* cursor,
const GetMoreRequest& request,
BSONArrayBuilder* nextBatch,
PlanExecutor::ExecState* state,
int* numResults) {
PlanExecutor* exec = cursor->getExecutor();
const bool isAwaitData = isCursorAwaitData(cursor);
// If an awaitData getMore is killed during this process due to our max time expiring at
// an interrupt point, we just continue as normal and return rather than reporting a
// timeout to the user.
BSONObj obj;
try {
while (PlanExecutor::ADVANCED == (*state = exec->getNext(&obj, NULL))) {
// If adding this object will cause us to exceed the BSON size limit, then we
// stash it for later.
if (nextBatch->len() + obj.objsize() > BSONObjMaxUserSize && *numResults > 0) {
exec->enqueue(obj);
break;
}
// Add result to output buffer.
nextBatch->append(obj);
(*numResults)++;
if (enoughForGetMore(request.batchSize.value_or(0),
*numResults, nextBatch->len())) {
break;
}
}
}
catch (const UserException& except) {
if (isAwaitData && except.getCode() == ErrorCodes::ExceededTimeLimit) {
// We ignore exceptions from interrupt points due to max time expiry for
// awaitData cursors.
}
else {
throw;
}
}
if (PlanExecutor::FAILURE == *state) {
const std::unique_ptr<PlanStageStats> stats(exec->getStats());
error() << "GetMore executor error, stats: " << Explain::statsToBSON(*stats);
return Status(ErrorCodes::OperationFailed,
str::stream() << "GetMore executor error: "
<< WorkingSetCommon::toStatusString(obj));
}
else if (PlanExecutor::DEAD == *state) {
return Status(ErrorCodes::OperationFailed,
str::stream() << "Plan executor killed during getMore command, "
<< "ns: " << request.nss.ns());
}
return Status::OK();
}
示例2: run
//.........这里部分代码省略.........
if (!shardingState->getVersion(nss.ns()).isWriteCompatibleWith(shardingVersionAtStart)) {
// Version changed while retrieving a PlanExecutor. Terminate the operation,
// signaling that mongos should retry.
throw SendStaleConfigException(nss.ns(),
"version changed during find command",
shardingVersionAtStart,
shardingState->getVersion(nss.ns()));
}
if (!collection) {
// No collection. Just fill out curop indicating that there were zero results and
// there is no ClientCursor id, and then return.
const long long numResults = 0;
const CursorId cursorId = 0;
endQueryOp(txn, *exec, dbProfilingLevel, numResults, cursorId);
appendCursorResponseObject(cursorId, nss.ns(), BSONArray(), &result);
return true;
}
const LiteParsedQuery& pq = exec->getCanonicalQuery()->getParsed();
// 4) If possible, register the execution plan inside a ClientCursor, and pin that
// cursor. In this case, ownership of the PlanExecutor is transferred to the
// ClientCursor, and 'exec' becomes null.
//
// First unregister the PlanExecutor so it can be re-registered with ClientCursor.
exec->deregisterExec();
// Create a ClientCursor containing this plan executor. We don't have to worry
// about leaking it as it's inserted into a global map by its ctor.
ClientCursor* cursor =
new ClientCursor(collection->getCursorManager(),
exec.release(),
nss.ns(),
txn->recoveryUnit()->isReadingFromMajorityCommittedSnapshot(),
pq.getOptions(),
pq.getFilter());
CursorId cursorId = cursor->cursorid();
ClientCursorPin ccPin(collection->getCursorManager(), cursorId);
// On early return, get rid of the the cursor.
ScopeGuard cursorFreer = MakeGuard(&ClientCursorPin::deleteUnderlying, ccPin);
invariant(!exec);
PlanExecutor* cursorExec = cursor->getExecutor();
// 5) Stream query results, adding them to a BSONArray as we go.
BSONArrayBuilder firstBatch;
BSONObj obj;
PlanExecutor::ExecState state;
long long numResults = 0;
while (!enoughForFirstBatch(pq, numResults, firstBatch.len()) &&
PlanExecutor::ADVANCED == (state = cursorExec->getNext(&obj, NULL))) {
// If adding this object will cause us to exceed the BSON size limit, then we stash
// it for later.
if (firstBatch.len() + obj.objsize() > BSONObjMaxUserSize && numResults > 0) {
cursorExec->enqueue(obj);
break;
}
// Add result to output buffer.
firstBatch.append(obj);
numResults++;
}
// Throw an assertion if query execution fails for any reason.
if (PlanExecutor::FAILURE == state || PlanExecutor::DEAD == state) {
const std::unique_ptr<PlanStageStats> stats(cursorExec->getStats());
error() << "Plan executor error during find command: " << PlanExecutor::statestr(state)
<< ", stats: " << Explain::statsToBSON(*stats);
return appendCommandStatus(result,
Status(ErrorCodes::OperationFailed,
str::stream()
<< "Executor error during find command: "
<< WorkingSetCommon::toStatusString(obj)));
}
// 6) Set up the cursor for getMore.
if (shouldSaveCursor(txn, collection, state, cursorExec)) {
// State will be restored on getMore.
cursorExec->saveState();
cursorExec->detachFromOperationContext();
cursor->setLeftoverMaxTimeMicros(CurOp::get(txn)->getRemainingMaxTimeMicros());
cursor->setPos(numResults);
} else {
cursorId = 0;
}
// Fill out curop based on the results.
endQueryOp(txn, *cursorExec, dbProfilingLevel, numResults, cursorId);
// 7) Generate the response object to send to the client.
appendCursorResponseObject(cursorId, nss.ns(), firstBatch.arr(), &result);
if (cursorId) {
cursorFreer.Dismiss();
}
return true;
}