// At the point which this is called we are in between the first and second record void interject(CountStage& count_stage, int interjection) { if (interjection == 0) { count_stage.invalidate(&_txn, _locs[0], INVALIDATION_MUTATION); OID id1 = _coll->docFor(&_txn, _locs[0]).value().getField("_id").OID(); update(_locs[0], BSON("_id" << id1 << "x" << 100)); count_stage.invalidate(&_txn, _locs[1], INVALIDATION_MUTATION); OID id2 = _coll->docFor(&_txn, _locs[1]).value().getField("_id").OID(); update(_locs[1], BSON("_id" << id2 << "x" << 100)); } }
// At the point which this is called we are in between counting the first + second record void interject(CountStage& count_stage, int interjection) { if (interjection == 0) { // At this point, our first interjection, we've counted _locs[0] // and are about to count _locs[1] count_stage.invalidate(&_txn, _locs[interjection], INVALIDATION_DELETION); remove(_locs[interjection]); count_stage.invalidate(&_txn, _locs[interjection+1], INVALIDATION_DELETION); remove(_locs[interjection+1]); } }
virtual bool run(OperationContext* txn, const string& dbname, BSONObj& cmdObj, int, string& errmsg, BSONObjBuilder& result, bool fromRepl) { CountRequest request; Status parseStatus = parseRequest(dbname, cmdObj, &request); if (!parseStatus.isOK()) { return appendCommandStatus(result, parseStatus); } AutoGetCollectionForRead ctx(txn, request.ns); Collection* collection = ctx.getCollection(); // Prevent chunks from being cleaned up during yields - this allows us to only check the // version on initial entry into count. RangePreserver preserver(collection); PlanExecutor* rawExec; Status getExecStatus = getExecutorCount(txn, collection, request, PlanExecutor::YIELD_AUTO, &rawExec); if (!getExecStatus.isOK()) { return appendCommandStatus(result, getExecStatus); } scoped_ptr<PlanExecutor> exec(rawExec); // Store the plan summary string in CurOp. if (NULL != txn->getCurOp()) { txn->getCurOp()->debug().planSummary = Explain::getPlanSummary(exec.get()); } Status execPlanStatus = exec->executePlan(); if (!execPlanStatus.isOK()) { return appendCommandStatus(result, execPlanStatus); } // Plan is done executing. We just need to pull the count out of the root stage. invariant(STAGE_COUNT == exec->getRootStage()->stageType()); CountStage* countStage = static_cast<CountStage*>(exec->getRootStage()); const CountStats* countStats = static_cast<const CountStats*>(countStage->getSpecificStats()); result.appendNumber("n", countStats->nCounted); return true; }
bool CmdCount::run(OperationContext* txn, const string& dbname, BSONObj& cmdObj, int, string& errmsg, BSONObjBuilder& result, bool) { CountRequest request; Status parseStatus = parseRequest(dbname, cmdObj, &request); if (!parseStatus.isOK()) { return appendCommandStatus(result, parseStatus); } // Acquire the db read lock. Client::ReadContext ctx(txn, request.ns); Collection* collection = ctx.ctx().db()->getCollection(txn, request.ns); PlanExecutor* rawExec; Status getExecStatus = getExecutorCount(txn, collection, request, &rawExec); if (!getExecStatus.isOK()) { return appendCommandStatus(result, getExecStatus); } scoped_ptr<PlanExecutor> exec(rawExec); // Store the plan summary string in CurOp. if (NULL != txn->getCurOp()) { PlanSummaryStats stats; Explain::getSummaryStats(exec.get(), &stats); txn->getCurOp()->debug().planSummary = stats.summaryStr.c_str(); } const ScopedExecutorRegistration safety(exec.get()); Status execPlanStatus = exec->executePlan(); if (!execPlanStatus.isOK()) { return appendCommandStatus(result, execPlanStatus); } // Plan is done executing. We just need to pull the count out of the root stage. invariant(STAGE_COUNT == exec->getRootStage()->stageType()); CountStage* countStage = static_cast<CountStage*>(exec->getRootStage()); const CountStats* countStats = static_cast<const CountStats*>(countStage->getSpecificStats()); result.appendNumber("n", countStats->nCounted); return true; }
long long runCount(OperationContext* txn, const string& ns, const BSONObj &cmd, string &err, int &errCode) { AutoGetCollectionForRead ctx(txn, ns); Collection* collection = ctx.getCollection(); if (NULL == collection) { err = "ns missing"; return -1; } const NamespaceString nss(ns); CountRequest request; CmdCount* countComm = static_cast<CmdCount*>(Command::findCommand("count")); Status parseStatus = countComm->parseRequest(nss.db().toString(), cmd, &request); if (!parseStatus.isOK()) { err = parseStatus.reason(); errCode = parseStatus.code(); return -1; } if (request.query.isEmpty()) { return applySkipLimit(collection->numRecords(txn), cmd); } PlanExecutor* rawExec; Status getExecStatus = getExecutorCount(txn, collection, request, PlanExecutor::YIELD_AUTO, &rawExec); if (!getExecStatus.isOK()) { err = getExecStatus.reason(); errCode = getExecStatus.code(); return -1; } scoped_ptr<PlanExecutor> exec(rawExec); // Store the plan summary string in CurOp. if (NULL != txn->getCurOp()) { txn->getCurOp()->debug().planSummary = Explain::getPlanSummary(exec.get()); } Status execPlanStatus = exec->executePlan(); if (!execPlanStatus.isOK()) { err = execPlanStatus.reason(); errCode = execPlanStatus.code(); return -2; } // Plan is done executing. We just need to pull the count out of the root stage. invariant(STAGE_COUNT == exec->getRootStage()->stageType()); CountStage* countStage = static_cast<CountStage*>(exec->getRootStage()); const CountStats* countStats = static_cast<const CountStats*>(countStage->getSpecificStats()); return countStats->nCounted; }
long long runCount(OperationContext* txn, const string& ns, const BSONObj &cmd, string &err, int &errCode) { // Lock 'ns'. Client::Context cx(txn, ns); Collection* collection = cx.db()->getCollection(txn, ns); const string& dbname = cx.db()->name(); if (NULL == collection) { err = "ns missing"; return -1; } CountRequest request; CmdCount* countComm = static_cast<CmdCount*>(Command::findCommand("count")); Status parseStatus = countComm->parseRequest(dbname, cmd, &request); if (!parseStatus.isOK()) { err = parseStatus.reason(); errCode = parseStatus.code(); return -1; } if (request.query.isEmpty()) { return applySkipLimit(collection->numRecords(txn), cmd); } PlanExecutor* rawExec; Status getExecStatus = getExecutorCount(txn, collection, request, &rawExec); if (!getExecStatus.isOK()) { err = getExecStatus.reason(); errCode = parseStatus.code(); return -1; } scoped_ptr<PlanExecutor> exec(rawExec); // Store the plan summary string in CurOp. if (NULL != txn->getCurOp()) { PlanSummaryStats stats; Explain::getSummaryStats(exec.get(), &stats); txn->getCurOp()->debug().planSummary = stats.summaryStr.c_str(); } const ScopedExecutorRegistration safety(exec.get()); Status execPlanStatus = exec->executePlan(); if (!execPlanStatus.isOK()) { err = execPlanStatus.reason(); errCode = execPlanStatus.code(); return -2; } // Plan is done executing. We just need to pull the count out of the root stage. invariant(STAGE_COUNT == exec->getRootStage()->stageType()); CountStage* countStage = static_cast<CountStage*>(exec->getRootStage()); const CountStats* countStats = static_cast<const CountStats*>(countStage->getSpecificStats()); return countStats->nCounted; }