RecordStoreV1Base* MMAPV1DatabaseCatalogEntry::_getIndexRecordStore( OperationContext* txn ) {
     NamespaceString nss( name(), "system.indexes" );
     RecordStoreV1Base* rs = _getRecordStore( txn, nss.ns() );
     if ( rs != NULL )
         return rs;
     CollectionOptions options;
     Status status = createCollection( txn, nss.ns(), options, true );
     massertStatusOK( status );
     rs = _getRecordStore( txn, nss.ns() );
     invariant( rs );
     return rs;
 }
Exemplo n.º 2
0
    RecordStoreV1Base* MMAP1DatabaseCatalogEntry::_getNamespaceRecordStore( OperationContext* txn,
                                                                            const StringData& whosAsking) {
        NamespaceString nss( _name, "system.namespaces" );
        if ( nss == whosAsking )
            return NULL;
        RecordStoreV1Base* rs = _getRecordStore( txn, nss.ns() );
        if ( rs != NULL )
            return rs;
        CollectionOptions options;
        Status status = createCollection( txn, nss.ns(), options, true );
        massertStatusOK( status );
        rs = _getRecordStore( txn, nss.ns() );
        invariant( rs );
        return rs;

    }
    IndexAccessMethod* MMAPV1DatabaseCatalogEntry::getIndex( OperationContext* txn,
                                                            const CollectionCatalogEntry* collection,
                                                            IndexCatalogEntry* entry ) {
        const string& type = entry->descriptor()->getAccessMethodName();

        string ns = collection->ns().ns();

        if ( IndexNames::TEXT == type ||
             entry->descriptor()->getInfoElement("expireAfterSeconds").isNumber() ) {
            NamespaceDetailsRSV1MetaData md( ns,
                                             _namespaceIndex.details( ns ),
                                             _getNamespaceRecordStore( txn, ns ) );
            md.setUserFlag( txn, NamespaceDetails::Flag_UsePowerOf2Sizes );
        }

        RecordStore* rs = _getRecordStore( txn, entry->descriptor()->indexNamespace() );
        invariant( rs );

        std::auto_ptr<BtreeInterface> btree(
            BtreeInterface::getInterface(entry->headManager(),
                                         rs,
                                         entry->ordering(),
                                         entry->descriptor()->indexNamespace(),
                                         entry->descriptor()->version(),
                                         &BtreeBasedAccessMethod::invalidateCursors));

        if (IndexNames::HASHED == type)
            return new HashAccessMethod( entry, btree.release() );

        if (IndexNames::GEO_2DSPHERE == type)
            return new S2AccessMethod( entry, btree.release() );

        if (IndexNames::TEXT == type)
            return new FTSAccessMethod( entry, btree.release() );

        if (IndexNames::GEO_HAYSTACK == type)
            return new HaystackAccessMethod( entry, btree.release() );

        if ("" == type)
            return new BtreeAccessMethod( entry, btree.release() );

        if (IndexNames::GEO_2D == type)
            return new TwoDAccessMethod( entry, btree.release() );

        log() << "Can't find index for keyPattern " << entry->descriptor()->keyPattern();
        fassertFailed(17489);
    }
 RecordStore* MMAPV1DatabaseCatalogEntry::getRecordStore( OperationContext* txn,
                                                         const StringData& ns ) {
     return _getRecordStore( txn, ns );
 }
    Status MMAPV1DatabaseCatalogEntry::createCollection( OperationContext* txn,
                                                        const StringData& ns,
                                                        const CollectionOptions& options,
                                                        bool allocateDefaultSpace ) {
        _namespaceIndex.init( txn );

        if ( _namespaceIndex.details( ns ) ) {
            return Status( ErrorCodes::NamespaceExists,
                           str::stream() << "namespace already exists: " << ns );
        }

        BSONObj optionsAsBSON = options.toBSON();
        _addNamespaceToNamespaceCollection( txn, ns, &optionsAsBSON );

        _namespaceIndex.add_ns( txn, ns, DiskLoc(), options.capped );

        // allocation strategy set explicitly in flags or by server-wide default
        if ( !options.capped ) {
            NamespaceDetailsRSV1MetaData md( ns,
                                             _namespaceIndex.details( ns ),
                                             _getNamespaceRecordStore( txn, ns ) );

            if ( options.flagsSet ) {
                md.setUserFlag( txn, options.flags );
            }
            else if ( newCollectionsUsePowerOf2Sizes ) {
                md.setUserFlag( txn, NamespaceDetails::Flag_UsePowerOf2Sizes );
            }
        }
        else if ( options.cappedMaxDocs > 0 ) {
            txn->recoveryUnit()->writingInt( _namespaceIndex.details( ns )->maxDocsInCapped ) =
                options.cappedMaxDocs;
        }

        if ( allocateDefaultSpace ) {
            scoped_ptr<RecordStoreV1Base> rs( _getRecordStore( txn, ns ) );
            if ( options.initialNumExtents > 0 ) {
                int size = _massageExtentSize( &_extentManager, options.cappedSize );
                for ( int i = 0; i < options.initialNumExtents; i++ ) {
                    rs->increaseStorageSize( txn, size, -1 );
                }
            }
            else if ( !options.initialExtentSizes.empty() ) {
                for ( size_t i = 0; i < options.initialExtentSizes.size(); i++ ) {
                    int size = options.initialExtentSizes[i];
                    size = _massageExtentSize( &_extentManager, size );
                    rs->increaseStorageSize( txn, size, -1 );
                }
            }
            else if ( options.capped ) {
                // normal
                do {
                    // Must do this at least once, otherwise we leave the collection with no
                    // extents, which is invalid.
                    int sz = _massageExtentSize( &_extentManager,
                                                 options.cappedSize - rs->storageSize() );
                    sz &= 0xffffff00;
                    rs->increaseStorageSize( txn, sz, -1 );
                } while( rs->storageSize() < options.cappedSize );
            }
            else {
                rs->increaseStorageSize( txn, _extentManager.initialSize( 128 ), -1 );
            }
        }

        return Status::OK();
    }