summaryrefslogtreecommitdiff
path: root/src/mongo/db/catalog/collection_info_cache.h
diff options
context:
space:
mode:
authorADAM David Alan Martin <adam.martin@10gen.com>2017-04-20 15:58:20 -0400
committerADAM David Alan Martin <adam.martin@10gen.com>2017-04-20 15:59:53 -0400
commit7e6025227bfbf41d6ac1ad90ef985dcb7afe668f (patch)
tree39ddf930efdffc0ea1b289eeaa8b81b91da015bd /src/mongo/db/catalog/collection_info_cache.h
parent47b98a643bc1844cf7a3cc9362748f125efa875c (diff)
downloadmongo-7e6025227bfbf41d6ac1ad90ef985dcb7afe668f.tar.gz
SERVER-28832 Slice `catalog/collection_info_cache`
The `CollectionInfoCache` class is used outside of the catalog library in many places. This change slices that dependency by providing an initializable vtable based pimpl class. This should permit a further reduction in the number of cyclic dependencies in the graph.
Diffstat (limited to 'src/mongo/db/catalog/collection_info_cache.h')
-rw-r--r--src/mongo/db/catalog/collection_info_cache.h193
1 files changed, 120 insertions, 73 deletions
diff --git a/src/mongo/db/catalog/collection_info_cache.h b/src/mongo/db/catalog/collection_info_cache.h
index b198cdf6eda..9bc07e80c61 100644
--- a/src/mongo/db/catalog/collection_info_cache.h
+++ b/src/mongo/db/catalog/collection_info_cache.h
@@ -1,30 +1,30 @@
/**
-* Copyright (C) 2013 10gen Inc.
-*
-* This program is free software: you can redistribute it and/or modify
-* it under the terms of the GNU Affero General Public License, version 3,
-* as published by the Free Software Foundation.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU Affero General Public License for more details.
-*
-* You should have received a copy of the GNU Affero General Public License
-* along with this program. If not, see <http://www.gnu.org/licenses/>.
-*
-* As a special exception, the copyright holders give permission to link the
-* code of portions of this program with the OpenSSL library under certain
-* conditions as described in each individual source file and distribute
-* linked combinations including the program with the OpenSSL library. You
-* must comply with the GNU Affero General Public License in all respects for
-* all of the code used other than as permitted herein. If you modify file(s)
-* with this exception, you may extend this exception to your version of the
-* file(s), but you are not obligated to do so. If you do not wish to do so,
-* delete this exception statement from your version. If you delete this
-* exception statement from all source files in the program, then also delete
-* it in the license file.
-*/
+ * Copyright (C) 2017 10gen Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * As a special exception, the copyright holders give permission to link the
+ * code of portions of this program with the OpenSSL library under certain
+ * conditions as described in each individual source file and distribute
+ * linked combinations including the program with the OpenSSL library. You
+ * must comply with the GNU Affero General Public License in all respects for
+ * all of the code used other than as permitted herein. If you modify file(s)
+ * with this exception, you may extend this exception to your version of the
+ * file(s), but you are not obligated to do so. If you do not wish to do so,
+ * delete this exception statement from your version. If you delete this
+ * exception statement from all source files in the program, then also delete
+ * it in the license file.
+ */
#pragma once
@@ -32,37 +32,83 @@
#include "mongo/db/query/plan_cache.h"
#include "mongo/db/query/query_settings.h"
#include "mongo/db/update_index_data.h"
+#include "mongo/stdx/functional.h"
namespace mongo {
-
class Collection;
class IndexDescriptor;
class OperationContext;
/**
* this is for storing things that you want to cache about a single collection
- * life cycle is managed for you from inside Collection
+ * life cycle is managed for you from inside Collection.
*/
class CollectionInfoCache {
public:
- explicit CollectionInfoCache(Collection* collection, const NamespaceString& ns);
+ class Impl {
+ public:
+ virtual ~Impl() = 0;
+
+ virtual PlanCache* getPlanCache() const = 0;
+
+ virtual QuerySettings* getQuerySettings() const = 0;
+
+ virtual const UpdateIndexData& getIndexKeys(OperationContext* opCtx) const = 0;
+
+ virtual CollectionIndexUsageMap getIndexUsageStats() const = 0;
+
+ virtual void init(OperationContext* opCtx) = 0;
+
+ virtual void addedIndex(OperationContext* opCtx, const IndexDescriptor* desc) = 0;
+
+ virtual void droppedIndex(OperationContext* opCtx, StringData indexName) = 0;
+
+ virtual void clearQueryCache() = 0;
+
+ virtual void notifyOfQuery(OperationContext* opCtx,
+ const std::set<std::string>& indexesUsed) = 0;
+ };
+
+private:
+ static std::unique_ptr<Impl> makeImpl(Collection* collection, const NamespaceString& ns);
+
+public:
+ using factory_function_type = decltype(makeImpl);
+
+ static void registerFactory(stdx::function<factory_function_type> factory);
- ~CollectionInfoCache();
+ explicit inline CollectionInfoCache(Collection* const collection, const NamespaceString& ns)
+ : _pimpl(makeImpl(collection, ns)) {}
+
+ inline ~CollectionInfoCache() = default;
+
+ /**
+ * Builds internal cache state based on the current state of the Collection's IndexCatalog.
+ */
+ inline void init(OperationContext* const opCtx) {
+ return this->_impl().init(opCtx);
+ }
/**
* Get the PlanCache for this collection.
*/
- PlanCache* getPlanCache() const;
+ inline PlanCache* getPlanCache() const {
+ return this->_impl().getPlanCache();
+ }
/**
* Get the QuerySettings for this collection.
*/
- QuerySettings* getQuerySettings() const;
+ inline QuerySettings* getQuerySettings() const {
+ return this->_impl().getQuerySettings();
+ }
/* get set of index keys for this namespace. handy to quickly check if a given
field is indexed (Note it might be a secondary component of a compound index.)
*/
- const UpdateIndexData& getIndexKeys(OperationContext* opCtx) const;
+ inline const UpdateIndexData& getIndexKeys(OperationContext* const opCtx) const {
+ return this->_impl().getIndexKeys(opCtx);
+ }
/**
* Returns cached index usage statistics for this collection. The map returned will contain
@@ -71,12 +117,9 @@ public:
*
* Note for performance that this method returns a copy of a StringMap.
*/
- CollectionIndexUsageMap getIndexUsageStats() const;
-
- /**
- * Builds internal cache state based on the current state of the Collection's IndexCatalog
- */
- void init(OperationContext* opCtx);
+ inline CollectionIndexUsageMap getIndexUsageStats() const {
+ return this->_impl().getIndexUsageStats();
+ }
/**
* Register a newly-created index with the cache. Must be called whenever an index is
@@ -84,7 +127,9 @@ public:
*
* Must be called under exclusive collection lock.
*/
- void addedIndex(OperationContext* opCtx, const IndexDescriptor* desc);
+ inline void addedIndex(OperationContext* const opCtx, const IndexDescriptor* const desc) {
+ return this->_impl().addedIndex(opCtx, desc);
+ }
/**
* Deregister a newly-dropped index with the cache. Must be called whenever an index is
@@ -92,47 +137,49 @@ public:
*
* Must be called under exclusive collection lock.
*/
- void droppedIndex(OperationContext* opCtx, StringData indexName);
+ inline void droppedIndex(OperationContext* const opCtx, const StringData indexName) {
+ return this->_impl().droppedIndex(opCtx, indexName);
+ }
/**
* Removes all cached query plans.
*/
- void clearQueryCache();
+ inline void clearQueryCache() {
+ return this->_impl().clearQueryCache();
+ }
/**
* Signal to the cache that a query operation has completed. 'indexesUsed' should list the
* set of indexes used by the winning plan, if any.
*/
- void notifyOfQuery(OperationContext* opCtx, const std::set<std::string>& indexesUsed);
-
-private:
- void computeIndexKeys(OperationContext* opCtx);
- void updatePlanCacheIndexEntries(OperationContext* opCtx);
-
- /**
- * Rebuilds cached information that is dependent on index composition. Must be called
- * when index composition changes.
- */
- void rebuildIndexData(OperationContext* opCtx);
-
- Collection* _collection; // not owned
- const NamespaceString _ns;
-
- // --- index keys cache
- bool _keysComputed;
- UpdateIndexData _indexedPaths;
-
- // A cache for query plans.
- std::unique_ptr<PlanCache> _planCache;
-
- // Query settings.
- // Includes index filters.
- std::unique_ptr<QuerySettings> _querySettings;
-
- // Tracks index usage statistics for this collection.
- CollectionIndexUsageTracker _indexUsageTracker;
-
- bool _hasTTLIndex = false;
+ inline void notifyOfQuery(OperationContext* const opCtx,
+ const std::set<std::string>& indexesUsed) {
+ return this->_impl().notifyOfQuery(opCtx, indexesUsed);
+ }
+
+ std::unique_ptr<Impl> _pimpl;
+
+ // This structure exists to give us a customization point to decide how to force users of this
+ // class to depend upon the corresponding `collection_info_cache.cpp` Translation Unit (TU).
+ // All public forwarding functions call `_impl(), and `_impl` creates an instance of this
+ // structure.
+ struct TUHook {
+ static void hook() noexcept;
+
+ explicit inline TUHook() noexcept {
+ if (kDebugBuild)
+ this->hook();
+ }
+ };
+
+ inline const Impl& _impl() const {
+ TUHook{};
+ return *this->_pimpl;
+ }
+
+ inline Impl& _impl() {
+ TUHook{};
+ return *this->_pimpl;
+ }
};
-
} // namespace mongo