本文整理汇总了C++中CursorManager::pinCursor方法的典型用法代码示例。如果您正苦于以下问题:C++ CursorManager::pinCursor方法的具体用法?C++ CursorManager::pinCursor怎么用?C++ CursorManager::pinCursor使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类CursorManager
的用法示例。
在下文中一共展示了CursorManager::pinCursor方法的3个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: useCursorManager
/**
* Test that using a cursor updates its time of last use.
*/
TEST_F(CursorManagerTest, UsingACursorShouldUpdateTimeOfLastUse) {
CursorManager* cursorManager = useCursorManager();
auto clock = useClock();
// Register a cursor which we will look at again.
auto cursorPin = cursorManager->registerCursor(
_opCtx.get(), {makeFakePlanExecutor(), kTestNss, {}, false, BSONObj()});
auto usedCursorId = cursorPin.getCursor()->cursorid();
cursorPin.release();
// Register a cursor to immediately forget about, to make sure it will time out on a normal
// schedule.
cursorManager->registerCursor(_opCtx.get(),
{makeFakePlanExecutor(), kTestNss, {}, false, BSONObj()});
// Advance the clock to simulate time passing.
clock->advance(Milliseconds(1));
// Touch the cursor with id 'usedCursorId' to advance its time of last use.
cursorManager->pinCursor(_opCtx.get(), usedCursorId).status_with_transitional_ignore();
// We should be able to time out the unused cursor, but the one we used should stay alive.
ASSERT_EQ(2UL, cursorManager->numCursors());
clock->advance(getDefaultCursorTimeoutMillis() - Milliseconds(1));
ASSERT_EQ(1UL, cursorManager->timeoutCursors(_opCtx.get(), clock->now()));
ASSERT_EQ(1UL, cursorManager->numCursors());
// We should be able to time out the used cursor after one more millisecond.
clock->advance(Milliseconds(1));
ASSERT_EQ(1UL, cursorManager->timeoutCursors(_opCtx.get(), clock->now()));
ASSERT_EQ(0UL, cursorManager->numCursors());
}
示例2: getMore
/**
* Called by db/instance.cpp. This is the getMore entry point.
*/
Message getMore(OperationContext* opCtx,
const char* ns,
int ntoreturn,
long long cursorid,
bool* exhaust,
bool* isCursorAuthorized) {
invariant(ntoreturn >= 0);
CurOp& curOp = *CurOp::get(opCtx);
curOp.ensureStarted();
// For testing, we may want to fail if we receive a getmore.
if (MONGO_FAIL_POINT(failReceivedGetmore)) {
MONGO_UNREACHABLE;
}
*exhaust = false;
const NamespaceString nss(ns);
// Cursors come in one of two flavors:
// - Cursors owned by the collection cursor manager, such as those generated via the find
// command. For these cursors, we hold the appropriate collection lock for the duration of the
// getMore using AutoGetCollectionForRead.
// - Cursors owned by the global cursor manager, such as those generated via the aggregate
// command. These cursors either hold no collection state or manage their collection state
// internally, so we acquire no locks.
//
// While we only need to acquire locks in the case of a cursor which is *not* globally owned, we
// need to create an AutoStatsTracker in either case. This is responsible for updating
// statistics in CurOp and Top. We avoid using AutoGetCollectionForReadCommand because we may
// need to drop and reacquire locks when the cursor is awaitData, but we don't want to update
// the stats twice.
//
// Note that we acquire our locks before our ClientCursorPin, in order to ensure that the pin's
// destructor is called before the lock's destructor (if there is one) so that the cursor
// cleanup can occur under the lock.
UninterruptibleLockGuard noInterrupt(opCtx->lockState());
boost::optional<AutoGetCollectionForRead> readLock;
boost::optional<AutoStatsTracker> statsTracker;
CursorManager* cursorManager;
if (CursorManager::isGloballyManagedCursor(cursorid)) {
cursorManager = CursorManager::getGlobalCursorManager();
if (boost::optional<NamespaceString> nssForCurOp = nss.isGloballyManagedNamespace()
? nss.getTargetNSForGloballyManagedNamespace()
: nss) {
AutoGetDb autoDb(opCtx, nssForCurOp->db(), MODE_IS);
const auto profilingLevel = autoDb.getDb()
? boost::optional<int>{autoDb.getDb()->getProfilingLevel()}
: boost::none;
statsTracker.emplace(opCtx, *nssForCurOp, Top::LockType::NotLocked, profilingLevel);
auto view = autoDb.getDb()
? autoDb.getDb()->getViewCatalog()->lookup(opCtx, nssForCurOp->ns())
: nullptr;
uassert(
ErrorCodes::CommandNotSupportedOnView,
str::stream() << "Namespace " << nssForCurOp->ns()
<< " is a view. OP_GET_MORE operations are not supported on views. "
<< "Only clients which support the getMore command can be used to "
"query views.",
!view);
}
} else {
readLock.emplace(opCtx, nss);
const int doNotChangeProfilingLevel = 0;
statsTracker.emplace(opCtx,
nss,
Top::LockType::ReadLocked,
readLock->getDb() ? readLock->getDb()->getProfilingLevel()
: doNotChangeProfilingLevel);
Collection* collection = readLock->getCollection();
uassert(
ErrorCodes::OperationFailed, "collection dropped between getMore calls", collection);
cursorManager = collection->getCursorManager();
// This checks to make sure the operation is allowed on a replicated node. Since we are not
// passing in a query object (necessary to check SlaveOK query option), we allow reads
// whether we are PRIMARY or SECONDARY.
uassertStatusOK(
repl::ReplicationCoordinator::get(opCtx)->checkCanServeReadsFor(opCtx, nss, true));
}
LOG(5) << "Running getMore, cursorid: " << cursorid;
// A pin performs a CC lookup and if there is a CC, increments the CC's pin value so it
// doesn't time out. Also informs ClientCursor that there is somebody actively holding the
// CC, so don't delete it.
auto ccPin = cursorManager->pinCursor(opCtx, cursorid);
// These are set in the QueryResult msg we return.
int resultFlags = ResultFlag_AwaitCapable;
int numResults = 0;
int startingResult = 0;
//.........这里部分代码省略.........
示例3: getMore
/**
* Called by db/instance.cpp. This is the getMore entry point.
*/
Message getMore(OperationContext* txn,
const char* ns,
int ntoreturn,
long long cursorid,
bool* exhaust,
bool* isCursorAuthorized) {
invariant(ntoreturn >= 0);
CurOp& curOp = *CurOp::get(txn);
// For testing, we may want to fail if we receive a getmore.
if (MONGO_FAIL_POINT(failReceivedGetmore)) {
invariant(0);
}
*exhaust = false;
const NamespaceString nss(ns);
// Depending on the type of cursor being operated on, we hold locks for the whole getMore,
// or none of the getMore, or part of the getMore. The three cases in detail:
//
// 1) Normal cursor: we lock with "ctx" and hold it for the whole getMore.
// 2) Cursor owned by global cursor manager: we don't lock anything. These cursors don't own
// any collection state. These cursors are generated either by the listCollections or
// listIndexes commands, as these special cursor-generating commands operate over catalog
// data rather than targeting the data within a collection.
// 3) Agg cursor: we lock with "ctx", then release, then relock with "unpinDBLock" and
// "unpinCollLock". This is because agg cursors handle locking internally (hence the
// release), but the pin and unpin of the cursor must occur under the collection lock.
// We don't use our AutoGetCollectionForRead "ctx" to relock, because
// AutoGetCollectionForRead checks the sharding version (and we want the relock for the
// unpin to succeed even if the sharding version has changed).
//
// Note that we declare our locks before our ClientCursorPin, in order to ensure that the
// pin's destructor is called before the lock destructors (so that the unpin occurs under
// the lock).
unique_ptr<AutoGetCollectionForRead> ctx;
unique_ptr<Lock::DBLock> unpinDBLock;
unique_ptr<Lock::CollectionLock> unpinCollLock;
CursorManager* cursorManager;
if (nss.isListIndexesCursorNS() || nss.isListCollectionsCursorNS()) {
// List collections and list indexes are special cursor-generating commands whose
// cursors are managed globally, as they operate over catalog data rather than targeting
// the data within a collection.
cursorManager = CursorManager::getGlobalCursorManager();
} else {
ctx = stdx::make_unique<AutoGetCollectionOrViewForRead>(txn, nss);
auto viewCtx = static_cast<AutoGetCollectionOrViewForRead*>(ctx.get());
if (viewCtx->getView()) {
uasserted(
ErrorCodes::CommandNotSupportedOnView,
str::stream() << "Namespace " << nss.ns()
<< " is a view. OP_GET_MORE operations are not supported on views. "
<< "Only clients which support the getMore command can be used to "
"query views.");
}
Collection* collection = ctx->getCollection();
uassert(17356, "collection dropped between getMore calls", collection);
cursorManager = collection->getCursorManager();
}
LOG(5) << "Running getMore, cursorid: " << cursorid;
// This checks to make sure the operation is allowed on a replicated node. Since we are not
// passing in a query object (necessary to check SlaveOK query option), the only state where
// reads are allowed is PRIMARY (or master in master/slave). This function uasserts if
// reads are not okay.
Status status = repl::getGlobalReplicationCoordinator()->checkCanServeReadsFor(txn, nss, true);
uassertStatusOK(status);
// A pin performs a CC lookup and if there is a CC, increments the CC's pin value so it
// doesn't time out. Also informs ClientCursor that there is somebody actively holding the
// CC, so don't delete it.
auto ccPin = cursorManager->pinCursor(cursorid);
// These are set in the QueryResult msg we return.
int resultFlags = ResultFlag_AwaitCapable;
int numResults = 0;
int startingResult = 0;
const int InitialBufSize =
512 + sizeof(QueryResult::Value) + FindCommon::kMaxBytesToReturnToClientAtOnce;
BufBuilder bb(InitialBufSize);
bb.skip(sizeof(QueryResult::Value));
if (!ccPin.isOK()) {
invariant(ccPin == ErrorCodes::CursorNotFound);
cursorid = 0;
resultFlags = ResultFlag_CursorNotFound;
} else {
ClientCursor* cc = ccPin.getValue().getCursor();
//.........这里部分代码省略.........