예제 #1
0
    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;
    }
예제 #2
0
 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() );
 }
예제 #3
0
    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;
    }