bool Helpers::findById(Database* database, const char *ns, BSONObj query, BSONObj& result , bool* nsFound , bool* indexFound ) { Lock::assertAtLeastReadLocked(ns); invariant( database ); Collection* collection = database->getCollection( ns ); if ( !collection ) { return false; } if ( nsFound ) *nsFound = true; IndexCatalog* catalog = collection->getIndexCatalog(); const IndexDescriptor* desc = catalog->findIdIndex(); if ( !desc ) return false; if ( indexFound ) *indexFound = 1; // See SERVER-12397. This may not always be true. BtreeBasedAccessMethod* accessMethod = static_cast<BtreeBasedAccessMethod*>(catalog->getIndex( desc )); DiskLoc loc = accessMethod->findSingle( query["_id"].wrap() ); if ( loc.isNull() ) return false; result = collection->docFor( loc ); return true; }
void BtreeBasedBuilder::addKeysToPhaseOne(Collection* collection, IndexDescriptor* idx, const BSONObj& order, SortPhaseOne* phaseOne, ProgressMeter* progressMeter, bool mayInterrupt ) { phaseOne->sortCmp.reset(getComparison(idx->version(), idx->keyPattern())); phaseOne->sorter.reset(new BSONObjExternalSorter(phaseOne->sortCmp.get())); phaseOne->sorter->hintNumObjects( collection->numRecords() ); BtreeBasedAccessMethod* iam =collection->getIndexCatalog()->getBtreeBasedIndex( idx ); auto_ptr<Runner> runner(InternalPlanner::collectionScan(collection->ns().ns())); BSONObj o; DiskLoc loc; Runner::RunnerState state; while (Runner::RUNNER_ADVANCED == (state = runner->getNext(&o, &loc))) { RARELY killCurrentOp.checkForInterrupt( !mayInterrupt ); BSONObjSet keys; iam->getKeys(o, &keys); phaseOne->addKeys(keys, loc, mayInterrupt); progressMeter->hit(); if (logger::globalLogDomain()->shouldLog(logger::LogSeverity::Debug(2)) && phaseOne->n % 10000 == 0 ) { printMemInfo( "\t iterating objects" ); } } uassert(17050, "Internal error reading docs from collection", Runner::RUNNER_EOF == state); }
bool Helpers::findById(Client& c, const char *ns, BSONObj query, BSONObj& result , bool* nsFound , bool* indexFound ) { Lock::assertAtLeastReadLocked(ns); Database *database = c.database(); verify( database ); Collection* collection = database->getCollection( ns ); if ( !collection ) { return false; } if ( nsFound ) *nsFound = true; IndexCatalog* catalog = collection->getIndexCatalog(); const IndexDescriptor* desc = catalog->findIdIndex(); if ( !desc ) return false; if ( indexFound ) *indexFound = 1; BtreeBasedAccessMethod* accessMethod = catalog->getBtreeBasedIndex( desc ); DiskLoc loc = accessMethod->findSingle( query["_id"].wrap() ); if ( loc.isNull() ) return false; result = collection->docFor( loc ); return true; }
DiskLoc Helpers::findById(Collection* collection, const BSONObj& idquery) { verify(collection); IndexCatalog* catalog = collection->getIndexCatalog(); const IndexDescriptor* desc = catalog->findIdIndex(); uassert(13430, "no _id index", desc); BtreeBasedAccessMethod* accessMethod = catalog->getBtreeBasedIndex( desc ); return accessMethod->findSingle( idquery["_id"].wrap() ); }
DiskLoc Helpers::findById(Collection* collection, const BSONObj& idquery) { verify(collection); IndexCatalog* catalog = collection->getIndexCatalog(); const IndexDescriptor* desc = catalog->findIdIndex(); uassert(13430, "no _id index", desc); // See SERVER-12397. This may not always be true. BtreeBasedAccessMethod* accessMethod = static_cast<BtreeBasedAccessMethod*>(catalog->getIndex( desc )); return accessMethod->findSingle( idquery["_id"].wrap() ); }
bool Helpers::findById(OperationContext* txn, Database* database, const char *ns, BSONObj query, BSONObj& result, bool* nsFound, bool* indexFound) { invariant(database); Collection* collection = database->getCollection( ns ); if ( !collection ) { return false; } if ( nsFound ) *nsFound = true; IndexCatalog* catalog = collection->getIndexCatalog(); const IndexDescriptor* desc = catalog->findIdIndex( txn ); if ( !desc ) return false; if ( indexFound ) *indexFound = 1; // See SERVER-12397. This may not always be true. BtreeBasedAccessMethod* accessMethod = static_cast<BtreeBasedAccessMethod*>(catalog->getIndex( desc )); RecordId loc = accessMethod->findSingle( txn, query["_id"].wrap() ); if ( loc.isNull() ) return false; result = collection->docFor(txn, loc).value(); return true; }
Runner::RunnerState IDHackRunner::getNext(BSONObj* objOut, DiskLoc* dlOut) { if (_killed) { return Runner::RUNNER_DEAD; } if (_done) { return Runner::RUNNER_EOF; } // Use the index catalog to get the id index. IndexCatalog* catalog = _collection->getIndexCatalog(); // Find the index we use. const IndexDescriptor* idDesc = catalog->findIdIndex(); if (NULL == idDesc) { _done = true; return Runner::RUNNER_EOF; } BtreeBasedAccessMethod* accessMethod = catalog->getBtreeBasedIndex( idDesc ); BSONObj key = _query->getQueryObj()["_id"].wrap(); // Look up the key by going directly to the Btree. DiskLoc loc = accessMethod->findSingle( key ); _done = true; // Key not found. if (loc.isNull()) { return Runner::RUNNER_EOF; } // Set out parameters and note that we're done w/lookup. if (NULL != objOut) { Record* record = loc.rec(); // If the record isn't in memory... if (!Record::likelyInPhysicalMemory(record->dataNoThrowing())) { // And we're allowed to yield ourselves... if (Runner::YIELD_AUTO == _policy) { // Note what we're yielding to fetch so that we don't crash if the loc is // deleted during a yield. _locFetching = loc; // Yield. TODO: Do we want to bother yielding if micros < 0? int micros = ClientCursor::suggestYieldMicros(); ClientCursor::staticYield(micros, "", record); // This can happen when we're yielded for various reasons (e.g. db/idx dropped). if (_killed) { return Runner::RUNNER_DEAD; } } } // Either the data was in memory or we paged it in. *objOut = loc.obj(); // If we're sharded make sure the key belongs to us. We need the object to do this. if (shardingState.needCollectionMetadata(_query->ns())) { CollectionMetadataPtr m = shardingState.getCollectionMetadata(_query->ns()); if (m) { KeyPattern kp(m->getKeyPattern()); if (!m->keyBelongsToMe( kp.extractSingleKey(*objOut))) { // We have something with a matching _id but it doesn't belong to me. return Runner::RUNNER_EOF; } } } // If there is a projection... if (NULL != _query->getProj()) { // Create something to execute it. auto_ptr<ProjectionExec> projExec(new ProjectionExec(_query->getParsed().getProj(), _query->root())); projExec->transform(*objOut, objOut); } } // Return the DiskLoc if the caller wants it. if (NULL != dlOut) { *dlOut = loc; } return Runner::RUNNER_ADVANCED; }