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