diff options
Diffstat (limited to 'src/mongo/db/catalog/index_catalog.h')
-rw-r--r-- | src/mongo/db/catalog/index_catalog.h | 481 |
1 files changed, 236 insertions, 245 deletions
diff --git a/src/mongo/db/catalog/index_catalog.h b/src/mongo/db/catalog/index_catalog.h index 6b746fe6fd5..9cb9186a25e 100644 --- a/src/mongo/db/catalog/index_catalog.h +++ b/src/mongo/db/catalog/index_catalog.h @@ -40,318 +40,309 @@ namespace mongo { - class Client; - class Collection; +class Client; +class Collection; - class IndexDescriptor; - class IndexAccessMethod; +class IndexDescriptor; +class IndexAccessMethod; - /** - * how many: 1 per Collection - * lifecycle: attached to a Collection - */ - class IndexCatalog { - public: - IndexCatalog( Collection* collection ); - ~IndexCatalog(); - - // must be called before used - Status init(OperationContext* txn); - - bool ok() const; - - // ---- accessors ----- - - bool haveAnyIndexes() const; - int numIndexesTotal( OperationContext* txn ) const; - int numIndexesReady( OperationContext* txn ) const; - int numIndexesInProgress( OperationContext* txn ) const { - return numIndexesTotal(txn) - numIndexesReady(txn); - } - - /** - * this is in "alive" until the Collection goes away - * in which case everything from this tree has to go away - */ - - bool haveIdIndex( OperationContext* txn ) const; +/** + * how many: 1 per Collection + * lifecycle: attached to a Collection + */ +class IndexCatalog { +public: + IndexCatalog(Collection* collection); + ~IndexCatalog(); - /** - * Returns the spec for the id index to create by default for this collection. - */ - BSONObj getDefaultIdIndexSpec() const; + // must be called before used + Status init(OperationContext* txn); - IndexDescriptor* findIdIndex( OperationContext* txn ) const; + bool ok() const; - /** - * @return null if cannot find - */ - IndexDescriptor* findIndexByName( OperationContext* txn, - StringData name, - bool includeUnfinishedIndexes = false ) const; + // ---- accessors ----- - /** - * @return null if cannot find - */ - IndexDescriptor* findIndexByKeyPattern( OperationContext* txn, - const BSONObj& key, - bool includeUnfinishedIndexes = false ) const; - - /** - * Returns an index suitable for shard key range scans. - * - * This index: - * - must be prefixed by 'shardKey', and - * - must not be a partial index. - * - * If the parameter 'requireSingleKey' is true, then this index additionally must not be - * multi-key. - * - * If no such index exists, returns NULL. - */ - IndexDescriptor* findShardKeyPrefixedIndex( OperationContext* txn, - const BSONObj& shardKey, - bool requireSingleKey ) const; - - void findIndexByType( OperationContext* txn, - const std::string& type, - std::vector<IndexDescriptor*>& matches, - bool includeUnfinishedIndexes = false ) const; + bool haveAnyIndexes() const; + int numIndexesTotal(OperationContext* txn) const; + int numIndexesReady(OperationContext* txn) const; + int numIndexesInProgress(OperationContext* txn) const { + return numIndexesTotal(txn) - numIndexesReady(txn); + } + /** + * this is in "alive" until the Collection goes away + * in which case everything from this tree has to go away + */ - /** - * Reload the index definition for 'oldDesc' from the CollectionCatalogEntry. 'oldDesc' - * must be a ready index that is already registered with the index catalog. Returns an - * unowned pointer to the descriptor for the new index definition. - * - * Use this method to notify the IndexCatalog that the spec for this index has changed. - * - * It is invalid to dereference 'oldDesc' after calling this method. This method broadcasts - * an invalidateAll() on the cursor manager to notify other users of the IndexCatalog that - * this descriptor is now invalid. - */ - const IndexDescriptor* refreshEntry( OperationContext* txn, - const IndexDescriptor* oldDesc ); + bool haveIdIndex(OperationContext* txn) const; - // never returns NULL - const IndexCatalogEntry* getEntry( const IndexDescriptor* desc ) const; + /** + * Returns the spec for the id index to create by default for this collection. + */ + BSONObj getDefaultIdIndexSpec() const; - IndexAccessMethod* getIndex( const IndexDescriptor* desc ); - const IndexAccessMethod* getIndex( const IndexDescriptor* desc ) const; + IndexDescriptor* findIdIndex(OperationContext* txn) const; - /** - * Returns a not-ok Status if there are any unfinished index builds. No new indexes should - * be built when in this state. - */ - Status checkUnfinished() const; - - class IndexIterator { - public: - bool more(); - IndexDescriptor* next(); + /** + * @return null if cannot find + */ + IndexDescriptor* findIndexByName(OperationContext* txn, + StringData name, + bool includeUnfinishedIndexes = false) const; - // returns the access method for the last return IndexDescriptor - IndexAccessMethod* accessMethod( const IndexDescriptor* desc ); + /** + * @return null if cannot find + */ + IndexDescriptor* findIndexByKeyPattern(OperationContext* txn, + const BSONObj& key, + bool includeUnfinishedIndexes = false) const; - // returns the IndexCatalogEntry for the last return IndexDescriptor - IndexCatalogEntry* catalogEntry( const IndexDescriptor* desc ); + /** + * Returns an index suitable for shard key range scans. + * + * This index: + * - must be prefixed by 'shardKey', and + * - must not be a partial index. + * + * If the parameter 'requireSingleKey' is true, then this index additionally must not be + * multi-key. + * + * If no such index exists, returns NULL. + */ + IndexDescriptor* findShardKeyPrefixedIndex(OperationContext* txn, + const BSONObj& shardKey, + bool requireSingleKey) const; - private: - IndexIterator( OperationContext* txn, - const IndexCatalog* cat, - bool includeUnfinishedIndexes ); + void findIndexByType(OperationContext* txn, + const std::string& type, + std::vector<IndexDescriptor*>& matches, + bool includeUnfinishedIndexes = false) const; - void _advance(); - bool _includeUnfinishedIndexes; + /** + * Reload the index definition for 'oldDesc' from the CollectionCatalogEntry. 'oldDesc' + * must be a ready index that is already registered with the index catalog. Returns an + * unowned pointer to the descriptor for the new index definition. + * + * Use this method to notify the IndexCatalog that the spec for this index has changed. + * + * It is invalid to dereference 'oldDesc' after calling this method. This method broadcasts + * an invalidateAll() on the cursor manager to notify other users of the IndexCatalog that + * this descriptor is now invalid. + */ + const IndexDescriptor* refreshEntry(OperationContext* txn, const IndexDescriptor* oldDesc); - OperationContext* const _txn; - const IndexCatalog* _catalog; - IndexCatalogEntryContainer::const_iterator _iterator; + // never returns NULL + const IndexCatalogEntry* getEntry(const IndexDescriptor* desc) const; - bool _start; // only true before we've called next() or more() + IndexAccessMethod* getIndex(const IndexDescriptor* desc); + const IndexAccessMethod* getIndex(const IndexDescriptor* desc) const; - IndexCatalogEntry* _prev; - IndexCatalogEntry* _next; + /** + * Returns a not-ok Status if there are any unfinished index builds. No new indexes should + * be built when in this state. + */ + Status checkUnfinished() const; - friend class IndexCatalog; - }; + class IndexIterator { + public: + bool more(); + IndexDescriptor* next(); - IndexIterator getIndexIterator( OperationContext* txn, - bool includeUnfinishedIndexes ) const { - return IndexIterator( txn, this, includeUnfinishedIndexes ); - }; + // returns the access method for the last return IndexDescriptor + IndexAccessMethod* accessMethod(const IndexDescriptor* desc); - // ---- index set modifiers ------ + // returns the IndexCatalogEntry for the last return IndexDescriptor + IndexCatalogEntry* catalogEntry(const IndexDescriptor* desc); - /** - * Call this only on an empty collection from inside a WriteUnitOfWork. Index creation on an - * empty collection can be rolled back as part of a larger WUOW. - */ - Status createIndexOnEmptyCollection(OperationContext* txn, BSONObj spec); + private: + IndexIterator(OperationContext* txn, + const IndexCatalog* cat, + bool includeUnfinishedIndexes); - StatusWith<BSONObj> prepareSpecForCreate( OperationContext* txn, - const BSONObj& original ) const; + void _advance(); - Status dropAllIndexes(OperationContext* txn, - bool includingIdIndex ); + bool _includeUnfinishedIndexes; - Status dropIndex(OperationContext* txn, - IndexDescriptor* desc ); + OperationContext* const _txn; + const IndexCatalog* _catalog; + IndexCatalogEntryContainer::const_iterator _iterator; - /** - * will drop all incompleted indexes and return specs - * after this, the indexes can be rebuilt - */ - std::vector<BSONObj> getAndClearUnfinishedIndexes(OperationContext* txn); + bool _start; // only true before we've called next() or more() + IndexCatalogEntry* _prev; + IndexCatalogEntry* _next; - struct IndexKillCriteria { - std::string ns; - std::string name; - BSONObj key; - }; + friend class IndexCatalog; + }; - // ---- modify single index + IndexIterator getIndexIterator(OperationContext* txn, bool includeUnfinishedIndexes) const { + return IndexIterator(txn, this, includeUnfinishedIndexes); + }; - bool isMultikey( OperationContext* txn, const IndexDescriptor* idex ); + // ---- index set modifiers ------ - // --- these probably become private? + /** + * Call this only on an empty collection from inside a WriteUnitOfWork. Index creation on an + * empty collection can be rolled back as part of a larger WUOW. + */ + Status createIndexOnEmptyCollection(OperationContext* txn, BSONObj spec); + StatusWith<BSONObj> prepareSpecForCreate(OperationContext* txn, const BSONObj& original) const; - /** - * disk creation order - * 1) system.indexes entry - * 2) collection's NamespaceDetails - * a) info + head - * b) _indexBuildsInProgress++ - * 3) indexes entry in .ns file - * 4) system.namespaces entry for index ns - */ - class IndexBuildBlock { - MONGO_DISALLOW_COPYING(IndexBuildBlock); - public: - IndexBuildBlock(OperationContext* txn, - Collection* collection, - const BSONObj& spec ); + Status dropAllIndexes(OperationContext* txn, bool includingIdIndex); - ~IndexBuildBlock(); + Status dropIndex(OperationContext* txn, IndexDescriptor* desc); - Status init(); + /** + * will drop all incompleted indexes and return specs + * after this, the indexes can be rebuilt + */ + std::vector<BSONObj> getAndClearUnfinishedIndexes(OperationContext* txn); - void success(); - /** - * index build failed, clean up meta data - */ - void fail(); + struct IndexKillCriteria { + std::string ns; + std::string name; + BSONObj key; + }; - IndexCatalogEntry* getEntry() { return _entry; } + // ---- modify single index - private: - Collection* const _collection; - IndexCatalog* const _catalog; - const std::string _ns; + bool isMultikey(OperationContext* txn, const IndexDescriptor* idex); - BSONObj _spec; + // --- these probably become private? - std::string _indexName; - std::string _indexNamespace; - IndexCatalogEntry* _entry; - bool _inProgress; + /** + * disk creation order + * 1) system.indexes entry + * 2) collection's NamespaceDetails + * a) info + head + * b) _indexBuildsInProgress++ + * 3) indexes entry in .ns file + * 4) system.namespaces entry for index ns + */ + class IndexBuildBlock { + MONGO_DISALLOW_COPYING(IndexBuildBlock); - OperationContext* _txn; - }; + public: + IndexBuildBlock(OperationContext* txn, Collection* collection, const BSONObj& spec); - // ----- data modifiers ------ + ~IndexBuildBlock(); - // this throws for now - Status indexRecord(OperationContext* txn, const BSONObj& obj, const RecordId &loc); + Status init(); - void unindexRecord(OperationContext* txn, - const BSONObj& obj, - const RecordId& loc, - bool noWarn); + void success(); - // ------- temp internal ------- + /** + * index build failed, clean up meta data + */ + void fail(); - std::string getAccessMethodName(OperationContext* txn, const BSONObj& keyPattern) { - return _getAccessMethodName( txn, keyPattern ); + IndexCatalogEntry* getEntry() { + return _entry; } - Status _upgradeDatabaseMinorVersionIfNeeded( OperationContext* txn, - const std::string& newPluginName ); + private: + Collection* const _collection; + IndexCatalog* const _catalog; + const std::string _ns; - // public static helpers + BSONObj _spec; - static BSONObj fixIndexKey( const BSONObj& key ); + std::string _indexName; + std::string _indexNamespace; - private: - static const BSONObj _idObj; // { _id : 1 } + IndexCatalogEntry* _entry; + bool _inProgress; - bool _shouldOverridePlugin( OperationContext* txn, const BSONObj& keyPattern ) const; + OperationContext* _txn; + }; - /** - * This differs from IndexNames::findPluginName in that returns the plugin name we *should* - * use, not the plugin name inside of the provided key pattern. To understand when these - * differ, see shouldOverridePlugin. - */ - std::string _getAccessMethodName(OperationContext* txn, const BSONObj& keyPattern) const; + // ----- data modifiers ------ - void _checkMagic() const; + // this throws for now + Status indexRecord(OperationContext* txn, const BSONObj& obj, const RecordId& loc); - Status _indexRecord(OperationContext* txn, - IndexCatalogEntry* index, - const BSONObj& obj, - const RecordId &loc ); + void unindexRecord(OperationContext* txn, const BSONObj& obj, const RecordId& loc, bool noWarn); - Status _unindexRecord(OperationContext* txn, - IndexCatalogEntry* index, - const BSONObj& obj, - const RecordId &loc, - bool logIfError); + // ------- temp internal ------- - /** - * this does no sanity checks - */ - Status _dropIndex(OperationContext* txn, - IndexCatalogEntry* entry ); + std::string getAccessMethodName(OperationContext* txn, const BSONObj& keyPattern) { + return _getAccessMethodName(txn, keyPattern); + } - // just does disk hanges - // doesn't change memory state, etc... - void _deleteIndexFromDisk( OperationContext* txn, - const std::string& indexName, - const std::string& indexNamespace ); + Status _upgradeDatabaseMinorVersionIfNeeded(OperationContext* txn, + const std::string& newPluginName); - // descriptor ownership passes to _setupInMemoryStructures - // initFromDisk: Avoids registering a change to undo this operation when set to true. - // You must set this flag if calling this function outside of a UnitOfWork. - IndexCatalogEntry* _setupInMemoryStructures(OperationContext* txn, - IndexDescriptor* descriptor, - bool initFromDisk); + // public static helpers - // Apply a set of transformations to the user-provided index object 'spec' to make it - // conform to the standard for insertion. This function adds the 'v' field if it didn't - // exist, removes the '_id' field if it exists, applies plugin-level transformations if - // appropriate, etc. - static BSONObj _fixIndexSpec( const BSONObj& spec ); + static BSONObj fixIndexKey(const BSONObj& key); - Status _isSpecOk( const BSONObj& spec ) const; +private: + static const BSONObj _idObj; // { _id : 1 } - Status _doesSpecConflictWithExisting( OperationContext* txn, const BSONObj& spec ) const; + bool _shouldOverridePlugin(OperationContext* txn, const BSONObj& keyPattern) const; - int _magic; - Collection* const _collection; - const int _maxNumIndexesAllowed; + /** + * This differs from IndexNames::findPluginName in that returns the plugin name we *should* + * use, not the plugin name inside of the provided key pattern. To understand when these + * differ, see shouldOverridePlugin. + */ + std::string _getAccessMethodName(OperationContext* txn, const BSONObj& keyPattern) const; - IndexCatalogEntryContainer _entries; + void _checkMagic() const; - // These are the index specs of indexes that were "leftover". - // "Leftover" means they were unfinished when a mongod shut down. - // Certain operations are prohibited until someone fixes. - // Retrieve by calling getAndClearUnfinishedIndexes(). - std::vector<BSONObj> _unfinishedIndexes; - }; + Status _indexRecord(OperationContext* txn, + IndexCatalogEntry* index, + const BSONObj& obj, + const RecordId& loc); + + Status _unindexRecord(OperationContext* txn, + IndexCatalogEntry* index, + const BSONObj& obj, + const RecordId& loc, + bool logIfError); + /** + * this does no sanity checks + */ + Status _dropIndex(OperationContext* txn, IndexCatalogEntry* entry); + + // just does disk hanges + // doesn't change memory state, etc... + void _deleteIndexFromDisk(OperationContext* txn, + const std::string& indexName, + const std::string& indexNamespace); + + // descriptor ownership passes to _setupInMemoryStructures + // initFromDisk: Avoids registering a change to undo this operation when set to true. + // You must set this flag if calling this function outside of a UnitOfWork. + IndexCatalogEntry* _setupInMemoryStructures(OperationContext* txn, + IndexDescriptor* descriptor, + bool initFromDisk); + + // Apply a set of transformations to the user-provided index object 'spec' to make it + // conform to the standard for insertion. This function adds the 'v' field if it didn't + // exist, removes the '_id' field if it exists, applies plugin-level transformations if + // appropriate, etc. + static BSONObj _fixIndexSpec(const BSONObj& spec); + + Status _isSpecOk(const BSONObj& spec) const; + + Status _doesSpecConflictWithExisting(OperationContext* txn, const BSONObj& spec) const; + + int _magic; + Collection* const _collection; + const int _maxNumIndexesAllowed; + + IndexCatalogEntryContainer _entries; + + // These are the index specs of indexes that were "leftover". + // "Leftover" means they were unfinished when a mongod shut down. + // Certain operations are prohibited until someone fixes. + // Retrieve by calling getAndClearUnfinishedIndexes(). + std::vector<BSONObj> _unfinishedIndexes; +}; } |