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() ); }
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; }