diff options
author | Divjot Arora <divjot.arora@10gen.com> | 2019-03-04 12:03:47 -0500 |
---|---|---|
committer | Divjot Arora <divjot.arora@10gen.com> | 2019-03-07 16:07:56 -0500 |
commit | f386c49be72744d88fbb0950c54d6621a9d242b8 (patch) | |
tree | 667898972de2a58ea65cdf0d35969756682fa67d /src | |
parent | c6f1019c261b5bde912e720605ce7f74f3113270 (diff) | |
download | mongo-f386c49be72744d88fbb0950c54d6621a9d242b8.tar.gz |
SERVER-39505 Make ViewCatalog a decoration on Database.
Diffstat (limited to 'src')
23 files changed, 77 insertions, 59 deletions
diff --git a/src/mongo/db/catalog/capped_utils.cpp b/src/mongo/db/catalog/capped_utils.cpp index 5c7b0fe4a60..48d10844bf8 100644 --- a/src/mongo/db/catalog/capped_utils.cpp +++ b/src/mongo/db/catalog/capped_utils.cpp @@ -51,6 +51,7 @@ #include "mongo/db/query/plan_yield_policy.h" #include "mongo/db/repl/replication_coordinator.h" #include "mongo/db/service_context.h" +#include "mongo/db/views/view_catalog.h" #include "mongo/util/scopeguard.h" namespace mongo { @@ -73,7 +74,7 @@ Status emptyCapped(OperationContext* opCtx, const NamespaceString& collectionNam Collection* collection = db->getCollection(opCtx, collectionName); uassert(ErrorCodes::CommandNotSupportedOnView, str::stream() << "emptycapped not supported on view: " << collectionName.ns(), - collection || !db->getViewCatalog()->lookup(opCtx, collectionName.ns())); + collection || !ViewCatalog::get(db)->lookup(opCtx, collectionName.ns())); uassert(ErrorCodes::NamespaceNotFound, "no such collection", collection); if (collectionName.isSystem() && !collectionName.isSystemDotProfile()) { @@ -124,7 +125,7 @@ void cloneCollectionAsCapped(OperationContext* opCtx, if (!fromCollection) { uassert(ErrorCodes::CommandNotSupportedOnView, str::stream() << "cloneCollectionAsCapped not supported for views: " << fromNss, - !db->getViewCatalog()->lookup(opCtx, fromNss.ns())); + !ViewCatalog::get(db)->lookup(opCtx, fromNss.ns())); uasserted(ErrorCodes::NamespaceNotFound, str::stream() << "source collection " << fromNss << " does not exist"); diff --git a/src/mongo/db/catalog/coll_mod.cpp b/src/mongo/db/catalog/coll_mod.cpp index d85562aa593..b28a7bbccdb 100644 --- a/src/mongo/db/catalog/coll_mod.cpp +++ b/src/mongo/db/catalog/coll_mod.cpp @@ -309,7 +309,7 @@ Status _collModInternal(OperationContext* opCtx, // May also modify a view instead of a collection. boost::optional<ViewDefinition> view; if (db && !coll) { - const auto sharedView = db->getViewCatalog()->lookup(opCtx, nss.ns()); + const auto sharedView = ViewCatalog::get(db)->lookup(opCtx, nss.ns()); if (sharedView) { // We copy the ViewDefinition as it is modified below to represent the requested state. view = {*sharedView}; @@ -355,7 +355,7 @@ Status _collModInternal(OperationContext* opCtx, if (!cmr.viewOn.empty()) view->setViewOn(NamespaceString(dbName, cmr.viewOn)); - ViewCatalog* catalog = db->getViewCatalog(); + ViewCatalog* catalog = ViewCatalog::get(db); BSONArrayBuilder pipeline; for (auto& item : view->pipeline()) { diff --git a/src/mongo/db/catalog/database.h b/src/mongo/db/catalog/database.h index 5848b816e16..30648c41bd9 100644 --- a/src/mongo/db/catalog/database.h +++ b/src/mongo/db/catalog/database.h @@ -39,7 +39,6 @@ #include "mongo/db/catalog/collection_options.h" #include "mongo/db/namespace_string.h" #include "mongo/db/repl/optime.h" -#include "mongo/db/views/view_catalog.h" #include "mongo/util/string_map.h" namespace mongo { @@ -204,12 +203,6 @@ public: virtual Collection* getCollection(OperationContext* opCtx, const NamespaceString& ns) const = 0; - /** - * Get the view catalog, which holds the definition for all views created on this database. You - * must be holding a database lock to use this accessor. - */ - virtual ViewCatalog* getViewCatalog() = 0; - virtual Collection* getOrCreateCollection(OperationContext* const opCtx, const NamespaceString& nss) = 0; diff --git a/src/mongo/db/catalog/database_impl.cpp b/src/mongo/db/catalog/database_impl.cpp index f3f0f1505a5..b8b445649b5 100644 --- a/src/mongo/db/catalog/database_impl.cpp +++ b/src/mongo/db/catalog/database_impl.cpp @@ -263,9 +263,12 @@ DatabaseImpl::DatabaseImpl(const StringData name, _dbEntry(dbEntry), _epoch(epoch), _profileName(_name + ".system.profile"), - _viewsName(_name + "." + DurableViewCatalog::viewsCollectionName().toString()), - _durableViews(DurableViewCatalogImpl(this)), - _views(&_durableViews) {} + _viewsName(_name + "." + DurableViewCatalog::viewsCollectionName().toString()) { + auto durableViewCatalog = std::make_unique<DurableViewCatalogImpl>(this); + auto viewCatalog = std::make_unique<ViewCatalog>(std::move(durableViewCatalog)); + + ViewCatalog::set(this, std::move(viewCatalog)); +} void DatabaseImpl::init(OperationContext* const opCtx) { Status status = validateDBName(_name); @@ -289,8 +292,9 @@ void DatabaseImpl::init(OperationContext* const opCtx) { // system.views collection would be found. Now we're sufficiently initialized, signal a version // change. Also force a reload, so if there are problems with the catalog contents as might be // caused by incorrect mongod versions or similar, they are found right away. - _views.invalidate(); - Status reloadStatus = _views.reloadIfNeeded(opCtx); + auto views = ViewCatalog::get(this); + views->invalidate(); + Status reloadStatus = views->reloadIfNeeded(opCtx); if (!reloadStatus.isOK()) { warning() << "Unable to parse views: " << redact(reloadStatus) @@ -417,7 +421,7 @@ void DatabaseImpl::getStats(OperationContext* opCtx, BSONObjBuilder* output, dou indexSize += collection->getIndexSize(opCtx); } - getViewCatalog()->iterate(opCtx, [&](const ViewDefinition& view) { nViews += 1; }); + ViewCatalog::get(this)->iterate(opCtx, [&](const ViewDefinition& view) { nViews += 1; }); output->appendNumber("collections", nCollections); output->appendNumber("views", nViews); @@ -449,7 +453,8 @@ void DatabaseImpl::getStats(OperationContext* opCtx, BSONObjBuilder* output, dou } Status DatabaseImpl::dropView(OperationContext* opCtx, StringData fullns) { - Status status = _views.dropView(opCtx, NamespaceString(fullns)); + auto views = ViewCatalog::get(this); + Status status = views->dropView(opCtx, NamespaceString(fullns)); Top::get(opCtx->getServiceContext()).collectionDropped(fullns); return status; } @@ -785,7 +790,8 @@ Status DatabaseImpl::createView(OperationContext* opCtx, return Status(ErrorCodes::InvalidNamespace, str::stream() << "invalid namespace name for a view: " + nss.toString()); - return _views.createView(opCtx, nss, viewOnNss, BSONArray(options.pipeline), options.collation); + auto views = ViewCatalog::get(this); + return views->createView(opCtx, nss, viewOnNss, BSONArray(options.pipeline), options.collation); } Collection* DatabaseImpl::createCollection(OperationContext* opCtx, @@ -1010,7 +1016,7 @@ Status DatabaseImpl::userCreateNS(OperationContext* opCtx, return Status(ErrorCodes::NamespaceExists, str::stream() << "a collection '" << fullns << "' already exists"); - if (getViewCatalog()->lookup(opCtx, fullns.ns())) + if (ViewCatalog::get(this)->lookup(opCtx, fullns.ns())) return Status(ErrorCodes::NamespaceExists, str::stream() << "a view '" << fullns << "' already exists"); diff --git a/src/mongo/db/catalog/database_impl.h b/src/mongo/db/catalog/database_impl.h index b5ee0179b3a..31e04fb8476 100644 --- a/src/mongo/db/catalog/database_impl.h +++ b/src/mongo/db/catalog/database_impl.h @@ -116,14 +116,6 @@ public: Collection* getCollection(OperationContext* opCtx, const NamespaceString& ns) const; - /** - * Get the view catalog, which holds the definition for all views created on this database. You - * must be holding a database lock to use this accessor. - */ - ViewCatalog* getViewCatalog() final { - return &_views; - } - Collection* getOrCreateCollection(OperationContext* opCtx, const NamespaceString& nss) final; /** @@ -223,9 +215,6 @@ private: std::unique_ptr<PseudoRandom> _uniqueCollectionNamespacePseudoRandom; CollectionMap _collections; - - DurableViewCatalogImpl _durableViews; // interface for system.views operations - ViewCatalog _views; // in-memory representation of _durableViews }; } // namespace mongo diff --git a/src/mongo/db/catalog/drop_collection.cpp b/src/mongo/db/catalog/drop_collection.cpp index 36058648978..594328bddfd 100644 --- a/src/mongo/db/catalog/drop_collection.cpp +++ b/src/mongo/db/catalog/drop_collection.cpp @@ -65,7 +65,7 @@ Status dropCollection(OperationContext* opCtx, Database* const db = autoDb.getDb(); Collection* coll = db ? db->getCollection(opCtx, collectionName) : nullptr; auto view = - db && !coll ? db->getViewCatalog()->lookup(opCtx, collectionName.ns()) : nullptr; + db && !coll ? ViewCatalog::get(db)->lookup(opCtx, collectionName.ns()) : nullptr; if (MONGO_FAIL_POINT(hangDuringDropCollection)) { log() << "hangDuringDropCollection fail point enabled. Blocking until fail point is " diff --git a/src/mongo/db/catalog/drop_indexes.cpp b/src/mongo/db/catalog/drop_indexes.cpp index 4be12c0d674..03b21ef9801 100644 --- a/src/mongo/db/catalog/drop_indexes.cpp +++ b/src/mongo/db/catalog/drop_indexes.cpp @@ -44,6 +44,7 @@ #include "mongo/db/op_observer.h" #include "mongo/db/repl/replication_coordinator.h" #include "mongo/db/service_context.h" +#include "mongo/db/views/view_catalog.h" #include "mongo/util/log.h" namespace mongo { @@ -217,7 +218,7 @@ Status dropIndexes(OperationContext* opCtx, Database* db = autoDb.getDb(); Collection* collection = db ? db->getCollection(opCtx, nss) : nullptr; if (!db || !collection) { - if (db && db->getViewCatalog()->lookup(opCtx, nss.ns())) { + if (db && ViewCatalog::get(db)->lookup(opCtx, nss.ns())) { return Status(ErrorCodes::CommandNotSupportedOnView, str::stream() << "Cannot drop indexes on view " << nss); } diff --git a/src/mongo/db/catalog/rename_collection.cpp b/src/mongo/db/catalog/rename_collection.cpp index 88f9898ddfd..01dffe8848a 100644 --- a/src/mongo/db/catalog/rename_collection.cpp +++ b/src/mongo/db/catalog/rename_collection.cpp @@ -55,6 +55,7 @@ #include "mongo/db/s/database_sharding_state.h" #include "mongo/db/server_options.h" #include "mongo/db/service_context.h" +#include "mongo/db/views/view_catalog.h" #include "mongo/util/fail_point_service.h" #include "mongo/util/log.h" #include "mongo/util/scopeguard.h" @@ -165,7 +166,7 @@ Status renameCollectionCommon(OperationContext* opCtx, } Collection* const sourceColl = sourceDB ? sourceDB->getCollection(opCtx, source) : nullptr; if (!sourceColl) { - if (sourceDB && sourceDB->getViewCatalog()->lookup(opCtx, source.ns())) + if (sourceDB && ViewCatalog::get(sourceDB)->lookup(opCtx, source.ns())) return Status(ErrorCodes::CommandNotSupportedOnView, str::stream() << "cannot rename view: " << source); return Status(ErrorCodes::NamespaceNotFound, "source namespace does not exist"); @@ -239,7 +240,7 @@ Status renameCollectionCommon(OperationContext* opCtx, return status; targetColl = nullptr; } - } else if (targetDB->getViewCatalog()->lookup(opCtx, target.ns())) { + } else if (ViewCatalog::get(targetDB)->lookup(opCtx, target.ns())) { return Status(ErrorCodes::NamespaceExists, str::stream() << "a view already exists with that name: " << target); } diff --git a/src/mongo/db/catalog_raii.cpp b/src/mongo/db/catalog_raii.cpp index a9a77a5e7e2..b3fafde57a8 100644 --- a/src/mongo/db/catalog_raii.cpp +++ b/src/mongo/db/catalog_raii.cpp @@ -34,6 +34,7 @@ #include "mongo/db/catalog/database_holder.h" #include "mongo/db/catalog/uuid_catalog.h" #include "mongo/db/s/database_sharding_state.h" +#include "mongo/db/views/view_catalog.h" #include "mongo/util/fail_point_service.h" namespace mongo { @@ -131,7 +132,7 @@ AutoGetCollection::AutoGetCollection(OperationContext* opCtx, return; } - _view = db->getViewCatalog()->lookup(opCtx, _resolvedNss.ns()); + _view = ViewCatalog::get(db)->lookup(opCtx, _resolvedNss.ns()); uassert(ErrorCodes::CommandNotSupportedOnView, str::stream() << "Namespace " << _resolvedNss.ns() << " is a view, not a collection", !_view || viewMode == kViewsPermitted); diff --git a/src/mongo/db/commands/compact.cpp b/src/mongo/db/commands/compact.cpp index 9ba9bf1b797..8e74b1d8e46 100644 --- a/src/mongo/db/commands/compact.cpp +++ b/src/mongo/db/commands/compact.cpp @@ -46,6 +46,7 @@ #include "mongo/db/index_builder.h" #include "mongo/db/jsobj.h" #include "mongo/db/repl/replication_coordinator.h" +#include "mongo/db/views/view_catalog.h" #include "mongo/util/log.h" namespace mongo { @@ -121,7 +122,7 @@ public: Collection* collection = collDB ? collDB->getCollection(opCtx, nss) : nullptr; auto view = - collDB && !collection ? collDB->getViewCatalog()->lookup(opCtx, nss.ns()) : nullptr; + collDB && !collection ? ViewCatalog::get(collDB)->lookup(opCtx, nss.ns()) : nullptr; // If db/collection does not exist, short circuit and return. if (!collDB || !collection) { diff --git a/src/mongo/db/commands/create_indexes.cpp b/src/mongo/db/commands/create_indexes.cpp index 3ef74df70ef..5700ad537a1 100644 --- a/src/mongo/db/commands/create_indexes.cpp +++ b/src/mongo/db/commands/create_indexes.cpp @@ -305,7 +305,7 @@ bool runCreateIndexes(OperationContext* opCtx, if (collection) { result.appendBool("createdCollectionAutomatically", false); } else { - if (db->getViewCatalog()->lookup(opCtx, ns.ns())) { + if (ViewCatalog::get(db)->lookup(opCtx, ns.ns())) { errmsg = "Cannot create indexes on a view"; uasserted(ErrorCodes::CommandNotSupportedOnView, errmsg); } @@ -562,7 +562,7 @@ bool runCreateIndexesWithCoordinator(OperationContext* opCtx, // We would not reach this point if we were able to check existing indexes on the // collection. invariant(!collection); - if (db->getViewCatalog()->lookup(opCtx, ns.ns())) { + if (ViewCatalog::get(db)->lookup(opCtx, ns.ns())) { errmsg = str::stream() << "Cannot create indexes on a view: " << ns.ns(); uasserted(ErrorCodes::CommandNotSupportedOnView, errmsg); } diff --git a/src/mongo/db/commands/drop_indexes.cpp b/src/mongo/db/commands/drop_indexes.cpp index e25258e7fb6..3d189e8472a 100644 --- a/src/mongo/db/commands/drop_indexes.cpp +++ b/src/mongo/db/commands/drop_indexes.cpp @@ -52,6 +52,7 @@ #include "mongo/db/logical_clock.h" #include "mongo/db/op_observer.h" #include "mongo/db/service_context.h" +#include "mongo/db/views/view_catalog.h" #include "mongo/util/log.h" namespace mongo { @@ -134,7 +135,7 @@ public: Collection* collection = autoDb.getDb()->getCollection(opCtx, toReIndexNss); if (!collection) { - if (autoDb.getDb()->getViewCatalog()->lookup(opCtx, toReIndexNss.ns())) + if (ViewCatalog::get(autoDb.getDb())->lookup(opCtx, toReIndexNss.ns())) uasserted(ErrorCodes::CommandNotSupportedOnView, "can't re-index a view"); else uasserted(ErrorCodes::NamespaceNotFound, "collection does not exist"); diff --git a/src/mongo/db/commands/list_collections.cpp b/src/mongo/db/commands/list_collections.cpp index 4c7784f447a..854d0a32722 100644 --- a/src/mongo/db/commands/list_collections.cpp +++ b/src/mongo/db/commands/list_collections.cpp @@ -342,7 +342,7 @@ public: SimpleBSONObjComparator::kInstance.evaluate( filterElt.Obj() == ListCollectionsFilter::makeTypeCollectionFilter()); if (!skipViews) { - db->getViewCatalog()->iterate(opCtx, [&](const ViewDefinition& view) { + ViewCatalog::get(db)->iterate(opCtx, [&](const ViewDefinition& view) { BSONObj viewBson = buildViewBson(view, nameOnly); if (!viewBson.isEmpty()) { _addWorkingSetMember( diff --git a/src/mongo/db/commands/run_aggregate.cpp b/src/mongo/db/commands/run_aggregate.cpp index d2bd92e3036..f371ef7b1a0 100644 --- a/src/mongo/db/commands/run_aggregate.cpp +++ b/src/mongo/db/commands/run_aggregate.cpp @@ -230,7 +230,7 @@ StatusWith<StringMap<ExpressionContext::ResolvedNamespace>> resolveInvolvedNames // 'resolvedNamespaces' because we won't re-resolve a view namespace we've already encountered. AutoGetDb autoDb(opCtx, request.getNamespaceString().db(), MODE_IS); Database* const db = autoDb.getDb(); - ViewCatalog* viewCatalog = db ? db->getViewCatalog() : nullptr; + ViewCatalog* viewCatalog = db ? ViewCatalog::get(db) : nullptr; std::deque<NamespaceString> involvedNamespacesQueue(pipelineInvolvedNamespaces.begin(), pipelineInvolvedNamespaces.end()); @@ -304,7 +304,7 @@ Status collatorCompatibleWithPipeline(OperationContext* opCtx, continue; } - auto view = db->getViewCatalog()->lookup(opCtx, potentialViewNs.ns()); + auto view = ViewCatalog::get(db)->lookup(opCtx, potentialViewNs.ns()); if (!view) { continue; } @@ -504,7 +504,7 @@ Status runAggregate(OperationContext* opCtx, } auto resolvedView = - uassertStatusOK(ctx->getDb()->getViewCatalog()->resolveView(opCtx, nss)); + uassertStatusOK(ViewCatalog::get(ctx->getDb())->resolveView(opCtx, nss)); uassert(std::move(resolvedView), "On sharded systems, resolved views must be executed by mongos", !ShardingState::get(opCtx)->enabled()); diff --git a/src/mongo/db/commands/validate.cpp b/src/mongo/db/commands/validate.cpp index 941f970deff..4ba5ca75025 100644 --- a/src/mongo/db/commands/validate.cpp +++ b/src/mongo/db/commands/validate.cpp @@ -38,6 +38,7 @@ #include "mongo/db/db_raii.h" #include "mongo/db/query/internal_plans.h" #include "mongo/db/storage/record_store.h" +#include "mongo/db/views/view_catalog.h" #include "mongo/util/fail_point_service.h" #include "mongo/util/log.h" #include "mongo/util/scopeguard.h" @@ -125,7 +126,7 @@ public: auto collLk = stdx::make_unique<Lock::CollectionLock>(opCtx->lockState(), nss.ns(), MODE_X); Collection* collection = ctx.getDb() ? ctx.getDb()->getCollection(opCtx, nss) : NULL; if (!collection) { - if (ctx.getDb() && ctx.getDb()->getViewCatalog()->lookup(opCtx, nss.ns())) { + if (ctx.getDb() && ViewCatalog::get(ctx.getDb())->lookup(opCtx, nss.ns())) { uasserted(ErrorCodes::CommandNotSupportedOnView, "Cannot validate a view"); } diff --git a/src/mongo/db/query/find.cpp b/src/mongo/db/query/find.cpp index a4e02a58f47..5072509ffc3 100644 --- a/src/mongo/db/query/find.cpp +++ b/src/mongo/db/query/find.cpp @@ -59,6 +59,7 @@ #include "mongo/db/service_context.h" #include "mongo/db/stats/top.h" #include "mongo/db/storage/storage_options.h" +#include "mongo/db/views/view_catalog.h" #include "mongo/s/chunk_version.h" #include "mongo/s/stale_exception.h" #include "mongo/stdx/memory.h" @@ -296,7 +297,7 @@ Message getMore(OperationContext* opCtx, Top::LockType::NotLocked, AutoStatsTracker::LogMode::kUpdateTopAndCurop, profilingLevel); - auto view = autoDb.getDb() ? autoDb.getDb()->getViewCatalog()->lookup(opCtx, nss.ns()) + auto view = autoDb.getDb() ? ViewCatalog::get(autoDb.getDb())->lookup(opCtx, nss.ns()) : nullptr; uassert( ErrorCodes::CommandNotSupportedOnView, diff --git a/src/mongo/db/repl/do_txn.cpp b/src/mongo/db/repl/do_txn.cpp index 8cf1ea35f32..fe1ce92052c 100644 --- a/src/mongo/db/repl/do_txn.cpp +++ b/src/mongo/db/repl/do_txn.cpp @@ -52,6 +52,7 @@ #include "mongo/db/repl/replication_coordinator.h" #include "mongo/db/service_context.h" #include "mongo/db/transaction_participant.h" +#include "mongo/db/views/view_catalog.h" #include "mongo/rpc/get_status_from_command_result.h" #include "mongo/util/fail_point_service.h" #include "mongo/util/log.h" @@ -147,7 +148,7 @@ Status _doTxn(OperationContext* opCtx, // implicitly created on upserts. We detect both cases here and fail early with // NamespaceNotFound. // Additionally for inserts, we fail early on non-existent collections. - if (!collection && db->getViewCatalog()->lookup(opCtx, nss.ns())) { + if (!collection && ViewCatalog::get(db)->lookup(opCtx, nss.ns())) { uasserted(ErrorCodes::CommandNotSupportedOnView, str::stream() << "doTxn not supported on a view: " << redact(opObj)); } diff --git a/src/mongo/db/repl/oplog.cpp b/src/mongo/db/repl/oplog.cpp index 6838330d601..b588d7f0adc 100644 --- a/src/mongo/db/repl/oplog.cpp +++ b/src/mongo/db/repl/oplog.cpp @@ -86,6 +86,7 @@ #include "mongo/db/storage/storage_engine.h" #include "mongo/db/storage/storage_options.h" #include "mongo/db/transaction_participant.h" +#include "mongo/db/views/view_catalog.h" #include "mongo/platform/random.h" #include "mongo/scripting/engine.h" #include "mongo/stdx/memory.h" @@ -1469,7 +1470,7 @@ Status applyOperation_inlock(OperationContext* opCtx, const bool haveWrappingWriteUnitOfWork = opCtx->lockState()->inAWriteUnitOfWork(); uassert(ErrorCodes::CommandNotSupportedOnView, str::stream() << "applyOps not supported on view: " << requestNss.ns(), - collection || !db->getViewCatalog()->lookup(opCtx, requestNss.ns())); + collection || !ViewCatalog::get(db)->lookup(opCtx, requestNss.ns())); // This code must decide what timestamp the storage engine should make the upcoming writes // visible with. The requirements and use-cases: @@ -1884,7 +1885,7 @@ Status applyCommand_inlock(OperationContext* opCtx, Lock::DBLock lock(opCtx, nss.db(), MODE_IS); auto databaseHolder = DatabaseHolder::get(opCtx); auto db = databaseHolder->getDb(opCtx, nss.ns()); - if (db && !db->getCollection(opCtx, nss) && db->getViewCatalog()->lookup(opCtx, nss.ns())) { + if (db && !db->getCollection(opCtx, nss) && ViewCatalog::get(db)->lookup(opCtx, nss.ns())) { return {ErrorCodes::CommandNotSupportedOnView, str::stream() << "applyOps not supported on view:" << nss.ns()}; } diff --git a/src/mongo/db/s/set_shard_version_command.cpp b/src/mongo/db/s/set_shard_version_command.cpp index 3e98c1e7088..2be706a5428 100644 --- a/src/mongo/db/s/set_shard_version_command.cpp +++ b/src/mongo/db/s/set_shard_version_command.cpp @@ -46,6 +46,7 @@ #include "mongo/db/s/shard_filtering_metadata_refresh.h" #include "mongo/db/s/sharded_connection_info.h" #include "mongo/db/s/sharding_state.h" +#include "mongo/db/views/view_catalog.h" #include "mongo/s/client/shard_registry.h" #include "mongo/s/grid.h" #include "mongo/s/request_types/set_shard_version_request.h" @@ -223,7 +224,7 @@ public: // Views do not require a shard version check. if (autoDb->getDb() && !autoDb->getDb()->getCollection(opCtx, nss) && - autoDb->getDb()->getViewCatalog()->lookup(opCtx, nss.ns())) { + ViewCatalog::get(autoDb->getDb())->lookup(opCtx, nss.ns())) { return true; } diff --git a/src/mongo/db/views/durable_view_catalog.cpp b/src/mongo/db/views/durable_view_catalog.cpp index e0f829b3922..24a23b928e9 100644 --- a/src/mongo/db/views/durable_view_catalog.cpp +++ b/src/mongo/db/views/durable_view_catalog.cpp @@ -44,6 +44,7 @@ #include "mongo/db/namespace_string.h" #include "mongo/db/operation_context.h" #include "mongo/db/storage/record_data.h" +#include "mongo/db/views/view_catalog.h" #include "mongo/stdx/unordered_set.h" #include "mongo/util/assert_util.h" #include "mongo/util/log.h" @@ -59,7 +60,7 @@ void DurableViewCatalog::onExternalChange(OperationContext* opCtx, const Namespa auto db = databaseHolder->getDb(opCtx, name.db()); if (db) { opCtx->recoveryUnit()->onCommit( - [db](boost::optional<Timestamp>) { db->getViewCatalog()->invalidate(); }); + [db](boost::optional<Timestamp>) { ViewCatalog::get(db)->invalidate(); }); } } diff --git a/src/mongo/db/views/view_catalog.cpp b/src/mongo/db/views/view_catalog.cpp index 55b23bc09ef..08dba9ada81 100644 --- a/src/mongo/db/views/view_catalog.cpp +++ b/src/mongo/db/views/view_catalog.cpp @@ -39,6 +39,7 @@ #include "mongo/base/status_with.h" #include "mongo/base/string_data.h" #include "mongo/bson/util/builder.h" +#include "mongo/db/catalog/database.h" #include "mongo/db/commands/feature_compatibility_version_command_parser.h" #include "mongo/db/namespace_string.h" #include "mongo/db/operation_context.h" @@ -57,7 +58,9 @@ #include "mongo/util/log.h" namespace mongo { + namespace { +auto getViewCatalog = Database::declareDecoration<std::unique_ptr<ViewCatalog>>(); StatusWith<std::unique_ptr<CollatorInterface>> parseCollator(OperationContext* opCtx, BSONObj collationSpec) { @@ -70,6 +73,14 @@ StatusWith<std::unique_ptr<CollatorInterface>> parseCollator(OperationContext* o } } // namespace +ViewCatalog* ViewCatalog::get(Database* db) { + return getViewCatalog(db).get(); +} + +void ViewCatalog::set(Database* db, std::unique_ptr<ViewCatalog> catalog) { + getViewCatalog(db) = std::move(catalog); +} + Status ViewCatalog::reloadIfNeeded(OperationContext* opCtx) { stdx::lock_guard<stdx::mutex> lk(_mutex); return _reloadIfNeeded(lk, opCtx); diff --git a/src/mongo/db/views/view_catalog.h b/src/mongo/db/views/view_catalog.h index ce0e84d7731..b2d13f97a26 100644 --- a/src/mongo/db/views/view_catalog.h +++ b/src/mongo/db/views/view_catalog.h @@ -50,6 +50,7 @@ namespace mongo { class OperationContext; +class Database; /** * In-memory data structure for view definitions. This data structure is thread-safe -- this is @@ -65,7 +66,11 @@ public: using ViewMap = StringMap<std::shared_ptr<ViewDefinition>>; using ViewIteratorCallback = stdx::function<void(const ViewDefinition& view)>; - explicit ViewCatalog(DurableViewCatalog* durable) : _durable(durable) {} + static ViewCatalog* get(Database* db); + static void set(Database* db, std::unique_ptr<ViewCatalog> catalog); + + explicit ViewCatalog(std::unique_ptr<DurableViewCatalog> durable) + : _durable(std::move(durable)) {} /** * Iterates through the catalog, applying 'callback' to each view. This callback function @@ -176,7 +181,7 @@ private: stdx::mutex _mutex; // Protects all members, except for _valid. ViewMap _viewMap; - DurableViewCatalog* _durable; + std::unique_ptr<DurableViewCatalog> _durable; AtomicWord<bool> _valid; ViewGraph _viewGraph; bool _viewGraphNeedsRefresh = true; // Defers initializing the graph until the first insert. diff --git a/src/mongo/db/views/view_catalog_test.cpp b/src/mongo/db/views/view_catalog_test.cpp index 5a705433e72..c005c2ff8ef 100644 --- a/src/mongo/db/views/view_catalog_test.cpp +++ b/src/mongo/db/views/view_catalog_test.cpp @@ -111,7 +111,7 @@ public: ViewCatalogFixture() : _queryServiceContext(stdx::make_unique<QueryTestServiceContext>()), opCtx(_queryServiceContext->makeOperationContext()), - viewCatalog(&durableViewCatalog) {} + viewCatalog(std::move(durableViewCatalogUnique)) {} private: std::unique_ptr<QueryTestServiceContext> _queryServiceContext; @@ -121,7 +121,9 @@ protected: return _queryServiceContext->getServiceContext(); } - DurableViewCatalogDummy durableViewCatalog; + std::unique_ptr<DurableViewCatalogDummy> durableViewCatalogUnique = + std::make_unique<DurableViewCatalogDummy>(); + DurableViewCatalogDummy* durableViewCatalog = durableViewCatalogUnique.get(); ServiceContext::UniqueOperationContext opCtx; ViewCatalog viewCatalog; const BSONArray emptyPipeline; @@ -469,7 +471,7 @@ TEST_F(ViewCatalogFixture, ModifyTenTimes) { ASSERT_OK(viewCatalog.modifyView(opCtx.get(), viewName, viewOn, emptyPipeline)); } - ASSERT_EQ(10, durableViewCatalog.getUpsertCount()); + ASSERT_EQ(10, durableViewCatalog->getUpsertCount()); } TEST_F(ViewCatalogFixture, Iterate) { @@ -567,14 +569,14 @@ TEST_F(ViewCatalogFixture, InvalidateThenReload) { const NamespaceString viewOn("db.coll"); ASSERT_OK(viewCatalog.createView(opCtx.get(), viewName, viewOn, emptyPipeline, emptyCollation)); - ASSERT_EQ(1, durableViewCatalog.getIterateCount()); + ASSERT_EQ(1, durableViewCatalog->getIterateCount()); ASSERT(viewCatalog.lookup(opCtx.get(), "db.view"_sd)); - ASSERT_EQ(1, durableViewCatalog.getIterateCount()); + ASSERT_EQ(1, durableViewCatalog->getIterateCount()); viewCatalog.invalidate(); ASSERT_OK(viewCatalog.reloadIfNeeded(opCtx.get())); - ASSERT_EQ(2, durableViewCatalog.getIterateCount()); + ASSERT_EQ(2, durableViewCatalog->getIterateCount()); } } // namespace } // namespace mongo |