summaryrefslogtreecommitdiff
path: root/src/mongo/db/catalog/index_catalog.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/db/catalog/index_catalog.h')
-rw-r--r--src/mongo/db/catalog/index_catalog.h481
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;
+};
}