summaryrefslogtreecommitdiff
path: root/src/mongo/db
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/db')
-rw-r--r--src/mongo/db/auth/auth_op_observer.cpp2
-rw-r--r--src/mongo/db/auth/auth_op_observer.h2
-rw-r--r--src/mongo/db/catalog/capped_utils.cpp6
-rw-r--r--src/mongo/db/catalog/capped_utils_test.cpp3
-rw-r--r--src/mongo/db/catalog/coll_mod.cpp2
-rw-r--r--src/mongo/db/catalog/coll_mod.h1
-rw-r--r--src/mongo/db/catalog/collection.cpp57
-rw-r--r--src/mongo/db/catalog/collection.h84
-rw-r--r--src/mongo/db/catalog/collection_catalog.cpp52
-rw-r--r--src/mongo/db/catalog/collection_catalog.h26
-rw-r--r--src/mongo/db/catalog/collection_catalog_helper.cpp5
-rw-r--r--src/mongo/db/catalog/collection_catalog_helper.h1
-rw-r--r--src/mongo/db/catalog/collection_catalog_test.cpp74
-rw-r--r--src/mongo/db/catalog/collection_compact.cpp11
-rw-r--r--src/mongo/db/catalog/collection_impl.cpp21
-rw-r--r--src/mongo/db/catalog/collection_impl.h1
-rw-r--r--src/mongo/db/catalog/collection_mock.h1
-rw-r--r--src/mongo/db/catalog/collection_test.cpp18
-rw-r--r--src/mongo/db/catalog/collection_validation.cpp2
-rw-r--r--src/mongo/db/catalog/collection_validation.h1
-rw-r--r--src/mongo/db/catalog/collection_validation_test.cpp6
-rw-r--r--src/mongo/db/catalog/create_collection.cpp4
-rw-r--r--src/mongo/db/catalog/create_collection_test.cpp3
-rw-r--r--src/mongo/db/catalog/database_impl.cpp12
-rw-r--r--src/mongo/db/catalog/database_impl.h6
-rw-r--r--src/mongo/db/catalog/drop_collection.cpp15
-rw-r--r--src/mongo/db/catalog/drop_indexes.cpp8
-rw-r--r--src/mongo/db/catalog/index_build_block.cpp2
-rw-r--r--src/mongo/db/catalog/index_build_block.h3
-rw-r--r--src/mongo/db/catalog/index_builds_manager.cpp16
-rw-r--r--src/mongo/db/catalog/index_builds_manager.h18
-rw-r--r--src/mongo/db/catalog/index_catalog.h9
-rw-r--r--src/mongo/db/catalog/index_catalog_entry.h3
-rw-r--r--src/mongo/db/catalog/index_catalog_entry_impl.cpp6
-rw-r--r--src/mongo/db/catalog/index_catalog_entry_impl.h6
-rw-r--r--src/mongo/db/catalog/index_catalog_impl.cpp18
-rw-r--r--src/mongo/db/catalog/index_catalog_impl.h19
-rw-r--r--src/mongo/db/catalog/index_catalog_noop.h8
-rw-r--r--src/mongo/db/catalog/index_signature_test.cpp2
-rw-r--r--src/mongo/db/catalog/list_indexes.cpp13
-rw-r--r--src/mongo/db/catalog/list_indexes.h2
-rw-r--r--src/mongo/db/catalog/multi_index_block.cpp32
-rw-r--r--src/mongo/db/catalog/multi_index_block.h26
-rw-r--r--src/mongo/db/catalog/rename_collection.cpp17
-rw-r--r--src/mongo/db/catalog/rename_collection_test.cpp31
-rw-r--r--src/mongo/db/catalog/throttle_cursor_test.cpp21
-rw-r--r--src/mongo/db/catalog/validate_adaptor.cpp2
-rw-r--r--src/mongo/db/catalog/validate_state.cpp4
-rw-r--r--src/mongo/db/catalog/validate_state.h4
-rw-r--r--src/mongo/db/catalog/validate_state_test.cpp15
-rw-r--r--src/mongo/db/catalog_raii.cpp73
-rw-r--r--src/mongo/db/catalog_raii.h56
-rw-r--r--src/mongo/db/client.h1
-rw-r--r--src/mongo/db/clientcursor.h1
-rw-r--r--src/mongo/db/cloner.cpp4
-rw-r--r--src/mongo/db/commands/count_cmd.cpp4
-rw-r--r--src/mongo/db/commands/create_indexes.cpp10
-rw-r--r--src/mongo/db/commands/dbcheck.cpp2
-rw-r--r--src/mongo/db/commands/dbcommands.cpp7
-rw-r--r--src/mongo/db/commands/dbcommands_d.cpp4
-rw-r--r--src/mongo/db/commands/dbhash.cpp70
-rw-r--r--src/mongo/db/commands/distinct.cpp4
-rw-r--r--src/mongo/db/commands/find_and_modify.cpp61
-rw-r--r--src/mongo/db/commands/find_cmd.cpp4
-rw-r--r--src/mongo/db/commands/getmore_cmd.cpp4
-rw-r--r--src/mongo/db/commands/haystack.cpp4
-rw-r--r--src/mongo/db/commands/index_filter_commands.cpp4
-rw-r--r--src/mongo/db/commands/list_collections.cpp6
-rw-r--r--src/mongo/db/commands/list_indexes.cpp12
-rw-r--r--src/mongo/db/commands/mr_test.cpp4
-rw-r--r--src/mongo/db/commands/plan_cache_clear_command.cpp2
-rw-r--r--src/mongo/db/commands/run_aggregate.cpp4
-rw-r--r--src/mongo/db/commands/test_commands.cpp2
-rw-r--r--src/mongo/db/concurrency/deferred_writer.cpp4
-rw-r--r--src/mongo/db/db_raii.cpp2
-rw-r--r--src/mongo/db/db_raii.h20
-rw-r--r--src/mongo/db/db_raii_test.cpp2
-rw-r--r--src/mongo/db/dbhelpers.cpp25
-rw-r--r--src/mongo/db/dbhelpers.h9
-rw-r--r--src/mongo/db/exec/cached_plan.cpp2
-rw-r--r--src/mongo/db/exec/cached_plan.h2
-rw-r--r--src/mongo/db/exec/collection_scan.cpp2
-rw-r--r--src/mongo/db/exec/collection_scan.h2
-rw-r--r--src/mongo/db/exec/collection_scan_common.h2
-rw-r--r--src/mongo/db/exec/count.cpp2
-rw-r--r--src/mongo/db/exec/count.h2
-rw-r--r--src/mongo/db/exec/count_scan.cpp2
-rw-r--r--src/mongo/db/exec/count_scan.h2
-rw-r--r--src/mongo/db/exec/delete.cpp2
-rw-r--r--src/mongo/db/exec/delete.h2
-rw-r--r--src/mongo/db/exec/distinct_scan.cpp2
-rw-r--r--src/mongo/db/exec/distinct_scan.h2
-rw-r--r--src/mongo/db/exec/fetch.cpp2
-rw-r--r--src/mongo/db/exec/fetch.h2
-rw-r--r--src/mongo/db/exec/geo_near.cpp14
-rw-r--r--src/mongo/db/exec/geo_near.h16
-rw-r--r--src/mongo/db/exec/idhack.cpp4
-rw-r--r--src/mongo/db/exec/idhack.h4
-rw-r--r--src/mongo/db/exec/index_scan.cpp2
-rw-r--r--src/mongo/db/exec/index_scan.h2
-rw-r--r--src/mongo/db/exec/multi_iterator.cpp2
-rw-r--r--src/mongo/db/exec/multi_iterator.h2
-rw-r--r--src/mongo/db/exec/multi_plan.cpp2
-rw-r--r--src/mongo/db/exec/multi_plan.h2
-rw-r--r--src/mongo/db/exec/near.cpp2
-rw-r--r--src/mongo/db/exec/near.h4
-rw-r--r--src/mongo/db/exec/plan_cache_util.h2
-rw-r--r--src/mongo/db/exec/plan_stage.h1
-rw-r--r--src/mongo/db/exec/record_store_fast_count.cpp2
-rw-r--r--src/mongo/db/exec/record_store_fast_count.h2
-rw-r--r--src/mongo/db/exec/requires_all_indices_stage.h2
-rw-r--r--src/mongo/db/exec/requires_collection_stage.cpp5
-rw-r--r--src/mongo/db/exec/requires_collection_stage.h8
-rw-r--r--src/mongo/db/exec/requires_index_stage.cpp2
-rw-r--r--src/mongo/db/exec/requires_index_stage.h4
-rw-r--r--src/mongo/db/exec/sbe/parser/parser.cpp15
-rw-r--r--src/mongo/db/exec/sbe/stages/ix_scan.cpp2
-rw-r--r--src/mongo/db/exec/sbe/stages/scan.cpp4
-rw-r--r--src/mongo/db/exec/sbe/stages/scan.h2
-rw-r--r--src/mongo/db/exec/sort_key_generator.h1
-rw-r--r--src/mongo/db/exec/stagedebug_cmd.cpp6
-rw-r--r--src/mongo/db/exec/subplan.cpp2
-rw-r--r--src/mongo/db/exec/subplan.h2
-rw-r--r--src/mongo/db/exec/text.cpp4
-rw-r--r--src/mongo/db/exec/text.h4
-rw-r--r--src/mongo/db/exec/text_or.cpp2
-rw-r--r--src/mongo/db/exec/text_or.h2
-rw-r--r--src/mongo/db/exec/trial_period_utils.cpp4
-rw-r--r--src/mongo/db/exec/trial_period_utils.h3
-rw-r--r--src/mongo/db/exec/update_stage.cpp4
-rw-r--r--src/mongo/db/exec/update_stage.h4
-rw-r--r--src/mongo/db/exec/upsert_stage.cpp2
-rw-r--r--src/mongo/db/exec/upsert_stage.h2
-rw-r--r--src/mongo/db/exec/write_stage_common.cpp2
-rw-r--r--src/mongo/db/exec/write_stage_common.h3
-rw-r--r--src/mongo/db/fcv_op_observer.h2
-rw-r--r--src/mongo/db/free_mon/free_mon_op_observer.h2
-rw-r--r--src/mongo/db/index/haystack_access_method.h1
-rw-r--r--src/mongo/db/index/haystack_access_method_internal.h4
-rw-r--r--src/mongo/db/index/index_access_method.cpp10
-rw-r--r--src/mongo/db/index/index_access_method.h20
-rw-r--r--src/mongo/db/index/index_build_interceptor.cpp6
-rw-r--r--src/mongo/db/index/index_build_interceptor.h6
-rw-r--r--src/mongo/db/index/index_descriptor.cpp2
-rw-r--r--src/mongo/db/index/index_descriptor.h3
-rw-r--r--src/mongo/db/index/skipped_record_tracker.cpp2
-rw-r--r--src/mongo/db/index/skipped_record_tracker.h2
-rw-r--r--src/mongo/db/index_build_entry_helpers.cpp33
-rw-r--r--src/mongo/db/index_builds_coordinator.cpp40
-rw-r--r--src/mongo/db/index_builds_coordinator.h14
-rw-r--r--src/mongo/db/index_builds_coordinator_mongod.cpp3
-rw-r--r--src/mongo/db/introspect.cpp5
-rw-r--r--src/mongo/db/matcher/expression_text.cpp2
-rw-r--r--src/mongo/db/mongod_main.cpp2
-rw-r--r--src/mongo/db/op_observer.h2
-rw-r--r--src/mongo/db/op_observer_impl.cpp5
-rw-r--r--src/mongo/db/op_observer_impl.h2
-rw-r--r--src/mongo/db/op_observer_noop.h2
-rw-r--r--src/mongo/db/op_observer_registry.h2
-rw-r--r--src/mongo/db/ops/delete.cpp2
-rw-r--r--src/mongo/db/ops/delete.h2
-rw-r--r--src/mongo/db/ops/update.cpp2
-rw-r--r--src/mongo/db/ops/write_ops_exec.cpp10
-rw-r--r--src/mongo/db/pipeline/document_source_cursor.cpp6
-rw-r--r--src/mongo/db/pipeline/document_source_cursor.h4
-rw-r--r--src/mongo/db/pipeline/document_source_geo_near_cursor.cpp4
-rw-r--r--src/mongo/db/pipeline/document_source_geo_near_cursor.h4
-rw-r--r--src/mongo/db/pipeline/pipeline_d.cpp25
-rw-r--r--src/mongo/db/pipeline/pipeline_d.h17
-rw-r--r--src/mongo/db/pipeline/plan_executor_pipeline.h2
-rw-r--r--src/mongo/db/pipeline/process_interface/common_mongod_process_interface.cpp19
-rw-r--r--src/mongo/db/pipeline/process_interface/non_shardsvr_process_interface.cpp2
-rw-r--r--src/mongo/db/query/classic_stage_builder.h2
-rw-r--r--src/mongo/db/query/collection_query_info.cpp16
-rw-r--r--src/mongo/db/query/collection_query_info.h27
-rw-r--r--src/mongo/db/query/explain.cpp11
-rw-r--r--src/mongo/db/query/explain.h7
-rw-r--r--src/mongo/db/query/find.cpp28
-rw-r--r--src/mongo/db/query/find.h4
-rw-r--r--src/mongo/db/query/get_executor.cpp46
-rw-r--r--src/mongo/db/query/get_executor.h19
-rw-r--r--src/mongo/db/query/internal_plans.cpp16
-rw-r--r--src/mongo/db/query/internal_plans.h15
-rw-r--r--src/mongo/db/query/plan_executor.h2
-rw-r--r--src/mongo/db/query/plan_executor_factory.cpp10
-rw-r--r--src/mongo/db/query/plan_executor_factory.h10
-rw-r--r--src/mongo/db/query/plan_executor_impl.cpp21
-rw-r--r--src/mongo/db/query/plan_executor_impl.h6
-rw-r--r--src/mongo/db/query/plan_executor_sbe.cpp4
-rw-r--r--src/mongo/db/query/plan_executor_sbe.h4
-rw-r--r--src/mongo/db/query/plan_yield_policy.h6
-rw-r--r--src/mongo/db/query/plan_yield_policy_impl.cpp21
-rw-r--r--src/mongo/db/query/plan_yield_policy_impl.h10
-rw-r--r--src/mongo/db/query/planner_analysis.h1
-rw-r--r--src/mongo/db/query/query_planner.cpp2
-rw-r--r--src/mongo/db/query/query_planner.h3
-rw-r--r--src/mongo/db/query/sbe_cached_solution_planner.h2
-rw-r--r--src/mongo/db/query/sbe_multi_planner.h2
-rw-r--r--src/mongo/db/query/sbe_runtime_planner.cpp1
-rw-r--r--src/mongo/db/query/sbe_runtime_planner.h4
-rw-r--r--src/mongo/db/query/sbe_stage_builder.h2
-rw-r--r--src/mongo/db/query/sbe_stage_builder_coll_scan.cpp12
-rw-r--r--src/mongo/db/query/sbe_stage_builder_coll_scan.h2
-rw-r--r--src/mongo/db/query/sbe_stage_builder_index_scan.cpp10
-rw-r--r--src/mongo/db/query/sbe_stage_builder_index_scan.h4
-rw-r--r--src/mongo/db/query/sbe_sub_planner.h2
-rw-r--r--src/mongo/db/query/stage_builder.h4
-rw-r--r--src/mongo/db/query/stage_builder_util.cpp4
-rw-r--r--src/mongo/db/query/stage_builder_util.h4
-rw-r--r--src/mongo/db/rebuild_indexes.cpp2
-rw-r--r--src/mongo/db/rebuild_indexes.h5
-rw-r--r--src/mongo/db/repair.cpp2
-rw-r--r--src/mongo/db/repl/SConscript1
-rw-r--r--src/mongo/db/repl/apply_ops.cpp2
-rw-r--r--src/mongo/db/repl/collection_bulk_loader.h1
-rw-r--r--src/mongo/db/repl/dbcheck.cpp13
-rw-r--r--src/mongo/db/repl/dbcheck.h21
-rw-r--r--src/mongo/db/repl/idempotency_test_fixture.cpp12
-rw-r--r--src/mongo/db/repl/idempotency_test_fixture.h3
-rw-r--r--src/mongo/db/repl/local_oplog_info.cpp8
-rw-r--r--src/mongo/db/repl/local_oplog_info.h6
-rw-r--r--src/mongo/db/repl/mock_repl_coord_server_fixture.cpp5
-rw-r--r--src/mongo/db/repl/oplog.cpp14
-rw-r--r--src/mongo/db/repl/oplog.h3
-rw-r--r--src/mongo/db/repl/oplog_applier_impl_test.cpp2
-rw-r--r--src/mongo/db/repl/oplog_applier_impl_test_fixture.cpp2
-rw-r--r--src/mongo/db/repl/oplog_applier_impl_test_fixture.h4
-rw-r--r--src/mongo/db/repl/primary_only_service_op_observer.h2
-rw-r--r--src/mongo/db/repl/replication_coordinator_external_state_impl.cpp3
-rw-r--r--src/mongo/db/repl/replication_coordinator_impl.cpp4
-rw-r--r--src/mongo/db/repl/rollback_impl.cpp6
-rw-r--r--src/mongo/db/repl/rollback_test_fixture.cpp19
-rw-r--r--src/mongo/db/repl/rs_rollback.cpp6
-rw-r--r--src/mongo/db/repl/rs_rollback_test.cpp16
-rw-r--r--src/mongo/db/repl/storage_interface.h5
-rw-r--r--src/mongo/db/repl/storage_interface_impl.cpp54
-rw-r--r--src/mongo/db/repl/storage_interface_impl.h4
-rw-r--r--src/mongo/db/repl/storage_interface_impl_test.cpp6
-rw-r--r--src/mongo/db/repl/storage_interface_mock.h4
-rw-r--r--src/mongo/db/repl/tenant_migration_donor_op_observer.h2
-rw-r--r--src/mongo/db/repl/tenant_migration_recipient_entry_helpers.cpp18
-rw-r--r--src/mongo/db/repl/tenant_oplog_applier_test.cpp4
-rw-r--r--src/mongo/db/s/check_sharding_index_command.cpp3
-rw-r--r--src/mongo/db/s/config/sharding_catalog_manager_config_initialization_test.cpp3
-rw-r--r--src/mongo/db/s/config_server_op_observer.h2
-rw-r--r--src/mongo/db/s/migration_chunk_cloner_source_legacy.cpp16
-rw-r--r--src/mongo/db/s/migration_chunk_cloner_source_legacy.h9
-rw-r--r--src/mongo/db/s/migration_chunk_cloner_source_legacy_commands.cpp2
-rw-r--r--src/mongo/db/s/migration_destination_manager.cpp12
-rw-r--r--src/mongo/db/s/migration_util.cpp2
-rw-r--r--src/mongo/db/s/range_deletion_util.cpp27
-rw-r--r--src/mongo/db/s/resharding/resharding_op_observer.h2
-rw-r--r--src/mongo/db/s/resharding_util.cpp2
-rw-r--r--src/mongo/db/s/shard_local.cpp4
-rw-r--r--src/mongo/db/s/shard_server_op_observer.cpp2
-rw-r--r--src/mongo/db/s/shard_server_op_observer.h2
-rw-r--r--src/mongo/db/s/shardsvr_shard_collection.cpp2
-rw-r--r--src/mongo/db/s/split_chunk.cpp10
-rw-r--r--src/mongo/db/s/split_vector.cpp9
-rw-r--r--src/mongo/db/session_catalog_mongod.cpp3
-rw-r--r--src/mongo/db/startup_recovery.cpp6
-rw-r--r--src/mongo/db/stats/storage_stats.cpp7
-rw-r--r--src/mongo/db/storage/oplog_cap_maintainer_thread.cpp2
-rw-r--r--src/mongo/db/storage/record_store.h1
-rw-r--r--src/mongo/db/storage/storage_engine_impl.cpp2
-rw-r--r--src/mongo/db/storage/storage_engine_test_fixture.h6
-rw-r--r--src/mongo/db/storage/wiredtiger/oplog_stones_server_status_section.cpp2
-rw-r--r--src/mongo/db/system_index.cpp2
-rw-r--r--src/mongo/db/system_index.h3
-rw-r--r--src/mongo/db/transaction_participant.cpp6
-rw-r--r--src/mongo/db/views/durable_view_catalog.cpp6
-rw-r--r--src/mongo/db/yieldable.h39
272 files changed, 1343 insertions, 1015 deletions
diff --git a/src/mongo/db/auth/auth_op_observer.cpp b/src/mongo/db/auth/auth_op_observer.cpp
index 4e10e8d2d21..b70883a7df1 100644
--- a/src/mongo/db/auth/auth_op_observer.cpp
+++ b/src/mongo/db/auth/auth_op_observer.cpp
@@ -90,7 +90,7 @@ void AuthOpObserver::onDelete(OperationContext* opCtx,
}
void AuthOpObserver::onCreateCollection(OperationContext* opCtx,
- const Collection* coll,
+ const CollectionPtr& coll,
const NamespaceString& collectionName,
const CollectionOptions& options,
const BSONObj& idIndex,
diff --git a/src/mongo/db/auth/auth_op_observer.h b/src/mongo/db/auth/auth_op_observer.h
index b8d0e132b7a..19831510685 100644
--- a/src/mongo/db/auth/auth_op_observer.h
+++ b/src/mongo/db/auth/auth_op_observer.h
@@ -106,7 +106,7 @@ public:
const boost::optional<OplogSlot> slot) final{};
void onCreateCollection(OperationContext* opCtx,
- const Collection* coll,
+ const CollectionPtr& coll,
const NamespaceString& collectionName,
const CollectionOptions& options,
const BSONObj& idIndex,
diff --git a/src/mongo/db/catalog/capped_utils.cpp b/src/mongo/db/catalog/capped_utils.cpp
index a96cb39b739..4b000f92e81 100644
--- a/src/mongo/db/catalog/capped_utils.cpp
+++ b/src/mongo/db/catalog/capped_utils.cpp
@@ -113,7 +113,7 @@ void cloneCollectionAsCapped(OperationContext* opCtx,
const NamespaceString& toNss,
long long size,
bool temp) {
- const Collection* fromCollection =
+ const CollectionPtr& fromCollection =
CollectionCatalog::get(opCtx).lookupCollectionByNamespace(opCtx, fromNss);
if (!fromCollection) {
uassert(ErrorCodes::CommandNotSupportedOnView,
@@ -152,7 +152,7 @@ void cloneCollectionAsCapped(OperationContext* opCtx,
uassertStatusOK(createCollection(opCtx, toNss.db().toString(), cmd.done()));
}
- const Collection* toCollection =
+ const CollectionPtr& toCollection =
CollectionCatalog::get(opCtx).lookupCollectionByNamespace(opCtx, toNss);
invariant(toCollection); // we created above
@@ -231,7 +231,7 @@ void cloneCollectionAsCapped(OperationContext* opCtx,
// abandonSnapshot.
exec->saveState();
opCtx->recoveryUnit()->abandonSnapshot();
- exec->restoreState(); // Handles any WCEs internally.
+ exec->restoreState(&fromCollection); // Handles any WCEs internally.
}
}
diff --git a/src/mongo/db/catalog/capped_utils_test.cpp b/src/mongo/db/catalog/capped_utils_test.cpp
index b3cef4c8279..9bba12741bd 100644
--- a/src/mongo/db/catalog/capped_utils_test.cpp
+++ b/src/mongo/db/catalog/capped_utils_test.cpp
@@ -98,8 +98,7 @@ bool collectionExists(OperationContext* opCtx, const NamespaceString& nss) {
* Returns collection options.
*/
CollectionOptions getCollectionOptions(OperationContext* opCtx, const NamespaceString& nss) {
- AutoGetCollectionForRead autoColl(opCtx, nss);
- auto collection = autoColl.getCollection();
+ AutoGetCollectionForRead collection(opCtx, nss);
ASSERT_TRUE(collection) << "Unable to get collections options for " << nss
<< " because collection does not exist.";
return DurableCatalog::get(opCtx)->getCollectionOptions(opCtx, collection->getCatalogId());
diff --git a/src/mongo/db/catalog/coll_mod.cpp b/src/mongo/db/catalog/coll_mod.cpp
index e46ec8fd298..52653d1c0d1 100644
--- a/src/mongo/db/catalog/coll_mod.cpp
+++ b/src/mongo/db/catalog/coll_mod.cpp
@@ -112,7 +112,7 @@ struct CollModRequest {
StatusWith<CollModRequest> parseCollModRequest(OperationContext* opCtx,
const NamespaceString& nss,
- const Collection* coll,
+ const CollectionPtr& coll,
const BSONObj& cmdObj,
BSONObjBuilder* oplogEntryBuilder) {
diff --git a/src/mongo/db/catalog/coll_mod.h b/src/mongo/db/catalog/coll_mod.h
index e92205e5888..a6b5236f355 100644
--- a/src/mongo/db/catalog/coll_mod.h
+++ b/src/mongo/db/catalog/coll_mod.h
@@ -35,6 +35,7 @@ namespace mongo {
class BSONObj;
class BSONObjBuilder;
class Collection;
+class CollectionPtr;
class NamespaceString;
class OperationContext;
diff --git a/src/mongo/db/catalog/collection.cpp b/src/mongo/db/catalog/collection.cpp
index e02689c7622..36f73778483 100644
--- a/src/mongo/db/catalog/collection.cpp
+++ b/src/mongo/db/catalog/collection.cpp
@@ -67,6 +67,63 @@ bool CappedInsertNotifier::isDead() {
return _dead;
}
+// We can't reference the catalog from this library as it would create a cyclic library dependency.
+// Setup a weak dependency using a std::function that is installed by the catalog lib
+std::function<CollectionPtr(OperationContext*, CollectionUUID, uint64_t)>& _catalogLookup() {
+ static std::function<CollectionPtr(OperationContext*, CollectionUUID, uint64_t)> func;
+ return func;
+}
+
+void CollectionPtr::installCatalogLookupImpl(
+ std::function<CollectionPtr(OperationContext*, CollectionUUID, uint64_t)> impl) {
+ _catalogLookup() = std::move(impl);
+}
+
+CollectionPtr CollectionPtr::null;
+
+CollectionPtr::CollectionPtr() : _collection(nullptr), _opCtx(nullptr) {}
+CollectionPtr::CollectionPtr(OperationContext* opCtx,
+ const Collection* collection,
+ uint64_t catalogEpoch)
+ : _collection(collection), _opCtx(opCtx), _catalogEpoch(catalogEpoch) {}
+CollectionPtr::CollectionPtr(const Collection* collection, NoYieldTag)
+ : CollectionPtr(nullptr, collection, 0) {}
+CollectionPtr::CollectionPtr(Collection* collection) : CollectionPtr(collection, NoYieldTag{}) {}
+CollectionPtr::CollectionPtr(const std::shared_ptr<const Collection>& collection)
+ : CollectionPtr(collection.get(), NoYieldTag{}) {}
+CollectionPtr::CollectionPtr(CollectionPtr&&) = default;
+CollectionPtr::~CollectionPtr() {}
+CollectionPtr& CollectionPtr::operator=(CollectionPtr&&) = default;
+
+CollectionPtr CollectionPtr::detached() const {
+ return CollectionPtr(_opCtx, _collection, _catalogEpoch);
+}
+
+bool CollectionPtr::_canYield() const {
+ // We only set the opCtx when we use a constructor that allows yielding.
+ // When we are doing a lock free read or having a writable pointer in a WUOW it is not allowed
+ // to yield.
+ return _opCtx;
+}
+
+void CollectionPtr::yield() const {
+ if (_canYield()) {
+ _uuid = _collection->uuid();
+ _ns = _collection->ns();
+ _collection = nullptr;
+ }
+}
+void CollectionPtr::restore() const {
+ if (_canYield()) {
+ // We may only do yield restore when we were holding locks that was yielded so we need to
+ // refresh from the catalog to make sure we have a valid collection pointer.
+ auto coll = _catalogLookup()(_opCtx, *_uuid, _catalogEpoch);
+ if (coll && coll->ns() == _ns) {
+ _collection = coll.get();
+ }
+ }
+}
+
// ----
namespace {
diff --git a/src/mongo/db/catalog/collection.h b/src/mongo/db/catalog/collection.h
index 134fc67df0e..756d2f16171 100644
--- a/src/mongo/db/catalog/collection.h
+++ b/src/mongo/db/catalog/collection.h
@@ -51,6 +51,7 @@
#include "mongo/db/storage/capped_callback.h"
#include "mongo/db/storage/record_store.h"
#include "mongo/db/storage/snapshot.h"
+#include "mongo/db/yieldable.h"
#include "mongo/logv2/log_attr.h"
#include "mongo/platform/mutex.h"
#include "mongo/stdx/condition_variable.h"
@@ -58,6 +59,7 @@
namespace mongo {
class CappedCallback;
+class CollectionPtr;
class ExtentManager;
class IndexCatalog;
class IndexCatalogEntry;
@@ -552,6 +554,7 @@ public:
*/
virtual std::unique_ptr<PlanExecutor, PlanExecutor::Deleter> makePlanExecutor(
OperationContext* opCtx,
+ const CollectionPtr& yieldableCollection,
PlanYieldPolicy::YieldPolicy yieldPolicy,
ScanDirection scanDirection,
boost::optional<RecordId> resumeAfterRecordId = boost::none) const = 0;
@@ -576,4 +579,85 @@ public:
}
};
+/**
+ * Smart-pointer'esque type to handle yielding of Collection lock that may invalidate pointers when
+ * resuming. CollectionPtr will re-load the Collection from the Catalog when restoring from a yield
+ * that dropped Collection locks. If this is constructed from a Lock-Free Reads context (shared_ptr)
+ * or writable pointer, then it is not allowed to reload from the catalog and the yield operations
+ * are no-ops.
+ */
+class CollectionPtr : public Yieldable {
+public:
+ static CollectionPtr null;
+
+ CollectionPtr();
+
+ // Creates a Yieldable CollectionPtr that reloads the Collection pointer from the catalog when
+ // restoring from yield
+ CollectionPtr(OperationContext* opCtx, const Collection* collection, uint64_t catalogEpoch);
+
+ // Creates non-yieldable CollectionPtr, performing yield/restore will be a no-op.
+ struct NoYieldTag {};
+ CollectionPtr(const Collection* collection, NoYieldTag);
+ CollectionPtr(const std::shared_ptr<const Collection>& collection);
+ CollectionPtr(Collection* collection);
+
+ CollectionPtr(const CollectionPtr&) = delete;
+ CollectionPtr(CollectionPtr&&);
+ ~CollectionPtr();
+
+ CollectionPtr& operator=(const CollectionPtr&) = delete;
+ CollectionPtr& operator=(CollectionPtr&&);
+
+ explicit operator bool() const {
+ return static_cast<bool>(_collection);
+ }
+
+ bool operator==(const CollectionPtr& other) const {
+ return get() == other.get();
+ }
+ bool operator!=(const CollectionPtr& other) const {
+ return !operator==(other);
+ }
+ const Collection* operator->() const {
+ return _collection;
+ }
+ const Collection* get() const {
+ return _collection;
+ }
+
+ // Creates a new CollectionPtr that is detached from the current, if the current instance is
+ // yieldable the new CollectionPtr will also be. Yielding on the new instance may cause the
+ // instance we detached from to dangle.
+ CollectionPtr detached() const;
+
+ void reset() {
+ *this = CollectionPtr();
+ }
+
+ void yield() const override;
+ void restore() const override;
+
+ static void installCatalogLookupImpl(
+ std::function<CollectionPtr(OperationContext*, CollectionUUID, uint64_t)> impl);
+
+ friend std::ostream& operator<<(std::ostream& os, const CollectionPtr& coll);
+
+private:
+ bool _canYield() const;
+
+ // These members needs to be mutable so the yield/restore interface can be const. We don't want
+ // yield/restore to require a non-const instance when it otherwise could be const.
+ mutable const Collection* _collection;
+ mutable OptionalCollectionUUID _uuid;
+ mutable NamespaceString _ns;
+ OperationContext* _opCtx;
+ uint64_t _catalogEpoch;
+};
+
+inline std::ostream& operator<<(std::ostream& os, const CollectionPtr& coll) {
+ os << coll.get();
+ return os;
+}
+
} // namespace mongo
diff --git a/src/mongo/db/catalog/collection_catalog.cpp b/src/mongo/db/catalog/collection_catalog.cpp
index 34444d2a45f..ce2fea09cb7 100644
--- a/src/mongo/db/catalog/collection_catalog.cpp
+++ b/src/mongo/db/catalog/collection_catalog.cpp
@@ -47,6 +47,19 @@ namespace {
const ServiceContext::Decoration<CollectionCatalog> getCatalog =
ServiceContext::declareDecoration<CollectionCatalog>();
+struct installCatalogLookupFn {
+ installCatalogLookupFn() {
+ CollectionPtr::installCatalogLookupImpl(
+ [](OperationContext* opCtx, CollectionUUID uuid, uint64_t catalogEpoch) {
+ const auto& catalog = CollectionCatalog::get(opCtx);
+ if (catalog.getEpoch() != catalogEpoch)
+ return CollectionPtr();
+
+ return catalog.lookupCollectionByUUID(opCtx, uuid);
+ });
+ }
+} inst;
+
class FinishDropCollectionChange : public RecoveryUnit::Change {
public:
FinishDropCollectionChange(CollectionCatalog* catalog,
@@ -70,10 +83,11 @@ private:
} // namespace
-CollectionCatalog::iterator::iterator(StringData dbName,
+CollectionCatalog::iterator::iterator(OperationContext* opCtx,
+ StringData dbName,
uint64_t genNum,
const CollectionCatalog& catalog)
- : _dbName(dbName), _genNum(genNum), _catalog(&catalog) {
+ : _opCtx(opCtx), _dbName(dbName), _genNum(genNum), _catalog(&catalog) {
auto minUuid = UUID::parse("00000000-0000-0000-0000-000000000000").getValue();
stdx::lock_guard<Latch> lock(_catalog->_catalogLock);
@@ -89,18 +103,19 @@ CollectionCatalog::iterator::iterator(StringData dbName,
}
}
-CollectionCatalog::iterator::iterator(std::map<std::pair<std::string, CollectionUUID>,
+CollectionCatalog::iterator::iterator(OperationContext* opCtx,
+ std::map<std::pair<std::string, CollectionUUID>,
std::shared_ptr<Collection>>::const_iterator mapIter)
- : _mapIter(mapIter) {}
+ : _opCtx(opCtx), _mapIter(mapIter) {}
CollectionCatalog::iterator::value_type CollectionCatalog::iterator::operator*() {
stdx::lock_guard<Latch> lock(_catalog->_catalogLock);
_repositionIfNeeded();
if (_exhausted()) {
- return _nullCollection;
+ return CollectionPtr();
}
- return _mapIter->second.get();
+ return {_opCtx, _mapIter->second.get(), _catalog->getEpoch()};
}
Collection* CollectionCatalog::iterator::getWritableCollection(OperationContext* opCtx,
@@ -297,15 +312,16 @@ Collection* CollectionCatalog::lookupCollectionByUUIDForMetadataWrite(OperationC
return nullptr;
}
-const Collection* CollectionCatalog::lookupCollectionByUUID(OperationContext* opCtx,
- CollectionUUID uuid) const {
+CollectionPtr CollectionCatalog::lookupCollectionByUUID(OperationContext* opCtx,
+ CollectionUUID uuid) const {
if (auto coll = UncommittedCollections::getForTxn(opCtx, uuid)) {
- return coll.get();
+ return {opCtx, coll.get(), getEpoch()};
}
stdx::lock_guard<Latch> lock(_catalogLock);
auto coll = _lookupCollectionByUUID(lock, uuid);
- return (coll && coll->isCommitted()) ? coll.get() : nullptr;
+ return (coll && coll->isCommitted()) ? CollectionPtr(opCtx, coll.get(), getEpoch())
+ : CollectionPtr();
}
void CollectionCatalog::makeCollectionVisible(CollectionUUID uuid) {
@@ -361,16 +377,16 @@ Collection* CollectionCatalog::lookupCollectionByNamespaceForMetadataWrite(
return nullptr;
}
-const Collection* CollectionCatalog::lookupCollectionByNamespace(OperationContext* opCtx,
- const NamespaceString& nss) const {
+CollectionPtr CollectionCatalog::lookupCollectionByNamespace(OperationContext* opCtx,
+ const NamespaceString& nss) const {
if (auto coll = UncommittedCollections::getForTxn(opCtx, nss)) {
- return coll.get();
+ return {opCtx, coll.get(), getEpoch()};
}
stdx::lock_guard<Latch> lock(_catalogLock);
auto it = _collections.find(nss);
auto coll = (it == _collections.end() ? nullptr : it->second);
- return (coll && coll->isCommitted()) ? coll.get() : nullptr;
+ return (coll && coll->isCommitted()) ? CollectionPtr(opCtx, coll.get(), getEpoch()) : nullptr;
}
boost::optional<NamespaceString> CollectionCatalog::lookupNSSByUUID(OperationContext* opCtx,
@@ -626,12 +642,12 @@ void CollectionCatalog::deregisterAllCollections() {
_generationNumber++;
}
-CollectionCatalog::iterator CollectionCatalog::begin(StringData db) const {
- return iterator(db, _generationNumber, *this);
+CollectionCatalog::iterator CollectionCatalog::begin(OperationContext* opCtx, StringData db) const {
+ return iterator(opCtx, db, _generationNumber, *this);
}
-CollectionCatalog::iterator CollectionCatalog::end() const {
- return iterator(_orderedCollections.end());
+CollectionCatalog::iterator CollectionCatalog::end(OperationContext* opCtx) const {
+ return iterator(opCtx, _orderedCollections.end());
}
boost::optional<std::string> CollectionCatalog::lookupResourceName(const ResourceId& rid) {
diff --git a/src/mongo/db/catalog/collection_catalog.h b/src/mongo/db/catalog/collection_catalog.h
index 32afe461f04..26b64a3ce6d 100644
--- a/src/mongo/db/catalog/collection_catalog.h
+++ b/src/mongo/db/catalog/collection_catalog.h
@@ -55,7 +55,7 @@ class CollectionCatalog {
friend class iterator;
public:
- using CollectionInfoFn = std::function<bool(const Collection* collection)>;
+ using CollectionInfoFn = std::function<bool(const CollectionPtr& collection)>;
enum class LifetimeMode {
// Lifetime of writable Collection is managed by an active write unit of work. The writable
@@ -73,10 +73,14 @@ public:
class iterator {
public:
- using value_type = const Collection*;
-
- iterator(StringData dbName, uint64_t genNum, const CollectionCatalog& catalog);
- iterator(std::map<std::pair<std::string, CollectionUUID>,
+ using value_type = CollectionPtr;
+
+ iterator(OperationContext* opCtx,
+ StringData dbName,
+ uint64_t genNum,
+ const CollectionCatalog& catalog);
+ iterator(OperationContext* opCtx,
+ std::map<std::pair<std::string, CollectionUUID>,
std::shared_ptr<Collection>>::const_iterator mapIter);
value_type operator*();
iterator operator++();
@@ -104,13 +108,13 @@ public:
bool _repositionIfNeeded();
bool _exhausted();
+ OperationContext* _opCtx;
std::string _dbName;
boost::optional<CollectionUUID> _uuid;
uint64_t _genNum;
std::map<std::pair<std::string, CollectionUUID>,
std::shared_ptr<Collection>>::const_iterator _mapIter;
const CollectionCatalog* _catalog;
- static constexpr Collection* _nullCollection = nullptr;
};
struct ProfileSettings {
@@ -182,7 +186,7 @@ public:
Collection* lookupCollectionByUUIDForMetadataWrite(OperationContext* opCtx,
LifetimeMode mode,
CollectionUUID uuid);
- const Collection* lookupCollectionByUUID(OperationContext* opCtx, CollectionUUID uuid) const;
+ CollectionPtr lookupCollectionByUUID(OperationContext* opCtx, CollectionUUID uuid) const;
std::shared_ptr<const Collection> lookupCollectionByUUIDForRead(OperationContext* opCtx,
CollectionUUID uuid) const;
@@ -205,8 +209,8 @@ public:
Collection* lookupCollectionByNamespaceForMetadataWrite(OperationContext* opCtx,
LifetimeMode mode,
const NamespaceString& nss);
- const Collection* lookupCollectionByNamespace(OperationContext* opCtx,
- const NamespaceString& nss) const;
+ CollectionPtr lookupCollectionByNamespace(OperationContext* opCtx,
+ const NamespaceString& nss) const;
std::shared_ptr<const Collection> lookupCollectionByNamespaceForRead(
OperationContext* opCtx, const NamespaceString& nss) const;
@@ -324,8 +328,8 @@ public:
*/
uint64_t getEpoch() const;
- iterator begin(StringData db) const;
- iterator end() const;
+ iterator begin(OperationContext* opCtx, StringData db) const;
+ iterator end(OperationContext* opCtx) const;
/**
* Lookup the name of a resource by its ResourceId. If there are multiple namespaces mapped to
diff --git a/src/mongo/db/catalog/collection_catalog_helper.cpp b/src/mongo/db/catalog/collection_catalog_helper.cpp
index 069bc1558f0..8b220b79464 100644
--- a/src/mongo/db/catalog/collection_catalog_helper.cpp
+++ b/src/mongo/db/catalog/collection_catalog_helper.cpp
@@ -45,14 +45,15 @@ void forEachCollectionFromDb(OperationContext* opCtx,
CollectionCatalog::CollectionInfoFn predicate) {
CollectionCatalog& catalog = CollectionCatalog::get(opCtx);
- for (auto collectionIt = catalog.begin(dbName); collectionIt != catalog.end(); ++collectionIt) {
+ for (auto collectionIt = catalog.begin(opCtx, dbName); collectionIt != catalog.end(opCtx);
+ ++collectionIt) {
auto uuid = collectionIt.uuid().get();
if (predicate && !catalog.checkIfCollectionSatisfiable(uuid, predicate)) {
continue;
}
boost::optional<Lock::CollectionLock> clk;
- const Collection* collection = nullptr;
+ CollectionPtr collection;
while (auto nss = catalog.lookupNSSByUUID(opCtx, uuid)) {
// Get a fresh snapshot for each locked collection to see any catalog changes.
diff --git a/src/mongo/db/catalog/collection_catalog_helper.h b/src/mongo/db/catalog/collection_catalog_helper.h
index db9010db85a..aa5756e7baf 100644
--- a/src/mongo/db/catalog/collection_catalog_helper.h
+++ b/src/mongo/db/catalog/collection_catalog_helper.h
@@ -36,6 +36,7 @@
namespace mongo {
class Collection;
+class CollectionPtr;
class CollectionCatalogEntry;
namespace catalog {
diff --git a/src/mongo/db/catalog/collection_catalog_test.cpp b/src/mongo/db/catalog/collection_catalog_test.cpp
index 5ac89ed76a8..e4bb122e48c 100644
--- a/src/mongo/db/catalog/collection_catalog_test.cpp
+++ b/src/mongo/db/catalog/collection_catalog_test.cpp
@@ -45,7 +45,7 @@ namespace mongo {
namespace {
/**
- * A test fixture that creates a CollectionCatalog and const Collection* pointer to store in it.
+ * A test fixture that creates a CollectionCatalog and const CollectionPtr& pointer to store in it.
*/
class CollectionCatalogTest : public ServiceContextMongoDTest {
public:
@@ -69,7 +69,7 @@ public:
ServiceContextMongoDTest::setUp();
std::shared_ptr<Collection> collection = std::make_shared<CollectionMock>(nss);
- col = collection.get();
+ col = CollectionPtr(collection.get(), CollectionPtr::NoYieldTag{});
// Register dummy collection in catalog.
catalog.registerCollection(colUUID, std::move(collection));
}
@@ -78,7 +78,7 @@ protected:
CollectionCatalog catalog;
OperationContextNoop opCtx;
NamespaceString nss;
- const Collection* col;
+ CollectionPtr col;
CollectionUUID colUUID;
CollectionUUID nextUUID;
CollectionUUID prevUUID;
@@ -112,13 +112,13 @@ public:
}
}
- std::map<CollectionUUID, const Collection*>::iterator collsIterator(std::string dbName) {
+ std::map<CollectionUUID, CollectionPtr>::iterator collsIterator(std::string dbName) {
auto it = dbMap.find(dbName);
ASSERT(it != dbMap.end());
return it->second.begin();
}
- std::map<CollectionUUID, const Collection*>::iterator collsIteratorEnd(std::string dbName) {
+ std::map<CollectionUUID, CollectionPtr>::iterator collsIteratorEnd(std::string dbName) {
auto it = dbMap.find(dbName);
ASSERT(it != dbMap.end());
return it->second.end();
@@ -127,13 +127,14 @@ public:
void checkCollections(std::string dbName) {
unsigned long counter = 0;
- for (auto [orderedIt, catalogIt] = std::tuple{collsIterator(dbName), catalog.begin(dbName)};
- catalogIt != catalog.end() && orderedIt != collsIteratorEnd(dbName);
+ for (auto [orderedIt, catalogIt] =
+ std::tuple{collsIterator(dbName), catalog.begin(&opCtx, dbName)};
+ catalogIt != catalog.end(&opCtx) && orderedIt != collsIteratorEnd(dbName);
++catalogIt, ++orderedIt) {
auto catalogColl = *catalogIt;
ASSERT(catalogColl != nullptr);
- auto orderedColl = orderedIt->second;
+ const auto& orderedColl = orderedIt->second;
ASSERT_EQ(catalogColl->ns(), orderedColl->ns());
++counter;
}
@@ -148,7 +149,7 @@ public:
protected:
CollectionCatalog catalog;
OperationContextNoop opCtx;
- std::map<std::string, std::map<CollectionUUID, const Collection*>> dbMap;
+ std::map<std::string, std::map<CollectionUUID, CollectionPtr>> dbMap;
};
class CollectionCatalogResourceMapTest : public unittest::Test {
@@ -281,7 +282,7 @@ public:
}
int numEntries = 0;
- for (auto it = catalog.begin("resourceDb"); it != catalog.end(); it++) {
+ for (auto it = catalog.begin(&opCtx, "resourceDb"); it != catalog.end(&opCtx); it++) {
auto coll = *it;
std::string collName = coll->ns().ns();
ResourceId rid(RESOURCE_COLLECTION, collName);
@@ -293,7 +294,7 @@ public:
}
void tearDown() {
- for (auto it = catalog.begin("resourceDb"); it != catalog.end(); ++it) {
+ for (auto it = catalog.begin(&opCtx, "resourceDb"); it != catalog.end(&opCtx); ++it) {
auto coll = *it;
auto uuid = coll->uuid();
if (!coll) {
@@ -304,7 +305,7 @@ public:
}
int numEntries = 0;
- for (auto it = catalog.begin("resourceDb"); it != catalog.end(); it++) {
+ for (auto it = catalog.begin(&opCtx, "resourceDb"); it != catalog.end(&opCtx); it++) {
numEntries++;
}
ASSERT_EQ(0, numEntries);
@@ -382,7 +383,7 @@ TEST_F(CollectionCatalogIterationTest, EndAtEndOfSection) {
// Delete an entry in the catalog while iterating.
TEST_F(CollectionCatalogIterationTest, InvalidateEntry) {
- auto it = catalog.begin("bar");
+ auto it = catalog.begin(&opCtx, "bar");
// Invalidate bar.coll1.
for (auto collsIt = collsIterator("bar"); collsIt != collsIteratorEnd("bar"); ++collsIt) {
@@ -394,7 +395,7 @@ TEST_F(CollectionCatalogIterationTest, InvalidateEntry) {
}
- for (; it != catalog.end(); ++it) {
+ for (; it != catalog.end(&opCtx); ++it) {
auto coll = *it;
ASSERT(coll && coll->ns().ns() != "bar.coll1");
}
@@ -402,13 +403,13 @@ TEST_F(CollectionCatalogIterationTest, InvalidateEntry) {
// Delete the entry pointed to by the iterator and dereference the iterator.
TEST_F(CollectionCatalogIterationTest, InvalidateAndDereference) {
- auto it = catalog.begin("bar");
+ auto it = catalog.begin(&opCtx, "bar");
auto collsIt = collsIterator("bar");
auto uuid = collsIt->first;
catalog.deregisterCollection(uuid);
++collsIt;
- ASSERT(it != catalog.end());
+ ASSERT(it != catalog.end(&opCtx));
auto catalogColl = *it;
ASSERT(catalogColl != nullptr);
ASSERT_EQUALS(catalogColl->ns(), collsIt->second->ns());
@@ -418,7 +419,7 @@ TEST_F(CollectionCatalogIterationTest, InvalidateAndDereference) {
// Delete the last entry for a database while pointing to it and dereference the iterator.
TEST_F(CollectionCatalogIterationTest, InvalidateLastEntryAndDereference) {
- auto it = catalog.begin("bar");
+ auto it = catalog.begin(&opCtx, "bar");
NamespaceString lastNs;
boost::optional<CollectionUUID> uuid;
for (auto collsIt = collsIterator("bar"); collsIt != collsIteratorEnd("bar"); ++collsIt) {
@@ -427,7 +428,7 @@ TEST_F(CollectionCatalogIterationTest, InvalidateLastEntryAndDereference) {
}
// Increment until it points to the last collection.
- for (; it != catalog.end(); ++it) {
+ for (; it != catalog.end(&opCtx); ++it) {
auto coll = *it;
ASSERT(coll != nullptr);
if (coll->ns() == lastNs) {
@@ -442,7 +443,7 @@ TEST_F(CollectionCatalogIterationTest, InvalidateLastEntryAndDereference) {
// Delete the last entry in the map while pointing to it and dereference the iterator.
TEST_F(CollectionCatalogIterationTest, InvalidateLastEntryInMapAndDereference) {
- auto it = catalog.begin("foo");
+ auto it = catalog.begin(&opCtx, "foo");
NamespaceString lastNs;
boost::optional<CollectionUUID> uuid;
for (auto collsIt = collsIterator("foo"); collsIt != collsIteratorEnd("foo"); ++collsIt) {
@@ -451,7 +452,7 @@ TEST_F(CollectionCatalogIterationTest, InvalidateLastEntryInMapAndDereference) {
}
// Increment until it points to the last collection.
- for (; it != catalog.end(); ++it) {
+ for (; it != catalog.end(&opCtx); ++it) {
auto coll = *it;
ASSERT(coll != nullptr);
if (coll->ns() == lastNs) {
@@ -465,7 +466,7 @@ TEST_F(CollectionCatalogIterationTest, InvalidateLastEntryInMapAndDereference) {
}
TEST_F(CollectionCatalogIterationTest, GetUUIDWontRepositionEvenIfEntryIsDropped) {
- auto it = catalog.begin("bar");
+ auto it = catalog.begin(&opCtx, "bar");
auto collsIt = collsIterator("bar");
auto uuid = collsIt->first;
catalog.deregisterCollection(uuid);
@@ -726,7 +727,7 @@ TEST_F(ForEachCollectionFromDbTest, ForEachCollectionFromDb) {
{
auto dbLock = std::make_unique<Lock::DBLock>(opCtx, "db", MODE_IX);
int numCollectionsTraversed = 0;
- catalog::forEachCollectionFromDb(opCtx, "db", MODE_X, [&](const Collection* collection) {
+ catalog::forEachCollectionFromDb(opCtx, "db", MODE_X, [&](const CollectionPtr& collection) {
ASSERT_TRUE(opCtx->lockState()->isCollectionLockedForMode(collection->ns(), MODE_X));
numCollectionsTraversed++;
return true;
@@ -738,11 +739,13 @@ TEST_F(ForEachCollectionFromDbTest, ForEachCollectionFromDb) {
{
auto dbLock = std::make_unique<Lock::DBLock>(opCtx, "db2", MODE_IX);
int numCollectionsTraversed = 0;
- catalog::forEachCollectionFromDb(opCtx, "db2", MODE_IS, [&](const Collection* collection) {
- ASSERT_TRUE(opCtx->lockState()->isCollectionLockedForMode(collection->ns(), MODE_IS));
- numCollectionsTraversed++;
- return true;
- });
+ catalog::forEachCollectionFromDb(
+ opCtx, "db2", MODE_IS, [&](const CollectionPtr& collection) {
+ ASSERT_TRUE(
+ opCtx->lockState()->isCollectionLockedForMode(collection->ns(), MODE_IS));
+ numCollectionsTraversed++;
+ return true;
+ });
ASSERT_EQUALS(numCollectionsTraversed, 1);
}
@@ -750,10 +753,11 @@ TEST_F(ForEachCollectionFromDbTest, ForEachCollectionFromDb) {
{
auto dbLock = std::make_unique<Lock::DBLock>(opCtx, "db3", MODE_IX);
int numCollectionsTraversed = 0;
- catalog::forEachCollectionFromDb(opCtx, "db3", MODE_S, [&](const Collection* collection) {
- numCollectionsTraversed++;
- return true;
- });
+ catalog::forEachCollectionFromDb(
+ opCtx, "db3", MODE_S, [&](const CollectionPtr& collection) {
+ numCollectionsTraversed++;
+ return true;
+ });
ASSERT_EQUALS(numCollectionsTraversed, 0);
}
@@ -770,13 +774,13 @@ TEST_F(ForEachCollectionFromDbTest, ForEachCollectionFromDbWithPredicate) {
opCtx,
"db",
MODE_X,
- [&](const Collection* collection) {
+ [&](const CollectionPtr& collection) {
ASSERT_TRUE(
opCtx->lockState()->isCollectionLockedForMode(collection->ns(), MODE_X));
numCollectionsTraversed++;
return true;
},
- [&](const Collection* collection) {
+ [&](const CollectionPtr& collection) {
ASSERT_TRUE(
opCtx->lockState()->isCollectionLockedForMode(collection->ns(), MODE_NONE));
return DurableCatalog::get(opCtx)
@@ -794,13 +798,13 @@ TEST_F(ForEachCollectionFromDbTest, ForEachCollectionFromDbWithPredicate) {
opCtx,
"db",
MODE_IX,
- [&](const Collection* collection) {
+ [&](const CollectionPtr& collection) {
ASSERT_TRUE(
opCtx->lockState()->isCollectionLockedForMode(collection->ns(), MODE_IX));
numCollectionsTraversed++;
return true;
},
- [&](const Collection* collection) {
+ [&](const CollectionPtr& collection) {
ASSERT_TRUE(
opCtx->lockState()->isCollectionLockedForMode(collection->ns(), MODE_NONE));
return !DurableCatalog::get(opCtx)
diff --git a/src/mongo/db/catalog/collection_compact.cpp b/src/mongo/db/catalog/collection_compact.cpp
index f143dd89d1d..dbb1130ce2c 100644
--- a/src/mongo/db/catalog/collection_compact.cpp
+++ b/src/mongo/db/catalog/collection_compact.cpp
@@ -50,14 +50,13 @@ using logv2::LogComponent;
namespace {
-const Collection* getCollectionForCompact(OperationContext* opCtx,
- Database* database,
- const NamespaceString& collectionNss) {
+CollectionPtr getCollectionForCompact(OperationContext* opCtx,
+ Database* database,
+ const NamespaceString& collectionNss) {
invariant(opCtx->lockState()->isCollectionLockedForMode(collectionNss, MODE_IX));
CollectionCatalog& collectionCatalog = CollectionCatalog::get(opCtx);
- const Collection* collection =
- collectionCatalog.lookupCollectionByNamespace(opCtx, collectionNss);
+ CollectionPtr collection = collectionCatalog.lookupCollectionByNamespace(opCtx, collectionNss);
if (!collection) {
std::shared_ptr<ViewDefinition> view =
@@ -82,7 +81,7 @@ StatusWith<int64_t> compactCollection(OperationContext* opCtx,
boost::optional<Lock::CollectionLock> collLk;
collLk.emplace(opCtx, collectionNss, MODE_X);
- const Collection* collection = getCollectionForCompact(opCtx, database, collectionNss);
+ CollectionPtr collection = getCollectionForCompact(opCtx, database, collectionNss);
DisableDocumentValidation validationDisabler(opCtx);
auto recordStore = collection->getRecordStore();
diff --git a/src/mongo/db/catalog/collection_impl.cpp b/src/mongo/db/catalog/collection_impl.cpp
index f6eb83db709..022735e9110 100644
--- a/src/mongo/db/catalog/collection_impl.cpp
+++ b/src/mongo/db/catalog/collection_impl.cpp
@@ -690,7 +690,8 @@ Status CollectionImpl::_insertDocuments(OperationContext* opCtx,
}
int64_t keysInserted;
- status = _indexCatalog->indexRecords(opCtx, this, bsonRecords, &keysInserted);
+ status = _indexCatalog->indexRecords(
+ opCtx, {this, CollectionPtr::NoYieldTag{}}, bsonRecords, &keysInserted);
if (opDebug) {
opDebug->additiveMetrics.incrementKeysInserted(keysInserted);
}
@@ -841,8 +842,13 @@ RecordId CollectionImpl::updateDocument(OperationContext* opCtx,
if (indexesAffected) {
int64_t keysInserted, keysDeleted;
- uassertStatusOK(_indexCatalog->updateRecord(
- opCtx, this, *args->preImageDoc, newDoc, oldLocation, &keysInserted, &keysDeleted));
+ uassertStatusOK(_indexCatalog->updateRecord(opCtx,
+ {this, CollectionPtr::NoYieldTag{}},
+ *args->preImageDoc,
+ newDoc,
+ oldLocation,
+ &keysInserted,
+ &keysDeleted));
if (opDebug) {
opDebug->additiveMetrics.incrementKeysInserted(keysInserted);
@@ -1233,13 +1239,18 @@ StatusWith<std::vector<BSONObj>> CollectionImpl::addCollationDefaultsToIndexSpec
std::unique_ptr<PlanExecutor, PlanExecutor::Deleter> CollectionImpl::makePlanExecutor(
OperationContext* opCtx,
+ const CollectionPtr& yieldableCollection,
PlanYieldPolicy::YieldPolicy yieldPolicy,
ScanDirection scanDirection,
boost::optional<RecordId> resumeAfterRecordId) const {
auto isForward = scanDirection == ScanDirection::kForward;
auto direction = isForward ? InternalPlanner::FORWARD : InternalPlanner::BACKWARD;
- return InternalPlanner::collectionScan(
- opCtx, _ns.ns(), this, yieldPolicy, direction, resumeAfterRecordId);
+ return InternalPlanner::collectionScan(opCtx,
+ yieldableCollection->ns().ns(),
+ yieldableCollection,
+ yieldPolicy,
+ direction,
+ resumeAfterRecordId);
}
void CollectionImpl::setNs(NamespaceString nss) {
diff --git a/src/mongo/db/catalog/collection_impl.h b/src/mongo/db/catalog/collection_impl.h
index 7f5c03cb018..e6037e04ebc 100644
--- a/src/mongo/db/catalog/collection_impl.h
+++ b/src/mongo/db/catalog/collection_impl.h
@@ -352,6 +352,7 @@ public:
std::unique_ptr<PlanExecutor, PlanExecutor::Deleter> makePlanExecutor(
OperationContext* opCtx,
+ const CollectionPtr& yieldableCollection,
PlanYieldPolicy::YieldPolicy yieldPolicy,
ScanDirection scanDirection,
boost::optional<RecordId> resumeAfterRecordId) const final;
diff --git a/src/mongo/db/catalog/collection_mock.h b/src/mongo/db/catalog/collection_mock.h
index 23220322696..ad5b6bc8580 100644
--- a/src/mongo/db/catalog/collection_mock.h
+++ b/src/mongo/db/catalog/collection_mock.h
@@ -273,6 +273,7 @@ public:
std::unique_ptr<PlanExecutor, PlanExecutor::Deleter> makePlanExecutor(
OperationContext* opCtx,
+ const CollectionPtr& yieldableCollection,
PlanYieldPolicy::YieldPolicy yieldPolicy,
ScanDirection scanDirection,
boost::optional<RecordId> resumeAfterRecordId) const {
diff --git a/src/mongo/db/catalog/collection_test.cpp b/src/mongo/db/catalog/collection_test.cpp
index b973cf5a949..d9c03af2d61 100644
--- a/src/mongo/db/catalog/collection_test.cpp
+++ b/src/mongo/db/catalog/collection_test.cpp
@@ -62,7 +62,7 @@ TEST_F(CollectionTest, CappedNotifierKillAndIsDead) {
makeCapped(nss);
AutoGetCollectionForRead acfr(operationContext(), nss);
- const Collection* col = acfr.getCollection();
+ const CollectionPtr& col = acfr.getCollection();
auto notifier = col->getCappedInsertNotifier();
ASSERT_FALSE(notifier->isDead());
notifier->kill();
@@ -74,7 +74,7 @@ TEST_F(CollectionTest, CappedNotifierTimeouts) {
makeCapped(nss);
AutoGetCollectionForRead acfr(operationContext(), nss);
- const Collection* col = acfr.getCollection();
+ const CollectionPtr& col = acfr.getCollection();
auto notifier = col->getCappedInsertNotifier();
ASSERT_EQ(notifier->getVersion(), 0u);
@@ -90,7 +90,7 @@ TEST_F(CollectionTest, CappedNotifierWaitAfterNotifyIsImmediate) {
makeCapped(nss);
AutoGetCollectionForRead acfr(operationContext(), nss);
- const Collection* col = acfr.getCollection();
+ const CollectionPtr& col = acfr.getCollection();
auto notifier = col->getCappedInsertNotifier();
auto prevVersion = notifier->getVersion();
@@ -109,7 +109,7 @@ TEST_F(CollectionTest, CappedNotifierWaitUntilAsynchronousNotifyAll) {
makeCapped(nss);
AutoGetCollectionForRead acfr(operationContext(), nss);
- const Collection* col = acfr.getCollection();
+ const CollectionPtr& col = acfr.getCollection();
auto notifier = col->getCappedInsertNotifier();
auto prevVersion = notifier->getVersion();
auto thisVersion = prevVersion + 1;
@@ -134,7 +134,7 @@ TEST_F(CollectionTest, CappedNotifierWaitUntilAsynchronousKill) {
makeCapped(nss);
AutoGetCollectionForRead acfr(operationContext(), nss);
- const Collection* col = acfr.getCollection();
+ const CollectionPtr& col = acfr.getCollection();
auto notifier = col->getCappedInsertNotifier();
auto prevVersion = notifier->getVersion();
@@ -158,7 +158,7 @@ TEST_F(CollectionTest, HaveCappedWaiters) {
makeCapped(nss);
AutoGetCollectionForRead acfr(operationContext(), nss);
- const Collection* col = acfr.getCollection();
+ const CollectionPtr& col = acfr.getCollection();
ASSERT_FALSE(col->getCappedCallback()->haveCappedWaiters());
{
auto notifier = col->getCappedInsertNotifier();
@@ -172,7 +172,7 @@ TEST_F(CollectionTest, NotifyCappedWaitersIfNeeded) {
makeCapped(nss);
AutoGetCollectionForRead acfr(operationContext(), nss);
- const Collection* col = acfr.getCollection();
+ const CollectionPtr& col = acfr.getCollection();
col->getCappedCallback()->notifyCappedWaitersIfNeeded();
{
auto notifier = col->getCappedInsertNotifier();
@@ -187,14 +187,14 @@ TEST_F(CollectionTest, AsynchronouslyNotifyCappedWaitersIfNeeded) {
makeCapped(nss);
AutoGetCollectionForRead acfr(operationContext(), nss);
- const Collection* col = acfr.getCollection();
+ const CollectionPtr& col = acfr.getCollection();
auto notifier = col->getCappedInsertNotifier();
auto prevVersion = notifier->getVersion();
auto thisVersion = prevVersion + 1;
auto before = Date_t::now();
notifier->waitUntil(prevVersion, before + Milliseconds(25));
- stdx::thread thread([before, prevVersion, col] {
+ stdx::thread thread([before, prevVersion, &col] {
auto after = Date_t::now();
ASSERT_GTE(after - before, Milliseconds(25));
col->getCappedCallback()->notifyCappedWaitersIfNeeded();
diff --git a/src/mongo/db/catalog/collection_validation.cpp b/src/mongo/db/catalog/collection_validation.cpp
index 2dad6e071cd..621435fec39 100644
--- a/src/mongo/db/catalog/collection_validation.cpp
+++ b/src/mongo/db/catalog/collection_validation.cpp
@@ -354,7 +354,7 @@ std::string multikeyPathsToString(MultikeyPaths paths) {
void _validateCatalogEntry(OperationContext* opCtx,
ValidateState* validateState,
ValidateResults* results) {
- const Collection* collection = validateState->getCollection();
+ const auto& collection = validateState->getCollection();
CollectionOptions options =
DurableCatalog::get(opCtx)->getCollectionOptions(opCtx, collection->getCatalogId());
if (options.uuid) {
diff --git a/src/mongo/db/catalog/collection_validation.h b/src/mongo/db/catalog/collection_validation.h
index e5ac3d1329e..d8eca6226d6 100644
--- a/src/mongo/db/catalog/collection_validation.h
+++ b/src/mongo/db/catalog/collection_validation.h
@@ -36,6 +36,7 @@ namespace mongo {
class OperationContext;
class Collection;
+class CollectionPtr;
class BSONObjBuilder;
class Status;
diff --git a/src/mongo/db/catalog/collection_validation_test.cpp b/src/mongo/db/catalog/collection_validation_test.cpp
index 63dcc0d415a..c0955df1ed9 100644
--- a/src/mongo/db/catalog/collection_validation_test.cpp
+++ b/src/mongo/db/catalog/collection_validation_test.cpp
@@ -163,8 +163,7 @@ int insertDataRange(OperationContext* opCtx, int startIDNum, int endIDNum) {
<< " to " << endIDNum);
- AutoGetCollection autoColl(opCtx, kNss, MODE_IX);
- const Collection* coll = autoColl.getCollection();
+ AutoGetCollection coll(opCtx, kNss, MODE_IX);
std::vector<InsertStatement> inserts;
for (int i = startIDNum; i < endIDNum; ++i) {
auto doc = BSON("_id" << i);
@@ -183,8 +182,7 @@ int insertDataRange(OperationContext* opCtx, int startIDNum, int endIDNum) {
* Inserts a single invalid document into the kNss collection and then returns that count.
*/
int setUpInvalidData(OperationContext* opCtx) {
- AutoGetCollection autoColl(opCtx, kNss, MODE_IX);
- const Collection* coll = autoColl.getCollection();
+ AutoGetCollection coll(opCtx, kNss, MODE_IX);
RecordStore* rs = coll->getRecordStore();
{
diff --git a/src/mongo/db/catalog/create_collection.cpp b/src/mongo/db/catalog/create_collection.cpp
index 1c74a34159f..26cf5eb1f89 100644
--- a/src/mongo/db/catalog/create_collection.cpp
+++ b/src/mongo/db/catalog/create_collection.cpp
@@ -76,7 +76,7 @@ Status _createView(OperationContext* opCtx,
// Create 'system.views' in a separate WUOW if it does not exist.
WriteUnitOfWork wuow(opCtx);
- const Collection* coll = CollectionCatalog::get(opCtx).lookupCollectionByNamespace(
+ CollectionPtr coll = CollectionCatalog::get(opCtx).lookupCollectionByNamespace(
opCtx, NamespaceString(db->getSystemViewsName()));
if (!coll) {
coll = db->createCollection(opCtx, NamespaceString(db->getSystemViewsName()));
@@ -119,7 +119,7 @@ Status _createCollection(OperationContext* opCtx,
// This is a top-level handler for collection creation name conflicts. New commands coming
// in, or commands that generated a WriteConflict must return a NamespaceExists error here
// on conflict.
- if (CollectionCatalog::get(opCtx).lookupCollectionByNamespace(opCtx, nss) != nullptr) {
+ if (CollectionCatalog::get(opCtx).lookupCollectionByNamespace(opCtx, nss)) {
return Status(ErrorCodes::NamespaceExists,
str::stream() << "Collection already exists. NS: " << nss);
}
diff --git a/src/mongo/db/catalog/create_collection_test.cpp b/src/mongo/db/catalog/create_collection_test.cpp
index 7f16293665f..eae07bc5804 100644
--- a/src/mongo/db/catalog/create_collection_test.cpp
+++ b/src/mongo/db/catalog/create_collection_test.cpp
@@ -125,8 +125,7 @@ bool collectionExists(OperationContext* opCtx, const NamespaceString& nss) {
* Returns collection options.
*/
CollectionOptions getCollectionOptions(OperationContext* opCtx, const NamespaceString& nss) {
- AutoGetCollectionForRead autoColl(opCtx, nss);
- auto collection = autoColl.getCollection();
+ AutoGetCollectionForRead collection(opCtx, nss);
ASSERT_TRUE(collection) << "Unable to get collections options for " << nss
<< " because collection does not exist.";
return DurableCatalog::get(opCtx)->getCollectionOptions(opCtx, collection->getCatalogId());
diff --git a/src/mongo/db/catalog/database_impl.cpp b/src/mongo/db/catalog/database_impl.cpp
index 97be806b2a3..83d902c9b2e 100644
--- a/src/mongo/db/catalog/database_impl.cpp
+++ b/src/mongo/db/catalog/database_impl.cpp
@@ -204,7 +204,7 @@ void DatabaseImpl::init(OperationContext* const opCtx) const {
void DatabaseImpl::clearTmpCollections(OperationContext* opCtx) const {
invariant(opCtx->lockState()->isDbLockedForMode(name(), MODE_IX));
- CollectionCatalog::CollectionInfoFn callback = [&](const Collection* collection) {
+ CollectionCatalog::CollectionInfoFn callback = [&](const CollectionPtr& collection) {
try {
WriteUnitOfWork wuow(opCtx);
Status status = dropCollection(opCtx, collection->ns(), {});
@@ -227,7 +227,7 @@ void DatabaseImpl::clearTmpCollections(OperationContext* opCtx) const {
return true;
};
- CollectionCatalog::CollectionInfoFn predicate = [&](const Collection* collection) {
+ CollectionCatalog::CollectionInfoFn predicate = [&](const CollectionPtr& collection) {
return DurableCatalog::get(opCtx)
->getCollectionOptions(opCtx, collection->getCatalogId())
.temp;
@@ -260,7 +260,7 @@ void DatabaseImpl::getStats(OperationContext* opCtx, BSONObjBuilder* output, dou
invariant(opCtx->lockState()->isDbLockedForMode(name(), MODE_IS));
catalog::forEachCollectionFromDb(
- opCtx, name(), MODE_IS, [&](const Collection* collection) -> bool {
+ opCtx, name(), MODE_IS, [&](const CollectionPtr& collection) -> bool {
nCollections += 1;
objects += collection->numRecords(opCtx);
size += collection->dataSize(opCtx);
@@ -490,7 +490,7 @@ void DatabaseImpl::_dropCollectionIndexes(OperationContext* opCtx,
Status DatabaseImpl::_finishDropCollection(OperationContext* opCtx,
const NamespaceString& nss,
- const Collection* collection) const {
+ const CollectionPtr& collection) const {
UUID uuid = collection->uuid();
LOGV2(20318,
"Finishing collection drop for {namespace} ({uuid}).",
@@ -565,7 +565,7 @@ Status DatabaseImpl::renameCollection(OperationContext* opCtx,
void DatabaseImpl::_checkCanCreateCollection(OperationContext* opCtx,
const NamespaceString& nss,
const CollectionOptions& options) const {
- if (CollectionCatalog::get(opCtx).lookupCollectionByNamespace(opCtx, nss) != nullptr) {
+ if (CollectionCatalog::get(opCtx).lookupCollectionByNamespace(opCtx, nss)) {
if (options.isView()) {
uasserted(17399,
str::stream()
@@ -819,7 +819,7 @@ void DatabaseImpl::checkForIdIndexesAndDropPendingCollections(OperationContext*
if (nss.isSystem())
continue;
- const Collection* coll =
+ const CollectionPtr& coll =
CollectionCatalog::get(opCtx).lookupCollectionByNamespace(opCtx, nss);
if (!coll)
continue;
diff --git a/src/mongo/db/catalog/database_impl.h b/src/mongo/db/catalog/database_impl.h
index a1a7f9a153e..56bc5ec78b4 100644
--- a/src/mongo/db/catalog/database_impl.h
+++ b/src/mongo/db/catalog/database_impl.h
@@ -113,11 +113,11 @@ public:
void checkForIdIndexesAndDropPendingCollections(OperationContext* opCtx) const final;
CollectionCatalog::iterator begin(OperationContext* opCtx) const final {
- return CollectionCatalog::get(opCtx).begin(_name);
+ return CollectionCatalog::get(opCtx).begin(opCtx, _name);
}
CollectionCatalog::iterator end(OperationContext* opCtx) const final {
- return CollectionCatalog::get(opCtx).end();
+ return CollectionCatalog::get(opCtx).end(opCtx);
}
private:
@@ -137,7 +137,7 @@ private:
*/
Status _finishDropCollection(OperationContext* opCtx,
const NamespaceString& nss,
- const Collection* collection) const;
+ const CollectionPtr& collection) const;
/**
* Removes all indexes for a collection.
diff --git a/src/mongo/db/catalog/drop_collection.cpp b/src/mongo/db/catalog/drop_collection.cpp
index 3ed987e475f..99826f3082a 100644
--- a/src/mongo/db/catalog/drop_collection.cpp
+++ b/src/mongo/db/catalog/drop_collection.cpp
@@ -53,7 +53,7 @@ namespace mongo {
MONGO_FAIL_POINT_DEFINE(hangDropCollectionBeforeLockAcquisition);
MONGO_FAIL_POINT_DEFINE(hangDuringDropCollection);
-Status _checkNssAndReplState(OperationContext* opCtx, const Collection* coll) {
+Status _checkNssAndReplState(OperationContext* opCtx, const CollectionPtr& coll) {
if (!coll) {
return Status(ErrorCodes::NamespaceNotFound, "ns not found");
}
@@ -134,7 +134,7 @@ Status _abortIndexBuildsAndDropCollection(OperationContext* opCtx,
// which may have changed when we released the collection lock temporarily.
opCtx->recoveryUnit()->abandonSnapshot();
- const Collection* coll =
+ const CollectionPtr& coll =
CollectionCatalog::get(opCtx).lookupCollectionByNamespace(opCtx, startingNss);
Status status = _checkNssAndReplState(opCtx, coll);
if (!status.isOK()) {
@@ -185,7 +185,7 @@ Status _abortIndexBuildsAndDropCollection(OperationContext* opCtx,
// disk state, which may have changed when we released the collection lock temporarily.
opCtx->recoveryUnit()->abandonSnapshot();
- const Collection* coll =
+ const CollectionPtr& coll =
CollectionCatalog::get(opCtx).lookupCollectionByUUID(opCtx, collectionUUID);
status = _checkNssAndReplState(opCtx, coll);
if (!status.isOK()) {
@@ -237,7 +237,7 @@ Status _dropCollection(OperationContext* opCtx,
DropCollectionSystemCollectionMode systemCollectionMode,
BSONObjBuilder& result) {
Lock::CollectionLock collLock(opCtx, collectionName, MODE_X);
- const Collection* coll =
+ const CollectionPtr& coll =
CollectionCatalog::get(opCtx).lookupCollectionByNamespace(opCtx, collectionName);
Status status = _checkNssAndReplState(opCtx, coll);
if (!status.isOK()) {
@@ -300,8 +300,9 @@ Status dropCollection(OperationContext* opCtx,
return Status(ErrorCodes::NamespaceNotFound, "ns not found");
}
- const Collection* coll = CollectionCatalog::get(opCtx).lookupCollectionByNamespace(
- opCtx, collectionName);
+ const CollectionPtr& coll =
+ CollectionCatalog::get(opCtx).lookupCollectionByNamespace(opCtx,
+ collectionName);
if (!coll) {
return _dropView(opCtx, db, collectionName, result);
@@ -337,7 +338,7 @@ Status dropCollectionForApplyOps(OperationContext* opCtx,
return Status(ErrorCodes::NamespaceNotFound, "ns not found");
}
- const Collection* coll =
+ const CollectionPtr& coll =
CollectionCatalog::get(opCtx).lookupCollectionByNamespace(opCtx, collectionName);
BSONObjBuilder unusedBuilder;
diff --git a/src/mongo/db/catalog/drop_indexes.cpp b/src/mongo/db/catalog/drop_indexes.cpp
index bf684381922..98c2025918d 100644
--- a/src/mongo/db/catalog/drop_indexes.cpp
+++ b/src/mongo/db/catalog/drop_indexes.cpp
@@ -60,7 +60,7 @@ constexpr auto kIndexFieldName = "index"_sd;
Status checkView(OperationContext* opCtx,
const NamespaceString& nss,
Database* db,
- const Collection* collection) {
+ const CollectionPtr& collection) {
if (!collection) {
if (db && ViewCatalog::get(db)->lookup(opCtx, nss.ns())) {
return Status(ErrorCodes::CommandNotSupportedOnView,
@@ -73,7 +73,7 @@ Status checkView(OperationContext* opCtx,
Status checkReplState(OperationContext* opCtx,
NamespaceStringOrUUID dbAndUUID,
- const Collection* collection) {
+ const CollectionPtr& collection) {
auto replCoord = repl::ReplicationCoordinator::get(opCtx);
auto canAcceptWrites = replCoord->canAcceptWritesFor(opCtx, dbAndUUID);
bool writesAreReplicatedAndNotPrimary = opCtx->writesAreReplicated() && !canAcceptWrites;
@@ -142,7 +142,7 @@ StatusWith<const IndexDescriptor*> getDescriptorByKeyPattern(OperationContext* o
* to be held to look up the index name from the key pattern.
*/
StatusWith<std::vector<std::string>> getIndexNames(OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
const BSONElement& indexElem) {
invariant(opCtx->lockState()->isCollectionLockedForMode(collection->ns(), MODE_IX));
@@ -187,7 +187,7 @@ std::vector<UUID> abortIndexBuildByIndexNames(OperationContext* opCtx,
* Drops single index given a descriptor.
*/
Status dropIndexByDescriptor(OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
IndexCatalog* indexCatalog,
const IndexDescriptor* desc) {
if (desc->isIdIndex()) {
diff --git a/src/mongo/db/catalog/index_build_block.cpp b/src/mongo/db/catalog/index_build_block.cpp
index d49a71bbc7e..1409d7147cb 100644
--- a/src/mongo/db/catalog/index_build_block.cpp
+++ b/src/mongo/db/catalog/index_build_block.cpp
@@ -243,7 +243,7 @@ void IndexBuildBlock::success(OperationContext* opCtx, Collection* collection) {
}
const IndexCatalogEntry* IndexBuildBlock::getEntry(OperationContext* opCtx,
- const Collection* collection) const {
+ const CollectionPtr& collection) const {
auto descriptor = collection->getIndexCatalog()->findIndexByName(
opCtx, _indexName, true /* includeUnfinishedIndexes */);
diff --git a/src/mongo/db/catalog/index_build_block.h b/src/mongo/db/catalog/index_build_block.h
index 793d0e871fa..d248df83eab 100644
--- a/src/mongo/db/catalog/index_build_block.h
+++ b/src/mongo/db/catalog/index_build_block.h
@@ -97,7 +97,8 @@ public:
*
* This entry is owned by the IndexCatalog.
*/
- const IndexCatalogEntry* getEntry(OperationContext* opCtx, const Collection* collection) const;
+ const IndexCatalogEntry* getEntry(OperationContext* opCtx,
+ const CollectionPtr& collection) const;
IndexCatalogEntry* getEntry(OperationContext* opCtx, Collection* collection);
/**
diff --git a/src/mongo/db/catalog/index_builds_manager.cpp b/src/mongo/db/catalog/index_builds_manager.cpp
index 273be3df5a6..1edf3e07a87 100644
--- a/src/mongo/db/catalog/index_builds_manager.cpp
+++ b/src/mongo/db/catalog/index_builds_manager.cpp
@@ -121,7 +121,7 @@ Status IndexBuildsManager::setUpIndexBuild(OperationContext* opCtx,
}
Status IndexBuildsManager::startBuildingIndex(OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
const UUID& buildUUID,
boost::optional<RecordId> resumeAfterRecordId) {
auto builder = invariant(_getBuilder(buildUUID));
@@ -130,13 +130,13 @@ Status IndexBuildsManager::startBuildingIndex(OperationContext* opCtx,
}
Status IndexBuildsManager::resumeBuildingIndexFromBulkLoadPhase(OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
const UUID& buildUUID) {
return invariant(_getBuilder(buildUUID))->dumpInsertsFromBulk(opCtx, collection);
}
StatusWith<std::pair<long long, long long>> IndexBuildsManager::startBuildingIndexForRecovery(
- OperationContext* opCtx, const Collection* coll, const UUID& buildUUID, RepairData repair) {
+ OperationContext* opCtx, const CollectionPtr& coll, const UUID& buildUUID, RepairData repair) {
auto builder = invariant(_getBuilder(buildUUID));
// Iterate all records in the collection. Validate the records and index them
@@ -278,13 +278,13 @@ Status IndexBuildsManager::drainBackgroundWrites(
Status IndexBuildsManager::retrySkippedRecords(OperationContext* opCtx,
const UUID& buildUUID,
- const Collection* collection) {
+ const CollectionPtr& collection) {
auto builder = invariant(_getBuilder(buildUUID));
return builder->retrySkippedRecords(opCtx, collection);
}
Status IndexBuildsManager::checkIndexConstraintViolations(OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
const UUID& buildUUID) {
auto builder = invariant(_getBuilder(buildUUID));
@@ -334,7 +334,7 @@ bool IndexBuildsManager::abortIndexBuild(OperationContext* opCtx,
}
bool IndexBuildsManager::abortIndexBuildWithoutCleanupForRollback(OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
const UUID& buildUUID,
bool isResumable) {
auto builder = _getBuilder(buildUUID);
@@ -356,7 +356,7 @@ bool IndexBuildsManager::abortIndexBuildWithoutCleanupForRollback(OperationConte
}
bool IndexBuildsManager::abortIndexBuildWithoutCleanupForShutdown(OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
const UUID& buildUUID,
bool isResumable) {
auto builder = _getBuilder(buildUUID);
@@ -414,7 +414,7 @@ StatusWith<int> IndexBuildsManager::_moveRecordToLostAndFound(
invariant(opCtx->lockState()->isCollectionLockedForMode(nss, MODE_IX));
auto originalCollection = CollectionCatalog::get(opCtx).lookupCollectionByNamespace(opCtx, nss);
- const Collection* localCollection =
+ CollectionPtr localCollection =
CollectionCatalog::get(opCtx).lookupCollectionByNamespace(opCtx, lostAndFoundNss);
// Create the collection if it doesn't exist.
diff --git a/src/mongo/db/catalog/index_builds_manager.h b/src/mongo/db/catalog/index_builds_manager.h
index 5928e088afb..bf731dfeb15 100644
--- a/src/mongo/db/catalog/index_builds_manager.h
+++ b/src/mongo/db/catalog/index_builds_manager.h
@@ -44,6 +44,7 @@
namespace mongo {
class Collection;
+class CollectionPtr;
class OperationContext;
class ServiceContext;
@@ -97,12 +98,12 @@ public:
* Runs the scanning/insertion phase of the index build..
*/
Status startBuildingIndex(OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
const UUID& buildUUID,
boost::optional<RecordId> resumeAfterRecordId = boost::none);
Status resumeBuildingIndexFromBulkLoadPhase(OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
const UUID& buildUUID);
/**
@@ -112,7 +113,10 @@ public:
* Returns the number of records and the size of the data iterated over.
*/
StatusWith<std::pair<long long, long long>> startBuildingIndexForRecovery(
- OperationContext* opCtx, const Collection* coll, const UUID& buildUUID, RepairData repair);
+ OperationContext* opCtx,
+ const CollectionPtr& coll,
+ const UUID& buildUUID,
+ RepairData repair);
/**
* Document inserts observed during the scanning/insertion phase of an index build are not
@@ -129,13 +133,13 @@ public:
*/
Status retrySkippedRecords(OperationContext* opCtx,
const UUID& buildUUID,
- const Collection* collection);
+ const CollectionPtr& collection);
/**
* Runs the index constraint violation checking phase of the index build..
*/
Status checkIndexConstraintViolations(OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
const UUID& buildUUID);
/**
@@ -168,7 +172,7 @@ public:
* been cleared away, or not having yet started..
*/
bool abortIndexBuildWithoutCleanupForRollback(OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
const UUID& buildUUID,
bool isResumable);
@@ -178,7 +182,7 @@ public:
* index build and resumable index builds are supported.
*/
bool abortIndexBuildWithoutCleanupForShutdown(OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
const UUID& buildUUID,
bool isResumable);
diff --git a/src/mongo/db/catalog/index_catalog.h b/src/mongo/db/catalog/index_catalog.h
index 559d5529fb7..f59ee2a05c8 100644
--- a/src/mongo/db/catalog/index_catalog.h
+++ b/src/mongo/db/catalog/index_catalog.h
@@ -45,6 +45,7 @@ namespace mongo {
class Client;
class Collection;
+class CollectionPtr;
class IndexDescriptor;
struct InsertDeleteOptions;
@@ -410,7 +411,7 @@ public:
* See IndexCatalogEntry::setMultikey().
*/
virtual void setMultikeyPaths(OperationContext* const opCtx,
- const Collection* coll,
+ const CollectionPtr& coll,
const IndexDescriptor* const desc,
const KeyStringSet& multikeyMetadataKeys,
const MultikeyPaths& multikeyPaths) const = 0;
@@ -424,7 +425,7 @@ public:
* This method may throw.
*/
virtual Status indexRecords(OperationContext* const opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
const std::vector<BsonRecord>& bsonRecords,
int64_t* const keysInsertedOut) = 0;
@@ -435,7 +436,7 @@ public:
* This method may throw.
*/
virtual Status updateRecord(OperationContext* const opCtx,
- const Collection* coll,
+ const CollectionPtr& coll,
const BSONObj& oldDoc,
const BSONObj& newDoc,
const RecordId& recordId,
@@ -483,7 +484,7 @@ public:
InsertDeleteOptions* options) const = 0;
virtual void indexBuildSuccess(OperationContext* opCtx,
- const Collection* coll,
+ const CollectionPtr& coll,
IndexCatalogEntry* index) = 0;
};
} // namespace mongo
diff --git a/src/mongo/db/catalog/index_catalog_entry.h b/src/mongo/db/catalog/index_catalog_entry.h
index f0078b662af..8abc7000fdb 100644
--- a/src/mongo/db/catalog/index_catalog_entry.h
+++ b/src/mongo/db/catalog/index_catalog_entry.h
@@ -47,6 +47,7 @@
namespace mongo {
class CollatorInterface;
class Collection;
+class CollectionPtr;
class CollectionCatalogEntry;
class IndexAccessMethod;
class IndexBuildInterceptor;
@@ -132,7 +133,7 @@ public:
* as multikey here.
*/
virtual void setMultikey(OperationContext* const opCtx,
- const Collection* coll,
+ const CollectionPtr& coll,
const KeyStringSet& multikeyMetadataKeys,
const MultikeyPaths& multikeyPaths) = 0;
diff --git a/src/mongo/db/catalog/index_catalog_entry_impl.cpp b/src/mongo/db/catalog/index_catalog_entry_impl.cpp
index 7c604a98a99..7787183bb59 100644
--- a/src/mongo/db/catalog/index_catalog_entry_impl.cpp
+++ b/src/mongo/db/catalog/index_catalog_entry_impl.cpp
@@ -170,7 +170,7 @@ void IndexCatalogEntryImpl::setIsReady(bool newIsReady) {
}
void IndexCatalogEntryImpl::setMultikey(OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
const KeyStringSet& multikeyMetadataKeys,
const MultikeyPaths& multikeyPaths) {
// An index can either track path-level multikey information in the catalog or as metadata keys
@@ -256,7 +256,7 @@ void IndexCatalogEntryImpl::setMultikey(OperationContext* opCtx,
}
Status IndexCatalogEntryImpl::_setMultikeyInMultiDocumentTransaction(
- OperationContext* opCtx, const Collection* collection, const MultikeyPaths& multikeyPaths) {
+ OperationContext* opCtx, const CollectionPtr& collection, const MultikeyPaths& multikeyPaths) {
// If we are inside a multi-document transaction, we write the on-disk multikey update in a
// separate transaction so that it will not generate prepare conflicts with other operations
// that try to set the multikey flag. In general, it should always be safe to update the
@@ -340,7 +340,7 @@ bool IndexCatalogEntryImpl::_catalogIsMultikey(OperationContext* opCtx,
}
void IndexCatalogEntryImpl::_catalogSetMultikey(OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
const MultikeyPaths& multikeyPaths) {
// It's possible that the index type (e.g. ascending/descending index) supports tracking
// path-level multikey information, but this particular index doesn't.
diff --git a/src/mongo/db/catalog/index_catalog_entry_impl.h b/src/mongo/db/catalog/index_catalog_entry_impl.h
index 80a101c4a85..f1feb5e0f92 100644
--- a/src/mongo/db/catalog/index_catalog_entry_impl.h
+++ b/src/mongo/db/catalog/index_catalog_entry_impl.h
@@ -155,7 +155,7 @@ public:
* as multikey here.
*/
void setMultikey(OperationContext* opCtx,
- const Collection* coll,
+ const CollectionPtr& coll,
const KeyStringSet& multikeyMetadataKeys,
const MultikeyPaths& multikeyPaths) final;
@@ -188,7 +188,7 @@ private:
* Used by setMultikey() only.
*/
Status _setMultikeyInMultiDocumentTransaction(OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
const MultikeyPaths& multikeyPaths);
bool _catalogIsReady(OperationContext* opCtx) const;
@@ -205,7 +205,7 @@ private:
* Sets on-disk multikey flag for this index.
*/
void _catalogSetMultikey(OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
const MultikeyPaths& multikeyPaths);
KVPrefix _catalogGetPrefix(OperationContext* opCtx) const;
diff --git a/src/mongo/db/catalog/index_catalog_impl.cpp b/src/mongo/db/catalog/index_catalog_impl.cpp
index 8874008e553..2341345310b 100644
--- a/src/mongo/db/catalog/index_catalog_impl.cpp
+++ b/src/mongo/db/catalog/index_catalog_impl.cpp
@@ -1092,7 +1092,7 @@ void IndexCatalogImpl::deleteIndexFromDisk(OperationContext* opCtx, const string
}
void IndexCatalogImpl::setMultikeyPaths(OperationContext* const opCtx,
- const Collection* coll,
+ const CollectionPtr& coll,
const IndexDescriptor* desc,
const KeyStringSet& multikeyMetadataKeys,
const MultikeyPaths& multikeyPaths) const {
@@ -1325,7 +1325,7 @@ const IndexDescriptor* IndexCatalogImpl::refreshEntry(OperationContext* opCtx,
// ---------------------------
Status IndexCatalogImpl::_indexKeys(OperationContext* opCtx,
- const Collection* coll,
+ const CollectionPtr& coll,
IndexCatalogEntry* index,
const KeyStringSet& keys,
const KeyStringSet& multikeyMetadataKeys,
@@ -1378,7 +1378,7 @@ Status IndexCatalogImpl::_indexKeys(OperationContext* opCtx,
}
Status IndexCatalogImpl::_indexFilteredRecords(OperationContext* opCtx,
- const Collection* coll,
+ const CollectionPtr& coll,
IndexCatalogEntry* index,
const std::vector<BsonRecord>& bsonRecords,
int64_t* keysInsertedOut) {
@@ -1429,7 +1429,7 @@ Status IndexCatalogImpl::_indexFilteredRecords(OperationContext* opCtx,
}
Status IndexCatalogImpl::_indexRecords(OperationContext* opCtx,
- const Collection* coll,
+ const CollectionPtr& coll,
IndexCatalogEntry* index,
const std::vector<BsonRecord>& bsonRecords,
int64_t* keysInsertedOut) {
@@ -1451,7 +1451,7 @@ Status IndexCatalogImpl::_indexRecords(OperationContext* opCtx,
}
Status IndexCatalogImpl::_updateRecord(OperationContext* const opCtx,
- const Collection* coll,
+ const CollectionPtr& coll,
IndexCatalogEntry* index,
const BSONObj& oldDoc,
const BSONObj& newDoc,
@@ -1592,7 +1592,7 @@ void IndexCatalogImpl::_unindexRecord(OperationContext* opCtx,
}
Status IndexCatalogImpl::indexRecords(OperationContext* opCtx,
- const Collection* coll,
+ const CollectionPtr& coll,
const std::vector<BsonRecord>& bsonRecords,
int64_t* keysInsertedOut) {
if (keysInsertedOut) {
@@ -1615,7 +1615,7 @@ Status IndexCatalogImpl::indexRecords(OperationContext* opCtx,
}
Status IndexCatalogImpl::updateRecord(OperationContext* const opCtx,
- const Collection* coll,
+ const CollectionPtr& coll,
const BSONObj& oldDoc,
const BSONObj& newDoc,
const RecordId& recordId,
@@ -1741,7 +1741,7 @@ void IndexCatalogImpl::prepareInsertDeleteOptions(OperationContext* opCtx,
}
void IndexCatalogImpl::indexBuildSuccess(OperationContext* opCtx,
- const Collection* coll,
+ const CollectionPtr& coll,
IndexCatalogEntry* index) {
auto releasedEntry = _buildingIndexes.release(index->descriptor());
invariant(releasedEntry.get() == index);
@@ -1765,7 +1765,7 @@ void IndexCatalogImpl::indexBuildSuccess(OperationContext* opCtx,
}
StatusWith<BSONObj> IndexCatalogImpl::_fixIndexSpec(OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
const BSONObj& spec) const {
auto statusWithSpec = adjustIndexSpecObject(spec);
if (!statusWithSpec.isOK()) {
diff --git a/src/mongo/db/catalog/index_catalog_impl.h b/src/mongo/db/catalog/index_catalog_impl.h
index b18ed1a80e8..191a76bb529 100644
--- a/src/mongo/db/catalog/index_catalog_impl.h
+++ b/src/mongo/db/catalog/index_catalog_impl.h
@@ -46,6 +46,7 @@ namespace mongo {
class Client;
class Collection;
+class CollectionPtr;
class IndexDescriptor;
struct InsertDeleteOptions;
@@ -221,7 +222,7 @@ public:
// ---- modify single index
void setMultikeyPaths(OperationContext* const opCtx,
- const Collection* coll,
+ const CollectionPtr& coll,
const IndexDescriptor* desc,
const KeyStringSet& multikeyMetadataKeys,
const MultikeyPaths& multikeyPaths) const override;
@@ -235,7 +236,7 @@ public:
* This method may throw.
*/
Status indexRecords(OperationContext* opCtx,
- const Collection* coll,
+ const CollectionPtr& coll,
const std::vector<BsonRecord>& bsonRecords,
int64_t* keysInsertedOut) override;
@@ -243,7 +244,7 @@ public:
* See IndexCatalog::updateRecord
*/
Status updateRecord(OperationContext* const opCtx,
- const Collection* coll,
+ const CollectionPtr& coll,
const BSONObj& oldDoc,
const BSONObj& newDoc,
const RecordId& recordId,
@@ -281,7 +282,7 @@ public:
InsertDeleteOptions* options) const override;
void indexBuildSuccess(OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
IndexCatalogEntry* index) override;
private:
@@ -296,7 +297,7 @@ private:
std::string _getAccessMethodName(const BSONObj& keyPattern) const;
Status _indexKeys(OperationContext* opCtx,
- const Collection* coll,
+ const CollectionPtr& coll,
IndexCatalogEntry* index,
const KeyStringSet& keys,
const KeyStringSet& multikeyMetadataKeys,
@@ -307,19 +308,19 @@ private:
int64_t* keysInsertedOut);
Status _indexFilteredRecords(OperationContext* opCtx,
- const Collection* coll,
+ const CollectionPtr& coll,
IndexCatalogEntry* index,
const std::vector<BsonRecord>& bsonRecords,
int64_t* keysInsertedOut);
Status _indexRecords(OperationContext* opCtx,
- const Collection* coll,
+ const CollectionPtr& coll,
IndexCatalogEntry* index,
const std::vector<BsonRecord>& bsonRecords,
int64_t* keysInsertedOut);
Status _updateRecord(OperationContext* const opCtx,
- const Collection* coll,
+ const CollectionPtr& coll,
IndexCatalogEntry* index,
const BSONObj& oldDoc,
const BSONObj& newDoc,
@@ -348,7 +349,7 @@ private:
* plugin-level transformations if appropriate, etc.
*/
StatusWith<BSONObj> _fixIndexSpec(OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
const BSONObj& spec) const;
Status _isSpecOk(OperationContext* opCtx, const BSONObj& spec) const;
diff --git a/src/mongo/db/catalog/index_catalog_noop.h b/src/mongo/db/catalog/index_catalog_noop.h
index 9cc63d34ed5..64d7b9c46b2 100644
--- a/src/mongo/db/catalog/index_catalog_noop.h
+++ b/src/mongo/db/catalog/index_catalog_noop.h
@@ -194,19 +194,19 @@ public:
}
void setMultikeyPaths(OperationContext* const opCtx,
- const Collection* coll,
+ const CollectionPtr& coll,
const IndexDescriptor* const desc,
const MultikeyPaths& multikeyPaths) const override {}
Status indexRecords(OperationContext* const opCtx,
- const Collection* coll,
+ const CollectionPtr& coll,
const std::vector<BsonRecord>& bsonRecords,
int64_t* const keysInsertedOut) override {
return Status::OK();
}
Status updateRecord(OperationContext* const opCtx,
- const Collection* coll,
+ const CollectionPtr& coll,
const BSONObj& oldDoc,
const BSONObj& newDoc,
const RecordId& recordId,
@@ -243,7 +243,7 @@ public:
InsertDeleteOptions* options) const override {}
void indexBuildSuccess(OperationContext* opCtx,
- const Collection* coll,
+ const CollectionPtr& coll,
IndexCatalogEntry* index) override {}
};
diff --git a/src/mongo/db/catalog/index_signature_test.cpp b/src/mongo/db/catalog/index_signature_test.cpp
index 4aee9d6a052..e7a83ffefc6 100644
--- a/src/mongo/db/catalog/index_signature_test.cpp
+++ b/src/mongo/db/catalog/index_signature_test.cpp
@@ -68,7 +68,7 @@ public:
return _nss;
}
- const Collection* coll() const {
+ const CollectionPtr& coll() const {
return (*_coll).getCollection();
}
diff --git a/src/mongo/db/catalog/list_indexes.cpp b/src/mongo/db/catalog/list_indexes.cpp
index 937598f30fd..b97fcf4cf6b 100644
--- a/src/mongo/db/catalog/list_indexes.cpp
+++ b/src/mongo/db/catalog/list_indexes.cpp
@@ -52,20 +52,19 @@ namespace mongo {
StatusWith<std::list<BSONObj>> listIndexes(OperationContext* opCtx,
const NamespaceStringOrUUID& ns,
bool includeBuildUUIDs) {
- AutoGetCollectionForReadCommand ctx(opCtx, ns);
- const Collection* collection = ctx.getCollection();
- auto nss = ctx.getNss();
+ AutoGetCollectionForReadCommand collection(opCtx, ns);
+ auto nss = collection.getNss();
if (!collection) {
return StatusWith<std::list<BSONObj>>(ErrorCodes::NamespaceNotFound,
- str::stream()
- << "ns does not exist: " << ctx.getNss().ns());
+ str::stream() << "ns does not exist: "
+ << collection.getNss().ns());
}
return StatusWith<std::list<BSONObj>>(
- listIndexesInLock(opCtx, collection, nss, includeBuildUUIDs));
+ listIndexesInLock(opCtx, collection.getCollection(), nss, includeBuildUUIDs));
}
std::list<BSONObj> listIndexesInLock(OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
const NamespaceString& nss,
bool includeBuildUUIDs) {
invariant(opCtx->lockState()->isCollectionLockedForMode(nss, MODE_IS));
diff --git a/src/mongo/db/catalog/list_indexes.h b/src/mongo/db/catalog/list_indexes.h
index 8ceeb2d019e..1dd298c1b15 100644
--- a/src/mongo/db/catalog/list_indexes.h
+++ b/src/mongo/db/catalog/list_indexes.h
@@ -44,7 +44,7 @@ StatusWith<std::list<BSONObj>> listIndexes(OperationContext* opCtx,
const NamespaceStringOrUUID& ns,
bool includeBuildUUIDs);
std::list<BSONObj> listIndexesInLock(OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
const NamespaceString& nss,
bool includeBuildUUIDs);
std::list<BSONObj> listIndexesEmptyListIfMissing(OperationContext* opCtx,
diff --git a/src/mongo/db/catalog/multi_index_block.cpp b/src/mongo/db/catalog/multi_index_block.cpp
index bd6343b9c3d..f7ec01cb624 100644
--- a/src/mongo/db/catalog/multi_index_block.cpp
+++ b/src/mongo/db/catalog/multi_index_block.cpp
@@ -140,7 +140,7 @@ MultiIndexBlock::OnInitFn MultiIndexBlock::kNoopOnInitFn =
[](std::vector<BSONObj>& specs) -> Status { return Status::OK(); };
MultiIndexBlock::OnInitFn MultiIndexBlock::makeTimestampedIndexOnInitFn(OperationContext* opCtx,
- const Collection* coll) {
+ const CollectionPtr& coll) {
return [opCtx, ns = coll->ns()](std::vector<BSONObj>& specs) -> Status {
opCtx->getServiceContext()->getOpObserver()->onStartIndexBuildSinglePhase(opCtx, ns);
return Status::OK();
@@ -350,7 +350,7 @@ StatusWith<std::vector<BSONObj>> MultiIndexBlock::init(
Status MultiIndexBlock::insertAllDocumentsInCollection(
OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
boost::optional<RecordId> resumeAfterRecordId) {
invariant(!_buildIsCleanedUp);
invariant(opCtx->lockState()->isNoop() || !opCtx->lockState()->inAWriteUnitOfWork());
@@ -411,7 +411,7 @@ Status MultiIndexBlock::insertAllDocumentsInCollection(
yieldPolicy = PlanYieldPolicy::YieldPolicy::WRITE_CONFLICT_RETRY_ONLY;
}
auto exec = collection->makePlanExecutor(
- opCtx, yieldPolicy, Collection::ScanDirection::kForward, resumeAfterRecordId);
+ opCtx, collection, yieldPolicy, Collection::ScanDirection::kForward, resumeAfterRecordId);
// Hint to the storage engine that this collection scan should not keep data in the cache.
bool readOnce = useReadOnceCursorsForIndexBuilds.load();
@@ -558,13 +558,14 @@ Status MultiIndexBlock::insertSingleDocumentForInitialSyncOrRecovery(OperationCo
return Status::OK();
}
-Status MultiIndexBlock::dumpInsertsFromBulk(OperationContext* opCtx, const Collection* collection) {
+Status MultiIndexBlock::dumpInsertsFromBulk(OperationContext* opCtx,
+ const CollectionPtr& collection) {
return dumpInsertsFromBulk(opCtx, collection, nullptr);
}
Status MultiIndexBlock::dumpInsertsFromBulk(
OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
const IndexAccessMethod::RecordIdHandlerFn& onDuplicateRecord) {
invariant(!_buildIsCleanedUp);
invariant(opCtx->lockState()->isNoop() || !opCtx->lockState()->inAWriteUnitOfWork());
@@ -647,7 +648,7 @@ Status MultiIndexBlock::drainBackgroundWrites(
IndexBuildPhase_serializer(_phase).toString());
_phase = IndexBuildPhaseEnum::kDrainWrites;
- const Collection* coll =
+ const CollectionPtr& coll =
CollectionCatalog::get(opCtx).lookupCollectionByUUID(opCtx, _collectionUUID.get());
// Drain side-writes table for each index. This only drains what is visible. Assuming intent
@@ -672,7 +673,8 @@ Status MultiIndexBlock::drainBackgroundWrites(
return Status::OK();
}
-Status MultiIndexBlock::retrySkippedRecords(OperationContext* opCtx, const Collection* collection) {
+Status MultiIndexBlock::retrySkippedRecords(OperationContext* opCtx,
+ const CollectionPtr& collection) {
invariant(!_buildIsCleanedUp);
for (auto&& index : _indexes) {
auto interceptor = index.block->getEntry(opCtx, collection)->indexBuildInterceptor();
@@ -687,7 +689,7 @@ Status MultiIndexBlock::retrySkippedRecords(OperationContext* opCtx, const Colle
return Status::OK();
}
-Status MultiIndexBlock::checkConstraints(OperationContext* opCtx, const Collection* collection) {
+Status MultiIndexBlock::checkConstraints(OperationContext* opCtx, const CollectionPtr& collection) {
invariant(!_buildIsCleanedUp);
// For each index that may be unique, check that no recorded duplicates still exist. This can
@@ -707,12 +709,12 @@ Status MultiIndexBlock::checkConstraints(OperationContext* opCtx, const Collecti
}
boost::optional<ResumeIndexInfo> MultiIndexBlock::abortWithoutCleanupForRollback(
- OperationContext* opCtx, const Collection* collection, bool isResumable) {
+ OperationContext* opCtx, const CollectionPtr& collection, bool isResumable) {
return _abortWithoutCleanup(opCtx, collection, false /* shutdown */, isResumable);
}
void MultiIndexBlock::abortWithoutCleanupForShutdown(OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
bool isResumable) {
_abortWithoutCleanup(opCtx, collection, true /* shutdown */, isResumable);
}
@@ -794,10 +796,8 @@ void MultiIndexBlock::setIndexBuildMethod(IndexBuildMethod indexBuildMethod) {
_method = indexBuildMethod;
}
-boost::optional<ResumeIndexInfo> MultiIndexBlock::_abortWithoutCleanup(OperationContext* opCtx,
- const Collection* collection,
- bool shutdown,
- bool isResumable) {
+boost::optional<ResumeIndexInfo> MultiIndexBlock::_abortWithoutCleanup(
+ OperationContext* opCtx, const CollectionPtr& collection, bool shutdown, bool isResumable) {
invariant(!_buildIsCleanedUp);
UninterruptibleLockGuard noInterrupt(opCtx->lockState());
// Lock if it's not already locked, to ensure storage engine cannot be destructed out from
@@ -834,7 +834,7 @@ boost::optional<ResumeIndexInfo> MultiIndexBlock::_abortWithoutCleanup(Operation
}
void MultiIndexBlock::_writeStateToDisk(OperationContext* opCtx,
- const Collection* collection) const {
+ const CollectionPtr& collection) const {
auto obj = _constructStateObject(opCtx, collection);
auto rs = opCtx->getServiceContext()
->getStorageEngine()
@@ -864,7 +864,7 @@ void MultiIndexBlock::_writeStateToDisk(OperationContext* opCtx,
}
BSONObj MultiIndexBlock::_constructStateObject(OperationContext* opCtx,
- const Collection* collection) const {
+ const CollectionPtr& collection) const {
BSONObjBuilder builder;
_buildUUID->appendToBuilder(&builder, "_id");
builder.append("phase", IndexBuildPhase_serializer(_phase));
diff --git a/src/mongo/db/catalog/multi_index_block.h b/src/mongo/db/catalog/multi_index_block.h
index f601e22a12c..7ce46547d04 100644
--- a/src/mongo/db/catalog/multi_index_block.h
+++ b/src/mongo/db/catalog/multi_index_block.h
@@ -56,6 +56,7 @@ namespace mongo {
extern FailPoint leaveIndexBuildUnfinishedForShutdown;
class Collection;
+class CollectionPtr;
class MatchExpression;
class NamespaceString;
class OperationContext;
@@ -121,7 +122,7 @@ public:
const BSONObj& spec,
OnInitFn onInit);
StatusWith<std::vector<BSONObj>> initForResume(OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
const std::vector<BSONObj>& specs,
const ResumeIndexInfo& resumeInfo);
@@ -136,7 +137,8 @@ public:
* When called on primaries, this generates a new optime, writes a no-op oplog entry, and
* timestamps the first catalog write. Does nothing on secondaries.
*/
- static OnInitFn makeTimestampedIndexOnInitFn(OperationContext* opCtx, const Collection* coll);
+ static OnInitFn makeTimestampedIndexOnInitFn(OperationContext* opCtx,
+ const CollectionPtr& coll);
/**
* Inserts all documents in the Collection into the indexes and logs with timing info.
@@ -152,7 +154,7 @@ public:
*/
Status insertAllDocumentsInCollection(
OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
boost::optional<RecordId> resumeAfterRecordId = boost::none);
/**
@@ -177,9 +179,9 @@ public:
*
* Should not be called inside of a WriteUnitOfWork.
*/
- Status dumpInsertsFromBulk(OperationContext* opCtx, const Collection* collection);
+ Status dumpInsertsFromBulk(OperationContext* opCtx, const CollectionPtr& collection);
Status dumpInsertsFromBulk(OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
const IndexAccessMethod::RecordIdHandlerFn& onDuplicateRecord);
/**
* For background indexes using an IndexBuildInterceptor to capture inserts during a build,
@@ -208,7 +210,7 @@ public:
* of an index build, so it must ensure that before it finishes, it has indexed all documents in
* a collection, requiring a call to this function upon completion.
*/
- Status retrySkippedRecords(OperationContext* opCtx, const Collection* collection);
+ Status retrySkippedRecords(OperationContext* opCtx, const CollectionPtr& collection);
/**
* Check any constraits that may have been temporarily violated during the index build for
@@ -217,7 +219,7 @@ public:
*
* Must not be in a WriteUnitOfWork.
*/
- Status checkConstraints(OperationContext* opCtx, const Collection* collection);
+ Status checkConstraints(OperationContext* opCtx, const CollectionPtr& collection);
/**
* Marks the index ready for use. Should only be called as the last method after
@@ -279,7 +281,7 @@ public:
* This should only be used during rollback.
*/
boost::optional<ResumeIndexInfo> abortWithoutCleanupForRollback(OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
bool isResumable);
/**
@@ -292,7 +294,7 @@ public:
* This should only be used during shutdown.
*/
void abortWithoutCleanupForShutdown(OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
bool isResumable);
/**
@@ -321,13 +323,13 @@ private:
* supported.
*/
boost::optional<ResumeIndexInfo> _abortWithoutCleanup(OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
bool shutdown,
bool isResumable);
- void _writeStateToDisk(OperationContext* opCtx, const Collection* collection) const;
+ void _writeStateToDisk(OperationContext* opCtx, const CollectionPtr& collection) const;
- BSONObj _constructStateObject(OperationContext* opCtx, const Collection* collection) const;
+ BSONObj _constructStateObject(OperationContext* opCtx, const CollectionPtr& collection) const;
Status _failPointHangDuringBuild(OperationContext* opCtx,
FailPoint* fp,
diff --git a/src/mongo/db/catalog/rename_collection.cpp b/src/mongo/db/catalog/rename_collection.cpp
index 9272fd2e3ff..1a02467c000 100644
--- a/src/mongo/db/catalog/rename_collection.cpp
+++ b/src/mongo/db/catalog/rename_collection.cpp
@@ -220,7 +220,7 @@ Status renameCollectionAndDropTarget(OperationContext* opCtx,
OptionalCollectionUUID uuid,
NamespaceString source,
NamespaceString target,
- const Collection* targetColl,
+ const CollectionPtr& targetColl,
RenameCollectionOptions options,
repl::OpTime renameOpTimeFromApplyOps) {
return writeConflictRetry(opCtx, "renameCollection", target.ns(), [&] {
@@ -560,7 +560,7 @@ Status renameBetweenDBs(OperationContext* opCtx,
"temporaryCollection"_attr = tmpName,
"sourceCollection"_attr = source);
- const Collection* tmpColl = nullptr;
+ CollectionPtr tmpColl = nullptr;
{
auto collectionOptions =
DurableCatalog::get(opCtx)->getCollectionOptions(opCtx, sourceColl->getCatalogId());
@@ -648,10 +648,10 @@ Status renameBetweenDBs(OperationContext* opCtx,
// drop the exclusive database lock on the target and grab an intent lock on the temporary
// collection.
targetDBLock.reset();
+ tmpColl.reset();
AutoGetCollection autoTmpColl(opCtx, tmpCollUUID, MODE_IX);
- tmpColl = autoTmpColl.getCollection();
- if (!tmpColl) {
+ if (!autoTmpColl) {
return Status(ErrorCodes::NamespaceNotFound,
str::stream() << "Temporary collection '" << tmpName
<< "' was removed while renaming collection across DBs");
@@ -672,7 +672,7 @@ Status renameBetweenDBs(OperationContext* opCtx,
for (int i = 0; record && (i < internalInsertMaxBatchSize.load()); i++) {
const InsertStatement stmt(record->data.releaseToBson());
OpDebug* const opDebug = nullptr;
- auto status = tmpColl->insertDocument(opCtx, stmt, opDebug, true);
+ auto status = autoTmpColl->insertDocument(opCtx, stmt, opDebug, true);
if (!status.isOK()) {
return status;
}
@@ -892,11 +892,10 @@ Status renameCollectionForApplyOps(OperationContext* opCtx,
str::stream() << "Cannot rename collection to the oplog");
}
- const Collection* const sourceColl =
- AutoGetCollectionForRead(opCtx, sourceNss, AutoGetCollectionViewMode::kViewsPermitted)
- .getCollection();
+ AutoGetCollectionForRead sourceColl(
+ opCtx, sourceNss, AutoGetCollectionViewMode::kViewsPermitted);
- if (sourceNss.isDropPendingNamespace() || sourceColl == nullptr) {
+ if (sourceNss.isDropPendingNamespace() || !sourceColl) {
boost::optional<NamespaceString> dropTargetNss;
if (options.dropTarget)
diff --git a/src/mongo/db/catalog/rename_collection_test.cpp b/src/mongo/db/catalog/rename_collection_test.cpp
index 726265f469f..67ae7957158 100644
--- a/src/mongo/db/catalog/rename_collection_test.cpp
+++ b/src/mongo/db/catalog/rename_collection_test.cpp
@@ -110,7 +110,7 @@ public:
bool fromMigrate) override;
void onCreateCollection(OperationContext* opCtx,
- const Collection* coll,
+ const CollectionPtr& coll,
const NamespaceString& collectionName,
const CollectionOptions& options,
const BSONObj& idIndex,
@@ -224,7 +224,7 @@ void OpObserverMock::onInserts(OperationContext* opCtx,
}
void OpObserverMock::onCreateCollection(OperationContext* opCtx,
- const Collection* coll,
+ const CollectionPtr& coll,
const NamespaceString& collectionName,
const CollectionOptions& options,
const BSONObj& idIndex,
@@ -419,8 +419,7 @@ bool _collectionExists(OperationContext* opCtx, const NamespaceString& nss) {
* Returns collection options.
*/
CollectionOptions _getCollectionOptions(OperationContext* opCtx, const NamespaceString& nss) {
- AutoGetCollectionForRead autoColl(opCtx, nss);
- auto collection = autoColl.getCollection();
+ AutoGetCollectionForRead collection(opCtx, nss);
ASSERT_TRUE(collection) << "Unable to get collections options for " << nss
<< " because collection does not exist.";
return DurableCatalog::get(opCtx)->getCollectionOptions(opCtx, collection->getCatalogId());
@@ -439,7 +438,7 @@ CollectionUUID _getCollectionUuid(OperationContext* opCtx, const NamespaceString
* Get collection namespace by UUID.
*/
NamespaceString _getCollectionNssFromUUID(OperationContext* opCtx, const UUID& uuid) {
- const Collection* source = CollectionCatalog::get(opCtx).lookupCollectionByUUID(opCtx, uuid);
+ const CollectionPtr& source = CollectionCatalog::get(opCtx).lookupCollectionByUUID(opCtx, uuid);
return source ? source->ns() : NamespaceString();
}
@@ -447,8 +446,7 @@ NamespaceString _getCollectionNssFromUUID(OperationContext* opCtx, const UUID& u
* Returns true if namespace refers to a temporary collection.
*/
bool _isTempCollection(OperationContext* opCtx, const NamespaceString& nss) {
- AutoGetCollectionForRead autoColl(opCtx, nss);
- auto collection = autoColl.getCollection();
+ AutoGetCollectionForRead collection(opCtx, nss);
ASSERT_TRUE(collection) << "Unable to check if " << nss
<< " is a temporary collection because collection does not exist.";
auto options = _getCollectionOptions(opCtx, nss);
@@ -483,8 +481,7 @@ void _createIndexOnEmptyCollection(OperationContext* opCtx,
*/
void _insertDocument(OperationContext* opCtx, const NamespaceString& nss, const BSONObj& doc) {
writeConflictRetry(opCtx, "_insertDocument", nss.ns(), [=] {
- AutoGetCollection autoColl(opCtx, nss, MODE_X);
- auto collection = autoColl.getCollection();
+ AutoGetCollection collection(opCtx, nss, MODE_X);
ASSERT_TRUE(collection) << "Cannot insert document " << doc << " into collection " << nss
<< " because collection " << nss << " does not exist.";
@@ -499,7 +496,7 @@ void _insertDocument(OperationContext* opCtx, const NamespaceString& nss, const
* Retrieves the pointer to a collection associated with the given namespace string from the
* catalog. The caller must hold the appropriate locks from the lock manager.
*/
-const Collection* _getCollection_inlock(OperationContext* opCtx, const NamespaceString& nss) {
+CollectionPtr _getCollection_inlock(OperationContext* opCtx, const NamespaceString& nss) {
invariant(opCtx->lockState()->isCollectionLockedForMode(nss, MODE_IS));
auto databaseHolder = DatabaseHolder::get(opCtx);
auto* db = databaseHolder->getDb(opCtx, nss.db());
@@ -1185,14 +1182,14 @@ TEST_F(RenameCollectionTest, CollectionPointerRemainsValidThroughRename) {
// Get a pointer to the source collection, and ensure that it reports the expected namespace
// string.
- const Collection* sourceColl = _getCollection_inlock(_opCtx.get(), _sourceNss);
+ CollectionPtr sourceColl = _getCollection_inlock(_opCtx.get(), _sourceNss);
ASSERT(sourceColl);
ASSERT_OK(renameCollection(_opCtx.get(), _sourceNss, _targetNss, {}));
// Retrieve the pointer associated with the target namespace, and ensure that its the same
// pointer (i.e. the renamed collection has the very same Collection instance).
- const Collection* targetColl = _getCollection_inlock(_opCtx.get(), _targetNss);
+ CollectionPtr targetColl = _getCollection_inlock(_opCtx.get(), _targetNss);
ASSERT(targetColl);
ASSERT_EQ(targetColl, sourceColl);
@@ -1202,8 +1199,7 @@ TEST_F(RenameCollectionTest, CollectionPointerRemainsValidThroughRename) {
TEST_F(RenameCollectionTest, CatalogPointersRenameValidThroughRenameForApplyOps) {
_createCollection(_opCtx.get(), _sourceNss);
- const Collection* sourceColl =
- AutoGetCollectionForRead(_opCtx.get(), _sourceNss).getCollection();
+ AutoGetCollectionForRead sourceColl(_opCtx.get(), _sourceNss);
ASSERT(sourceColl);
auto uuid = UUID::gen();
@@ -1211,10 +1207,9 @@ TEST_F(RenameCollectionTest, CatalogPointersRenameValidThroughRenameForApplyOps)
ASSERT_OK(renameCollectionForApplyOps(_opCtx.get(), _sourceNss.db().toString(), uuid, cmd, {}));
ASSERT_FALSE(_collectionExists(_opCtx.get(), _sourceNss));
- const Collection* targetColl =
- AutoGetCollectionForRead(_opCtx.get(), _targetNss).getCollection();
+ AutoGetCollectionForRead targetColl(_opCtx.get(), _targetNss);
ASSERT(targetColl);
- ASSERT_EQ(targetColl, sourceColl);
+ ASSERT_EQ(targetColl.getCollection(), sourceColl.getCollection());
ASSERT_EQ(targetColl->ns(), _targetNss);
}
@@ -1223,7 +1218,7 @@ TEST_F(RenameCollectionTest, CollectionCatalogMappingRemainsIntactThroughRename)
Lock::DBLock sourceLk(_opCtx.get(), _sourceNss.db(), MODE_X);
Lock::DBLock targetLk(_opCtx.get(), _targetNss.db(), MODE_X);
auto& catalog = CollectionCatalog::get(_opCtx.get());
- const Collection* sourceColl = _getCollection_inlock(_opCtx.get(), _sourceNss);
+ CollectionPtr sourceColl = _getCollection_inlock(_opCtx.get(), _sourceNss);
ASSERT(sourceColl);
ASSERT_EQ(sourceColl, catalog.lookupCollectionByUUID(_opCtx.get(), sourceColl->uuid()));
ASSERT_OK(renameCollection(_opCtx.get(), _sourceNss, _targetNss, {}));
diff --git a/src/mongo/db/catalog/throttle_cursor_test.cpp b/src/mongo/db/catalog/throttle_cursor_test.cpp
index 91097350d36..97db1fffad4 100644
--- a/src/mongo/db/catalog/throttle_cursor_test.cpp
+++ b/src/mongo/db/catalog/throttle_cursor_test.cpp
@@ -59,7 +59,7 @@ public:
Date_t getTime();
int64_t getDifferenceInMillis(Date_t start, Date_t end);
- SortedDataInterfaceThrottleCursor getIdIndex(const Collection* coll);
+ SortedDataInterfaceThrottleCursor getIdIndex(const CollectionPtr& coll);
std::unique_ptr<DataThrottle> _dataThrottle;
};
@@ -72,8 +72,7 @@ void ThrottleCursorTest::setUp() {
// Insert random data into the collection. We don't need to create an index as the _id index is
// created by default.
- AutoGetCollection autoColl(operationContext(), kNss, MODE_X);
- const Collection* collection = autoColl.getCollection();
+ AutoGetCollection collection(operationContext(), kNss, MODE_X);
invariant(collection);
OpDebug* const nullOpDebug = nullptr;
@@ -108,7 +107,7 @@ int64_t ThrottleCursorTest::getDifferenceInMillis(Date_t start, Date_t end) {
return end.toMillisSinceEpoch() - start.toMillisSinceEpoch();
}
-SortedDataInterfaceThrottleCursor ThrottleCursorTest::getIdIndex(const Collection* coll) {
+SortedDataInterfaceThrottleCursor ThrottleCursorTest::getIdIndex(const CollectionPtr& coll) {
const IndexDescriptor* idDesc = coll->getIndexCatalog()->findIdIndex(operationContext());
const IndexCatalogEntry* idEntry = coll->getIndexCatalog()->getEntry(idDesc);
const IndexAccessMethod* iam = idEntry->accessMethod();
@@ -119,7 +118,7 @@ SortedDataInterfaceThrottleCursor ThrottleCursorTest::getIdIndex(const Collectio
TEST_F(ThrottleCursorTest, TestSeekableRecordThrottleCursorOff) {
auto opCtx = operationContext();
AutoGetCollection autoColl(opCtx, kNss, MODE_X);
- const Collection* coll = autoColl.getCollection();
+ const CollectionPtr& coll = autoColl.getCollection();
// Use a fixed record data size to simplify the timing calculations.
FailPointEnableBlock failPoint("fixedCursorDataSizeOf512KBForDataThrottle");
@@ -152,7 +151,7 @@ TEST_F(ThrottleCursorTest, TestSeekableRecordThrottleCursorOff) {
TEST_F(ThrottleCursorTest, TestSeekableRecordThrottleCursorOn) {
auto opCtx = operationContext();
AutoGetCollection autoColl(opCtx, kNss, MODE_X);
- const Collection* coll = autoColl.getCollection();
+ const CollectionPtr& coll = autoColl.getCollection();
// Use a fixed record data size to simplify the timing calculations.
FailPointEnableBlock failPoint("fixedCursorDataSizeOf512KBForDataThrottle");
@@ -204,7 +203,7 @@ TEST_F(ThrottleCursorTest, TestSeekableRecordThrottleCursorOn) {
TEST_F(ThrottleCursorTest, TestSeekableRecordThrottleCursorOnLargeDocs) {
auto opCtx = operationContext();
AutoGetCollection autoColl(opCtx, kNss, MODE_X);
- const Collection* coll = autoColl.getCollection();
+ const CollectionPtr& coll = autoColl.getCollection();
// Use a fixed record data size to simplify the timing calculations.
FailPointEnableBlock failPoint("fixedCursorDataSizeOf2MBForDataThrottle");
@@ -265,7 +264,7 @@ TEST_F(ThrottleCursorTest, TestSeekableRecordThrottleCursorOnLargeDocs) {
TEST_F(ThrottleCursorTest, TestSortedDataInterfaceThrottleCursorOff) {
auto opCtx = operationContext();
AutoGetCollection autoColl(opCtx, kNss, MODE_X);
- const Collection* coll = autoColl.getCollection();
+ const CollectionPtr& coll = autoColl.getCollection();
// Use a fixed record data size to simplify the timing calculations.
FailPointEnableBlock failPoint("fixedCursorDataSizeOf512KBForDataThrottle");
@@ -292,7 +291,7 @@ TEST_F(ThrottleCursorTest, TestSortedDataInterfaceThrottleCursorOff) {
TEST_F(ThrottleCursorTest, TestSortedDataInterfaceThrottleCursorOn) {
auto opCtx = operationContext();
AutoGetCollection autoColl(opCtx, kNss, MODE_X);
- const Collection* coll = autoColl.getCollection();
+ const CollectionPtr& coll = autoColl.getCollection();
// Use a fixed record data size to simplify the timing calculations.
FailPointEnableBlock failPoint("fixedCursorDataSizeOf512KBForDataThrottle");
@@ -343,7 +342,7 @@ TEST_F(ThrottleCursorTest, TestSortedDataInterfaceThrottleCursorOn) {
TEST_F(ThrottleCursorTest, TestMixedCursorsWithSharedThrottleOff) {
auto opCtx = operationContext();
AutoGetCollection autoColl(opCtx, kNss, MODE_X);
- const Collection* coll = autoColl.getCollection();
+ const CollectionPtr& coll = autoColl.getCollection();
// Use a fixed record data size to simplify the timing calculations.
FailPointEnableBlock failPoint("fixedCursorDataSizeOf512KBForDataThrottle");
@@ -385,7 +384,7 @@ TEST_F(ThrottleCursorTest, TestMixedCursorsWithSharedThrottleOff) {
TEST_F(ThrottleCursorTest, TestMixedCursorsWithSharedThrottleOn) {
auto opCtx = operationContext();
AutoGetCollection autoColl(opCtx, kNss, MODE_X);
- const Collection* coll = autoColl.getCollection();
+ const CollectionPtr& coll = autoColl.getCollection();
// Use a fixed record data size to simplify the timing calculations.
FailPointEnableBlock failPoint("fixedCursorDataSizeOf512KBForDataThrottle");
diff --git a/src/mongo/db/catalog/validate_adaptor.cpp b/src/mongo/db/catalog/validate_adaptor.cpp
index 15af297f6b7..d5b07f65207 100644
--- a/src/mongo/db/catalog/validate_adaptor.cpp
+++ b/src/mongo/db/catalog/validate_adaptor.cpp
@@ -82,7 +82,7 @@ Status ValidateAdaptor::validateRecord(OperationContext* opCtx,
LOGV2(4666601, "[validate]", "recordId"_attr = recordId, "recordData"_attr = recordBson);
}
- const Collection* coll = _validateState->getCollection();
+ const CollectionPtr& coll = _validateState->getCollection();
if (!coll->getIndexCatalog()->haveAnyIndexes()) {
return status;
}
diff --git a/src/mongo/db/catalog/validate_state.cpp b/src/mongo/db/catalog/validate_state.cpp
index 3d91889e954..23dea464e37 100644
--- a/src/mongo/db/catalog/validate_state.cpp
+++ b/src/mongo/db/catalog/validate_state.cpp
@@ -77,8 +77,8 @@ ValidateState::ValidateState(OperationContext* opCtx,
}
_database = _databaseLock->getDb() ? _databaseLock->getDb() : nullptr;
- _collection = _database ? CollectionCatalog::get(opCtx).lookupCollectionByNamespace(opCtx, _nss)
- : nullptr;
+ if (_database)
+ _collection = CollectionCatalog::get(opCtx).lookupCollectionByNamespace(opCtx, _nss);
if (!_collection) {
if (_database && ViewCatalog::get(_database)->lookup(opCtx, _nss.ns())) {
diff --git a/src/mongo/db/catalog/validate_state.h b/src/mongo/db/catalog/validate_state.h
index ec2e35d689d..b9d5db77714 100644
--- a/src/mongo/db/catalog/validate_state.h
+++ b/src/mongo/db/catalog/validate_state.h
@@ -100,7 +100,7 @@ public:
return _database;
}
- const Collection* getCollection() const {
+ const CollectionPtr& getCollection() const {
invariant(_collection);
return _collection;
}
@@ -204,7 +204,7 @@ private:
boost::optional<Lock::CollectionLock> _collectionLock;
Database* _database;
- const Collection* _collection;
+ CollectionPtr _collection;
// Stores the indexes that are going to be validated. When validate yields periodically we'll
// use this list to determine if validation should abort when an existing index that was
diff --git a/src/mongo/db/catalog/validate_state_test.cpp b/src/mongo/db/catalog/validate_state_test.cpp
index bcd94aa94ad..ac023d807dd 100644
--- a/src/mongo/db/catalog/validate_state_test.cpp
+++ b/src/mongo/db/catalog/validate_state_test.cpp
@@ -63,8 +63,7 @@ public:
/**
* Create collection 'nss' and insert some documents. It will possess a default _id index.
*/
- const Collection* createCollectionAndPopulateIt(OperationContext* opCtx,
- const NamespaceString& nss);
+ void createCollectionAndPopulateIt(OperationContext* opCtx, const NamespaceString& nss);
private:
void setUp() override;
@@ -76,13 +75,12 @@ void ValidateStateTest::createCollection(OperationContext* opCtx, const Namespac
ASSERT_OK(storageInterface()->createCollection(opCtx, nss, defaultCollectionOptions));
}
-const Collection* ValidateStateTest::createCollectionAndPopulateIt(OperationContext* opCtx,
- const NamespaceString& nss) {
+void ValidateStateTest::createCollectionAndPopulateIt(OperationContext* opCtx,
+ const NamespaceString& nss) {
// Create collection.
createCollection(opCtx, nss);
- AutoGetCollection autoColl(opCtx, nss, MODE_X);
- const Collection* collection = autoColl.getCollection();
+ AutoGetCollection collection(opCtx, nss, MODE_X);
invariant(collection);
// Insert some data.
@@ -93,8 +91,6 @@ const Collection* ValidateStateTest::createCollectionAndPopulateIt(OperationCont
collection->insertDocument(opCtx, InsertStatement(BSON("_id" << i)), nullOpDebug));
wuow.commit();
}
-
- return collection;
}
void ValidateStateTest::setUp() {
@@ -124,8 +120,7 @@ void ValidateStateTest::setUp() {
* Builds an index on the given 'nss'. 'indexKey' specifies the index key, e.g. {'a': 1};
*/
void createIndex(OperationContext* opCtx, const NamespaceString& nss, const BSONObj& indexKey) {
- AutoGetCollection autoColl(opCtx, nss, MODE_X);
- auto collection = autoColl.getCollection();
+ AutoGetCollection collection(opCtx, nss, MODE_X);
ASSERT(collection);
ASSERT_EQ(1, indexKey.nFields()) << nss << "/" << indexKey;
diff --git a/src/mongo/db/catalog_raii.cpp b/src/mongo/db/catalog_raii.cpp
index ab90c0a3587..41e5e2576b6 100644
--- a/src/mongo/db/catalog_raii.cpp
+++ b/src/mongo/db/catalog_raii.cpp
@@ -112,7 +112,7 @@ AutoGetCollectionBase<CatalogCollectionLookupT>::AutoGetCollectionBase(
if (!db)
return;
- _coll = CatalogCollectionLookupT::lookupCollection(opCtx, _resolvedNss);
+ _coll = _lookup.lookupCollection(opCtx, _resolvedNss);
invariant(!nsOrUUID.uuid() || _coll,
str::stream() << "Collection for " << _resolvedNss.ns()
<< " disappeared after successufully resolving "
@@ -165,28 +165,38 @@ Collection* AutoGetCollection::getWritableCollection(CollectionCatalog::Lifetime
class WritableCollectionReset : public RecoveryUnit::Change {
public:
WritableCollectionReset(AutoGetCollection& autoColl,
- const Collection* rollbackCollection)
- : _autoColl(autoColl), _rollbackCollection(rollbackCollection) {}
+ const CollectionPtr& rollbackCollection,
+ uint64_t catalogEpoch)
+ : _autoColl(autoColl),
+ _rollbackCollection(rollbackCollection.get()),
+ _catalogEpoch(catalogEpoch) {}
void commit(boost::optional<Timestamp> commitTime) final {
+ // Restore coll to a yieldable collection
+ _autoColl._coll = {
+ _autoColl.getOperationContext(), _autoColl._coll.get(), _catalogEpoch};
_autoColl._writableColl = nullptr;
}
void rollback() final {
- _autoColl._coll = _rollbackCollection;
+ _autoColl._coll = {
+ _autoColl.getOperationContext(), _rollbackCollection, _catalogEpoch};
_autoColl._writableColl = nullptr;
}
private:
AutoGetCollection& _autoColl;
const Collection* _rollbackCollection;
+ uint64_t _catalogEpoch;
};
- _writableColl = CollectionCatalog::get(_opCtx).lookupCollectionByNamespaceForMetadataWrite(
- _opCtx, mode, _resolvedNss);
+ auto& catalog = CollectionCatalog::get(_opCtx);
+ _writableColl =
+ catalog.lookupCollectionByNamespaceForMetadataWrite(_opCtx, mode, _resolvedNss);
if (mode == CollectionCatalog::LifetimeMode::kManagedInWriteUnitOfWork) {
_opCtx->recoveryUnit()->registerChange(
- std::make_unique<WritableCollectionReset>(*this, _coll));
+ std::make_unique<WritableCollectionReset>(*this, _coll, catalog.getEpoch()));
}
+ // Set to writable collection. We are no longer yieldable.
_coll = _writableColl;
}
return _writableColl;
@@ -202,9 +212,12 @@ struct CollectionWriter::SharedImpl {
CollectionWriter::CollectionWriter(OperationContext* opCtx,
const CollectionUUID& uuid,
CollectionCatalog::LifetimeMode mode)
- : _opCtx(opCtx), _mode(mode), _sharedImpl(std::make_shared<SharedImpl>(this)) {
+ : _collection(&_storedCollection),
+ _opCtx(opCtx),
+ _mode(mode),
+ _sharedImpl(std::make_shared<SharedImpl>(this)) {
- _collection = CollectionCatalog::get(opCtx).lookupCollectionByUUID(opCtx, uuid);
+ _storedCollection = CollectionCatalog::get(opCtx).lookupCollectionByUUID(opCtx, uuid);
_sharedImpl->_writableCollectionInitializer = [opCtx,
uuid](CollectionCatalog::LifetimeMode mode) {
return CollectionCatalog::get(opCtx).lookupCollectionByUUIDForMetadataWrite(
@@ -215,8 +228,11 @@ CollectionWriter::CollectionWriter(OperationContext* opCtx,
CollectionWriter::CollectionWriter(OperationContext* opCtx,
const NamespaceString& nss,
CollectionCatalog::LifetimeMode mode)
- : _opCtx(opCtx), _mode(mode), _sharedImpl(std::make_shared<SharedImpl>(this)) {
- _collection = CollectionCatalog::get(opCtx).lookupCollectionByNamespace(opCtx, nss);
+ : _collection(&_storedCollection),
+ _opCtx(opCtx),
+ _mode(mode),
+ _sharedImpl(std::make_shared<SharedImpl>(this)) {
+ _storedCollection = CollectionCatalog::get(opCtx).lookupCollectionByNamespace(opCtx, nss);
_sharedImpl->_writableCollectionInitializer = [opCtx,
nss](CollectionCatalog::LifetimeMode mode) {
return CollectionCatalog::get(opCtx).lookupCollectionByNamespaceForMetadataWrite(
@@ -226,10 +242,10 @@ CollectionWriter::CollectionWriter(OperationContext* opCtx,
CollectionWriter::CollectionWriter(AutoGetCollection& autoCollection,
CollectionCatalog::LifetimeMode mode)
- : _opCtx(autoCollection.getOperationContext()),
+ : _collection(&autoCollection.getCollection()),
+ _opCtx(autoCollection.getOperationContext()),
_mode(mode),
_sharedImpl(std::make_shared<SharedImpl>(this)) {
- _collection = autoCollection.getCollection();
_sharedImpl->_writableCollectionInitializer =
[&autoCollection](CollectionCatalog::LifetimeMode mode) {
return autoCollection.getWritableCollection(mode);
@@ -237,7 +253,8 @@ CollectionWriter::CollectionWriter(AutoGetCollection& autoCollection,
}
CollectionWriter::CollectionWriter(Collection* writableCollection)
- : _collection(writableCollection),
+ : _collection(&_storedCollection),
+ _storedCollection(writableCollection),
_writableCollection(writableCollection),
_mode(CollectionCatalog::LifetimeMode::kInplace) {}
@@ -264,30 +281,34 @@ Collection* CollectionWriter::getWritableCollection() {
class WritableCollectionReset : public RecoveryUnit::Change {
public:
WritableCollectionReset(std::shared_ptr<SharedImpl> shared,
- const Collection* rollbackCollection)
- : _shared(std::move(shared)), _rollbackCollection(rollbackCollection) {}
+ CollectionPtr rollbackCollection)
+ : _shared(std::move(shared)), _rollbackCollection(std::move(rollbackCollection)) {}
void commit(boost::optional<Timestamp> commitTime) final {
if (_shared->_parent)
_shared->_parent->_writableCollection = nullptr;
}
void rollback() final {
if (_shared->_parent) {
- _shared->_parent->_collection = _rollbackCollection;
+ _shared->_parent->_storedCollection = std::move(_rollbackCollection);
_shared->_parent->_writableCollection = nullptr;
}
}
private:
std::shared_ptr<SharedImpl> _shared;
- const Collection* _rollbackCollection;
+ CollectionPtr _rollbackCollection;
};
- if (_mode == CollectionCatalog::LifetimeMode::kManagedInWriteUnitOfWork) {
- _opCtx->recoveryUnit()->registerChange(
- std::make_unique<WritableCollectionReset>(_sharedImpl, _collection));
- }
+ // If we are using our stored Collection then we are not managed by an AutoGetCollection and
+ // we need to manage lifetime here.
+ if (*_collection == _storedCollection) {
+ if (_mode == CollectionCatalog::LifetimeMode::kManagedInWriteUnitOfWork) {
+ _opCtx->recoveryUnit()->registerChange(std::make_unique<WritableCollectionReset>(
+ _sharedImpl, std::move(_storedCollection)));
+ }
- _collection = _writableCollection;
+ _storedCollection = _writableCollection;
+ }
}
return _writableCollection;
}
@@ -306,7 +327,9 @@ CatalogCollectionLookup::CollectionStorage CatalogCollectionLookup::lookupCollec
CatalogCollectionLookupForRead::CollectionStorage CatalogCollectionLookupForRead::lookupCollection(
OperationContext* opCtx, const NamespaceString& nss) {
- return CollectionCatalog::get(opCtx).lookupCollectionByNamespaceForRead(opCtx, nss);
+ auto ptr = CollectionCatalog::get(opCtx).lookupCollectionByNamespaceForRead(opCtx, nss);
+ _collection = CollectionPtr(ptr);
+ return ptr;
}
LockMode fixLockModeForSystemDotViewsChanges(const NamespaceString& nss, LockMode mode) {
@@ -364,7 +387,7 @@ AutoGetOplog::AutoGetOplog(OperationContext* opCtx, OplogAccessMode mode, Date_t
}
_oplogInfo = repl::LocalOplogInfo::get(opCtx);
- _oplog = _oplogInfo->getCollection();
+ _oplog = &_oplogInfo->getCollection();
}
template class AutoGetCollectionBase<CatalogCollectionLookup>;
diff --git a/src/mongo/db/catalog_raii.h b/src/mongo/db/catalog_raii.h
index 917bff29707..76fe75ba9c8 100644
--- a/src/mongo/db/catalog_raii.h
+++ b/src/mongo/db/catalog_raii.h
@@ -37,6 +37,7 @@
#include "mongo/db/operation_context.h"
#include "mongo/db/repl/local_oplog_info.h"
#include "mongo/db/views/view.h"
+#include "mongo/db/yieldable.h"
namespace mongo {
@@ -106,7 +107,6 @@ class AutoGetCollectionBase {
AutoGetCollectionBase& operator=(const AutoGetCollectionBase&) = delete;
using CollectionStorage = typename CatalogCollectionLookupT::CollectionStorage;
- using CollectionPtr = typename CatalogCollectionLookupT::CollectionPtr;
public:
AutoGetCollectionBase(
@@ -123,15 +123,15 @@ public:
/**
* AutoGetCollection can be used as a pointer with the -> operator.
*/
- CollectionPtr operator->() const {
- return getCollection();
+ const Collection* operator->() const {
+ return getCollection().get();
}
/**
* Dereference operator, returns a lvalue reference to the collection.
*/
- std::add_lvalue_reference_t<std::remove_pointer_t<CollectionPtr>> operator*() const {
- return *getCollection();
+ const Collection& operator*() const {
+ return *getCollection().get();
}
/**
@@ -151,8 +151,8 @@ public:
/**
* Returns nullptr if the collection didn't exist.
*/
- CollectionPtr getCollection() const {
- return CatalogCollectionLookupT::toCollectionPtr(_coll);
+ const CollectionPtr& getCollection() const {
+ return _lookup.toCollectionPtr(_coll);
}
/**
@@ -181,26 +181,28 @@ protected:
boost::optional<Lock::CollectionLock> _collLock;
CollectionStorage _coll = nullptr;
+ CatalogCollectionLookupT _lookup;
std::shared_ptr<ViewDefinition> _view;
};
struct CatalogCollectionLookup {
- using CollectionStorage = const Collection*;
- using CollectionPtr = const Collection*;
+ using CollectionStorage = CollectionPtr;
- static CollectionStorage lookupCollection(OperationContext* opCtx, const NamespaceString& nss);
- static CollectionPtr toCollectionPtr(CollectionStorage collection) {
+ CollectionStorage lookupCollection(OperationContext* opCtx, const NamespaceString& nss);
+ const CollectionPtr& toCollectionPtr(const CollectionStorage& collection) const {
return collection;
}
};
struct CatalogCollectionLookupForRead {
using CollectionStorage = std::shared_ptr<const Collection>;
- using CollectionPtr = const Collection*;
- static CollectionStorage lookupCollection(OperationContext* opCtx, const NamespaceString& nss);
- static CollectionPtr toCollectionPtr(const CollectionStorage& collection) {
- return collection.get();
+ CollectionStorage lookupCollection(OperationContext* opCtx, const NamespaceString& nss);
+ const CollectionPtr& toCollectionPtr(const CollectionStorage&) const {
+ return _collection;
}
+
+private:
+ CollectionPtr _collection;
};
class AutoGetCollection : public AutoGetCollectionBase<CatalogCollectionLookup> {
@@ -266,19 +268,19 @@ public:
CollectionWriter& operator=(CollectionWriter&&) = delete;
explicit operator bool() const {
- return get();
+ return static_cast<bool>(get());
}
const Collection* operator->() const {
- return get();
+ return get().get();
}
const Collection& operator*() const {
- return *get();
+ return *get().get();
}
- const Collection* get() const {
- return _collection;
+ const CollectionPtr& get() const {
+ return *_collection;
}
// Returns writable Collection, any previous Collection that has been returned may be
@@ -289,7 +291,13 @@ public:
void commitToCatalog();
private:
- const Collection* _collection = nullptr;
+ // If this class is instantiated with the constructors that take UUID or nss we need somewhere
+ // to store the CollectionPtr used. But if it is instantiated with an AutoGetCollection then the
+ // lifetime of the object is managed there. To unify the two code paths we have a pointer that
+ // points to either the CollectionPtr in an AutoGetCollection or to a stored CollectionPtr in
+ // this instance. This can also be used to determine how we were instantiated.
+ const CollectionPtr* _collection = nullptr;
+ CollectionPtr _storedCollection;
Collection* _writableCollection = nullptr;
OperationContext* _opCtx = nullptr;
CollectionCatalog::LifetimeMode _mode;
@@ -418,8 +426,8 @@ public:
/**
* Returns a pointer to the oplog collection or nullptr if the oplog collection didn't exist.
*/
- const Collection* getCollection() const {
- return _oplog;
+ const CollectionPtr& getCollection() const {
+ return *_oplog;
}
private:
@@ -429,7 +437,7 @@ private:
boost::optional<Lock::DBLock> _dbWriteLock;
boost::optional<Lock::CollectionLock> _collWriteLock;
repl::LocalOplogInfo* _oplogInfo;
- const Collection* _oplog;
+ const CollectionPtr* _oplog;
};
} // namespace mongo
diff --git a/src/mongo/db/client.h b/src/mongo/db/client.h
index cc784cdf75c..b56ea4eb37b 100644
--- a/src/mongo/db/client.h
+++ b/src/mongo/db/client.h
@@ -52,7 +52,6 @@
namespace mongo {
-class Collection;
class Locker;
class OperationContext;
class ThreadClient;
diff --git a/src/mongo/db/clientcursor.h b/src/mongo/db/clientcursor.h
index f4d7960a759..745b03157f3 100644
--- a/src/mongo/db/clientcursor.h
+++ b/src/mongo/db/clientcursor.h
@@ -44,7 +44,6 @@
namespace mongo {
-class Collection;
class CursorManager;
class RecoveryUnit;
diff --git a/src/mongo/db/cloner.cpp b/src/mongo/db/cloner.cpp
index b0f8954adc6..47e1e5601ad 100644
--- a/src/mongo/db/cloner.cpp
+++ b/src/mongo/db/cloner.cpp
@@ -156,7 +156,7 @@ struct Cloner::Fun {
collection = CollectionCatalog::get(opCtx).lookupCollectionByNamespace(opCtx, nss);
uassert(28594,
str::stream() << "Collection " << nss << " dropped while cloning",
- collection != nullptr);
+ collection);
}
BSONObj tmp = i.nextSafe();
@@ -367,7 +367,7 @@ Status Cloner::_createCollectionsForDb(
opCtx->checkForInterrupt();
WriteUnitOfWork wunit(opCtx);
- const Collection* collection =
+ CollectionPtr collection =
CollectionCatalog::get(opCtx).lookupCollectionByNamespace(opCtx, nss);
if (collection) {
if (!params.shardedColl) {
diff --git a/src/mongo/db/commands/count_cmd.cpp b/src/mongo/db/commands/count_cmd.cpp
index 2014df3dcc7..b15ecdc4383 100644
--- a/src/mongo/db/commands/count_cmd.cpp
+++ b/src/mongo/db/commands/count_cmd.cpp
@@ -177,7 +177,7 @@ public:
result);
}
- const Collection* const collection = ctx->getCollection();
+ const auto& collection = ctx->getCollection();
// Prevent chunks from being cleaned up during yields - this allows us to only check the
// version on initial entry into count.
@@ -240,7 +240,7 @@ public:
return true;
}
- const Collection* const collection = ctx->getCollection();
+ const auto& collection = ctx->getCollection();
// Prevent chunks from being cleaned up during yields - this allows us to only check the
// version on initial entry into count.
diff --git a/src/mongo/db/commands/create_indexes.cpp b/src/mongo/db/commands/create_indexes.cpp
index c3bf793ca6b..fac19ca99eb 100644
--- a/src/mongo/db/commands/create_indexes.cpp
+++ b/src/mongo/db/commands/create_indexes.cpp
@@ -317,7 +317,7 @@ boost::optional<CommitQuorumOptions> parseAndGetCommitQuorum(OperationContext* o
* returned vector is empty after returning, no new indexes need to be built. Throws on error.
*/
std::vector<BSONObj> resolveDefaultsAndRemoveExistingIndexes(OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
std::vector<BSONObj> indexSpecs) {
// Normalize the specs' collations, wildcard projections, and partial filters as applicable.
auto normalSpecs = IndexBuildsCoordinator::normalizeIndexSpecs(opCtx, collection, indexSpecs);
@@ -339,7 +339,7 @@ void fillCommandResultWithIndexesAlreadyExistInfo(int numIndexes, BSONObjBuilder
* Returns true, after filling in the command result, if the index creation can return early.
*/
bool indexesAlreadyExist(OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
const std::vector<BSONObj>& specs,
BSONObjBuilder* result) {
auto specsCopy = resolveDefaultsAndRemoveExistingIndexes(opCtx, collection, specs);
@@ -518,12 +518,12 @@ bool runCreateIndexesWithCoordinator(OperationContext* opCtx,
}
bool indexExists = writeConflictRetry(opCtx, "createCollectionWithIndexes", ns.ns(), [&] {
- AutoGetCollection autoColl(opCtx, ns, MODE_IS);
- auto collection = autoColl.getCollection();
+ AutoGetCollection collection(opCtx, ns, MODE_IS);
// Before potentially taking an exclusive collection lock, check if all indexes already
// exist while holding an intent lock.
- if (collection && indexesAlreadyExist(opCtx, collection, specs, &result)) {
+ if (collection &&
+ indexesAlreadyExist(opCtx, collection.getCollection(), specs, &result)) {
repl::ReplClientInfo::forClient(opCtx->getClient())
.setLastOpToSystemLastOpTime(opCtx);
return true;
diff --git a/src/mongo/db/commands/dbcheck.cpp b/src/mongo/db/commands/dbcheck.cpp
index fd72f8fb4b9..73b4b1cf00d 100644
--- a/src/mongo/db/commands/dbcheck.cpp
+++ b/src/mongo/db/commands/dbcheck.cpp
@@ -393,7 +393,7 @@ private:
return Status(ErrorCodes::PrimarySteppedDown, "dbCheck terminated due to stepdown");
}
- auto collection = agc.getCollection();
+ const auto& collection = agc.getCollection();
if (!collection) {
return {ErrorCodes::NamespaceNotFound, "dbCheck collection no longer exists"};
diff --git a/src/mongo/db/commands/dbcommands.cpp b/src/mongo/db/commands/dbcommands.cpp
index 7a7a57d1f0c..57c21d78ebc 100644
--- a/src/mongo/db/commands/dbcommands.cpp
+++ b/src/mongo/db/commands/dbcommands.cpp
@@ -479,8 +479,7 @@ public:
bool estimate = jsobj["estimate"].trueValue();
const NamespaceString nss(ns);
- AutoGetCollectionForReadCommand ctx(opCtx, nss);
- const Collection* collection = ctx.getCollection();
+ AutoGetCollectionForReadCommand collection(opCtx, nss);
const auto collDesc =
CollectionShardingState::get(opCtx, nss)->getCollectionDescription(opCtx);
@@ -527,7 +526,7 @@ public:
return 1;
}
exec = InternalPlanner::collectionScan(
- opCtx, ns, collection, PlanYieldPolicy::YieldPolicy::NO_YIELD);
+ opCtx, ns, collection.getCollection(), PlanYieldPolicy::YieldPolicy::NO_YIELD);
} else if (min.isEmpty() || max.isEmpty()) {
errmsg = "only one of min or max specified";
return false;
@@ -552,7 +551,7 @@ public:
max = Helpers::toKeyFormat(kp.extendRangeBound(max, false));
exec = InternalPlanner::indexScan(opCtx,
- collection,
+ collection.getCollection(),
idx,
min,
max,
diff --git a/src/mongo/db/commands/dbcommands_d.cpp b/src/mongo/db/commands/dbcommands_d.cpp
index 944a63b39bd..5a8aafa3f3a 100644
--- a/src/mongo/db/commands/dbcommands_d.cpp
+++ b/src/mongo/db/commands/dbcommands_d.cpp
@@ -301,7 +301,7 @@ public:
// We drop and re-acquire these locks every document because md5'ing is expensive
unique_ptr<AutoGetCollectionForReadCommand> ctx(
new AutoGetCollectionForReadCommand(opCtx, nss));
- const Collection* coll = ctx->getCollection();
+ const CollectionPtr& coll = ctx->getCollection();
auto exec = uassertStatusOK(getExecutor(opCtx,
coll,
@@ -389,7 +389,7 @@ public:
}
// Now that we have the lock again, we can restore the PlanExecutor.
- exec->restoreState();
+ exec->restoreState(&coll);
}
} catch (DBException& exception) {
exception.addContext("Executor error during filemd5 command");
diff --git a/src/mongo/db/commands/dbhash.cpp b/src/mongo/db/commands/dbhash.cpp
index be9243982ca..6ef685dd420 100644
--- a/src/mongo/db/commands/dbhash.cpp
+++ b/src/mongo/db/commands/dbhash.cpp
@@ -231,48 +231,50 @@ public:
std::set<std::string> cappedCollectionSet;
bool noError = true;
- catalog::forEachCollectionFromDb(opCtx, dbname, MODE_IS, [&](const Collection* collection) {
- auto collNss = collection->ns();
-
- if (collNss.size() - 1 <= dbname.size()) {
- errmsg = str::stream() << "weird fullCollectionName [" << collNss.toString() << "]";
- noError = false;
- return false;
- }
+ catalog::forEachCollectionFromDb(
+ opCtx, dbname, MODE_IS, [&](const CollectionPtr& collection) {
+ auto collNss = collection->ns();
+
+ if (collNss.size() - 1 <= dbname.size()) {
+ errmsg = str::stream()
+ << "weird fullCollectionName [" << collNss.toString() << "]";
+ noError = false;
+ return false;
+ }
- if (repl::ReplicationCoordinator::isOplogDisabledForNS(collNss)) {
- return true;
- }
+ if (repl::ReplicationCoordinator::isOplogDisabledForNS(collNss)) {
+ return true;
+ }
- if (collNss.coll().startsWith("tmp.mr.")) {
- // We skip any incremental map reduce collections as they also aren't
- // replicated.
- return true;
- }
+ if (collNss.coll().startsWith("tmp.mr.")) {
+ // We skip any incremental map reduce collections as they also aren't
+ // replicated.
+ return true;
+ }
- if (desiredCollections.size() > 0 &&
- desiredCollections.count(collNss.coll().toString()) == 0)
- return true;
+ if (desiredCollections.size() > 0 &&
+ desiredCollections.count(collNss.coll().toString()) == 0)
+ return true;
- // Don't include 'drop pending' collections.
- if (collNss.isDropPendingNamespace())
- return true;
+ // Don't include 'drop pending' collections.
+ if (collNss.isDropPendingNamespace())
+ return true;
- if (collection->isCapped()) {
- cappedCollectionSet.insert(collNss.coll().toString());
- }
+ if (collection->isCapped()) {
+ cappedCollectionSet.insert(collNss.coll().toString());
+ }
- if (OptionalCollectionUUID uuid = collection->uuid()) {
- collectionToUUIDMap[collNss.coll().toString()] = uuid;
- }
+ if (OptionalCollectionUUID uuid = collection->uuid()) {
+ collectionToUUIDMap[collNss.coll().toString()] = uuid;
+ }
- // Compute the hash for this collection.
- std::string hash = _hashCollection(opCtx, db, collNss);
+ // Compute the hash for this collection.
+ std::string hash = _hashCollection(opCtx, db, collNss);
- collectionToHashMap[collNss.coll().toString()] = hash;
+ collectionToHashMap[collNss.coll().toString()] = hash;
- return true;
- });
+ return true;
+ });
if (!noError)
return false;
@@ -315,7 +317,7 @@ public:
private:
std::string _hashCollection(OperationContext* opCtx, Database* db, const NamespaceString& nss) {
- const Collection* collection =
+ CollectionPtr collection =
CollectionCatalog::get(opCtx).lookupCollectionByNamespace(opCtx, nss);
invariant(collection);
diff --git a/src/mongo/db/commands/distinct.cpp b/src/mongo/db/commands/distinct.cpp
index 6ab423127d9..d6b76a3e7e0 100644
--- a/src/mongo/db/commands/distinct.cpp
+++ b/src/mongo/db/commands/distinct.cpp
@@ -174,7 +174,7 @@ public:
result);
}
- const Collection* const collection = ctx->getCollection();
+ const auto& collection = ctx->getCollection();
auto executor = uassertStatusOK(
getExecutorDistinct(collection, QueryPlannerParams::DEFAULT, &parsedDistinct));
@@ -235,7 +235,7 @@ public:
return true;
}
- const Collection* const collection = ctx->getCollection();
+ const auto& collection = ctx->getCollection();
auto executor =
getExecutorDistinct(collection, QueryPlannerParams::DEFAULT, &parsedDistinct);
diff --git a/src/mongo/db/commands/find_and_modify.cpp b/src/mongo/db/commands/find_and_modify.cpp
index ea36a9dcf1c..26851277138 100644
--- a/src/mongo/db/commands/find_and_modify.cpp
+++ b/src/mongo/db/commands/find_and_modify.cpp
@@ -203,7 +203,7 @@ void recordStatsForTopCommand(OperationContext* opCtx) {
curOp->getReadWriteType());
}
-void checkIfTransactionOnCappedColl(const Collection* coll, bool inTransaction) {
+void checkIfTransactionOnCappedColl(const CollectionPtr& coll, bool inTransaction) {
if (coll && coll->isCapped()) {
uassert(
ErrorCodes::OperationNotSupportedInTransaction,
@@ -282,20 +282,19 @@ public:
// Explain calls of the findAndModify command are read-only, but we take write
// locks so that the timing information is more accurate.
- AutoGetCollection autoColl(opCtx, nsString, MODE_IX);
+ AutoGetCollection collection(opCtx, nsString, MODE_IX);
uassert(ErrorCodes::NamespaceNotFound,
str::stream() << "database " << dbName << " does not exist",
- autoColl.getDb());
+ collection.getDb());
CollectionShardingState::get(opCtx, nsString)->checkShardVersionOrThrow(opCtx);
- const Collection* const collection = autoColl.getCollection();
-
- const auto exec =
- uassertStatusOK(getExecutorDelete(opDebug, collection, &parsedDelete, verbosity));
+ const auto exec = uassertStatusOK(
+ getExecutorDelete(opDebug, collection.getCollection(), &parsedDelete, verbosity));
auto bodyBuilder = result->getBodyBuilder();
- Explain::explainStages(exec.get(), collection, verbosity, BSONObj(), &bodyBuilder);
+ Explain::explainStages(
+ exec.get(), collection.getCollection(), verbosity, BSONObj(), &bodyBuilder);
} else {
auto request = UpdateRequest();
request.setNamespaceString(nsString);
@@ -307,19 +306,19 @@ public:
// Explain calls of the findAndModify command are read-only, but we take write
// locks so that the timing information is more accurate.
- AutoGetCollection autoColl(opCtx, nsString, MODE_IX);
+ AutoGetCollection collection(opCtx, nsString, MODE_IX);
uassert(ErrorCodes::NamespaceNotFound,
str::stream() << "database " << dbName << " does not exist",
- autoColl.getDb());
+ collection.getDb());
CollectionShardingState::get(opCtx, nsString)->checkShardVersionOrThrow(opCtx);
- const Collection* const collection = autoColl.getCollection();
- const auto exec =
- uassertStatusOK(getExecutorUpdate(opDebug, collection, &parsedUpdate, verbosity));
+ const auto exec = uassertStatusOK(
+ getExecutorUpdate(opDebug, collection.getCollection(), &parsedUpdate, verbosity));
auto bodyBuilder = result->getBodyBuilder();
- Explain::explainStages(exec.get(), collection, verbosity, BSONObj(), &bodyBuilder);
+ Explain::explainStages(
+ exec.get(), collection.getCollection(), verbosity, BSONObj(), &bodyBuilder);
}
return Status::OK();
@@ -461,7 +460,7 @@ public:
ParsedDelete parsedDelete(opCtx, &request);
uassertStatusOK(parsedDelete.parseRequest());
- AutoGetCollection autoColl(opCtx, nsString, MODE_IX);
+ AutoGetCollection collection(opCtx, nsString, MODE_IX);
{
stdx::lock_guard<Client> lk(*opCtx->getClient());
@@ -472,11 +471,10 @@ public:
assertCanWrite(opCtx, nsString);
- const Collection* const collection = autoColl.getCollection();
- checkIfTransactionOnCappedColl(collection, inTransaction);
+ checkIfTransactionOnCappedColl(collection.getCollection(), inTransaction);
- const auto exec = uassertStatusOK(
- getExecutorDelete(opDebug, collection, &parsedDelete, boost::none /* verbosity */));
+ const auto exec = uassertStatusOK(getExecutorDelete(
+ opDebug, collection.getCollection(), &parsedDelete, boost::none /* verbosity */));
{
stdx::lock_guard<Client> lk(*opCtx->getClient());
@@ -490,8 +488,8 @@ public:
PlanSummaryStats summaryStats;
exec->getSummaryStats(&summaryStats);
- if (collection) {
- CollectionQueryInfo::get(collection).notifyOfQuery(opCtx, collection, summaryStats);
+ if (const auto& coll = collection.getCollection()) {
+ CollectionQueryInfo::get(coll).notifyOfQuery(opCtx, coll, summaryStats);
}
opDebug->setPlanSummaryMetrics(summaryStats);
@@ -528,29 +526,34 @@ public:
assertCanWrite(opCtx, nsString);
- const Collection* collection = autoColl.getCollection();
+ CollectionPtr createdCollection;
+ const CollectionPtr* collectionPtr = &autoColl.getCollection();
- // Create the collection if it does not exist when performing an upsert because the
- // update stage does not create its own collection
- if (!collection && args.isUpsert()) {
+ // TODO SERVER-50983: Create abstraction for creating collection when using
+ // AutoGetCollection Create the collection if it does not exist when performing an upsert
+ // because the update stage does not create its own collection
+ if (!*collectionPtr && args.isUpsert()) {
assertCanWrite(opCtx, nsString);
- collection = CollectionCatalog::get(opCtx).lookupCollectionByNamespace(opCtx, nsString);
+ createdCollection =
+ CollectionCatalog::get(opCtx).lookupCollectionByNamespace(opCtx, nsString);
// If someone else beat us to creating the collection, do nothing
- if (!collection) {
+ if (!createdCollection) {
uassertStatusOK(userAllowedCreateNS(nsString));
WriteUnitOfWork wuow(opCtx);
CollectionOptions defaultCollectionOptions;
uassertStatusOK(db->userCreateNS(opCtx, nsString, defaultCollectionOptions));
wuow.commit();
- collection =
+ createdCollection =
CollectionCatalog::get(opCtx).lookupCollectionByNamespace(opCtx, nsString);
}
- invariant(collection);
+ invariant(createdCollection);
+ collectionPtr = &createdCollection;
}
+ const auto& collection = *collectionPtr;
checkIfTransactionOnCappedColl(collection, inTransaction);
diff --git a/src/mongo/db/commands/find_cmd.cpp b/src/mongo/db/commands/find_cmd.cpp
index 2cae02d0a10..1459df1fe91 100644
--- a/src/mongo/db/commands/find_cmd.cpp
+++ b/src/mongo/db/commands/find_cmd.cpp
@@ -289,7 +289,7 @@ public:
// The collection may be NULL. If so, getExecutor() should handle it by returning an
// execution tree with an EOFStage.
- const Collection* const collection = ctx->getCollection();
+ const auto& collection = ctx->getCollection();
// Get the execution plan for the query.
bool permitYield = true;
@@ -412,7 +412,7 @@ public:
return;
}
- const Collection* const collection = ctx->getCollection();
+ const auto& collection = ctx->getCollection();
if (cq->getQueryRequest().isReadOnce()) {
// The readOnce option causes any storage-layer cursors created during plan
diff --git a/src/mongo/db/commands/getmore_cmd.cpp b/src/mongo/db/commands/getmore_cmd.cpp
index 0285be5ab5c..bf4a69408a7 100644
--- a/src/mongo/db/commands/getmore_cmd.cpp
+++ b/src/mongo/db/commands/getmore_cmd.cpp
@@ -513,7 +513,7 @@ public:
opCtx->recoveryUnit()->setReadOnce(true);
}
exec->reattachToOperationContext(opCtx);
- exec->restoreState();
+ exec->restoreState(nullptr);
auto planSummary = exec->getPlanSummary();
{
@@ -584,7 +584,7 @@ public:
[exec, dropAndReacquireReadLock]() {
exec->saveState();
dropAndReacquireReadLock();
- exec->restoreState();
+ exec->restoreState(nullptr);
};
waitWithPinnedCursorDuringGetMoreBatch.execute([&](const BSONObj& data) {
diff --git a/src/mongo/db/commands/haystack.cpp b/src/mongo/db/commands/haystack.cpp
index bd991dffa1e..b17c97d22f9 100644
--- a/src/mongo/db/commands/haystack.cpp
+++ b/src/mongo/db/commands/haystack.cpp
@@ -110,7 +110,7 @@ public:
void searchHaystack(const HaystackAccessMethod* ham,
OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
const BSONObj& nearObj,
double maxDistance,
const BSONObj& search,
@@ -233,7 +233,7 @@ public:
uassertStatusOK(replCoord->checkCanServeReadsFor(
opCtx, nss, ReadPreferenceSetting::get(opCtx).canRunOnSecondary()));
- const Collection* collection = ctx.getCollection();
+ const auto& collection = ctx.getCollection();
if (!collection) {
errmsg = "can't find ns";
return false;
diff --git a/src/mongo/db/commands/index_filter_commands.cpp b/src/mongo/db/commands/index_filter_commands.cpp
index a7d6239eaab..ec7529c608e 100644
--- a/src/mongo/db/commands/index_filter_commands.cpp
+++ b/src/mongo/db/commands/index_filter_commands.cpp
@@ -65,13 +65,13 @@ using namespace mongo;
* Retrieves a collection's query settings and plan cache from the database.
*/
static Status getQuerySettingsAndPlanCache(OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
const string& ns,
QuerySettings** querySettingsOut,
PlanCache** planCacheOut) {
*querySettingsOut = nullptr;
*planCacheOut = nullptr;
- if (nullptr == collection) {
+ if (!collection) {
return Status(ErrorCodes::BadValue, "no such collection");
}
diff --git a/src/mongo/db/commands/list_collections.cpp b/src/mongo/db/commands/list_collections.cpp
index ba05d17ff45..d8485d09937 100644
--- a/src/mongo/db/commands/list_collections.cpp
+++ b/src/mongo/db/commands/list_collections.cpp
@@ -163,7 +163,7 @@ BSONObj buildViewBson(const ViewDefinition& view, bool nameOnly) {
* Return an object describing the collection. Takes a collection lock if nameOnly is false.
*/
BSONObj buildCollectionBson(OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
bool includePendingDrops,
bool nameOnly) {
if (!collection) {
@@ -321,7 +321,7 @@ public:
}
Lock::CollectionLock clk(opCtx, nss, MODE_IS);
- const Collection* collection =
+ CollectionPtr collection =
CollectionCatalog::get(opCtx).lookupCollectionByNamespace(opCtx, nss);
BSONObj collBson =
buildCollectionBson(opCtx, collection, includePendingDrops, nameOnly);
@@ -332,7 +332,7 @@ public:
}
} else {
mongo::catalog::forEachCollectionFromDb(
- opCtx, dbname, MODE_IS, [&](const Collection* collection) {
+ opCtx, dbname, MODE_IS, [&](const CollectionPtr& collection) {
if (authorizedCollections &&
(!as->isAuthorizedForAnyActionOnResource(
ResourcePattern::forExactNamespace(collection->ns())))) {
diff --git a/src/mongo/db/commands/list_indexes.cpp b/src/mongo/db/commands/list_indexes.cpp
index bd2eab3b3fc..94d4eb1e51d 100644
--- a/src/mongo/db/commands/list_indexes.cpp
+++ b/src/mongo/db/commands/list_indexes.cpp
@@ -157,18 +157,18 @@ public:
std::unique_ptr<PlanExecutor, PlanExecutor::Deleter> exec;
BSONArrayBuilder firstBatch;
{
- AutoGetCollectionForReadCommand ctx(opCtx,
- CommandHelpers::parseNsOrUUID(dbname, cmdObj));
- const Collection* collection = ctx.getCollection();
+ AutoGetCollectionForReadCommand collection(
+ opCtx, CommandHelpers::parseNsOrUUID(dbname, cmdObj));
uassert(ErrorCodes::NamespaceNotFound,
- str::stream() << "ns does not exist: " << ctx.getNss().ns(),
+ str::stream() << "ns does not exist: " << collection.getNss().ns(),
collection);
- nss = ctx.getNss();
+ nss = collection.getNss();
auto expCtx = make_intrusive<ExpressionContext>(
opCtx, std::unique_ptr<CollatorInterface>(nullptr), nss);
- auto indexList = listIndexesInLock(opCtx, collection, nss, includeBuildUUIDs);
+ auto indexList =
+ listIndexesInLock(opCtx, collection.getCollection(), nss, includeBuildUUIDs);
auto ws = std::make_unique<WorkingSet>();
auto root = std::make_unique<QueuedDataStage>(expCtx.get(), ws.get());
diff --git a/src/mongo/db/commands/mr_test.cpp b/src/mongo/db/commands/mr_test.cpp
index f6af27117eb..a4ed9383018 100644
--- a/src/mongo/db/commands/mr_test.cpp
+++ b/src/mongo/db/commands/mr_test.cpp
@@ -267,7 +267,7 @@ public:
* Tracks the temporary collections mapReduces creates.
*/
void onCreateCollection(OperationContext* opCtx,
- const Collection* coll,
+ const CollectionPtr& coll,
const NamespaceString& collectionName,
const CollectionOptions& options,
const BSONObj& idIndex,
@@ -321,7 +321,7 @@ void MapReduceOpObserver::onInserts(OperationContext* opCtx,
}
void MapReduceOpObserver::onCreateCollection(OperationContext*,
- const Collection*,
+ const CollectionPtr&,
const NamespaceString& collectionName,
const CollectionOptions& options,
const BSONObj&,
diff --git a/src/mongo/db/commands/plan_cache_clear_command.cpp b/src/mongo/db/commands/plan_cache_clear_command.cpp
index 61660438f04..5dc3822bd4a 100644
--- a/src/mongo/db/commands/plan_cache_clear_command.cpp
+++ b/src/mongo/db/commands/plan_cache_clear_command.cpp
@@ -47,7 +47,7 @@
namespace mongo {
namespace {
-PlanCache* getPlanCache(OperationContext* opCtx, const Collection* collection) {
+PlanCache* getPlanCache(OperationContext* opCtx, const CollectionPtr& collection) {
invariant(collection);
PlanCache* planCache = CollectionQueryInfo::get(collection).getPlanCache();
invariant(planCache);
diff --git a/src/mongo/db/commands/run_aggregate.cpp b/src/mongo/db/commands/run_aggregate.cpp
index b3a36985b1c..927b93d9e96 100644
--- a/src/mongo/db/commands/run_aggregate.cpp
+++ b/src/mongo/db/commands/run_aggregate.cpp
@@ -563,7 +563,7 @@ Status runAggregate(OperationContext* opCtx,
}
}
- const Collection* collection = ctx ? ctx->getCollection() : nullptr;
+ const auto& collection = ctx ? ctx->getCollection() : CollectionPtr::null;
// If this is a view, resolve it by finding the underlying collection and stitching view
// pipelines and this request's pipeline together. We then release our locks before
@@ -781,7 +781,7 @@ Status runAggregate(OperationContext* opCtx,
// For an optimized away pipeline, signal the cache that a query operation has completed.
// For normal pipelines this is done in DocumentSourceCursor.
if (ctx && ctx->getCollection()) {
- const Collection* coll = ctx->getCollection();
+ const CollectionPtr& coll = ctx->getCollection();
CollectionQueryInfo::get(coll).notifyOfQuery(opCtx, coll, stats);
}
}
diff --git a/src/mongo/db/commands/test_commands.cpp b/src/mongo/db/commands/test_commands.cpp
index de86a427505..a5844835ccb 100644
--- a/src/mongo/db/commands/test_commands.cpp
+++ b/src/mongo/db/commands/test_commands.cpp
@@ -92,7 +92,7 @@ public:
WriteUnitOfWork wunit(opCtx);
UnreplicatedWritesBlock unreplicatedWritesBlock(opCtx);
- const Collection* collection =
+ CollectionPtr collection =
CollectionCatalog::get(opCtx).lookupCollectionByNamespace(opCtx, nss);
if (!collection) {
collection = db->createCollection(opCtx, nss);
diff --git a/src/mongo/db/concurrency/deferred_writer.cpp b/src/mongo/db/concurrency/deferred_writer.cpp
index 3883ae2cd40..6c0f0ed3c77 100644
--- a/src/mongo/db/concurrency/deferred_writer.cpp
+++ b/src/mongo/db/concurrency/deferred_writer.cpp
@@ -112,11 +112,11 @@ void DeferredWriter::_worker(InsertStatement stmt) {
auto agc = std::move(result.getValue());
- const Collection& collection = *agc->getCollection();
+ const CollectionPtr& collection = agc->getCollection();
Status status = writeConflictRetry(opCtx, "deferred insert", _nss.ns(), [&] {
WriteUnitOfWork wuow(opCtx);
- Status status = collection.insertDocument(opCtx, stmt, nullptr, false);
+ Status status = collection->insertDocument(opCtx, stmt, nullptr, false);
if (!status.isOK()) {
return status;
}
diff --git a/src/mongo/db/db_raii.cpp b/src/mongo/db/db_raii.cpp
index 5e294acefe4..7e2397f2521 100644
--- a/src/mongo/db/db_raii.cpp
+++ b/src/mongo/db/db_raii.cpp
@@ -104,7 +104,7 @@ AutoGetCollectionForRead::AutoGetCollectionForRead(OperationContext* opCtx,
// If the collection doesn't exist or disappears after releasing locks and waiting, there is no
// need to check for pending catalog changes.
- while (auto coll = _autoColl->getCollection()) {
+ while (const auto& coll = _autoColl->getCollection()) {
// Ban snapshot reads on capped collections.
uassert(ErrorCodes::SnapshotUnavailable,
"Reading from capped collections with readConcern snapshot is not supported",
diff --git a/src/mongo/db/db_raii.h b/src/mongo/db/db_raii.h
index e8a1157b9ff..89406e31939 100644
--- a/src/mongo/db/db_raii.h
+++ b/src/mongo/db/db_raii.h
@@ -107,11 +107,19 @@ public:
AutoGetCollectionViewMode viewMode = AutoGetCollectionViewMode::kViewsForbidden,
Date_t deadline = Date_t::max());
+ explicit operator bool() const {
+ return static_cast<bool>(getCollection());
+ }
+
+ const Collection* operator->() const {
+ return getCollection().get();
+ }
+
Database* getDb() const {
return _autoColl->getDb();
}
- const Collection* getCollection() const {
+ const CollectionPtr& getCollection() const {
return _autoColl->getCollection();
}
@@ -151,11 +159,19 @@ public:
Date_t deadline = Date_t::max(),
AutoStatsTracker::LogMode logMode = AutoStatsTracker::LogMode::kUpdateTopAndCurOp);
+ explicit operator bool() const {
+ return static_cast<bool>(getCollection());
+ }
+
+ const Collection* operator->() const {
+ return getCollection().get();
+ }
+
Database* getDb() const {
return _autoCollForRead.getDb();
}
- const Collection* getCollection() const {
+ const CollectionPtr& getCollection() const {
return _autoCollForRead.getCollection();
}
diff --git a/src/mongo/db/db_raii_test.cpp b/src/mongo/db/db_raii_test.cpp
index a9239f0a92e..48f946ed895 100644
--- a/src/mongo/db/db_raii_test.cpp
+++ b/src/mongo/db/db_raii_test.cpp
@@ -69,7 +69,7 @@ public:
};
std::unique_ptr<PlanExecutor, PlanExecutor::Deleter> makeTailableQueryPlan(
- OperationContext* opCtx, const Collection* collection) {
+ OperationContext* opCtx, const CollectionPtr& collection) {
auto qr = std::make_unique<QueryRequest>(collection->ns());
qr->setTailableMode(TailableModeEnum::kTailableAndAwaitData);
diff --git a/src/mongo/db/dbhelpers.cpp b/src/mongo/db/dbhelpers.cpp
index f20ce257252..21e602052ea 100644
--- a/src/mongo/db/dbhelpers.cpp
+++ b/src/mongo/db/dbhelpers.cpp
@@ -61,7 +61,7 @@ using std::unique_ptr;
set your db SavedContext first
*/
bool Helpers::findOne(OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
const BSONObj& query,
BSONObj& result,
bool requireIndex) {
@@ -76,7 +76,7 @@ bool Helpers::findOne(OperationContext* opCtx,
set your db SavedContext first
*/
RecordId Helpers::findOne(OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
const BSONObj& query,
bool requireIndex) {
if (!collection)
@@ -88,7 +88,7 @@ RecordId Helpers::findOne(OperationContext* opCtx,
}
RecordId Helpers::findOne(OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
std::unique_ptr<QueryRequest> qr,
bool requireIndex) {
if (!collection)
@@ -130,7 +130,7 @@ bool Helpers::findById(OperationContext* opCtx,
invariant(database);
// TODO ForRead?
- const Collection* collection =
+ CollectionPtr collection =
CollectionCatalog::get(opCtx).lookupCollectionByNamespace(opCtx, NamespaceString(ns));
if (!collection) {
return false;
@@ -156,7 +156,7 @@ bool Helpers::findById(OperationContext* opCtx,
}
RecordId Helpers::findById(OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
const BSONObj& idquery) {
verify(collection);
const IndexCatalog* catalog = collection->getIndexCatalog();
@@ -167,10 +167,11 @@ RecordId Helpers::findById(OperationContext* opCtx,
// Acquires necessary locks to read the collection with the given namespace. If this is an oplog
// read, use AutoGetOplog for simplified locking.
-const Collection* getCollectionForRead(OperationContext* opCtx,
- const NamespaceString& ns,
- boost::optional<AutoGetCollectionForReadCommand>& autoColl,
- boost::optional<AutoGetOplog>& autoOplog) {
+const CollectionPtr& getCollectionForRead(
+ OperationContext* opCtx,
+ const NamespaceString& ns,
+ boost::optional<AutoGetCollectionForReadCommand>& autoColl,
+ boost::optional<AutoGetOplog>& autoOplog) {
if (ns.isOplog()) {
// Simplify locking rules for oplog collection.
autoOplog.emplace(opCtx, OplogAccessMode::kRead);
@@ -184,7 +185,7 @@ const Collection* getCollectionForRead(OperationContext* opCtx,
bool Helpers::getSingleton(OperationContext* opCtx, const char* ns, BSONObj& result) {
boost::optional<AutoGetCollectionForReadCommand> autoColl;
boost::optional<AutoGetOplog> autoOplog;
- auto collection = getCollectionForRead(opCtx, NamespaceString(ns), autoColl, autoOplog);
+ const auto& collection = getCollectionForRead(opCtx, NamespaceString(ns), autoColl, autoOplog);
auto exec = InternalPlanner::collectionScan(
opCtx, ns, collection, PlanYieldPolicy::YieldPolicy::NO_YIELD);
@@ -206,7 +207,7 @@ bool Helpers::getSingleton(OperationContext* opCtx, const char* ns, BSONObj& res
bool Helpers::getLast(OperationContext* opCtx, const char* ns, BSONObj& result) {
boost::optional<AutoGetCollectionForReadCommand> autoColl;
boost::optional<AutoGetOplog> autoOplog;
- auto collection = getCollectionForRead(opCtx, NamespaceString(ns), autoColl, autoOplog);
+ const auto& collection = getCollectionForRead(opCtx, NamespaceString(ns), autoColl, autoOplog);
auto exec = InternalPlanner::collectionScan(
opCtx, ns, collection, PlanYieldPolicy::YieldPolicy::NO_YIELD, InternalPlanner::BACKWARD);
@@ -306,7 +307,7 @@ BSONObj Helpers::inferKeyPattern(const BSONObj& o) {
void Helpers::emptyCollection(OperationContext* opCtx, const NamespaceString& nss) {
OldClientContext context(opCtx, nss.ns());
repl::UnreplicatedWritesBlock uwb(opCtx);
- const Collection* collection = context.db()
+ CollectionPtr collection = context.db()
? CollectionCatalog::get(opCtx).lookupCollectionByNamespace(opCtx, nss)
: nullptr;
deleteObjects(opCtx, collection, nss, BSONObj(), false);
diff --git a/src/mongo/db/dbhelpers.h b/src/mongo/db/dbhelpers.h
index 3bdf368490a..339f5165455 100644
--- a/src/mongo/db/dbhelpers.h
+++ b/src/mongo/db/dbhelpers.h
@@ -35,6 +35,7 @@
namespace mongo {
class Collection;
+class CollectionPtr;
class Database;
class OperationContext;
class QueryRequest;
@@ -59,18 +60,18 @@ struct Helpers {
@return true if object found
*/
static bool findOne(OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
const BSONObj& query,
BSONObj& result,
bool requireIndex = false);
static RecordId findOne(OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
const BSONObj& query,
bool requireIndex);
static RecordId findOne(OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
std::unique_ptr<QueryRequest> qr,
bool requireIndex);
@@ -90,7 +91,7 @@ struct Helpers {
* uasserts if no _id index.
* @return null loc if not found */
static RecordId findById(OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
const BSONObj& query);
/**
diff --git a/src/mongo/db/exec/cached_plan.cpp b/src/mongo/db/exec/cached_plan.cpp
index f39253281de..f0c6181d2de 100644
--- a/src/mongo/db/exec/cached_plan.cpp
+++ b/src/mongo/db/exec/cached_plan.cpp
@@ -59,7 +59,7 @@ namespace mongo {
const char* CachedPlanStage::kStageType = "CACHED_PLAN";
CachedPlanStage::CachedPlanStage(ExpressionContext* expCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
WorkingSet* ws,
CanonicalQuery* cq,
const QueryPlannerParams& params,
diff --git a/src/mongo/db/exec/cached_plan.h b/src/mongo/db/exec/cached_plan.h
index 6719b965225..a1098c3c406 100644
--- a/src/mongo/db/exec/cached_plan.h
+++ b/src/mongo/db/exec/cached_plan.h
@@ -57,7 +57,7 @@ class PlanYieldPolicy;
class CachedPlanStage final : public RequiresAllIndicesStage {
public:
CachedPlanStage(ExpressionContext* expCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
WorkingSet* ws,
CanonicalQuery* cq,
const QueryPlannerParams& params,
diff --git a/src/mongo/db/exec/collection_scan.cpp b/src/mongo/db/exec/collection_scan.cpp
index ffabd1886b4..fc5b9c854d5 100644
--- a/src/mongo/db/exec/collection_scan.cpp
+++ b/src/mongo/db/exec/collection_scan.cpp
@@ -57,7 +57,7 @@ using std::vector;
const char* CollectionScan::kStageType = "COLLSCAN";
CollectionScan::CollectionScan(ExpressionContext* expCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
const CollectionScanParams& params,
WorkingSet* workingSet,
const MatchExpression* filter)
diff --git a/src/mongo/db/exec/collection_scan.h b/src/mongo/db/exec/collection_scan.h
index b67d8cd6603..ac9681af48e 100644
--- a/src/mongo/db/exec/collection_scan.h
+++ b/src/mongo/db/exec/collection_scan.h
@@ -55,7 +55,7 @@ public:
static const char* kStageType;
CollectionScan(ExpressionContext* expCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
const CollectionScanParams& params,
WorkingSet* workingSet,
const MatchExpression* filter);
diff --git a/src/mongo/db/exec/collection_scan_common.h b/src/mongo/db/exec/collection_scan_common.h
index aa0c790d1fd..fb847553b36 100644
--- a/src/mongo/db/exec/collection_scan_common.h
+++ b/src/mongo/db/exec/collection_scan_common.h
@@ -34,8 +34,6 @@
namespace mongo {
-class Collection;
-
struct CollectionScanParams {
enum Direction {
FORWARD = 1,
diff --git a/src/mongo/db/exec/count.cpp b/src/mongo/db/exec/count.cpp
index e5f3604efc1..832db7435cb 100644
--- a/src/mongo/db/exec/count.cpp
+++ b/src/mongo/db/exec/count.cpp
@@ -46,7 +46,7 @@ using std::vector;
const char* CountStage::kStageType = "COUNT";
CountStage::CountStage(ExpressionContext* expCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
long long limit,
long long skip,
WorkingSet* ws,
diff --git a/src/mongo/db/exec/count.h b/src/mongo/db/exec/count.h
index 8c21f2e1cff..b8de89a9594 100644
--- a/src/mongo/db/exec/count.h
+++ b/src/mongo/db/exec/count.h
@@ -47,7 +47,7 @@ namespace mongo {
class CountStage final : public PlanStage {
public:
CountStage(ExpressionContext* expCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
long long limit,
long long skip,
WorkingSet* ws,
diff --git a/src/mongo/db/exec/count_scan.cpp b/src/mongo/db/exec/count_scan.cpp
index fea2fa70c4d..8174e35ce2e 100644
--- a/src/mongo/db/exec/count_scan.cpp
+++ b/src/mongo/db/exec/count_scan.cpp
@@ -74,7 +74,7 @@ const char* CountScan::kStageType = "COUNT_SCAN";
// the CountScanParams rather than resolving them via the IndexDescriptor, since these may differ
// from the descriptor's contents.
CountScan::CountScan(ExpressionContext* expCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
CountScanParams params,
WorkingSet* workingSet)
: RequiresIndexStage(kStageType, expCtx, collection, params.indexDescriptor, workingSet),
diff --git a/src/mongo/db/exec/count_scan.h b/src/mongo/db/exec/count_scan.h
index 44a092c19b8..3b571bc5723 100644
--- a/src/mongo/db/exec/count_scan.h
+++ b/src/mongo/db/exec/count_scan.h
@@ -88,7 +88,7 @@ struct CountScanParams {
class CountScan final : public RequiresIndexStage {
public:
CountScan(ExpressionContext* expCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
CountScanParams params,
WorkingSet* workingSet);
diff --git a/src/mongo/db/exec/delete.cpp b/src/mongo/db/exec/delete.cpp
index 456e1be27e6..73de1abdbc5 100644
--- a/src/mongo/db/exec/delete.cpp
+++ b/src/mongo/db/exec/delete.cpp
@@ -71,7 +71,7 @@ bool shouldRestartDeleteIfNoLongerMatches(const DeleteStageParams* params) {
DeleteStage::DeleteStage(ExpressionContext* expCtx,
std::unique_ptr<DeleteStageParams> params,
WorkingSet* ws,
- const Collection* collection,
+ const CollectionPtr& collection,
PlanStage* child)
: RequiresMutableCollectionStage(kStageType.rawData(), expCtx, collection),
_params(std::move(params)),
diff --git a/src/mongo/db/exec/delete.h b/src/mongo/db/exec/delete.h
index 0123902e508..225705510d2 100644
--- a/src/mongo/db/exec/delete.h
+++ b/src/mongo/db/exec/delete.h
@@ -104,7 +104,7 @@ public:
DeleteStage(ExpressionContext* expCtx,
std::unique_ptr<DeleteStageParams> params,
WorkingSet* ws,
- const Collection* collection,
+ const CollectionPtr& collection,
PlanStage* child);
bool isEOF() final;
diff --git a/src/mongo/db/exec/distinct_scan.cpp b/src/mongo/db/exec/distinct_scan.cpp
index b0644a44c82..395130f09cb 100644
--- a/src/mongo/db/exec/distinct_scan.cpp
+++ b/src/mongo/db/exec/distinct_scan.cpp
@@ -47,7 +47,7 @@ using std::vector;
const char* DistinctScan::kStageType = "DISTINCT_SCAN";
DistinctScan::DistinctScan(ExpressionContext* expCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
DistinctParams params,
WorkingSet* workingSet)
: RequiresIndexStage(kStageType, expCtx, collection, params.indexDescriptor, workingSet),
diff --git a/src/mongo/db/exec/distinct_scan.h b/src/mongo/db/exec/distinct_scan.h
index b4d73e7b407..606e5b0b8f4 100644
--- a/src/mongo/db/exec/distinct_scan.h
+++ b/src/mongo/db/exec/distinct_scan.h
@@ -96,7 +96,7 @@ struct DistinctParams {
class DistinctScan final : public RequiresIndexStage {
public:
DistinctScan(ExpressionContext* expCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
DistinctParams params,
WorkingSet* workingSet);
diff --git a/src/mongo/db/exec/fetch.cpp b/src/mongo/db/exec/fetch.cpp
index 9528e9dc085..166b4604f8b 100644
--- a/src/mongo/db/exec/fetch.cpp
+++ b/src/mongo/db/exec/fetch.cpp
@@ -53,7 +53,7 @@ FetchStage::FetchStage(ExpressionContext* expCtx,
WorkingSet* ws,
std::unique_ptr<PlanStage> child,
const MatchExpression* filter,
- const Collection* collection)
+ const CollectionPtr& collection)
: RequiresCollectionStage(kStageType, expCtx, collection),
_ws(ws),
_filter((filter && !filter->isTriviallyTrue()) ? filter : nullptr),
diff --git a/src/mongo/db/exec/fetch.h b/src/mongo/db/exec/fetch.h
index 10dddc50a4f..0e3db734142 100644
--- a/src/mongo/db/exec/fetch.h
+++ b/src/mongo/db/exec/fetch.h
@@ -54,7 +54,7 @@ public:
WorkingSet* ws,
std::unique_ptr<PlanStage> child,
const MatchExpression* filter,
- const Collection* collection);
+ const CollectionPtr& collection);
~FetchStage();
diff --git a/src/mongo/db/exec/geo_near.cpp b/src/mongo/db/exec/geo_near.cpp
index e55f085a85f..8f97ab6107a 100644
--- a/src/mongo/db/exec/geo_near.cpp
+++ b/src/mongo/db/exec/geo_near.cpp
@@ -266,7 +266,7 @@ static R2Annulus twoDDistanceBounds(const GeoNearParams& nearParams,
return fullBounds;
}
-GeoNear2DStage::DensityEstimator::DensityEstimator(const Collection* collection,
+GeoNear2DStage::DensityEstimator::DensityEstimator(const CollectionPtr& collection,
PlanStage::Children* children,
BSONObj infoObj,
const GeoNearParams* nearParams,
@@ -454,7 +454,7 @@ static const string kTwoDIndexNearStage("GEO_NEAR_2D");
GeoNear2DStage::GeoNear2DStage(const GeoNearParams& nearParams,
ExpressionContext* expCtx,
WorkingSet* workingSet,
- const Collection* collection,
+ const CollectionPtr& collection,
const IndexDescriptor* twoDIndex)
: NearStage(expCtx,
kTwoDIndexNearStage.c_str(),
@@ -480,7 +480,7 @@ public:
WorkingSet* ws,
std::unique_ptr<PlanStage> child,
MatchExpression* filter,
- const Collection* collection)
+ const CollectionPtr& collection)
: FetchStage(expCtx, ws, std::move(child), filter, collection), _matcher(filter) {}
private:
@@ -520,7 +520,7 @@ static R2Annulus projectBoundsToTwoDDegrees(R2Annulus sphereBounds) {
}
std::unique_ptr<NearStage::CoveredInterval> GeoNear2DStage::nextInterval(
- OperationContext* opCtx, WorkingSet* workingSet, const Collection* collection) {
+ OperationContext* opCtx, WorkingSet* workingSet, const CollectionPtr& collection) {
// The search is finished if we searched at least once and all the way to the edge
if (_currBounds.getInner() >= 0 && _currBounds.getOuter() == _fullBounds.getOuter()) {
return nullptr;
@@ -697,7 +697,7 @@ static const string kS2IndexNearStage("GEO_NEAR_2DSPHERE");
GeoNear2DSphereStage::GeoNear2DSphereStage(const GeoNearParams& nearParams,
ExpressionContext* expCtx,
WorkingSet* workingSet,
- const Collection* collection,
+ const CollectionPtr& collection,
const IndexDescriptor* s2Index)
: NearStage(expCtx,
kS2IndexNearStage.c_str(),
@@ -762,7 +762,7 @@ S2Region* buildS2Region(const R2Annulus& sphereBounds) {
}
} // namespace
-GeoNear2DSphereStage::DensityEstimator::DensityEstimator(const Collection* collection,
+GeoNear2DSphereStage::DensityEstimator::DensityEstimator(const CollectionPtr& collection,
PlanStage::Children* children,
const GeoNearParams* nearParams,
const S2IndexingParams& indexParams,
@@ -919,7 +919,7 @@ PlanStage::StageState GeoNear2DSphereStage::initialize(OperationContext* opCtx,
}
std::unique_ptr<NearStage::CoveredInterval> GeoNear2DSphereStage::nextInterval(
- OperationContext* opCtx, WorkingSet* workingSet, const Collection* collection) {
+ OperationContext* opCtx, WorkingSet* workingSet, const CollectionPtr& collection) {
// The search is finished if we searched at least once and all the way to the edge
if (_currBounds.getInner() >= 0 && _currBounds.getOuter() == _fullBounds.getOuter()) {
return nullptr;
diff --git a/src/mongo/db/exec/geo_near.h b/src/mongo/db/exec/geo_near.h
index 08001ecc77c..d29d7536bea 100644
--- a/src/mongo/db/exec/geo_near.h
+++ b/src/mongo/db/exec/geo_near.h
@@ -71,13 +71,13 @@ public:
GeoNear2DStage(const GeoNearParams& nearParams,
ExpressionContext* expCtx,
WorkingSet* workingSet,
- const Collection* collection,
+ const CollectionPtr& collection,
const IndexDescriptor* twoDIndex);
protected:
std::unique_ptr<CoveredInterval> nextInterval(OperationContext* opCtx,
WorkingSet* workingSet,
- const Collection* collection) final;
+ const CollectionPtr& collection) final;
double computeDistance(WorkingSetMember* member) final;
@@ -88,7 +88,7 @@ protected:
private:
class DensityEstimator {
public:
- DensityEstimator(const Collection* collection,
+ DensityEstimator(const CollectionPtr& collection,
PlanStage::Children* children,
BSONObj infoObj,
const GeoNearParams* nearParams,
@@ -105,7 +105,7 @@ private:
WorkingSet* workingSet,
const IndexDescriptor* twoDIndex);
- const Collection* _collection;
+ const CollectionPtr& _collection;
PlanStage::Children* _children; // Points to PlanStage::_children in the NearStage.
const GeoNearParams* _nearParams; // Not owned here.
const R2Annulus& _fullBounds;
@@ -140,13 +140,13 @@ public:
GeoNear2DSphereStage(const GeoNearParams& nearParams,
ExpressionContext* expCtx,
WorkingSet* workingSet,
- const Collection* collection,
+ const CollectionPtr& collection,
const IndexDescriptor* s2Index);
protected:
std::unique_ptr<CoveredInterval> nextInterval(OperationContext* opCtx,
WorkingSet* workingSet,
- const Collection* collection) final;
+ const CollectionPtr& collection) final;
double computeDistance(WorkingSetMember* member) final;
@@ -158,7 +158,7 @@ private:
// Estimate the density of data by search the nearest cells level by level around center.
class DensityEstimator {
public:
- DensityEstimator(const Collection* collection,
+ DensityEstimator(const CollectionPtr& collection,
PlanStage::Children* children,
const GeoNearParams* nearParams,
const S2IndexingParams& indexParams,
@@ -177,7 +177,7 @@ private:
WorkingSet* workingSet,
const IndexDescriptor* s2Index);
- const Collection* _collection;
+ const CollectionPtr& _collection;
PlanStage::Children* _children; // Points to PlanStage::_children in the NearStage.
const GeoNearParams* _nearParams; // Not owned here.
const S2IndexingParams _indexParams;
diff --git a/src/mongo/db/exec/idhack.cpp b/src/mongo/db/exec/idhack.cpp
index 196993562d2..22319c36e74 100644
--- a/src/mongo/db/exec/idhack.cpp
+++ b/src/mongo/db/exec/idhack.cpp
@@ -52,7 +52,7 @@ const char* IDHackStage::kStageType = "IDHACK";
IDHackStage::IDHackStage(ExpressionContext* expCtx,
CanonicalQuery* query,
WorkingSet* ws,
- const Collection* collection,
+ const CollectionPtr& collection,
const IndexDescriptor* descriptor)
: RequiresIndexStage(kStageType, expCtx, collection, descriptor, ws),
_workingSet(ws),
@@ -64,7 +64,7 @@ IDHackStage::IDHackStage(ExpressionContext* expCtx,
IDHackStage::IDHackStage(ExpressionContext* expCtx,
const BSONObj& key,
WorkingSet* ws,
- const Collection* collection,
+ const CollectionPtr& collection,
const IndexDescriptor* descriptor)
: RequiresIndexStage(kStageType, expCtx, collection, descriptor, ws),
_workingSet(ws),
diff --git a/src/mongo/db/exec/idhack.h b/src/mongo/db/exec/idhack.h
index a06366459e5..effe1766efa 100644
--- a/src/mongo/db/exec/idhack.h
+++ b/src/mongo/db/exec/idhack.h
@@ -51,13 +51,13 @@ public:
IDHackStage(ExpressionContext* expCtx,
CanonicalQuery* query,
WorkingSet* ws,
- const Collection* collection,
+ const CollectionPtr& collection,
const IndexDescriptor* descriptor);
IDHackStage(ExpressionContext* expCtx,
const BSONObj& key,
WorkingSet* ws,
- const Collection* collection,
+ const CollectionPtr& collection,
const IndexDescriptor* descriptor);
~IDHackStage();
diff --git a/src/mongo/db/exec/index_scan.cpp b/src/mongo/db/exec/index_scan.cpp
index 62cc788b790..f746f3f8bad 100644
--- a/src/mongo/db/exec/index_scan.cpp
+++ b/src/mongo/db/exec/index_scan.cpp
@@ -60,7 +60,7 @@ namespace mongo {
const char* IndexScan::kStageType = "IXSCAN";
IndexScan::IndexScan(ExpressionContext* expCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
IndexScanParams params,
WorkingSet* workingSet,
const MatchExpression* filter)
diff --git a/src/mongo/db/exec/index_scan.h b/src/mongo/db/exec/index_scan.h
index cad8df9b9a0..c2be1169117 100644
--- a/src/mongo/db/exec/index_scan.h
+++ b/src/mongo/db/exec/index_scan.h
@@ -109,7 +109,7 @@ public:
};
IndexScan(ExpressionContext* expCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
IndexScanParams params,
WorkingSet* workingSet,
const MatchExpression* filter);
diff --git a/src/mongo/db/exec/multi_iterator.cpp b/src/mongo/db/exec/multi_iterator.cpp
index d9aee1eb09f..ca6dfe67210 100644
--- a/src/mongo/db/exec/multi_iterator.cpp
+++ b/src/mongo/db/exec/multi_iterator.cpp
@@ -45,7 +45,7 @@ const char* MultiIteratorStage::kStageType = "MULTI_ITERATOR";
MultiIteratorStage::MultiIteratorStage(ExpressionContext* expCtx,
WorkingSet* ws,
- const Collection* collection)
+ const CollectionPtr& collection)
: RequiresCollectionStage(kStageType, expCtx, collection), _ws(ws) {}
void MultiIteratorStage::addIterator(unique_ptr<RecordCursor> it) {
diff --git a/src/mongo/db/exec/multi_iterator.h b/src/mongo/db/exec/multi_iterator.h
index 1519901c52f..cf6e5e322c6 100644
--- a/src/mongo/db/exec/multi_iterator.h
+++ b/src/mongo/db/exec/multi_iterator.h
@@ -47,7 +47,7 @@ namespace mongo {
*/
class MultiIteratorStage final : public RequiresCollectionStage {
public:
- MultiIteratorStage(ExpressionContext* expCtx, WorkingSet* ws, const Collection* collection);
+ MultiIteratorStage(ExpressionContext* expCtx, WorkingSet* ws, const CollectionPtr& collection);
void addIterator(std::unique_ptr<RecordCursor> it);
diff --git a/src/mongo/db/exec/multi_plan.cpp b/src/mongo/db/exec/multi_plan.cpp
index ab89c47642c..a9e985cd533 100644
--- a/src/mongo/db/exec/multi_plan.cpp
+++ b/src/mongo/db/exec/multi_plan.cpp
@@ -72,7 +72,7 @@ void markShouldCollectTimingInfoOnSubtree(PlanStage* root) {
} // namespace
MultiPlanStage::MultiPlanStage(ExpressionContext* expCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
CanonicalQuery* cq,
PlanCachingMode cachingMode)
: RequiresCollectionStage(kStageType, expCtx, collection),
diff --git a/src/mongo/db/exec/multi_plan.h b/src/mongo/db/exec/multi_plan.h
index 59791dc7d2d..f76caef83a5 100644
--- a/src/mongo/db/exec/multi_plan.h
+++ b/src/mongo/db/exec/multi_plan.h
@@ -60,7 +60,7 @@ public:
* when possible. If 'shouldCache' is false, the plan cache will never be written.
*/
MultiPlanStage(ExpressionContext* expCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
CanonicalQuery* cq,
PlanCachingMode cachingMode = PlanCachingMode::AlwaysCache);
diff --git a/src/mongo/db/exec/near.cpp b/src/mongo/db/exec/near.cpp
index 94af9d88f74..3b095958986 100644
--- a/src/mongo/db/exec/near.cpp
+++ b/src/mongo/db/exec/near.cpp
@@ -46,7 +46,7 @@ NearStage::NearStage(ExpressionContext* expCtx,
const char* typeName,
StageType type,
WorkingSet* workingSet,
- const Collection* collection,
+ const CollectionPtr& collection,
const IndexDescriptor* indexDescriptor)
: RequiresIndexStage(typeName, expCtx, collection, indexDescriptor, workingSet),
_workingSet(workingSet),
diff --git a/src/mongo/db/exec/near.h b/src/mongo/db/exec/near.h
index fef83f58640..315b7c8f4b8 100644
--- a/src/mongo/db/exec/near.h
+++ b/src/mongo/db/exec/near.h
@@ -108,7 +108,7 @@ protected:
const char* typeName,
StageType type,
WorkingSet* workingSet,
- const Collection* collection,
+ const CollectionPtr& collection,
const IndexDescriptor* indexDescriptor);
//
@@ -122,7 +122,7 @@ protected:
*/
virtual std::unique_ptr<CoveredInterval> nextInterval(OperationContext* opCtx,
WorkingSet* workingSet,
- const Collection* collection) = 0;
+ const CollectionPtr& collection) = 0;
/**
* Computes the distance value for the given member data, or -1 if the member should not be
diff --git a/src/mongo/db/exec/plan_cache_util.h b/src/mongo/db/exec/plan_cache_util.h
index 3bb25315724..14946877777 100644
--- a/src/mongo/db/exec/plan_cache_util.h
+++ b/src/mongo/db/exec/plan_cache_util.h
@@ -80,7 +80,7 @@ void logNotCachingNoData(std::string&& solution);
template <typename PlanStageType, typename ResultType, typename Data>
void updatePlanCache(
OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
PlanCachingMode cachingMode,
const CanonicalQuery& query,
std::unique_ptr<plan_ranker::PlanRankingDecision> ranking,
diff --git a/src/mongo/db/exec/plan_stage.h b/src/mongo/db/exec/plan_stage.h
index 4392837219c..69c048ec8f7 100644
--- a/src/mongo/db/exec/plan_stage.h
+++ b/src/mongo/db/exec/plan_stage.h
@@ -41,6 +41,7 @@ namespace mongo {
class ClockSource;
class Collection;
+class CollectionPtr;
class OperationContext;
class RecordId;
diff --git a/src/mongo/db/exec/record_store_fast_count.cpp b/src/mongo/db/exec/record_store_fast_count.cpp
index c454a1af19f..f810b55dc79 100644
--- a/src/mongo/db/exec/record_store_fast_count.cpp
+++ b/src/mongo/db/exec/record_store_fast_count.cpp
@@ -36,7 +36,7 @@ namespace mongo {
const char* RecordStoreFastCountStage::kStageType = "RECORD_STORE_FAST_COUNT";
RecordStoreFastCountStage::RecordStoreFastCountStage(ExpressionContext* expCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
long long skip,
long long limit)
: RequiresCollectionStage(kStageType, expCtx, collection), _skip(skip), _limit(limit) {
diff --git a/src/mongo/db/exec/record_store_fast_count.h b/src/mongo/db/exec/record_store_fast_count.h
index 1a73829afa2..883e6e843d2 100644
--- a/src/mongo/db/exec/record_store_fast_count.h
+++ b/src/mongo/db/exec/record_store_fast_count.h
@@ -43,7 +43,7 @@ public:
static const char* kStageType;
RecordStoreFastCountStage(ExpressionContext* expCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
long long skip,
long long limit);
diff --git a/src/mongo/db/exec/requires_all_indices_stage.h b/src/mongo/db/exec/requires_all_indices_stage.h
index 15beac52ebf..06d3a72ae55 100644
--- a/src/mongo/db/exec/requires_all_indices_stage.h
+++ b/src/mongo/db/exec/requires_all_indices_stage.h
@@ -43,7 +43,7 @@ class RequiresAllIndicesStage : public RequiresCollectionStage {
public:
RequiresAllIndicesStage(const char* stageType,
ExpressionContext* expCtx,
- const Collection* coll)
+ const CollectionPtr& coll)
: RequiresCollectionStage(stageType, expCtx, coll) {
auto allEntriesShared = coll->getIndexCatalog()->getAllReadyEntriesShared();
_indexCatalogEntries.reserve(allEntriesShared.size());
diff --git a/src/mongo/db/exec/requires_collection_stage.cpp b/src/mongo/db/exec/requires_collection_stage.cpp
index 92a4a1e0279..c4b726d08cb 100644
--- a/src/mongo/db/exec/requires_collection_stage.cpp
+++ b/src/mongo/db/exec/requires_collection_stage.cpp
@@ -37,7 +37,7 @@ void RequiresCollectionStage::doSaveState() {
doSaveStateRequiresCollection();
// A stage may not access storage while in a saved state.
- _collection = nullptr;
+ _collection = CollectionPtr();
}
void RequiresCollectionStage::doRestoreState() {
@@ -64,6 +64,9 @@ void RequiresCollectionStage::doRestoreState() {
// restored locks on the correct name. It is now safe to restore the Collection pointer. The
// collection must exist, since we already successfully looked up the namespace string by UUID
// under the correct lock manager locks.
+ // TODO SERVER-51115: We can't have every instance of RequiresCollectionStage do a catalog
+ // lookup with lock free reads. If we have multiple instances within a single executor they
+ // might get different pointers.
_collection = catalog.lookupCollectionByUUID(opCtx(), _collectionUUID);
invariant(_collection);
diff --git a/src/mongo/db/exec/requires_collection_stage.h b/src/mongo/db/exec/requires_collection_stage.h
index eb9498f5e04..bbe6ea76d97 100644
--- a/src/mongo/db/exec/requires_collection_stage.h
+++ b/src/mongo/db/exec/requires_collection_stage.h
@@ -51,9 +51,9 @@ class RequiresCollectionStage : public PlanStage {
public:
RequiresCollectionStage(const char* stageType,
ExpressionContext* expCtx,
- const Collection* coll)
+ const CollectionPtr& coll)
: PlanStage(stageType, expCtx),
- _collection(coll),
+ _collection(coll.detached()),
_collectionUUID(_collection->uuid()),
_catalogEpoch(getCatalogEpoch()),
_nss(_collection->ns()) {
@@ -77,7 +77,7 @@ protected:
*/
virtual void doRestoreStateRequiresCollection() = 0;
- const Collection* collection() const {
+ const CollectionPtr& collection() const {
return _collection;
}
@@ -91,7 +91,7 @@ private:
return CollectionCatalog::get(opCtx()).getEpoch();
}
- const Collection* _collection;
+ CollectionPtr _collection;
const UUID _collectionUUID;
const uint64_t _catalogEpoch;
diff --git a/src/mongo/db/exec/requires_index_stage.cpp b/src/mongo/db/exec/requires_index_stage.cpp
index f1b43466822..9b7115b4ccc 100644
--- a/src/mongo/db/exec/requires_index_stage.cpp
+++ b/src/mongo/db/exec/requires_index_stage.cpp
@@ -35,7 +35,7 @@ namespace mongo {
RequiresIndexStage::RequiresIndexStage(const char* stageType,
ExpressionContext* expCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
const IndexDescriptor* indexDescriptor,
WorkingSet* workingSet)
: RequiresCollectionStage(stageType, expCtx, collection),
diff --git a/src/mongo/db/exec/requires_index_stage.h b/src/mongo/db/exec/requires_index_stage.h
index cd3ba14fe4e..37257e98084 100644
--- a/src/mongo/db/exec/requires_index_stage.h
+++ b/src/mongo/db/exec/requires_index_stage.h
@@ -37,7 +37,7 @@ namespace mongo {
/**
* A base class for plan stages which require access to a particular index within a particular
- * collection. Provides subclasses access to the index's const Collection*, as well as to catalog
+ * collection. Provides subclasses access to the index's const CollectionPtr&, as well as to catalog
* types representing the index itself such as the IndexDescriptor. This base class is responsible
* for checking that the collection and index are still valid (e.g. have not been dropped) when
* recovering from yield.
@@ -49,7 +49,7 @@ class RequiresIndexStage : public RequiresCollectionStage {
public:
RequiresIndexStage(const char* stageType,
ExpressionContext* expCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
const IndexDescriptor* indexDescriptor,
WorkingSet* workingSet);
diff --git a/src/mongo/db/exec/sbe/parser/parser.cpp b/src/mongo/db/exec/sbe/parser/parser.cpp
index 6be9d63afbf..f650ac6ed1c 100644
--- a/src/mongo/db/exec/sbe/parser/parser.cpp
+++ b/src/mongo/db/exec/sbe/parser/parser.cpp
@@ -532,8 +532,7 @@ void Parser::walkScan(AstQuery& ast) {
}
NamespaceString nssColl{dbName, collName};
- AutoGetCollectionForRead ctxColl(_opCtx, nssColl);
- auto collection = ctxColl.getCollection();
+ AutoGetCollectionForRead collection(_opCtx, nssColl);
NamespaceStringOrUUID name =
collection ? NamespaceStringOrUUID{dbName, collection->uuid()} : nssColl;
const auto forward = (ast.nodes[forwardPos]->token == "true") ? true : false;
@@ -576,8 +575,7 @@ void Parser::walkParallelScan(AstQuery& ast) {
}
NamespaceString nssColl{dbName, collName};
- AutoGetCollectionForRead ctxColl(_opCtx, nssColl);
- auto collection = ctxColl.getCollection();
+ AutoGetCollectionForRead collection(_opCtx, nssColl);
NamespaceStringOrUUID name =
collection ? NamespaceStringOrUUID{dbName, collection->uuid()} : nssColl;
@@ -616,8 +614,7 @@ void Parser::walkSeek(AstQuery& ast) {
}
NamespaceString nssColl{dbName, collName};
- AutoGetCollectionForRead ctxColl(_opCtx, nssColl);
- auto collection = ctxColl.getCollection();
+ AutoGetCollectionForRead collection(_opCtx, nssColl);
NamespaceStringOrUUID name =
collection ? NamespaceStringOrUUID{dbName, collection->uuid()} : nssColl;
@@ -667,8 +664,7 @@ void Parser::walkIndexScan(AstQuery& ast) {
}
NamespaceString nssColl{dbName, collName};
- AutoGetCollectionForRead ctxColl(_opCtx, nssColl);
- auto collection = ctxColl.getCollection();
+ AutoGetCollectionForRead collection(_opCtx, nssColl);
NamespaceStringOrUUID name =
collection ? NamespaceStringOrUUID{dbName, collection->uuid()} : nssColl;
const auto forward = (ast.nodes[forwardPos]->token == "true") ? true : false;
@@ -724,8 +720,7 @@ void Parser::walkIndexSeek(AstQuery& ast) {
}
NamespaceString nssColl{dbName, collName};
- AutoGetCollectionForRead ctxColl(_opCtx, nssColl);
- auto collection = ctxColl.getCollection();
+ AutoGetCollectionForRead collection(_opCtx, nssColl);
NamespaceStringOrUUID name =
collection ? NamespaceStringOrUUID{dbName, collection->uuid()} : nssColl;
const auto forward = (ast.nodes[forwardPos]->token == "true") ? true : false;
diff --git a/src/mongo/db/exec/sbe/stages/ix_scan.cpp b/src/mongo/db/exec/sbe/stages/ix_scan.cpp
index 5c6a6051839..68c8c6c44cc 100644
--- a/src/mongo/db/exec/sbe/stages/ix_scan.cpp
+++ b/src/mongo/db/exec/sbe/stages/ix_scan.cpp
@@ -178,7 +178,7 @@ void IndexScanStage::open(bool reOpen) {
_open = true;
_firstGetNext = true;
- if (auto collection = _coll->getCollection()) {
+ if (const auto& collection = _coll->getCollection()) {
auto indexCatalog = collection->getIndexCatalog();
auto indexDesc = indexCatalog->findIndexByName(_opCtx, _indexName);
if (indexDesc) {
diff --git a/src/mongo/db/exec/sbe/stages/scan.cpp b/src/mongo/db/exec/sbe/stages/scan.cpp
index 967c94e1a37..7c3f3e5c29c 100644
--- a/src/mongo/db/exec/sbe/stages/scan.cpp
+++ b/src/mongo/db/exec/sbe/stages/scan.cpp
@@ -178,7 +178,7 @@ void ScanStage::open(bool reOpen) {
_openCallback(_opCtx, _coll->getCollection(), reOpen);
}
- if (auto collection = _coll->getCollection()) {
+ if (const auto& collection = _coll->getCollection()) {
if (_seekKeyAccessor) {
auto [tag, val] = _seekKeyAccessor->getViewOfValue();
const auto msgTag = tag;
@@ -453,7 +453,7 @@ void ParallelScanStage::open(bool reOpen) {
uassertStatusOK(repl::ReplicationCoordinator::get(_opCtx)->checkCanServeReadsFor(
_opCtx, _coll->getNss(), true));
- auto collection = _coll->getCollection();
+ const auto& collection = _coll->getCollection();
if (collection) {
{
diff --git a/src/mongo/db/exec/sbe/stages/scan.h b/src/mongo/db/exec/sbe/stages/scan.h
index 0566c0d4f61..5c071ff32a6 100644
--- a/src/mongo/db/exec/sbe/stages/scan.h
+++ b/src/mongo/db/exec/sbe/stages/scan.h
@@ -37,7 +37,7 @@
namespace mongo {
namespace sbe {
-using ScanOpenCallback = std::function<void(OperationContext*, const Collection*, bool)>;
+using ScanOpenCallback = std::function<void(OperationContext*, const CollectionPtr&, bool)>;
class ScanStage final : public PlanStage {
public:
diff --git a/src/mongo/db/exec/sort_key_generator.h b/src/mongo/db/exec/sort_key_generator.h
index 2679902dd2e..f3196861947 100644
--- a/src/mongo/db/exec/sort_key_generator.h
+++ b/src/mongo/db/exec/sort_key_generator.h
@@ -42,6 +42,7 @@ namespace mongo {
class CollatorInterface;
class Collection;
+class CollectionPtr;
class WorkingSetMember;
/**
diff --git a/src/mongo/db/exec/stagedebug_cmd.cpp b/src/mongo/db/exec/stagedebug_cmd.cpp
index 06dd3532fdc..856d2d527c4 100644
--- a/src/mongo/db/exec/stagedebug_cmd.cpp
+++ b/src/mongo/db/exec/stagedebug_cmd.cpp
@@ -148,14 +148,14 @@ public:
auto expCtx = make_intrusive<ExpressionContext>(
opCtx, std::unique_ptr<CollatorInterface>(nullptr), nss);
- // Need a context to get the actual const Collection*
+ // Need a context to get the actual const CollectionPtr&
// TODO A write lock is currently taken here to accommodate stages that perform writes
// (e.g. DeleteStage). This should be changed to use a read lock for read-only
// execution trees.
AutoGetCollection autoColl(opCtx, nss, MODE_IX);
// Make sure the collection is valid.
- const Collection* collection = autoColl.getCollection();
+ const auto& collection = autoColl.getCollection();
uassert(ErrorCodes::NamespaceNotFound,
str::stream() << "Couldn't find collection " << nss.ns(),
collection);
@@ -201,7 +201,7 @@ public:
}
PlanStage* parseQuery(const boost::intrusive_ptr<ExpressionContext>& expCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
BSONObj obj,
WorkingSet* workingSet,
const NamespaceString& nss,
diff --git a/src/mongo/db/exec/subplan.cpp b/src/mongo/db/exec/subplan.cpp
index 667a0cecfec..c97c85d361e 100644
--- a/src/mongo/db/exec/subplan.cpp
+++ b/src/mongo/db/exec/subplan.cpp
@@ -57,7 +57,7 @@ using std::vector;
const char* SubplanStage::kStageType = "SUBPLAN";
SubplanStage::SubplanStage(ExpressionContext* expCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
WorkingSet* ws,
const QueryPlannerParams& params,
CanonicalQuery* cq)
diff --git a/src/mongo/db/exec/subplan.h b/src/mongo/db/exec/subplan.h
index 6b5d5b7448b..0136954d6a1 100644
--- a/src/mongo/db/exec/subplan.h
+++ b/src/mongo/db/exec/subplan.h
@@ -71,7 +71,7 @@ class OperationContext;
class SubplanStage final : public RequiresAllIndicesStage {
public:
SubplanStage(ExpressionContext* expCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
WorkingSet* ws,
const QueryPlannerParams& params,
CanonicalQuery* cq);
diff --git a/src/mongo/db/exec/text.cpp b/src/mongo/db/exec/text.cpp
index 2657556af7e..a6f252d2cc3 100644
--- a/src/mongo/db/exec/text.cpp
+++ b/src/mongo/db/exec/text.cpp
@@ -57,7 +57,7 @@ using fts::MAX_WEIGHT;
const char* TextStage::kStageType = "TEXT";
TextStage::TextStage(ExpressionContext* expCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
const TextStageParams& params,
WorkingSet* ws,
const MatchExpression* filter)
@@ -96,7 +96,7 @@ const SpecificStats* TextStage::getSpecificStats() const {
}
unique_ptr<PlanStage> TextStage::buildTextTree(OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
WorkingSet* ws,
const MatchExpression* filter,
bool wantTextScore) const {
diff --git a/src/mongo/db/exec/text.h b/src/mongo/db/exec/text.h
index 9c0c54baadd..040ecb9f424 100644
--- a/src/mongo/db/exec/text.h
+++ b/src/mongo/db/exec/text.h
@@ -74,7 +74,7 @@ struct TextStageParams {
class TextStage final : public PlanStage {
public:
TextStage(ExpressionContext* expCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
const TextStageParams& params,
WorkingSet* ws,
const MatchExpression* filter);
@@ -97,7 +97,7 @@ private:
* Helper method to built the query execution plan for the text stage.
*/
std::unique_ptr<PlanStage> buildTextTree(OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
WorkingSet* ws,
const MatchExpression* filter,
bool wantTextScore) const;
diff --git a/src/mongo/db/exec/text_or.cpp b/src/mongo/db/exec/text_or.cpp
index 75e90e278cc..23e6d0fcbc5 100644
--- a/src/mongo/db/exec/text_or.cpp
+++ b/src/mongo/db/exec/text_or.cpp
@@ -56,7 +56,7 @@ TextOrStage::TextOrStage(ExpressionContext* expCtx,
const FTSSpec& ftsSpec,
WorkingSet* ws,
const MatchExpression* filter,
- const Collection* collection)
+ const CollectionPtr& collection)
: RequiresCollectionStage(kStageType, expCtx, collection),
_ftsSpec(ftsSpec),
_ws(ws),
diff --git a/src/mongo/db/exec/text_or.h b/src/mongo/db/exec/text_or.h
index 8b57b2f07e7..2e358bf71ed 100644
--- a/src/mongo/db/exec/text_or.h
+++ b/src/mongo/db/exec/text_or.h
@@ -71,7 +71,7 @@ public:
const FTSSpec& ftsSpec,
WorkingSet* ws,
const MatchExpression* filter,
- const Collection* collection);
+ const CollectionPtr& collection);
void addChild(std::unique_ptr<PlanStage> child);
diff --git a/src/mongo/db/exec/trial_period_utils.cpp b/src/mongo/db/exec/trial_period_utils.cpp
index 759e41b3577..4369ff40a08 100644
--- a/src/mongo/db/exec/trial_period_utils.cpp
+++ b/src/mongo/db/exec/trial_period_utils.cpp
@@ -34,11 +34,11 @@
#include "mongo/db/catalog/collection.h"
namespace mongo::trial_period {
-size_t getTrialPeriodMaxWorks(OperationContext* opCtx, const Collection* collection) {
+size_t getTrialPeriodMaxWorks(OperationContext* opCtx, const CollectionPtr& collection) {
// Run each plan some number of times. This number is at least as great as
// 'internalQueryPlanEvaluationWorks', but may be larger for big collections.
size_t numWorks = internalQueryPlanEvaluationWorks.load();
- if (nullptr != collection) {
+ if (collection) {
// For large collections, the number of works is set to be this fraction of the collection
// size.
double fraction = internalQueryPlanEvaluationCollFraction;
diff --git a/src/mongo/db/exec/trial_period_utils.h b/src/mongo/db/exec/trial_period_utils.h
index 4919e8be1c9..609d5f3b484 100644
--- a/src/mongo/db/exec/trial_period_utils.h
+++ b/src/mongo/db/exec/trial_period_utils.h
@@ -33,6 +33,7 @@
namespace mongo {
class Collection;
+class CollectionPtr;
namespace trial_period {
/**
@@ -40,7 +41,7 @@ namespace trial_period {
*
* Calculated based on a fixed query knob and the size of the collection.
*/
-size_t getTrialPeriodMaxWorks(OperationContext* opCtx, const Collection* collection);
+size_t getTrialPeriodMaxWorks(OperationContext* opCtx, const CollectionPtr& collection);
/**
* Returns the max number of documents which we should allow any plan to return during the
diff --git a/src/mongo/db/exec/update_stage.cpp b/src/mongo/db/exec/update_stage.cpp
index 3f0340c66b9..5cecfb72314 100644
--- a/src/mongo/db/exec/update_stage.cpp
+++ b/src/mongo/db/exec/update_stage.cpp
@@ -109,7 +109,7 @@ CollectionUpdateArgs::StoreDocOption getStoreDocMode(const UpdateRequest& update
UpdateStage::UpdateStage(ExpressionContext* expCtx,
const UpdateStageParams& params,
WorkingSet* ws,
- const Collection* collection,
+ const CollectionPtr& collection,
PlanStage* child)
: UpdateStage(expCtx, params, ws, collection) {
// We should never reach here if the request is an upsert.
@@ -121,7 +121,7 @@ UpdateStage::UpdateStage(ExpressionContext* expCtx,
UpdateStage::UpdateStage(ExpressionContext* expCtx,
const UpdateStageParams& params,
WorkingSet* ws,
- const Collection* collection)
+ const CollectionPtr& collection)
: RequiresMutableCollectionStage(kStageType.rawData(), expCtx, collection),
_params(params),
_ws(ws),
diff --git a/src/mongo/db/exec/update_stage.h b/src/mongo/db/exec/update_stage.h
index 7fc304f776c..d99fb902854 100644
--- a/src/mongo/db/exec/update_stage.h
+++ b/src/mongo/db/exec/update_stage.h
@@ -86,7 +86,7 @@ public:
UpdateStage(ExpressionContext* expCtx,
const UpdateStageParams& params,
WorkingSet* ws,
- const Collection* collection,
+ const CollectionPtr& collection,
PlanStage* child);
bool isEOF() override;
@@ -104,7 +104,7 @@ protected:
UpdateStage(ExpressionContext* expCtx,
const UpdateStageParams& params,
WorkingSet* ws,
- const Collection* collection);
+ const CollectionPtr& collection);
void doSaveStateRequiresCollection() final {}
diff --git a/src/mongo/db/exec/upsert_stage.cpp b/src/mongo/db/exec/upsert_stage.cpp
index 4bf02125604..4f0fa990c23 100644
--- a/src/mongo/db/exec/upsert_stage.cpp
+++ b/src/mongo/db/exec/upsert_stage.cpp
@@ -51,7 +51,7 @@ const FieldRef idFieldRef(idFieldName);
UpsertStage::UpsertStage(ExpressionContext* expCtx,
const UpdateStageParams& params,
WorkingSet* ws,
- const Collection* collection,
+ const CollectionPtr& collection,
PlanStage* child)
: UpdateStage(expCtx, params, ws, collection) {
// We should never create this stage for a non-upsert request.
diff --git a/src/mongo/db/exec/upsert_stage.h b/src/mongo/db/exec/upsert_stage.h
index 7735d5b996b..e6d0ab0f0f8 100644
--- a/src/mongo/db/exec/upsert_stage.h
+++ b/src/mongo/db/exec/upsert_stage.h
@@ -54,7 +54,7 @@ public:
UpsertStage(ExpressionContext* expCtx,
const UpdateStageParams& params,
WorkingSet* ws,
- const Collection* collection,
+ const CollectionPtr& collection,
PlanStage* child);
bool isEOF() final;
diff --git a/src/mongo/db/exec/write_stage_common.cpp b/src/mongo/db/exec/write_stage_common.cpp
index 301ced6f3a5..b060d57ab45 100644
--- a/src/mongo/db/exec/write_stage_common.cpp
+++ b/src/mongo/db/exec/write_stage_common.cpp
@@ -39,7 +39,7 @@
namespace mongo {
namespace write_stage_common {
-bool ensureStillMatches(const Collection* collection,
+bool ensureStillMatches(const CollectionPtr& collection,
OperationContext* opCtx,
WorkingSet* ws,
WorkingSetID id,
diff --git a/src/mongo/db/exec/write_stage_common.h b/src/mongo/db/exec/write_stage_common.h
index 1d3934443e6..f413745dfa6 100644
--- a/src/mongo/db/exec/write_stage_common.h
+++ b/src/mongo/db/exec/write_stage_common.h
@@ -37,6 +37,7 @@ namespace mongo {
class CanonicalQuery;
class Collection;
+class CollectionPtr;
class OperationContext;
namespace write_stage_common {
@@ -49,7 +50,7 @@ namespace write_stage_common {
* May throw a WriteConflictException if there was a conflict while searching to see if the document
* still exists.
*/
-bool ensureStillMatches(const Collection* collection,
+bool ensureStillMatches(const CollectionPtr& collection,
OperationContext* opCtx,
WorkingSet* ws,
WorkingSetID id,
diff --git a/src/mongo/db/fcv_op_observer.h b/src/mongo/db/fcv_op_observer.h
index 374c4387dc1..1be55f57d07 100644
--- a/src/mongo/db/fcv_op_observer.h
+++ b/src/mongo/db/fcv_op_observer.h
@@ -112,7 +112,7 @@ public:
const boost::optional<repl::OpTime> prevWriteOpTimeInTransaction,
const boost::optional<OplogSlot> slot) final {}
void onCreateCollection(OperationContext* opCtx,
- const Collection* coll,
+ const CollectionPtr& coll,
const NamespaceString& collectionName,
const CollectionOptions& options,
const BSONObj& idIndex,
diff --git a/src/mongo/db/free_mon/free_mon_op_observer.h b/src/mongo/db/free_mon/free_mon_op_observer.h
index 34496b448c9..5f6a9b912c0 100644
--- a/src/mongo/db/free_mon/free_mon_op_observer.h
+++ b/src/mongo/db/free_mon/free_mon_op_observer.h
@@ -106,7 +106,7 @@ public:
const boost::optional<OplogSlot> slot) final{};
void onCreateCollection(OperationContext* opCtx,
- const Collection* coll,
+ const CollectionPtr& coll,
const NamespaceString& collectionName,
const CollectionOptions& options,
const BSONObj& idIndex,
diff --git a/src/mongo/db/index/haystack_access_method.h b/src/mongo/db/index/haystack_access_method.h
index 0507887132d..f4aaa6a39a8 100644
--- a/src/mongo/db/index/haystack_access_method.h
+++ b/src/mongo/db/index/haystack_access_method.h
@@ -37,6 +37,7 @@
namespace mongo {
class Collection;
+class CollectionPtr;
class OperationContext;
/**
diff --git a/src/mongo/db/index/haystack_access_method_internal.h b/src/mongo/db/index/haystack_access_method_internal.h
index 18fe86ad0fb..58ce3d6a6c4 100644
--- a/src/mongo/db/index/haystack_access_method_internal.h
+++ b/src/mongo/db/index/haystack_access_method_internal.h
@@ -55,7 +55,7 @@ public:
double maxDistance,
unsigned limit,
const std::string& geoField,
- const Collection* collection)
+ const CollectionPtr& collection)
: _opCtx(opCtx),
_collection(collection),
_near(nearObj),
@@ -87,7 +87,7 @@ public:
private:
OperationContext* _opCtx;
- const Collection* _collection;
+ const CollectionPtr& _collection;
Point _near;
double _maxDistance;
diff --git a/src/mongo/db/index/index_access_method.cpp b/src/mongo/db/index/index_access_method.cpp
index 1a510c09b49..6080125c723 100644
--- a/src/mongo/db/index/index_access_method.cpp
+++ b/src/mongo/db/index/index_access_method.cpp
@@ -121,7 +121,7 @@ AbstractIndexAccessMethod::AbstractIndexAccessMethod(IndexCatalogEntry* btreeSta
// Find the keys for obj, put them in the tree pointing to loc.
Status AbstractIndexAccessMethod::insert(OperationContext* opCtx,
- const Collection* coll,
+ const CollectionPtr& coll,
const BSONObj& obj,
const RecordId& loc,
const InsertDeleteOptions& options,
@@ -158,7 +158,7 @@ Status AbstractIndexAccessMethod::insert(OperationContext* opCtx,
Status AbstractIndexAccessMethod::insertKeysAndUpdateMultikeyPaths(
OperationContext* opCtx,
- const Collection* coll,
+ const CollectionPtr& coll,
const KeyStringSet& keys,
const KeyStringSet& multikeyMetadataKeys,
const MultikeyPaths& multikeyPaths,
@@ -185,7 +185,7 @@ Status AbstractIndexAccessMethod::insertKeysAndUpdateMultikeyPaths(
}
Status AbstractIndexAccessMethod::insertKeys(OperationContext* opCtx,
- const Collection* coll,
+ const CollectionPtr& coll,
const KeyStringSet& keys,
const RecordId& loc,
const InsertDeleteOptions& options,
@@ -422,7 +422,7 @@ void AbstractIndexAccessMethod::prepareUpdate(OperationContext* opCtx,
}
Status AbstractIndexAccessMethod::update(OperationContext* opCtx,
- const Collection* coll,
+ const CollectionPtr& coll,
const UpdateTicket& ticket,
int64_t* numInserted,
int64_t* numDeleted) {
@@ -775,7 +775,7 @@ Status AbstractIndexAccessMethod::commitBulk(OperationContext* opCtx,
}
void AbstractIndexAccessMethod::setIndexIsMultikey(OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
KeyStringSet multikeyMetadataKeys,
MultikeyPaths paths) {
_indexCatalogEntry->setMultikey(opCtx, collection, multikeyMetadataKeys, paths);
diff --git a/src/mongo/db/index/index_access_method.h b/src/mongo/db/index/index_access_method.h
index 3d57dcb901a..15d32be7f1b 100644
--- a/src/mongo/db/index/index_access_method.h
+++ b/src/mongo/db/index/index_access_method.h
@@ -87,7 +87,7 @@ public:
* The behavior of the insertion can be specified through 'options'.
*/
virtual Status insert(OperationContext* opCtx,
- const Collection* coll,
+ const CollectionPtr& coll,
const BSONObj& obj,
const RecordId& loc,
const InsertDeleteOptions& options,
@@ -100,7 +100,7 @@ public:
* multikey in the catalog, and sets the path-level multikey information if applicable.
*/
virtual Status insertKeysAndUpdateMultikeyPaths(OperationContext* opCtx,
- const Collection* coll,
+ const CollectionPtr& coll,
const KeyStringSet& keys,
const KeyStringSet& multikeyMetadataKeys,
const MultikeyPaths& multikeyPaths,
@@ -114,7 +114,7 @@ public:
* insertion of these keys should cause the index to become multikey.
*/
virtual Status insertKeys(OperationContext* opCtx,
- const Collection* coll,
+ const CollectionPtr& coll,
const KeyStringSet& keys,
const RecordId& loc,
const InsertDeleteOptions& options,
@@ -155,7 +155,7 @@ public:
* 'numDeleted' will be set to the number of keys removed from the index for the document.
*/
virtual Status update(OperationContext* opCtx,
- const Collection* coll,
+ const CollectionPtr& coll,
const UpdateTicket& ticket,
int64_t* numInserted,
int64_t* numDeleted) = 0;
@@ -215,7 +215,7 @@ public:
* Sets this index as multikey with the provided paths.
*/
virtual void setIndexIsMultikey(OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
KeyStringSet multikeyMetadataKeys,
MultikeyPaths paths) = 0;
@@ -454,7 +454,7 @@ public:
std::unique_ptr<SortedDataInterface> btree);
Status insert(OperationContext* opCtx,
- const Collection* coll,
+ const CollectionPtr& coll,
const BSONObj& obj,
const RecordId& loc,
const InsertDeleteOptions& options,
@@ -462,7 +462,7 @@ public:
int64_t* numInserted) final;
Status insertKeys(OperationContext* opCtx,
- const Collection* coll,
+ const CollectionPtr& coll,
const KeyStringSet& keys,
const RecordId& loc,
const InsertDeleteOptions& options,
@@ -470,7 +470,7 @@ public:
int64_t* numInserted) final;
Status insertKeysAndUpdateMultikeyPaths(OperationContext* opCtx,
- const Collection* coll,
+ const CollectionPtr& coll,
const KeyStringSet& keys,
const KeyStringSet& multikeyMetadataKeys,
const MultikeyPaths& multikeyPaths,
@@ -494,7 +494,7 @@ public:
UpdateTicket* ticket) const final;
Status update(OperationContext* opCtx,
- const Collection* coll,
+ const CollectionPtr& coll,
const UpdateTicket& ticket,
int64_t* numInserted,
int64_t* numDeleted) final;
@@ -520,7 +520,7 @@ public:
Status compact(OperationContext* opCtx) final;
void setIndexIsMultikey(OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
KeyStringSet multikeyMetadataKeys,
MultikeyPaths paths) final;
diff --git a/src/mongo/db/index/index_build_interceptor.cpp b/src/mongo/db/index/index_build_interceptor.cpp
index 6a897960e60..e81ea389524 100644
--- a/src/mongo/db/index/index_build_interceptor.cpp
+++ b/src/mongo/db/index/index_build_interceptor.cpp
@@ -150,7 +150,7 @@ Status IndexBuildInterceptor::checkDuplicateKeyConstraints(OperationContext* opC
}
Status IndexBuildInterceptor::drainWritesIntoIndex(OperationContext* opCtx,
- const Collection* coll,
+ const CollectionPtr& coll,
const InsertDeleteOptions& options,
TrackDuplicates trackDuplicates,
DrainYieldPolicy drainYieldPolicy) {
@@ -307,7 +307,7 @@ Status IndexBuildInterceptor::drainWritesIntoIndex(OperationContext* opCtx,
}
Status IndexBuildInterceptor::_applyWrite(OperationContext* opCtx,
- const Collection* coll,
+ const CollectionPtr& coll,
const BSONObj& operation,
const InsertDeleteOptions& options,
TrackDuplicates trackDups,
@@ -531,7 +531,7 @@ Status IndexBuildInterceptor::sideWrite(OperationContext* opCtx,
}
Status IndexBuildInterceptor::retrySkippedRecords(OperationContext* opCtx,
- const Collection* collection) {
+ const CollectionPtr& collection) {
return _skippedRecordTracker.retrySkippedRecords(opCtx, collection);
}
diff --git a/src/mongo/db/index/index_build_interceptor.h b/src/mongo/db/index/index_build_interceptor.h
index 2ea3e61ebfa..2eb571650d9 100644
--- a/src/mongo/db/index/index_build_interceptor.h
+++ b/src/mongo/db/index/index_build_interceptor.h
@@ -132,7 +132,7 @@ public:
* following the last inserted record from a previous call to drainWritesIntoIndex.
*/
Status drainWritesIntoIndex(OperationContext* opCtx,
- const Collection* coll,
+ const CollectionPtr& coll,
const InsertDeleteOptions& options,
TrackDuplicates trackDups,
DrainYieldPolicy drainYieldPolicy);
@@ -150,7 +150,7 @@ public:
* successful, keys are written directly to the index. Unsuccessful key generation or writes
* will return errors.
*/
- Status retrySkippedRecords(OperationContext* opCtx, const Collection* collection);
+ Status retrySkippedRecords(OperationContext* opCtx, const CollectionPtr& collection);
/**
* Returns 'true' if there are no visible records remaining to be applied from the side writes
@@ -179,7 +179,7 @@ private:
void _initializeMultiKeyPaths(IndexCatalogEntry* entry);
Status _applyWrite(OperationContext* opCtx,
- const Collection* coll,
+ const CollectionPtr& coll,
const BSONObj& doc,
const InsertDeleteOptions& options,
TrackDuplicates trackDups,
diff --git a/src/mongo/db/index/index_descriptor.cpp b/src/mongo/db/index/index_descriptor.cpp
index f998864355e..dec4d7bb7e3 100644
--- a/src/mongo/db/index/index_descriptor.cpp
+++ b/src/mongo/db/index/index_descriptor.cpp
@@ -99,7 +99,7 @@ constexpr StringData IndexDescriptor::kUniqueFieldName;
constexpr StringData IndexDescriptor::kHiddenFieldName;
constexpr StringData IndexDescriptor::kWeightsFieldName;
-IndexDescriptor::IndexDescriptor(const Collection* collection,
+IndexDescriptor::IndexDescriptor(const CollectionPtr& collection,
const std::string& accessMethodName,
BSONObj infoObj)
: _accessMethodName(accessMethodName),
diff --git a/src/mongo/db/index/index_descriptor.h b/src/mongo/db/index/index_descriptor.h
index b4710c8e4b8..ad4c17b6cf6 100644
--- a/src/mongo/db/index/index_descriptor.h
+++ b/src/mongo/db/index/index_descriptor.h
@@ -43,6 +43,7 @@
namespace mongo {
class Collection;
+class CollectionPtr;
class IndexCatalogEntry;
class IndexCatalogEntryContainer;
class OperationContext;
@@ -95,7 +96,7 @@ public:
/**
* infoObj is a copy of the index-describing BSONObj contained in the catalog.
*/
- IndexDescriptor(const Collection* collection,
+ IndexDescriptor(const CollectionPtr& collection,
const std::string& accessMethodName,
BSONObj infoObj);
diff --git a/src/mongo/db/index/skipped_record_tracker.cpp b/src/mongo/db/index/skipped_record_tracker.cpp
index 34c1eabf431..1a825164ced 100644
--- a/src/mongo/db/index/skipped_record_tracker.cpp
+++ b/src/mongo/db/index/skipped_record_tracker.cpp
@@ -99,7 +99,7 @@ bool SkippedRecordTracker::areAllRecordsApplied(OperationContext* opCtx) const {
}
Status SkippedRecordTracker::retrySkippedRecords(OperationContext* opCtx,
- const Collection* collection) {
+ const CollectionPtr& collection) {
dassert(opCtx->lockState()->isCollectionLockedForMode(collection->ns(), MODE_X));
if (!_skippedRecordsTable) {
return Status::OK();
diff --git a/src/mongo/db/index/skipped_record_tracker.h b/src/mongo/db/index/skipped_record_tracker.h
index 856ebed9197..00112b9fab5 100644
--- a/src/mongo/db/index/skipped_record_tracker.h
+++ b/src/mongo/db/index/skipped_record_tracker.h
@@ -74,7 +74,7 @@ public:
* Attempts to generates keys for each skipped record and insert into the index. Returns OK if
* all records were either indexed or no longer exist.
*/
- Status retrySkippedRecords(OperationContext* opCtx, const Collection* collection);
+ Status retrySkippedRecords(OperationContext* opCtx, const CollectionPtr& collection);
boost::optional<std::string> getTableIdent() const {
return _skippedRecordsTable ? boost::make_optional(_skippedRecordsTable->rs()->getIdent())
diff --git a/src/mongo/db/index_build_entry_helpers.cpp b/src/mongo/db/index_build_entry_helpers.cpp
index 7a24324cac8..6b4265e8552 100644
--- a/src/mongo/db/index_build_entry_helpers.cpp
+++ b/src/mongo/db/index_build_entry_helpers.cpp
@@ -60,9 +60,8 @@ Status upsert(OperationContext* opCtx, const IndexBuildEntry& indexBuildEntry) {
"upsertIndexBuildEntry",
NamespaceString::kIndexBuildEntryNamespace.ns(),
[&]() -> Status {
- AutoGetCollection autoCollection(
+ AutoGetCollection collection(
opCtx, NamespaceString::kIndexBuildEntryNamespace, MODE_IX);
- const Collection* collection = autoCollection.getCollection();
if (!collection) {
str::stream ss;
ss << "Collection not found: "
@@ -116,9 +115,8 @@ Status upsert(OperationContext* opCtx, const BSONObj& filter, const BSONObj& upd
"upsertIndexBuildEntry",
NamespaceString::kIndexBuildEntryNamespace.ns(),
[&]() -> Status {
- AutoGetCollection autoCollection(
+ AutoGetCollection collection(
opCtx, NamespaceString::kIndexBuildEntryNamespace, MODE_IX);
- const Collection* collection = autoCollection.getCollection();
if (!collection) {
str::stream ss;
ss << "Collection not found: "
@@ -142,9 +140,8 @@ Status update(OperationContext* opCtx, const BSONObj& filter, const BSONObj& upd
"updateIndexBuildEntry",
NamespaceString::kIndexBuildEntryNamespace.ns(),
[&]() -> Status {
- AutoGetCollection autoCollection(
+ AutoGetCollection collection(
opCtx, NamespaceString::kIndexBuildEntryNamespace, MODE_IX);
- const Collection* collection = autoCollection.getCollection();
if (!collection) {
str::stream ss;
ss << "Collection not found: "
@@ -184,7 +181,7 @@ void ensureIndexBuildEntriesNamespaceExists(OperationContext* opCtx) {
opCtx, NamespaceString::kIndexBuildEntryNamespace)) {
WriteUnitOfWork wuow(opCtx);
CollectionOptions defaultCollectionOptions;
- const Collection* collection =
+ CollectionPtr collection =
db->createCollection(opCtx,
NamespaceString::kIndexBuildEntryNamespace,
defaultCollectionOptions);
@@ -223,9 +220,8 @@ Status addIndexBuildEntry(OperationContext* opCtx, const IndexBuildEntry& indexB
"addIndexBuildEntry",
NamespaceString::kIndexBuildEntryNamespace.ns(),
[&]() -> Status {
- AutoGetCollection autoCollection(
+ AutoGetCollection collection(
opCtx, NamespaceString::kIndexBuildEntryNamespace, MODE_IX);
- const Collection* collection = autoCollection.getCollection();
if (!collection) {
str::stream ss;
ss << "Collection not found: " << NamespaceString::kIndexBuildEntryNamespace.ns();
@@ -257,17 +253,18 @@ Status removeIndexBuildEntry(OperationContext* opCtx, UUID indexBuildUUID) {
"removeIndexBuildEntry",
NamespaceString::kIndexBuildEntryNamespace.ns(),
[&]() -> Status {
- AutoGetCollection autoCollection(
+ AutoGetCollection collection(
opCtx, NamespaceString::kIndexBuildEntryNamespace, MODE_IX);
- const Collection* collection = autoCollection.getCollection();
if (!collection) {
str::stream ss;
ss << "Collection not found: " << NamespaceString::kIndexBuildEntryNamespace.ns();
return Status(ErrorCodes::NamespaceNotFound, ss);
}
- RecordId rid = Helpers::findOne(
- opCtx, collection, BSON("_id" << indexBuildUUID), /*requireIndex=*/true);
+ RecordId rid = Helpers::findOne(opCtx,
+ collection.getCollection(),
+ BSON("_id" << indexBuildUUID),
+ /*requireIndex=*/true);
if (rid.isNull()) {
str::stream ss;
ss << "No matching IndexBuildEntry found with indexBuildUUID: " << indexBuildUUID;
@@ -286,8 +283,7 @@ StatusWith<IndexBuildEntry> getIndexBuildEntry(OperationContext* opCtx, UUID ind
// Read the most up to date data.
invariant(RecoveryUnit::ReadSource::kNoTimestamp ==
opCtx->recoveryUnit()->getTimestampReadSource());
- AutoGetCollectionForRead autoCollection(opCtx, NamespaceString::kIndexBuildEntryNamespace);
- const Collection* collection = autoCollection.getCollection();
+ AutoGetCollectionForRead collection(opCtx, NamespaceString::kIndexBuildEntryNamespace);
// Must not be interruptible. This fail point is used to test the scenario where the index
// build's OperationContext is interrupted by an abort, which will subsequently remove index
@@ -301,8 +297,11 @@ StatusWith<IndexBuildEntry> getIndexBuildEntry(OperationContext* opCtx, UUID ind
}
BSONObj obj;
- bool foundObj = Helpers::findOne(
- opCtx, collection, BSON("_id" << indexBuildUUID), obj, /*requireIndex=*/true);
+ bool foundObj = Helpers::findOne(opCtx,
+ collection.getCollection(),
+ BSON("_id" << indexBuildUUID),
+ obj,
+ /*requireIndex=*/true);
if (!foundObj) {
str::stream ss;
ss << "No matching IndexBuildEntry found with indexBuildUUID: " << indexBuildUUID;
diff --git a/src/mongo/db/index_builds_coordinator.cpp b/src/mongo/db/index_builds_coordinator.cpp
index 07e79bd8dd4..0dce52b94d6 100644
--- a/src/mongo/db/index_builds_coordinator.cpp
+++ b/src/mongo/db/index_builds_coordinator.cpp
@@ -118,7 +118,7 @@ void checkShardKeyRestrictions(OperationContext* opCtx,
* bypass the index build registration.
*/
bool shouldBuildIndexesOnEmptyCollectionSinglePhased(OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
IndexBuildProtocol protocol) {
const auto& nss = collection->ns();
invariant(opCtx->lockState()->isCollectionLockedForMode(nss, MODE_X), str::stream() << nss);
@@ -1436,7 +1436,7 @@ void IndexBuildsCoordinator::_completeSelfAbort(OperationContext* opCtx,
void IndexBuildsCoordinator::_completeAbortForShutdown(
OperationContext* opCtx,
std::shared_ptr<ReplIndexBuildState> replState,
- const Collection* collection) {
+ const CollectionPtr& collection) {
// Leave it as-if kill -9 happened. Startup recovery will restart the index build.
auto isResumable = !replState->lastOpTimeBeforeInterceptors.isNull();
_indexBuildsManager.abortIndexBuildWithoutCleanupForShutdown(
@@ -1984,8 +1984,7 @@ IndexBuildsCoordinator::_filterSpecsAndRegisterBuild(OperationContext* opCtx,
// AutoGetCollection throws an exception if it is unable to look up the collection by UUID.
NamespaceStringOrUUID nssOrUuid{dbName.toString(), collectionUUID};
- AutoGetCollection autoColl(opCtx, nssOrUuid, MODE_X);
- const Collection* collection = autoColl.getCollection();
+ AutoGetCollection collection(opCtx, nssOrUuid, MODE_X);
const auto& nss = collection->ns();
// Disallow index builds on drop-pending namespaces (system.drop.*) if we are primary.
@@ -2008,7 +2007,7 @@ IndexBuildsCoordinator::_filterSpecsAndRegisterBuild(OperationContext* opCtx,
std::vector<BSONObj> filteredSpecs;
try {
- filteredSpecs = prepareSpecListForCreate(opCtx, collection, nss, specs);
+ filteredSpecs = prepareSpecListForCreate(opCtx, collection.getCollection(), nss, specs);
} catch (const DBException& ex) {
return ex.toStatus();
}
@@ -2017,16 +2016,17 @@ IndexBuildsCoordinator::_filterSpecsAndRegisterBuild(OperationContext* opCtx,
// The requested index (specs) are already built or are being built. Return success
// early (this is v4.0 behavior compatible).
ReplIndexBuildState::IndexCatalogStats indexCatalogStats;
- int numIndexes = getNumIndexesTotal(opCtx, collection);
+ int numIndexes = getNumIndexesTotal(opCtx, collection.getCollection());
indexCatalogStats.numIndexesBefore = numIndexes;
indexCatalogStats.numIndexesAfter = numIndexes;
return SharedSemiFuture(indexCatalogStats);
}
// Bypass the thread pool if we are building indexes on an empty collection.
- if (shouldBuildIndexesOnEmptyCollectionSinglePhased(opCtx, collection, protocol)) {
+ if (shouldBuildIndexesOnEmptyCollectionSinglePhased(
+ opCtx, collection.getCollection(), protocol)) {
ReplIndexBuildState::IndexCatalogStats indexCatalogStats;
- indexCatalogStats.numIndexesBefore = getNumIndexesTotal(opCtx, collection);
+ indexCatalogStats.numIndexesBefore = getNumIndexesTotal(opCtx, collection.getCollection());
try {
// Replicate this index build using the old-style createIndexes oplog entry to avoid
// timestamping issues that would result from this empty collection optimization on a
@@ -2044,13 +2044,14 @@ IndexBuildsCoordinator::_filterSpecsAndRegisterBuild(OperationContext* opCtx,
ex.addContext(str::stream() << "index build on empty collection failed: " << buildUUID);
return ex.toStatus();
}
- indexCatalogStats.numIndexesAfter = getNumIndexesTotal(opCtx, collection);
+ indexCatalogStats.numIndexesAfter = getNumIndexesTotal(opCtx, collection.getCollection());
return SharedSemiFuture(indexCatalogStats);
}
auto replIndexBuildState = std::make_shared<ReplIndexBuildState>(
buildUUID, collectionUUID, dbName.toString(), filteredSpecs, protocol);
- replIndexBuildState->stats.numIndexesBefore = getNumIndexesTotal(opCtx, collection);
+ replIndexBuildState->stats.numIndexesBefore =
+ getNumIndexesTotal(opCtx, collection.getCollection());
auto status = _registerIndexBuild(lk, replIndexBuildState);
if (!status.isOK()) {
@@ -2317,7 +2318,7 @@ void runOnAlternateContext(OperationContext* opCtx, std::string name, Func func)
void IndexBuildsCoordinator::_cleanUpSinglePhaseAfterFailure(
OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
std::shared_ptr<ReplIndexBuildState> replState,
const IndexBuildOptions& indexBuildOptions,
const Status& status) {
@@ -2345,7 +2346,7 @@ void IndexBuildsCoordinator::_cleanUpSinglePhaseAfterFailure(
void IndexBuildsCoordinator::_cleanUpTwoPhaseAfterFailure(
OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
std::shared_ptr<ReplIndexBuildState> replState,
const IndexBuildOptions& indexBuildOptions,
const Status& status) {
@@ -2446,12 +2447,11 @@ void IndexBuildsCoordinator::_runIndexBuildInner(
status.isA<ErrorCategory::ShutdownError>(),
str::stream() << "Unexpected error code during index build cleanup: " << status);
if (IndexBuildProtocol::kSinglePhase == replState->protocol) {
- _cleanUpSinglePhaseAfterFailure(
- opCtx, collection.get(), replState, indexBuildOptions, status);
+ _cleanUpSinglePhaseAfterFailure(opCtx, collection, replState, indexBuildOptions, status);
} else {
invariant(IndexBuildProtocol::kTwoPhase == replState->protocol,
str::stream() << replState->buildUUID);
- _cleanUpTwoPhaseAfterFailure(opCtx, collection.get(), replState, indexBuildOptions, status);
+ _cleanUpTwoPhaseAfterFailure(opCtx, collection, replState, indexBuildOptions, status);
}
// Any error that escapes at this point is not fatal and can be handled by the caller.
@@ -2642,7 +2642,7 @@ void IndexBuildsCoordinator::_insertSortedKeysIntoIndexForResume(
}
}
-const Collection* IndexBuildsCoordinator::_setUpForScanCollectionAndInsertSortedKeysIntoIndex(
+CollectionPtr IndexBuildsCoordinator::_setUpForScanCollectionAndInsertSortedKeysIntoIndex(
OperationContext* opCtx, std::shared_ptr<ReplIndexBuildState> replState) {
// Rebuilding system indexes during startup using the IndexBuildsCoordinator is done by all
// storage engines if they're missing.
@@ -3029,7 +3029,7 @@ std::vector<std::shared_ptr<ReplIndexBuildState>> IndexBuildsCoordinator::_filte
}
int IndexBuildsCoordinator::getNumIndexesTotal(OperationContext* opCtx,
- const Collection* collection) {
+ const CollectionPtr& collection) {
invariant(collection);
const auto& nss = collection->ns();
invariant(opCtx->lockState()->isLocked(),
@@ -3044,7 +3044,7 @@ int IndexBuildsCoordinator::getNumIndexesTotal(OperationContext* opCtx,
std::vector<BSONObj> IndexBuildsCoordinator::prepareSpecListForCreate(
OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
const NamespaceString& nss,
const std::vector<BSONObj>& indexSpecs) {
UncommittedCollections::get(opCtx).invariantHasExclusiveAccessToCollection(opCtx,
@@ -3077,7 +3077,9 @@ std::vector<BSONObj> IndexBuildsCoordinator::prepareSpecListForCreate(
}
std::vector<BSONObj> IndexBuildsCoordinator::normalizeIndexSpecs(
- OperationContext* opCtx, const Collection* collection, const std::vector<BSONObj>& indexSpecs) {
+ OperationContext* opCtx,
+ const CollectionPtr& collection,
+ const std::vector<BSONObj>& indexSpecs) {
// This helper function may be called before the collection is created, when we are attempting
// to check whether the candidate index collides with any existing indexes. If 'collection' is
// nullptr, skip normalization. Since the collection does not exist there cannot be a conflict,
diff --git a/src/mongo/db/index_builds_coordinator.h b/src/mongo/db/index_builds_coordinator.h
index 49388122054..5aff6eaa608 100644
--- a/src/mongo/db/index_builds_coordinator.h
+++ b/src/mongo/db/index_builds_coordinator.h
@@ -434,7 +434,7 @@ public:
* This function throws on error. Expects caller to have exclusive access to `collection`.
*/
static std::vector<BSONObj> prepareSpecListForCreate(OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
const NamespaceString& nss,
const std::vector<BSONObj>& indexSpecs);
@@ -451,7 +451,7 @@ public:
* This function throws on error.
*/
static std::vector<BSONObj> normalizeIndexSpecs(OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
const std::vector<BSONObj>& indexSpecs);
/**
@@ -461,7 +461,7 @@ public:
*
* Expects a lock to be held by the caller, so that 'collection' is safe to use.
*/
- static int getNumIndexesTotal(OperationContext* opCtx, const Collection* collection);
+ static int getNumIndexesTotal(OperationContext* opCtx, const CollectionPtr& collection);
/**
@@ -597,7 +597,7 @@ protected:
* Cleans up a single-phase index build after a failure.
*/
void _cleanUpSinglePhaseAfterFailure(OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
std::shared_ptr<ReplIndexBuildState> replState,
const IndexBuildOptions& indexBuildOptions,
const Status& status);
@@ -606,7 +606,7 @@ protected:
* Cleans up a two-phase index build after a failure.
*/
void _cleanUpTwoPhaseAfterFailure(OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
std::shared_ptr<ReplIndexBuildState> replState,
const IndexBuildOptions& indexBuildOptions,
const Status& status);
@@ -631,7 +631,7 @@ protected:
Status reason);
void _completeAbortForShutdown(OperationContext* opCtx,
std::shared_ptr<ReplIndexBuildState> replState,
- const Collection* collection);
+ const CollectionPtr& collection);
/**
* Waits for the last optime before the interceptors were installed on the node to be majority
@@ -661,7 +661,7 @@ protected:
*/
void _insertSortedKeysIntoIndexForResume(OperationContext* opCtx,
std::shared_ptr<ReplIndexBuildState> replState);
- const Collection* _setUpForScanCollectionAndInsertSortedKeysIntoIndex(
+ CollectionPtr _setUpForScanCollectionAndInsertSortedKeysIntoIndex(
OperationContext* opCtx, std::shared_ptr<ReplIndexBuildState> replState);
/**
diff --git a/src/mongo/db/index_builds_coordinator_mongod.cpp b/src/mongo/db/index_builds_coordinator_mongod.cpp
index 89627a1f42e..d65581979a5 100644
--- a/src/mongo/db/index_builds_coordinator_mongod.cpp
+++ b/src/mongo/db/index_builds_coordinator_mongod.cpp
@@ -786,8 +786,7 @@ Status IndexBuildsCoordinatorMongod::setCommitQuorum(OperationContext* opCtx,
<< nss << "' without providing any indexes.");
}
- AutoGetCollectionForRead autoColl(opCtx, nss);
- const Collection* collection = autoColl.getCollection();
+ AutoGetCollectionForRead collection(opCtx, nss);
if (!collection) {
return Status(ErrorCodes::NamespaceNotFound,
str::stream() << "Collection '" << nss << "' was not found.");
diff --git a/src/mongo/db/introspect.cpp b/src/mongo/db/introspect.cpp
index 95e8f4843fd..0a6dab11e7c 100644
--- a/src/mongo/db/introspect.cpp
+++ b/src/mongo/db/introspect.cpp
@@ -130,8 +130,7 @@ void profile(OperationContext* opCtx, NetworkOp op) {
EnforcePrepareConflictsBlock enforcePrepare(opCtx);
uassertStatusOK(createProfileCollection(opCtx, db));
- const Collection* const coll =
- CollectionCatalog::get(opCtx).lookupCollectionByNamespace(opCtx, dbProfilingNS);
+ auto coll = CollectionCatalog::get(opCtx).lookupCollectionByNamespace(opCtx, dbProfilingNS);
invariant(!opCtx->shouldParticipateInFlowControl());
WriteUnitOfWork wuow(opCtx);
@@ -160,7 +159,7 @@ Status createProfileCollection(OperationContext* opCtx, Database* db) {
// collection creation would endlessly throw errors because the collection exists: must check
// and see the collection exists in order to break free.
return writeConflictRetry(opCtx, "createProfileCollection", dbProfilingNS.ns(), [&] {
- const Collection* const collection =
+ const CollectionPtr collection =
CollectionCatalog::get(opCtx).lookupCollectionByNamespace(opCtx, dbProfilingNS);
if (collection) {
if (!collection->isCapped()) {
diff --git a/src/mongo/db/matcher/expression_text.cpp b/src/mongo/db/matcher/expression_text.cpp
index c2ea279d6b6..3f72bafb102 100644
--- a/src/mongo/db/matcher/expression_text.cpp
+++ b/src/mongo/db/matcher/expression_text.cpp
@@ -66,7 +66,7 @@ TextMatchExpression::TextMatchExpression(OperationContext* opCtx,
<< nss.ns() << "')",
db);
- const Collection* collection =
+ CollectionPtr collection =
CollectionCatalog::get(opCtx).lookupCollectionByNamespace(opCtx, nss);
uassert(ErrorCodes::IndexNotFound,
diff --git a/src/mongo/db/mongod_main.cpp b/src/mongo/db/mongod_main.cpp
index 5a09ab036b5..07629f33788 100644
--- a/src/mongo/db/mongod_main.cpp
+++ b/src/mongo/db/mongod_main.cpp
@@ -257,7 +257,7 @@ void logStartup(OperationContext* opCtx) {
Lock::GlobalWrite lk(opCtx);
AutoGetOrCreateDb autoDb(opCtx, startupLogCollectionName.db(), mongo::MODE_X);
Database* db = autoDb.getDb();
- const Collection* collection =
+ CollectionPtr collection =
CollectionCatalog::get(opCtx).lookupCollectionByNamespace(opCtx, startupLogCollectionName);
WriteUnitOfWork wunit(opCtx);
if (!collection) {
diff --git a/src/mongo/db/op_observer.h b/src/mongo/db/op_observer.h
index 49c4123049d..7b435bc80d1 100644
--- a/src/mongo/db/op_observer.h
+++ b/src/mongo/db/op_observer.h
@@ -182,7 +182,7 @@ public:
}
virtual void onCreateCollection(OperationContext* opCtx,
- const Collection* coll,
+ const CollectionPtr& coll,
const NamespaceString& collectionName,
const CollectionOptions& options,
const BSONObj& idIndex,
diff --git a/src/mongo/db/op_observer_impl.cpp b/src/mongo/db/op_observer_impl.cpp
index f0041e43a75..bb187fc2149 100644
--- a/src/mongo/db/op_observer_impl.cpp
+++ b/src/mongo/db/op_observer_impl.cpp
@@ -664,7 +664,7 @@ void OpObserverImpl::onInternalOpMessage(
}
void OpObserverImpl::onCreateCollection(OperationContext* opCtx,
- const Collection* coll,
+ const CollectionPtr& coll,
const NamespaceString& collectionName,
const CollectionOptions& options,
const BSONObj& idIndex,
@@ -736,7 +736,8 @@ void OpObserverImpl::onCollMod(OperationContext* opCtx,
if (!db) {
return;
}
- const Collection* coll = CollectionCatalog::get(opCtx).lookupCollectionByNamespace(opCtx, nss);
+ const CollectionPtr& coll =
+ CollectionCatalog::get(opCtx).lookupCollectionByNamespace(opCtx, nss);
invariant(coll->uuid() == uuid);
invariant(DurableCatalog::get(opCtx)->isEqualToMetadataUUID(opCtx, coll->getCatalogId(), uuid));
diff --git a/src/mongo/db/op_observer_impl.h b/src/mongo/db/op_observer_impl.h
index 1e73732c1c9..70f348382b6 100644
--- a/src/mongo/db/op_observer_impl.h
+++ b/src/mongo/db/op_observer_impl.h
@@ -118,7 +118,7 @@ public:
const boost::optional<repl::OpTime> prevWriteOpTimeInTransaction,
const boost::optional<OplogSlot> slot) final;
void onCreateCollection(OperationContext* opCtx,
- const Collection* coll,
+ const CollectionPtr& coll,
const NamespaceString& collectionName,
const CollectionOptions& options,
const BSONObj& idIndex,
diff --git a/src/mongo/db/op_observer_noop.h b/src/mongo/db/op_observer_noop.h
index 0a90da9d0d1..4c4429482d8 100644
--- a/src/mongo/db/op_observer_noop.h
+++ b/src/mongo/db/op_observer_noop.h
@@ -92,7 +92,7 @@ public:
const boost::optional<repl::OpTime> prevWriteOpTimeInTransaction,
const boost::optional<OplogSlot> slot) override {}
void onCreateCollection(OperationContext* opCtx,
- const Collection* coll,
+ const CollectionPtr& coll,
const NamespaceString& collectionName,
const CollectionOptions& options,
const BSONObj& idIndex,
diff --git a/src/mongo/db/op_observer_registry.h b/src/mongo/db/op_observer_registry.h
index 029393ef199..ed34acbe127 100644
--- a/src/mongo/db/op_observer_registry.h
+++ b/src/mongo/db/op_observer_registry.h
@@ -172,7 +172,7 @@ public:
}
void onCreateCollection(OperationContext* const opCtx,
- const Collection* coll,
+ const CollectionPtr& coll,
const NamespaceString& collectionName,
const CollectionOptions& options,
const BSONObj& idIndex,
diff --git a/src/mongo/db/ops/delete.cpp b/src/mongo/db/ops/delete.cpp
index 14b81cc207b..a546a57ea76 100644
--- a/src/mongo/db/ops/delete.cpp
+++ b/src/mongo/db/ops/delete.cpp
@@ -41,7 +41,7 @@
namespace mongo {
long long deleteObjects(OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
const NamespaceString& ns,
BSONObj pattern,
bool justOne,
diff --git a/src/mongo/db/ops/delete.h b/src/mongo/db/ops/delete.h
index 58eebd434d7..a239b336ab3 100644
--- a/src/mongo/db/ops/delete.h
+++ b/src/mongo/db/ops/delete.h
@@ -44,7 +44,7 @@ class OperationContext;
* not yield. If 'god' is true, deletes are allowed on system namespaces.
*/
long long deleteObjects(OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
const NamespaceString& ns,
BSONObj pattern,
bool justOne,
diff --git a/src/mongo/db/ops/update.cpp b/src/mongo/db/ops/update.cpp
index da11e24b03d..899dbac9713 100644
--- a/src/mongo/db/ops/update.cpp
+++ b/src/mongo/db/ops/update.cpp
@@ -62,7 +62,7 @@ UpdateResult update(OperationContext* opCtx, Database* db, const UpdateRequest&
const NamespaceString& nsString = request.getNamespaceString();
invariant(opCtx->lockState()->isCollectionLockedForMode(nsString, MODE_IX));
- const Collection* collection;
+ CollectionPtr collection;
// The update stage does not create its own collection. As such, if the update is
// an upsert, create the collection that the update stage inserts into beforehand.
diff --git a/src/mongo/db/ops/write_ops_exec.cpp b/src/mongo/db/ops/write_ops_exec.cpp
index 29d07007956..d0cdf8a29cd 100644
--- a/src/mongo/db/ops/write_ops_exec.cpp
+++ b/src/mongo/db/ops/write_ops_exec.cpp
@@ -281,7 +281,7 @@ bool handleError(OperationContext* opCtx,
}
void insertDocuments(OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
std::vector<InsertStatement>::iterator begin,
std::vector<InsertStatement>::iterator end,
bool fromMigrate) {
@@ -336,7 +336,7 @@ void insertDocuments(OperationContext* opCtx,
* they only allow one operation at a time because they enforce insertion order with a MODE_X
* collection lock, which we cannot hold in transactions.
*/
-Status checkIfTransactionOnCappedColl(OperationContext* opCtx, const Collection* collection) {
+Status checkIfTransactionOnCappedColl(OperationContext* opCtx, const CollectionPtr& collection) {
if (opCtx->inMultiDocumentTransaction() && collection->isCapped()) {
return {ErrorCodes::OperationNotSupportedInTransaction,
str::stream() << "Collection '" << collection->ns()
@@ -649,7 +649,7 @@ static SingleWriteResult performSingleUpdateOp(OperationContext* opCtx,
makeCollection(opCtx, ns);
}
- if (auto coll = collection->getCollection()) {
+ if (const auto& coll = collection->getCollection()) {
// Transactions are not allowed to operate on capped collections.
uassertStatusOK(checkIfTransactionOnCappedColl(opCtx, coll));
}
@@ -677,7 +677,7 @@ static SingleWriteResult performSingleUpdateOp(OperationContext* opCtx,
PlanSummaryStats summary;
exec->getSummaryStats(&summary);
- if (auto coll = collection->getCollection()) {
+ if (const auto& coll = collection->getCollection()) {
CollectionQueryInfo::get(coll).notifyOfQuery(opCtx, coll, summary);
}
@@ -915,7 +915,7 @@ static SingleWriteResult performSingleDeleteOp(OperationContext* opCtx,
PlanSummaryStats summary;
exec->getSummaryStats(&summary);
- if (auto coll = collection.getCollection()) {
+ if (const auto& coll = collection.getCollection()) {
CollectionQueryInfo::get(coll).notifyOfQuery(opCtx, coll, summary);
}
curOp.debug().setPlanSummaryMetrics(summary);
diff --git a/src/mongo/db/pipeline/document_source_cursor.cpp b/src/mongo/db/pipeline/document_source_cursor.cpp
index ba6151d341a..a651b387ce4 100644
--- a/src/mongo/db/pipeline/document_source_cursor.cpp
+++ b/src/mongo/db/pipeline/document_source_cursor.cpp
@@ -142,7 +142,7 @@ void DocumentSourceCursor::loadBatch() {
->checkCanServeReadsFor(pExpCtx->opCtx, _exec->nss(), true));
}
- _exec->restoreState();
+ _exec->restoreState(autoColl ? &autoColl->getCollection() : nullptr);
try {
ON_BLOCK_EXIT([this] { recordPlanSummaryStats(); });
@@ -285,7 +285,7 @@ DocumentSourceCursor::~DocumentSourceCursor() {
}
DocumentSourceCursor::DocumentSourceCursor(
- const Collection* collection,
+ const CollectionPtr& collection,
std::unique_ptr<PlanExecutor, PlanExecutor::Deleter> exec,
const intrusive_ptr<ExpressionContext>& pCtx,
CursorType cursorType,
@@ -316,7 +316,7 @@ DocumentSourceCursor::DocumentSourceCursor(
}
intrusive_ptr<DocumentSourceCursor> DocumentSourceCursor::create(
- const Collection* collection,
+ const CollectionPtr& collection,
std::unique_ptr<PlanExecutor, PlanExecutor::Deleter> exec,
const intrusive_ptr<ExpressionContext>& pExpCtx,
CursorType cursorType,
diff --git a/src/mongo/db/pipeline/document_source_cursor.h b/src/mongo/db/pipeline/document_source_cursor.h
index a7794df2e2c..4ee177593c5 100644
--- a/src/mongo/db/pipeline/document_source_cursor.h
+++ b/src/mongo/db/pipeline/document_source_cursor.h
@@ -63,7 +63,7 @@ public:
* $cursor stage can return a sequence of empty documents for the caller to count.
*/
static boost::intrusive_ptr<DocumentSourceCursor> create(
- const Collection* collection,
+ const CollectionPtr& collection,
std::unique_ptr<PlanExecutor, PlanExecutor::Deleter> exec,
const boost::intrusive_ptr<ExpressionContext>& pExpCtx,
CursorType cursorType,
@@ -112,7 +112,7 @@ public:
}
protected:
- DocumentSourceCursor(const Collection* collection,
+ DocumentSourceCursor(const CollectionPtr& collection,
std::unique_ptr<PlanExecutor, PlanExecutor::Deleter> exec,
const boost::intrusive_ptr<ExpressionContext>& pExpCtx,
CursorType cursorType,
diff --git a/src/mongo/db/pipeline/document_source_geo_near_cursor.cpp b/src/mongo/db/pipeline/document_source_geo_near_cursor.cpp
index 4277bd26424..8e6885567d0 100644
--- a/src/mongo/db/pipeline/document_source_geo_near_cursor.cpp
+++ b/src/mongo/db/pipeline/document_source_geo_near_cursor.cpp
@@ -51,7 +51,7 @@
namespace mongo {
boost::intrusive_ptr<DocumentSourceGeoNearCursor> DocumentSourceGeoNearCursor::create(
- const Collection* collection,
+ const CollectionPtr& collection,
std::unique_ptr<PlanExecutor, PlanExecutor::Deleter> exec,
const boost::intrusive_ptr<ExpressionContext>& expCtx,
FieldPath distanceField,
@@ -66,7 +66,7 @@ boost::intrusive_ptr<DocumentSourceGeoNearCursor> DocumentSourceGeoNearCursor::c
}
DocumentSourceGeoNearCursor::DocumentSourceGeoNearCursor(
- const Collection* collection,
+ const CollectionPtr& collection,
std::unique_ptr<PlanExecutor, PlanExecutor::Deleter> exec,
const boost::intrusive_ptr<ExpressionContext>& expCtx,
FieldPath distanceField,
diff --git a/src/mongo/db/pipeline/document_source_geo_near_cursor.h b/src/mongo/db/pipeline/document_source_geo_near_cursor.h
index f8d3b483914..b3ddf9a834b 100644
--- a/src/mongo/db/pipeline/document_source_geo_near_cursor.h
+++ b/src/mongo/db/pipeline/document_source_geo_near_cursor.h
@@ -60,7 +60,7 @@ public:
* nonnegative.
*/
static boost::intrusive_ptr<DocumentSourceGeoNearCursor> create(
- const Collection*,
+ const CollectionPtr&,
std::unique_ptr<PlanExecutor, PlanExecutor::Deleter>,
const boost::intrusive_ptr<ExpressionContext>&,
FieldPath distanceField,
@@ -70,7 +70,7 @@ public:
const char* getSourceName() const final;
private:
- DocumentSourceGeoNearCursor(const Collection*,
+ DocumentSourceGeoNearCursor(const CollectionPtr&,
std::unique_ptr<PlanExecutor, PlanExecutor::Deleter>,
const boost::intrusive_ptr<ExpressionContext>&,
FieldPath distanceField,
diff --git a/src/mongo/db/pipeline/pipeline_d.cpp b/src/mongo/db/pipeline/pipeline_d.cpp
index c7b8bd273ec..6d0406f7495 100644
--- a/src/mongo/db/pipeline/pipeline_d.cpp
+++ b/src/mongo/db/pipeline/pipeline_d.cpp
@@ -99,7 +99,7 @@ namespace {
* storage engine support for random cursors.
*/
StatusWith<unique_ptr<PlanExecutor, PlanExecutor::Deleter>> createRandomCursorExecutor(
- const Collection* coll,
+ const CollectionPtr& coll,
const boost::intrusive_ptr<ExpressionContext>& expCtx,
long long sampleSize,
long long numRecords,
@@ -187,7 +187,7 @@ StatusWith<unique_ptr<PlanExecutor, PlanExecutor::Deleter>> createRandomCursorEx
StatusWith<std::unique_ptr<PlanExecutor, PlanExecutor::Deleter>> attemptToGetExecutor(
const intrusive_ptr<ExpressionContext>& expCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
const NamespaceString& nss,
BSONObj queryObj,
BSONObj projectionObj,
@@ -273,7 +273,8 @@ StatusWith<std::unique_ptr<PlanExecutor, PlanExecutor::Deleter>> attemptToGetExe
*
* The 'collection' is required to exist. Throws if no usable 2d or 2dsphere index could be found.
*/
-StringData extractGeoNearFieldFromIndexes(OperationContext* opCtx, const Collection* collection) {
+StringData extractGeoNearFieldFromIndexes(OperationContext* opCtx,
+ const CollectionPtr& collection) {
invariant(collection);
std::vector<const IndexDescriptor*> idxs;
@@ -313,7 +314,7 @@ StringData extractGeoNearFieldFromIndexes(OperationContext* opCtx, const Collect
} // namespace
std::pair<PipelineD::AttachExecutorCallback, std::unique_ptr<PlanExecutor, PlanExecutor::Deleter>>
-PipelineD::buildInnerQueryExecutor(const Collection* collection,
+PipelineD::buildInnerQueryExecutor(const CollectionPtr& collection,
const NamespaceString& nss,
const AggregationRequest* aggRequest,
Pipeline* pipeline) {
@@ -348,7 +349,7 @@ PipelineD::buildInnerQueryExecutor(const Collection* collection,
? DocumentSourceCursor::CursorType::kEmptyDocuments
: DocumentSourceCursor::CursorType::kRegular;
auto attachExecutorCallback =
- [cursorType](const Collection* collection,
+ [cursorType](const CollectionPtr& collection,
std::unique_ptr<PlanExecutor, PlanExecutor::Deleter> exec,
Pipeline* pipeline) {
auto cursor = DocumentSourceCursor::create(
@@ -372,7 +373,7 @@ PipelineD::buildInnerQueryExecutor(const Collection* collection,
}
void PipelineD::attachInnerQueryExecutorToPipeline(
- const Collection* collection,
+ const CollectionPtr& collection,
PipelineD::AttachExecutorCallback attachExecutorCallback,
std::unique_ptr<PlanExecutor, PlanExecutor::Deleter> exec,
Pipeline* pipeline) {
@@ -384,7 +385,7 @@ void PipelineD::attachInnerQueryExecutorToPipeline(
}
}
-void PipelineD::buildAndAttachInnerQueryExecutorToPipeline(const Collection* collection,
+void PipelineD::buildAndAttachInnerQueryExecutorToPipeline(const CollectionPtr& collection,
const NamespaceString& nss,
const AggregationRequest* aggRequest,
Pipeline* pipeline) {
@@ -483,7 +484,7 @@ auto buildProjectionForPushdown(const DepsTracker& deps, Pipeline* pipeline) {
} // namespace
std::pair<PipelineD::AttachExecutorCallback, std::unique_ptr<PlanExecutor, PlanExecutor::Deleter>>
-PipelineD::buildInnerQueryExecutorGeneric(const Collection* collection,
+PipelineD::buildInnerQueryExecutorGeneric(const CollectionPtr& collection,
const NamespaceString& nss,
const AggregationRequest* aggRequest,
Pipeline* pipeline) {
@@ -561,7 +562,7 @@ PipelineD::buildInnerQueryExecutorGeneric(const Collection* collection,
(pipeline->peekFront() && pipeline->peekFront()->constraints().isChangeStreamStage());
auto attachExecutorCallback =
- [cursorType, trackOplogTS](const Collection* collection,
+ [cursorType, trackOplogTS](const CollectionPtr& collection,
std::unique_ptr<PlanExecutor, PlanExecutor::Deleter> exec,
Pipeline* pipeline) {
auto cursor = DocumentSourceCursor::create(
@@ -572,7 +573,7 @@ PipelineD::buildInnerQueryExecutorGeneric(const Collection* collection,
}
std::pair<PipelineD::AttachExecutorCallback, std::unique_ptr<PlanExecutor, PlanExecutor::Deleter>>
-PipelineD::buildInnerQueryExecutorGeoNear(const Collection* collection,
+PipelineD::buildInnerQueryExecutorGeoNear(const CollectionPtr& collection,
const NamespaceString& nss,
const AggregationRequest* aggRequest,
Pipeline* pipeline) {
@@ -616,7 +617,7 @@ PipelineD::buildInnerQueryExecutorGeoNear(const Collection* collection,
locationField = geoNearStage->getLocationField(),
distanceMultiplier =
geoNearStage->getDistanceMultiplier().value_or(1.0)](
- const Collection* collection,
+ const CollectionPtr& collection,
std::unique_ptr<PlanExecutor, PlanExecutor::Deleter> exec,
Pipeline* pipeline) {
auto cursor = DocumentSourceGeoNearCursor::create(collection,
@@ -634,7 +635,7 @@ PipelineD::buildInnerQueryExecutorGeoNear(const Collection* collection,
StatusWith<std::unique_ptr<PlanExecutor, PlanExecutor::Deleter>> PipelineD::prepareExecutor(
const intrusive_ptr<ExpressionContext>& expCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
const NamespaceString& nss,
Pipeline* pipeline,
const boost::intrusive_ptr<DocumentSourceSort>& sortStage,
diff --git a/src/mongo/db/pipeline/pipeline_d.h b/src/mongo/db/pipeline/pipeline_d.h
index ec1baacf6fd..96a2b83c57c 100644
--- a/src/mongo/db/pipeline/pipeline_d.h
+++ b/src/mongo/db/pipeline/pipeline_d.h
@@ -43,6 +43,7 @@
namespace mongo {
class Collection;
+class CollectionPtr;
class DocumentSourceCursor;
class DocumentSourceMatch;
class DocumentSourceSort;
@@ -67,7 +68,7 @@ public:
* the new stage to the pipeline.
*/
using AttachExecutorCallback = std::function<void(
- const Collection*, std::unique_ptr<PlanExecutor, PlanExecutor::Deleter>, Pipeline*)>;
+ const CollectionPtr&, std::unique_ptr<PlanExecutor, PlanExecutor::Deleter>, Pipeline*)>;
/**
* This method looks for early pipeline stages that can be folded into the underlying
@@ -88,7 +89,7 @@ public:
* 'nullptr'.
*/
static std::pair<AttachExecutorCallback, std::unique_ptr<PlanExecutor, PlanExecutor::Deleter>>
- buildInnerQueryExecutor(const Collection* collection,
+ buildInnerQueryExecutor(const CollectionPtr& collection,
const NamespaceString& nss,
const AggregationRequest* aggRequest,
Pipeline* pipeline);
@@ -101,7 +102,7 @@ public:
* 'nullptr'.
*/
static void attachInnerQueryExecutorToPipeline(
- const Collection* collection,
+ const CollectionPtr& collection,
AttachExecutorCallback attachExecutorCallback,
std::unique_ptr<PlanExecutor, PlanExecutor::Deleter> exec,
Pipeline* pipeline);
@@ -112,7 +113,7 @@ public:
* used when the executor attachment phase doesn't need to be deferred and the $cursor stage
* can be created right after buiding the executor.
*/
- static void buildAndAttachInnerQueryExecutorToPipeline(const Collection* collection,
+ static void buildAndAttachInnerQueryExecutorToPipeline(const CollectionPtr& collection,
const NamespaceString& nss,
const AggregationRequest* aggRequest,
Pipeline* pipeline);
@@ -130,7 +131,7 @@ public:
*/
static std::unique_ptr<CollatorInterface> resolveCollator(OperationContext* opCtx,
BSONObj userCollation,
- const Collection* collection) {
+ const CollectionPtr& collection) {
if (!userCollation.isEmpty()) {
return uassertStatusOK(CollatorFactoryInterface::get(opCtx->getServiceContext())
->makeFromBSON(userCollation));
@@ -149,7 +150,7 @@ private:
* the 'pipeline'.
*/
static std::pair<AttachExecutorCallback, std::unique_ptr<PlanExecutor, PlanExecutor::Deleter>>
- buildInnerQueryExecutorGeneric(const Collection* collection,
+ buildInnerQueryExecutorGeneric(const CollectionPtr& collection,
const NamespaceString& nss,
const AggregationRequest* aggRequest,
Pipeline* pipeline);
@@ -160,7 +161,7 @@ private:
* not exist, as the $geoNearCursor requires a 2d or 2dsphere index.
*/
static std::pair<AttachExecutorCallback, std::unique_ptr<PlanExecutor, PlanExecutor::Deleter>>
- buildInnerQueryExecutorGeoNear(const Collection* collection,
+ buildInnerQueryExecutorGeoNear(const CollectionPtr& collection,
const NamespaceString& nss,
const AggregationRequest* aggRequest,
Pipeline* pipeline);
@@ -179,7 +180,7 @@ private:
*/
static StatusWith<std::unique_ptr<PlanExecutor, PlanExecutor::Deleter>> prepareExecutor(
const boost::intrusive_ptr<ExpressionContext>& expCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
const NamespaceString& nss,
Pipeline* pipeline,
const boost::intrusive_ptr<DocumentSourceSort>& sortStage,
diff --git a/src/mongo/db/pipeline/plan_executor_pipeline.h b/src/mongo/db/pipeline/plan_executor_pipeline.h
index 54a66979bfc..72d61471720 100644
--- a/src/mongo/db/pipeline/plan_executor_pipeline.h
+++ b/src/mongo/db/pipeline/plan_executor_pipeline.h
@@ -62,7 +62,7 @@ public:
// underlying data access plan is saved/restored internally in between DocumentSourceCursor
// batches, or when the underlying PlanStage tree yields.
void saveState() override {}
- void restoreState() override {}
+ void restoreState(const Yieldable* yieldable) override {}
void detachFromOperationContext() override {
_pipeline->detachFromOperationContext();
diff --git a/src/mongo/db/pipeline/process_interface/common_mongod_process_interface.cpp b/src/mongo/db/pipeline/process_interface/common_mongod_process_interface.cpp
index 35a3c11acad..7e795c181a0 100644
--- a/src/mongo/db/pipeline/process_interface/common_mongod_process_interface.cpp
+++ b/src/mongo/db/pipeline/process_interface/common_mongod_process_interface.cpp
@@ -156,9 +156,8 @@ std::vector<Document> CommonMongodProcessInterface::getIndexStats(OperationConte
const NamespaceString& ns,
StringData host,
bool addShardName) {
- AutoGetCollectionForReadCommand autoColl(opCtx, ns);
+ AutoGetCollectionForReadCommand collection(opCtx, ns);
- const Collection* collection = autoColl.getCollection();
std::vector<Document> indexStats;
if (!collection) {
LOGV2_DEBUG(23881,
@@ -227,15 +226,13 @@ Status CommonMongodProcessInterface::appendRecordCount(OperationContext* opCtx,
Status CommonMongodProcessInterface::appendQueryExecStats(OperationContext* opCtx,
const NamespaceString& nss,
BSONObjBuilder* builder) const {
- AutoGetCollectionForReadCommand autoColl(opCtx, nss);
+ AutoGetCollectionForReadCommand collection(opCtx, nss);
- if (!autoColl.getDb()) {
+ if (!collection.getDb()) {
return {ErrorCodes::NamespaceNotFound,
str::stream() << "Database [" << nss.db().toString() << "] not found."};
}
- const Collection* collection = autoColl.getCollection();
-
if (!collection) {
return {ErrorCodes::NamespaceNotFound,
str::stream() << "Collection [" << nss.toString() << "] not found."};
@@ -261,12 +258,11 @@ Status CommonMongodProcessInterface::appendQueryExecStats(OperationContext* opCt
BSONObj CommonMongodProcessInterface::getCollectionOptions(OperationContext* opCtx,
const NamespaceString& nss) {
- AutoGetCollectionForReadCommand autoColl(opCtx, nss);
+ AutoGetCollectionForReadCommand collection(opCtx, nss);
BSONObj collectionOptions = {};
- if (!autoColl.getDb()) {
+ if (!collection.getDb()) {
return collectionOptions;
}
- const Collection* collection = autoColl.getCollection();
if (!collection) {
return collectionOptions;
}
@@ -412,12 +408,11 @@ std::vector<BSONObj> CommonMongodProcessInterface::getMatchingPlanCacheEntryStat
return !matchExp ? true : matchExp->matchesBSON(obj);
};
- AutoGetCollection autoColl(opCtx, nss, MODE_IS);
- const auto collection = autoColl.getCollection();
+ AutoGetCollection collection(opCtx, nss, MODE_IS);
uassert(
50933, str::stream() << "collection '" << nss.toString() << "' does not exist", collection);
- const auto planCache = CollectionQueryInfo::get(collection).getPlanCache();
+ const auto planCache = CollectionQueryInfo::get(collection.getCollection()).getPlanCache();
invariant(planCache);
return planCache->getMatchingStats(serializer, predicate);
diff --git a/src/mongo/db/pipeline/process_interface/non_shardsvr_process_interface.cpp b/src/mongo/db/pipeline/process_interface/non_shardsvr_process_interface.cpp
index 537d89749d1..5d085033f96 100644
--- a/src/mongo/db/pipeline/process_interface/non_shardsvr_process_interface.cpp
+++ b/src/mongo/db/pipeline/process_interface/non_shardsvr_process_interface.cpp
@@ -116,7 +116,7 @@ void NonShardServerProcessInterface::createIndexesOnEmptyCollection(
str::stream() << "The database is in the process of being dropped " << ns.db(),
autoColl.getDb() && !autoColl.getDb()->isDropPending(opCtx));
- auto collection = autoColl.getCollection();
+ const auto& collection = autoColl.getCollection();
uassert(ErrorCodes::NamespaceNotFound,
str::stream() << "Failed to create indexes for aggregation because collection "
"does not exist: "
diff --git a/src/mongo/db/query/classic_stage_builder.h b/src/mongo/db/query/classic_stage_builder.h
index bdf68d4677b..1c63e6714b5 100644
--- a/src/mongo/db/query/classic_stage_builder.h
+++ b/src/mongo/db/query/classic_stage_builder.h
@@ -39,7 +39,7 @@ namespace mongo::stage_builder {
class ClassicStageBuilder : public StageBuilder<PlanStage> {
public:
ClassicStageBuilder(OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
const CanonicalQuery& cq,
const QuerySolution& solution,
WorkingSet* ws)
diff --git a/src/mongo/db/query/collection_query_info.cpp b/src/mongo/db/query/collection_query_info.cpp
index 46f9422e759..38df12525f7 100644
--- a/src/mongo/db/query/collection_query_info.cpp
+++ b/src/mongo/db/query/collection_query_info.cpp
@@ -87,7 +87,7 @@ const UpdateIndexData& CollectionQueryInfo::getIndexKeys(OperationContext* opCtx
return _indexedPaths;
}
-void CollectionQueryInfo::computeIndexKeys(OperationContext* opCtx, const Collection* coll) {
+void CollectionQueryInfo::computeIndexKeys(OperationContext* opCtx, const CollectionPtr& coll) {
_indexedPaths.clear();
std::unique_ptr<IndexCatalog::IndexIterator> it =
@@ -160,7 +160,7 @@ void CollectionQueryInfo::computeIndexKeys(OperationContext* opCtx, const Collec
}
void CollectionQueryInfo::notifyOfQuery(OperationContext* opCtx,
- const Collection* coll,
+ const CollectionPtr& coll,
const PlanSummaryStats& summaryStats) const {
auto& collectionIndexUsageTracker =
CollectionIndexUsageTrackerDecoration::get(coll->getSharedDecorations());
@@ -181,7 +181,7 @@ void CollectionQueryInfo::notifyOfQuery(OperationContext* opCtx,
}
}
-void CollectionQueryInfo::clearQueryCache(const Collection* coll) const {
+void CollectionQueryInfo::clearQueryCache(const CollectionPtr& coll) const {
LOGV2_DEBUG(20907,
1,
"Clearing plan cache - collection info cache reset",
@@ -196,7 +196,7 @@ PlanCache* CollectionQueryInfo::getPlanCache() const {
}
void CollectionQueryInfo::updatePlanCacheIndexEntries(OperationContext* opCtx,
- const Collection* coll) {
+ const CollectionPtr& coll) {
std::vector<CoreIndexInfo> indexCores;
// TODO We shouldn't need to include unfinished indexes, but we must here because the index
@@ -212,7 +212,7 @@ void CollectionQueryInfo::updatePlanCacheIndexEntries(OperationContext* opCtx,
_planCache->notifyOfIndexUpdates(indexCores);
}
-void CollectionQueryInfo::init(OperationContext* opCtx, const Collection* coll) {
+void CollectionQueryInfo::init(OperationContext* opCtx, const CollectionPtr& coll) {
const bool includeUnfinishedIndexes = false;
std::unique_ptr<IndexCatalog::IndexIterator> ii =
coll->getIndexCatalog()->getIndexIterator(opCtx, includeUnfinishedIndexes);
@@ -226,7 +226,7 @@ void CollectionQueryInfo::init(OperationContext* opCtx, const Collection* coll)
}
void CollectionQueryInfo::addedIndex(OperationContext* opCtx,
- const Collection* coll,
+ const CollectionPtr& coll,
const IndexDescriptor* desc) {
invariant(desc);
@@ -236,14 +236,14 @@ void CollectionQueryInfo::addedIndex(OperationContext* opCtx,
}
void CollectionQueryInfo::droppedIndex(OperationContext* opCtx,
- const Collection* coll,
+ const CollectionPtr& coll,
StringData indexName) {
rebuildIndexData(opCtx, coll);
CollectionIndexUsageTrackerDecoration::get(coll->getSharedDecorations())
.unregisterIndex(indexName);
}
-void CollectionQueryInfo::rebuildIndexData(OperationContext* opCtx, const Collection* coll) {
+void CollectionQueryInfo::rebuildIndexData(OperationContext* opCtx, const CollectionPtr& coll) {
clearQueryCache(coll);
_keysComputed = false;
diff --git a/src/mongo/db/query/collection_query_info.h b/src/mongo/db/query/collection_query_info.h
index a9fda7742ed..1175dab7837 100644
--- a/src/mongo/db/query/collection_query_info.h
+++ b/src/mongo/db/query/collection_query_info.h
@@ -48,7 +48,14 @@ class CollectionQueryInfo {
public:
CollectionQueryInfo();
- inline static const auto get = Collection::declareDecoration<CollectionQueryInfo>();
+ inline static const auto getCollectionQueryInfo =
+ Collection::declareDecoration<CollectionQueryInfo>();
+ static const CollectionQueryInfo& get(const CollectionPtr& collection) {
+ return CollectionQueryInfo::getCollectionQueryInfo(collection.get());
+ }
+ static CollectionQueryInfo& get(Collection* collection) {
+ return CollectionQueryInfo::getCollectionQueryInfo(collection);
+ }
/**
* Get the PlanCache for this collection.
@@ -63,7 +70,7 @@ public:
/**
* Builds internal cache state based on the current state of the Collection's IndexCatalog.
*/
- void init(OperationContext* opCtx, const Collection* coll);
+ void init(OperationContext* opCtx, const CollectionPtr& coll);
/**
* Register a newly-created index with the cache. Must be called whenever an index is
@@ -71,7 +78,9 @@ public:
*
* Must be called under exclusive collection lock.
*/
- void addedIndex(OperationContext* opCtx, const Collection* coll, const IndexDescriptor* desc);
+ void addedIndex(OperationContext* opCtx,
+ const CollectionPtr& coll,
+ const IndexDescriptor* desc);
/**
* Deregister a newly-dropped index with the cache. Must be called whenever an index is
@@ -79,26 +88,26 @@ public:
*
* Must be called under exclusive collection lock.
*/
- void droppedIndex(OperationContext* opCtx, const Collection* coll, StringData indexName);
+ void droppedIndex(OperationContext* opCtx, const CollectionPtr& coll, StringData indexName);
/**
* Removes all cached query plans.
*/
- void clearQueryCache(const Collection* coll) const;
+ void clearQueryCache(const CollectionPtr& coll) const;
void notifyOfQuery(OperationContext* opCtx,
- const Collection* coll,
+ const CollectionPtr& coll,
const PlanSummaryStats& summaryStats) const;
private:
- void computeIndexKeys(OperationContext* opCtx, const Collection* coll);
- void updatePlanCacheIndexEntries(OperationContext* opCtx, const Collection* coll);
+ void computeIndexKeys(OperationContext* opCtx, const CollectionPtr& coll);
+ void updatePlanCacheIndexEntries(OperationContext* opCtx, const CollectionPtr& coll);
/**
* Rebuilds cached information that is dependent on index composition. Must be called
* when index composition changes.
*/
- void rebuildIndexData(OperationContext* opCtx, const Collection* coll);
+ void rebuildIndexData(OperationContext* opCtx, const CollectionPtr& coll);
// --- index keys cache
bool _keysComputed;
diff --git a/src/mongo/db/query/explain.cpp b/src/mongo/db/query/explain.cpp
index c4be694ad3d..003c5fe202c 100644
--- a/src/mongo/db/query/explain.cpp
+++ b/src/mongo/db/query/explain.cpp
@@ -591,7 +591,7 @@ void Explain::statsToBSON(const PlanStageStats& stats,
}
void Explain::generatePlannerInfo(PlanExecutor* exec,
- const Collection* collection,
+ const CollectionPtr& collection,
BSONObj extraInfo,
BSONObjBuilder* out) {
auto planExecImpl = dynamic_cast<PlanExecutorImpl*>(exec);
@@ -795,7 +795,7 @@ void Explain::generateExecutionInfo(PlanExecutor* exec,
}
void Explain::explainStages(PlanExecutor* exec,
- const Collection* collection,
+ const CollectionPtr& collection,
ExplainOptions::Verbosity verbosity,
Status executePlanStatus,
PlanStageStats* winningPlanTrialStats,
@@ -833,7 +833,7 @@ void Explain::explainPipelineExecutor(PlanExecutorPipeline* exec,
}
void Explain::explainStages(PlanExecutor* exec,
- const Collection* collection,
+ const CollectionPtr& collection,
ExplainOptions::Verbosity verbosity,
BSONObj extraInfo,
BSONObjBuilder* out) {
@@ -844,6 +844,7 @@ void Explain::explainStages(PlanExecutor* exec,
auto winningPlanTrialStats = Explain::getWinningPlanTrialStats(exec);
Status executePlanStatus = Status::OK();
+ const CollectionPtr* collectionPtr = &collection;
// If we need execution stats, then run the plan in order to gather the stats.
if (verbosity >= ExplainOptions::Verbosity::kExecStats) {
@@ -857,12 +858,12 @@ void Explain::explainStages(PlanExecutor* exec,
// then the collection may no longer be valid. We conservatively set our collection pointer
// to null in case it is invalid.
if (executePlanStatus != ErrorCodes::NoQueryExecutionPlans) {
- collection = nullptr;
+ collectionPtr = &CollectionPtr::null;
}
}
explainStages(exec,
- collection,
+ *collectionPtr,
verbosity,
executePlanStatus,
winningPlanTrialStats.get(),
diff --git a/src/mongo/db/query/explain.h b/src/mongo/db/query/explain.h
index 666959883b2..a8848decfc1 100644
--- a/src/mongo/db/query/explain.h
+++ b/src/mongo/db/query/explain.h
@@ -42,6 +42,7 @@
namespace mongo {
class Collection;
+class CollectionPtr;
class OperationContext;
class PlanExecutorPipeline;
struct PlanSummaryStats;
@@ -72,7 +73,7 @@ public:
* added to the "executionStats" section of the explain.
*/
static void explainStages(PlanExecutor* exec,
- const Collection* collection,
+ const CollectionPtr& collection,
ExplainOptions::Verbosity verbosity,
BSONObj extraInfo,
BSONObjBuilder* out);
@@ -92,7 +93,7 @@ public:
* - 'out' is the builder for the explain output.
*/
static void explainStages(PlanExecutor* exec,
- const Collection* collection,
+ const CollectionPtr& collection,
ExplainOptions::Verbosity verbosity,
Status executePlanStatus,
PlanStageStats* winningPlanTrialStats,
@@ -205,7 +206,7 @@ private:
* - 'out' is a builder for the explain output.
*/
static void generatePlannerInfo(PlanExecutor* exec,
- const Collection* collection,
+ const CollectionPtr& collection,
BSONObj extraInfo,
BSONObjBuilder* out);
diff --git a/src/mongo/db/query/find.cpp b/src/mongo/db/query/find.cpp
index fe77d388ff2..27e10256727 100644
--- a/src/mongo/db/query/find.cpp
+++ b/src/mongo/db/query/find.cpp
@@ -82,7 +82,7 @@ MONGO_FAIL_POINT_DEFINE(failReceivedGetmore);
MONGO_FAIL_POINT_DEFINE(legacyGetMoreWaitWithCursor)
bool shouldSaveCursor(OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
PlanExecutor::ExecState finalState,
PlanExecutor* exec) {
const QueryRequest& qr = exec->getCanonicalQuery()->getQueryRequest();
@@ -121,7 +121,7 @@ void beginQueryOp(OperationContext* opCtx,
}
void endQueryOp(OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
const PlanExecutor& exec,
long long numResults,
CursorId cursorId) {
@@ -410,7 +410,7 @@ Message getMore(OperationContext* opCtx,
PlanExecutor* exec = cursorPin->getExecutor();
exec->reattachToOperationContext(opCtx);
- exec->restoreState();
+ exec->restoreState(readLock ? &readLock->getCollection() : nullptr);
auto planSummary = exec->getPlanSummary();
{
@@ -476,7 +476,7 @@ Message getMore(OperationContext* opCtx,
// Reacquiring locks.
readLock.emplace(opCtx, nss);
- exec->restoreState();
+ exec->restoreState(&readLock->getCollection());
// We woke up because either the timed_wait expired, or there was more data. Either way,
// attempt to generate another batch of results.
@@ -605,8 +605,8 @@ bool runQuery(OperationContext* opCtx,
LOGV2_DEBUG(20914, 2, "Running query", "query"_attr = redact(cq->toStringShort()));
// Parse, canonicalize, plan, transcribe, and get a plan executor.
- AutoGetCollectionForReadCommand ctx(opCtx, nss, AutoGetCollectionViewMode::kViewsForbidden);
- const Collection* const collection = ctx.getCollection();
+ AutoGetCollectionForReadCommand collection(
+ opCtx, nss, AutoGetCollectionViewMode::kViewsForbidden);
const QueryRequest& qr = cq->getQueryRequest();
opCtx->setExhaust(qr.isExhaust());
@@ -625,7 +625,8 @@ bool runQuery(OperationContext* opCtx,
// Get the execution plan for the query.
constexpr auto verbosity = ExplainOptions::Verbosity::kExecAllPlans;
expCtx->explain = qr.isExplain() ? boost::make_optional(verbosity) : boost::none;
- auto exec = uassertStatusOK(getExecutorLegacyFind(opCtx, collection, std::move(cq)));
+ auto exec =
+ uassertStatusOK(getExecutorLegacyFind(opCtx, collection.getCollection(), std::move(cq)));
// If it's actually an explain, do the explain and return rather than falling through
// to the normal query execution loop.
@@ -634,7 +635,8 @@ bool runQuery(OperationContext* opCtx,
bb.skip(sizeof(QueryResult::Value));
BSONObjBuilder explainBob;
- Explain::explainStages(exec.get(), collection, verbosity, BSONObj(), &explainBob);
+ Explain::explainStages(
+ exec.get(), collection.getCollection(), verbosity, BSONObj(), &explainBob);
// Add the resulting object to the return buffer.
BSONObj explainObj = explainBob.obj();
@@ -721,7 +723,7 @@ bool runQuery(OperationContext* opCtx,
// this cursorid later.
long long ccId = 0;
- if (shouldSaveCursor(opCtx, collection, state, exec.get())) {
+ if (shouldSaveCursor(opCtx, collection.getCollection(), state, exec.get())) {
// We won't use the executor until it's getMore'd.
exec->saveState();
exec->detachFromOperationContext();
@@ -763,11 +765,15 @@ bool runQuery(OperationContext* opCtx,
pinnedCursor.getCursor()->setLeftoverMaxTimeMicros(opCtx->getRemainingMaxTimeMicros());
}
- endQueryOp(opCtx, collection, *pinnedCursor.getCursor()->getExecutor(), numResults, ccId);
+ endQueryOp(opCtx,
+ collection.getCollection(),
+ *pinnedCursor.getCursor()->getExecutor(),
+ numResults,
+ ccId);
} else {
LOGV2_DEBUG(
20917, 5, "Not caching executor but returning results", "numResults"_attr = numResults);
- endQueryOp(opCtx, collection, *exec, numResults, ccId);
+ endQueryOp(opCtx, collection.getCollection(), *exec, numResults, ccId);
}
// Fill out the output buffer's header.
diff --git a/src/mongo/db/query/find.h b/src/mongo/db/query/find.h
index 805fd18884d..6913404cebb 100644
--- a/src/mongo/db/query/find.h
+++ b/src/mongo/db/query/find.h
@@ -50,7 +50,7 @@ class OperationContext;
* a cursor ID of 0.
*/
bool shouldSaveCursor(OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
PlanExecutor::ExecState finalState,
PlanExecutor* exec);
@@ -79,7 +79,7 @@ void beginQueryOp(OperationContext* opCtx,
* Uses explain functionality to extract stats from 'exec'.
*/
void endQueryOp(OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
const PlanExecutor& exec,
long long numResults,
CursorId cursorId);
diff --git a/src/mongo/db/query/get_executor.cpp b/src/mongo/db/query/get_executor.cpp
index b13605fb2aa..daecec36c15 100644
--- a/src/mongo/db/query/get_executor.cpp
+++ b/src/mongo/db/query/get_executor.cpp
@@ -145,7 +145,7 @@ bool turnIxscanIntoCount(QuerySolution* soln);
/**
* Returns 'true' if 'query' on the given 'collection' can be answered using a special IDHACK plan.
*/
-bool isIdHackEligibleQuery(const Collection* collection, const CanonicalQuery& query) {
+bool isIdHackEligibleQuery(const CollectionPtr& collection, const CanonicalQuery& query) {
return !query.getQueryRequest().showRecordId() && query.getQueryRequest().getHint().isEmpty() &&
query.getQueryRequest().getMin().isEmpty() && query.getQueryRequest().getMax().isEmpty() &&
!query.getQueryRequest().getSkip() &&
@@ -247,7 +247,7 @@ IndexEntry indexEntryFromIndexCatalogEntry(OperationContext* opCtx,
* If query supports index filters, filter params.indices according to any index filters that have
* been configured. In addition, sets that there were indeed index filters applied.
*/
-void applyIndexFilters(const Collection* collection,
+void applyIndexFilters(const CollectionPtr& collection,
const CanonicalQuery& canonicalQuery,
QueryPlannerParams* plannerParams) {
if (!isIdHackEligibleQuery(collection, canonicalQuery)) {
@@ -266,7 +266,7 @@ void applyIndexFilters(const Collection* collection,
}
void fillOutPlannerParams(OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
CanonicalQuery* canonicalQuery,
QueryPlannerParams* plannerParams) {
invariant(canonicalQuery);
@@ -334,7 +334,7 @@ void fillOutPlannerParams(OperationContext* opCtx,
}
bool shouldWaitForOplogVisibility(OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
bool tailable) {
// Only non-tailable cursors on the oplog are affected. Only forward cursors, not reverse
@@ -514,7 +514,7 @@ template <typename PlanStageType, typename ResultType>
class PrepareExecutionHelper {
public:
PrepareExecutionHelper(OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
CanonicalQuery* cq,
PlanYieldPolicy* yieldPolicy,
size_t plannerOptions)
@@ -527,7 +527,7 @@ public:
}
StatusWith<std::unique_ptr<ResultType>> prepare() {
- if (nullptr == _collection) {
+ if (!_collection) {
LOGV2_DEBUG(20921,
2,
"Collection does not exist. Using EOF plan",
@@ -720,7 +720,7 @@ protected:
const QueryPlannerParams& plannerParams) = 0;
OperationContext* _opCtx;
- const Collection* _collection;
+ const CollectionPtr& _collection;
CanonicalQuery* _cq;
PlanYieldPolicy* _yieldPolicy;
const size_t _plannerOptions;
@@ -733,7 +733,7 @@ class ClassicPrepareExecutionHelper final
: public PrepareExecutionHelper<std::unique_ptr<PlanStage>, ClassicPrepareExecutionResult> {
public:
ClassicPrepareExecutionHelper(OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
WorkingSet* ws,
CanonicalQuery* cq,
PlanYieldPolicy* yieldPolicy,
@@ -954,7 +954,7 @@ private:
StatusWith<std::unique_ptr<PlanExecutor, PlanExecutor::Deleter>> getClassicExecutor(
OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
std::unique_ptr<CanonicalQuery> canonicalQuery,
PlanYieldPolicy::YieldPolicy yieldPolicy,
size_t plannerOptions) {
@@ -986,7 +986,7 @@ StatusWith<std::unique_ptr<PlanExecutor, PlanExecutor::Deleter>> getClassicExecu
*/
std::unique_ptr<sbe::RuntimePlanner> makeRuntimePlannerIfNeeded(
OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
CanonicalQuery* canonicalQuery,
size_t numSolutions,
boost::optional<size_t> decisionWorks,
@@ -1051,7 +1051,7 @@ std::unique_ptr<PlanYieldPolicySBE> makeSbeYieldPolicy(
StatusWith<std::unique_ptr<PlanExecutor, PlanExecutor::Deleter>> getSlotBasedExecutor(
OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
std::unique_ptr<CanonicalQuery> cq,
PlanYieldPolicy::YieldPolicy requestedYieldPolicy,
size_t plannerOptions) {
@@ -1100,7 +1100,7 @@ StatusWith<std::unique_ptr<PlanExecutor, PlanExecutor::Deleter>> getSlotBasedExe
StatusWith<std::unique_ptr<PlanExecutor, PlanExecutor::Deleter>> getExecutor(
OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
std::unique_ptr<CanonicalQuery> canonicalQuery,
PlanYieldPolicy::YieldPolicy yieldPolicy,
size_t plannerOptions) {
@@ -1119,7 +1119,7 @@ namespace {
StatusWith<std::unique_ptr<PlanExecutor, PlanExecutor::Deleter>> _getExecutorFind(
OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
std::unique_ptr<CanonicalQuery> canonicalQuery,
PlanYieldPolicy::YieldPolicy yieldPolicy,
size_t plannerOptions) {
@@ -1134,7 +1134,7 @@ StatusWith<std::unique_ptr<PlanExecutor, PlanExecutor::Deleter>> _getExecutorFin
StatusWith<std::unique_ptr<PlanExecutor, PlanExecutor::Deleter>> getExecutorFind(
OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
std::unique_ptr<CanonicalQuery> canonicalQuery,
bool permitYield,
size_t plannerOptions) {
@@ -1147,7 +1147,7 @@ StatusWith<std::unique_ptr<PlanExecutor, PlanExecutor::Deleter>> getExecutorFind
StatusWith<std::unique_ptr<PlanExecutor, PlanExecutor::Deleter>> getExecutorLegacyFind(
OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
std::unique_ptr<CanonicalQuery> canonicalQuery) {
return _getExecutorFind(opCtx,
collection,
@@ -1206,7 +1206,7 @@ StatusWith<std::unique_ptr<projection_ast::Projection>> makeProjection(const BSO
StatusWith<std::unique_ptr<PlanExecutor, PlanExecutor::Deleter>> getExecutorDelete(
OpDebug* opDebug,
- const Collection* collection,
+ const CollectionPtr& collection,
ParsedDelete* parsedDelete,
boost::optional<ExplainOptions::Verbosity> verbosity) {
auto expCtx = parsedDelete->expCtx();
@@ -1364,7 +1364,7 @@ StatusWith<std::unique_ptr<PlanExecutor, PlanExecutor::Deleter>> getExecutorDele
StatusWith<std::unique_ptr<PlanExecutor, PlanExecutor::Deleter>> getExecutorUpdate(
OpDebug* opDebug,
- const Collection* collection,
+ const CollectionPtr& collection,
ParsedUpdate* parsedUpdate,
boost::optional<ExplainOptions::Verbosity> verbosity) {
auto expCtx = parsedUpdate->expCtx();
@@ -1662,7 +1662,7 @@ bool getDistinctNodeIndex(const std::vector<IndexEntry>& indices,
StatusWith<std::unique_ptr<PlanExecutor, PlanExecutor::Deleter>> getExecutorCount(
const boost::intrusive_ptr<ExpressionContext>& expCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
const CountCommand& request,
bool explain,
const NamespaceString& nss) {
@@ -1929,7 +1929,7 @@ namespace {
// Get the list of indexes that include the "distinct" field.
QueryPlannerParams fillOutPlannerParamsForDistinct(OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
size_t plannerOptions,
const ParsedDistinct& parsedDistinct) {
QueryPlannerParams plannerParams;
@@ -2013,7 +2013,7 @@ QueryPlannerParams fillOutPlannerParamsForDistinct(OperationContext* opCtx,
*/
StatusWith<std::unique_ptr<PlanExecutor, PlanExecutor::Deleter>> getExecutorForSimpleDistinct(
OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
const QueryPlannerParams& plannerParams,
PlanYieldPolicy::YieldPolicy yieldPolicy,
ParsedDistinct* parsedDistinct) {
@@ -2086,7 +2086,7 @@ StatusWith<std::unique_ptr<PlanExecutor, PlanExecutor::Deleter>> getExecutorForS
// 'strictDistinctOnly' parameter.
StatusWith<std::unique_ptr<PlanExecutor, PlanExecutor::Deleter>>
getExecutorDistinctFromIndexSolutions(OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
std::vector<std::unique_ptr<QuerySolution>> solutions,
PlanYieldPolicy::YieldPolicy yieldPolicy,
ParsedDistinct* parsedDistinct,
@@ -2126,7 +2126,7 @@ getExecutorDistinctFromIndexSolutions(OperationContext* opCtx,
*/
StatusWith<std::unique_ptr<PlanExecutor, PlanExecutor::Deleter>> getExecutorWithoutProjection(
OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
const CanonicalQuery* cq,
PlanYieldPolicy::YieldPolicy yieldPolicy,
size_t plannerOptions) {
@@ -2148,7 +2148,7 @@ StatusWith<std::unique_ptr<PlanExecutor, PlanExecutor::Deleter>> getExecutorWith
} // namespace
StatusWith<std::unique_ptr<PlanExecutor, PlanExecutor::Deleter>> getExecutorDistinct(
- const Collection* collection, size_t plannerOptions, ParsedDistinct* parsedDistinct) {
+ const CollectionPtr& collection, size_t plannerOptions, ParsedDistinct* parsedDistinct) {
auto expCtx = parsedDistinct->getQuery()->getExpCtx();
OperationContext* opCtx = expCtx->opCtx;
const auto yieldPolicy = opCtx->inMultiDocumentTransaction()
diff --git a/src/mongo/db/query/get_executor.h b/src/mongo/db/query/get_executor.h
index d14e07f9da3..1cdb332dcdc 100644
--- a/src/mongo/db/query/get_executor.h
+++ b/src/mongo/db/query/get_executor.h
@@ -46,6 +46,7 @@
namespace mongo {
class Collection;
+class CollectionPtr;
class CountRequest;
/**
@@ -73,7 +74,7 @@ void filterAllowedIndexEntries(const AllowedIndicesFilter& allowedIndicesFilter,
* 'collection'. Exposed for testing.
*/
void fillOutPlannerParams(OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
CanonicalQuery* canonicalQuery,
QueryPlannerParams* plannerParams);
@@ -106,7 +107,7 @@ IndexEntry indexEntryFromIndexCatalogEntry(OperationContext* opCtx,
* collection scans on the oplog.
*/
bool shouldWaitForOplogVisibility(OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
bool tailable);
/**
@@ -119,7 +120,7 @@ bool shouldWaitForOplogVisibility(OperationContext* opCtx,
*/
StatusWith<std::unique_ptr<PlanExecutor, PlanExecutor::Deleter>> getExecutor(
OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
std::unique_ptr<CanonicalQuery> canonicalQuery,
PlanYieldPolicy::YieldPolicy yieldPolicy,
size_t plannerOptions = 0);
@@ -136,7 +137,7 @@ StatusWith<std::unique_ptr<PlanExecutor, PlanExecutor::Deleter>> getExecutor(
*/
StatusWith<std::unique_ptr<PlanExecutor, PlanExecutor::Deleter>> getExecutorFind(
OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
std::unique_ptr<CanonicalQuery> canonicalQuery,
bool permitYield = false,
size_t plannerOptions = QueryPlannerParams::DEFAULT);
@@ -146,7 +147,7 @@ StatusWith<std::unique_ptr<PlanExecutor, PlanExecutor::Deleter>> getExecutorFind
*/
StatusWith<std::unique_ptr<PlanExecutor, PlanExecutor::Deleter>> getExecutorLegacyFind(
OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
std::unique_ptr<CanonicalQuery> canonicalQuery);
/**
@@ -203,7 +204,7 @@ bool turnIxscanIntoDistinctIxscan(QuerySolution* soln,
* distinct.
*/
StatusWith<std::unique_ptr<PlanExecutor, PlanExecutor::Deleter>> getExecutorDistinct(
- const Collection* collection, size_t plannerOptions, ParsedDistinct* parsedDistinct);
+ const CollectionPtr& collection, size_t plannerOptions, ParsedDistinct* parsedDistinct);
/*
* Get a PlanExecutor for a query executing as part of a count command.
@@ -214,7 +215,7 @@ StatusWith<std::unique_ptr<PlanExecutor, PlanExecutor::Deleter>> getExecutorDist
*/
StatusWith<std::unique_ptr<PlanExecutor, PlanExecutor::Deleter>> getExecutorCount(
const boost::intrusive_ptr<ExpressionContext>& expCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
const CountCommand& request,
bool explain,
const NamespaceString& nss);
@@ -240,7 +241,7 @@ StatusWith<std::unique_ptr<PlanExecutor, PlanExecutor::Deleter>> getExecutorCoun
*/
StatusWith<std::unique_ptr<PlanExecutor, PlanExecutor::Deleter>> getExecutorDelete(
OpDebug* opDebug,
- const Collection* collection,
+ const CollectionPtr& collection,
ParsedDelete* parsedDelete,
boost::optional<ExplainOptions::Verbosity> verbosity);
@@ -266,7 +267,7 @@ StatusWith<std::unique_ptr<PlanExecutor, PlanExecutor::Deleter>> getExecutorDele
*/
StatusWith<std::unique_ptr<PlanExecutor, PlanExecutor::Deleter>> getExecutorUpdate(
OpDebug* opDebug,
- const Collection* collection,
+ const CollectionPtr& collection,
ParsedUpdate* parsedUpdate,
boost::optional<ExplainOptions::Verbosity> verbosity);
} // namespace mongo
diff --git a/src/mongo/db/query/internal_plans.cpp b/src/mongo/db/query/internal_plans.cpp
index 8d4f5d8ca47..f7c6beeefac 100644
--- a/src/mongo/db/query/internal_plans.cpp
+++ b/src/mongo/db/query/internal_plans.cpp
@@ -51,7 +51,7 @@ namespace mongo {
std::unique_ptr<PlanExecutor, PlanExecutor::Deleter> InternalPlanner::collectionScan(
OperationContext* opCtx,
StringData ns,
- const Collection* collection,
+ const CollectionPtr& collection,
PlanYieldPolicy::YieldPolicy yieldPolicy,
const Direction direction,
boost::optional<RecordId> resumeAfterRecordId) {
@@ -60,7 +60,7 @@ std::unique_ptr<PlanExecutor, PlanExecutor::Deleter> InternalPlanner::collection
auto expCtx = make_intrusive<ExpressionContext>(
opCtx, std::unique_ptr<CollatorInterface>(nullptr), NamespaceString(ns));
- if (nullptr == collection) {
+ if (!collection) {
auto eof = std::make_unique<EOFStage>(expCtx.get());
// Takes ownership of 'ws' and 'eof'.
auto statusWithPlanExecutor = plan_executor_factory::make(
@@ -82,7 +82,7 @@ std::unique_ptr<PlanExecutor, PlanExecutor::Deleter> InternalPlanner::collection
std::unique_ptr<PlanExecutor, PlanExecutor::Deleter> InternalPlanner::deleteWithCollectionScan(
OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
std::unique_ptr<DeleteStageParams> params,
PlanYieldPolicy::YieldPolicy yieldPolicy,
Direction direction) {
@@ -106,7 +106,7 @@ std::unique_ptr<PlanExecutor, PlanExecutor::Deleter> InternalPlanner::deleteWith
std::unique_ptr<PlanExecutor, PlanExecutor::Deleter> InternalPlanner::indexScan(
OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
const IndexDescriptor* descriptor,
const BSONObj& startKey,
const BSONObj& endKey,
@@ -137,7 +137,7 @@ std::unique_ptr<PlanExecutor, PlanExecutor::Deleter> InternalPlanner::indexScan(
std::unique_ptr<PlanExecutor, PlanExecutor::Deleter> InternalPlanner::deleteWithIndexScan(
OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
std::unique_ptr<DeleteStageParams> params,
const IndexDescriptor* descriptor,
const BSONObj& startKey,
@@ -172,7 +172,7 @@ std::unique_ptr<PlanExecutor, PlanExecutor::Deleter> InternalPlanner::deleteWith
std::unique_ptr<PlanExecutor, PlanExecutor::Deleter> InternalPlanner::updateWithIdHack(
OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
const UpdateStageParams& params,
const IndexDescriptor* descriptor,
const BSONObj& key,
@@ -201,7 +201,7 @@ std::unique_ptr<PlanExecutor, PlanExecutor::Deleter> InternalPlanner::updateWith
std::unique_ptr<PlanStage> InternalPlanner::_collectionScan(
const boost::intrusive_ptr<ExpressionContext>& expCtx,
WorkingSet* ws,
- const Collection* collection,
+ const CollectionPtr& collection,
Direction direction,
boost::optional<RecordId> resumeAfterRecordId) {
invariant(collection);
@@ -223,7 +223,7 @@ std::unique_ptr<PlanStage> InternalPlanner::_collectionScan(
std::unique_ptr<PlanStage> InternalPlanner::_indexScan(
const boost::intrusive_ptr<ExpressionContext>& expCtx,
WorkingSet* ws,
- const Collection* collection,
+ const CollectionPtr& collection,
const IndexDescriptor* descriptor,
const BSONObj& startKey,
const BSONObj& endKey,
diff --git a/src/mongo/db/query/internal_plans.h b/src/mongo/db/query/internal_plans.h
index 3846dca76bc..c7507243369 100644
--- a/src/mongo/db/query/internal_plans.h
+++ b/src/mongo/db/query/internal_plans.h
@@ -39,6 +39,7 @@ namespace mongo {
class BSONObj;
class Collection;
+class CollectionPtr;
class IndexDescriptor;
class OperationContext;
class PlanStage;
@@ -72,7 +73,7 @@ public:
static std::unique_ptr<PlanExecutor, PlanExecutor::Deleter> collectionScan(
OperationContext* opCtx,
StringData ns,
- const Collection* collection,
+ const CollectionPtr& collection,
PlanYieldPolicy::YieldPolicy yieldPolicy,
const Direction direction = FORWARD,
boost::optional<RecordId> resumeAfterRecordId = boost::none);
@@ -82,7 +83,7 @@ public:
*/
static std::unique_ptr<PlanExecutor, PlanExecutor::Deleter> deleteWithCollectionScan(
OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
std::unique_ptr<DeleteStageParams> params,
PlanYieldPolicy::YieldPolicy yieldPolicy,
Direction direction = FORWARD);
@@ -92,7 +93,7 @@ public:
*/
static std::unique_ptr<PlanExecutor, PlanExecutor::Deleter> indexScan(
OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
const IndexDescriptor* descriptor,
const BSONObj& startKey,
const BSONObj& endKey,
@@ -106,7 +107,7 @@ public:
*/
static std::unique_ptr<PlanExecutor, PlanExecutor::Deleter> deleteWithIndexScan(
OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
std::unique_ptr<DeleteStageParams> params,
const IndexDescriptor* descriptor,
const BSONObj& startKey,
@@ -120,7 +121,7 @@ public:
*/
static std::unique_ptr<PlanExecutor, PlanExecutor::Deleter> updateWithIdHack(
OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
const UpdateStageParams& params,
const IndexDescriptor* descriptor,
const BSONObj& key,
@@ -135,7 +136,7 @@ private:
static std::unique_ptr<PlanStage> _collectionScan(
const boost::intrusive_ptr<ExpressionContext>& expCtx,
WorkingSet* ws,
- const Collection* collection,
+ const CollectionPtr& collection,
Direction direction,
boost::optional<RecordId> resumeAfterRecordId = boost::none);
@@ -147,7 +148,7 @@ private:
static std::unique_ptr<PlanStage> _indexScan(
const boost::intrusive_ptr<ExpressionContext>& expCtx,
WorkingSet* ws,
- const Collection* collection,
+ const CollectionPtr& collection,
const IndexDescriptor* descriptor,
const BSONObj& startKey,
const BSONObj& endKey,
diff --git a/src/mongo/db/query/plan_executor.h b/src/mongo/db/query/plan_executor.h
index 3fe99fcad2d..60a832e0491 100644
--- a/src/mongo/db/query/plan_executor.h
+++ b/src/mongo/db/query/plan_executor.h
@@ -187,7 +187,7 @@ public:
* WriteConflictException is encountered. If the time limit is exceeded during this retry
* process, throws ErrorCodes::MaxTimeMSExpired.
*/
- virtual void restoreState() = 0;
+ virtual void restoreState(const Yieldable* yieldable) = 0;
/**
* Detaches from the OperationContext and releases any storage-engine state.
diff --git a/src/mongo/db/query/plan_executor_factory.cpp b/src/mongo/db/query/plan_executor_factory.cpp
index 3630e975646..93ee590d1dc 100644
--- a/src/mongo/db/query/plan_executor_factory.cpp
+++ b/src/mongo/db/query/plan_executor_factory.cpp
@@ -45,7 +45,7 @@ StatusWith<std::unique_ptr<PlanExecutor, PlanExecutor::Deleter>> make(
std::unique_ptr<CanonicalQuery> cq,
std::unique_ptr<WorkingSet> ws,
std::unique_ptr<PlanStage> rt,
- const Collection* collection,
+ const CollectionPtr& collection,
PlanYieldPolicy::YieldPolicy yieldPolicy,
NamespaceString nss,
std::unique_ptr<QuerySolution> qs) {
@@ -65,7 +65,7 @@ StatusWith<std::unique_ptr<PlanExecutor, PlanExecutor::Deleter>> make(
const boost::intrusive_ptr<ExpressionContext>& expCtx,
std::unique_ptr<WorkingSet> ws,
std::unique_ptr<PlanStage> rt,
- const Collection* collection,
+ const CollectionPtr& collection,
PlanYieldPolicy::YieldPolicy yieldPolicy,
NamespaceString nss,
std::unique_ptr<QuerySolution> qs) {
@@ -87,7 +87,7 @@ StatusWith<std::unique_ptr<PlanExecutor, PlanExecutor::Deleter>> make(
std::unique_ptr<QuerySolution> qs,
std::unique_ptr<CanonicalQuery> cq,
const boost::intrusive_ptr<ExpressionContext>& expCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
NamespaceString nss,
PlanYieldPolicy::YieldPolicy yieldPolicy) {
@@ -113,7 +113,7 @@ StatusWith<std::unique_ptr<PlanExecutor, PlanExecutor::Deleter>> make(
OperationContext* opCtx,
std::unique_ptr<CanonicalQuery> cq,
std::pair<std::unique_ptr<sbe::PlanStage>, stage_builder::PlanStageData> root,
- const Collection* collection,
+ const CollectionPtr& collection,
NamespaceString nss,
std::unique_ptr<PlanYieldPolicySBE> yieldPolicy) {
@@ -142,7 +142,7 @@ StatusWith<std::unique_ptr<PlanExecutor, PlanExecutor::Deleter>> make(
OperationContext* opCtx,
std::unique_ptr<CanonicalQuery> cq,
std::pair<std::unique_ptr<sbe::PlanStage>, stage_builder::PlanStageData> root,
- const Collection* collection,
+ const CollectionPtr& collection,
NamespaceString nss,
std::queue<std::pair<BSONObj, boost::optional<RecordId>>> stash,
std::unique_ptr<PlanYieldPolicySBE> yieldPolicy) {
diff --git a/src/mongo/db/query/plan_executor_factory.h b/src/mongo/db/query/plan_executor_factory.h
index 56f6fe87cf4..207e3065e20 100644
--- a/src/mongo/db/query/plan_executor_factory.h
+++ b/src/mongo/db/query/plan_executor_factory.h
@@ -65,7 +65,7 @@ StatusWith<std::unique_ptr<PlanExecutor, PlanExecutor::Deleter>> make(
std::unique_ptr<CanonicalQuery> cq,
std::unique_ptr<WorkingSet> ws,
std::unique_ptr<PlanStage> rt,
- const Collection* collection,
+ const CollectionPtr& collection,
PlanYieldPolicy::YieldPolicy yieldPolicy,
NamespaceString nss = NamespaceString(),
std::unique_ptr<QuerySolution> qs = nullptr);
@@ -81,7 +81,7 @@ StatusWith<std::unique_ptr<PlanExecutor, PlanExecutor::Deleter>> make(
const boost::intrusive_ptr<ExpressionContext>& expCtx,
std::unique_ptr<WorkingSet> ws,
std::unique_ptr<PlanStage> rt,
- const Collection* collection,
+ const CollectionPtr& collection,
PlanYieldPolicy::YieldPolicy yieldPolicy,
NamespaceString nss = NamespaceString(),
std::unique_ptr<QuerySolution> qs = nullptr);
@@ -93,7 +93,7 @@ StatusWith<std::unique_ptr<PlanExecutor, PlanExecutor::Deleter>> make(
std::unique_ptr<QuerySolution> qs,
std::unique_ptr<CanonicalQuery> cq,
const boost::intrusive_ptr<ExpressionContext>& expCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
NamespaceString nss,
PlanYieldPolicy::YieldPolicy yieldPolicy);
@@ -105,7 +105,7 @@ StatusWith<std::unique_ptr<PlanExecutor, PlanExecutor::Deleter>> make(
OperationContext* opCtx,
std::unique_ptr<CanonicalQuery> cq,
std::pair<std::unique_ptr<sbe::PlanStage>, stage_builder::PlanStageData> root,
- const Collection* collection,
+ const CollectionPtr& collection,
NamespaceString nss,
std::unique_ptr<PlanYieldPolicySBE> yieldPolicy);
@@ -118,7 +118,7 @@ StatusWith<std::unique_ptr<PlanExecutor, PlanExecutor::Deleter>> make(
OperationContext* opCtx,
std::unique_ptr<CanonicalQuery> cq,
std::pair<std::unique_ptr<sbe::PlanStage>, stage_builder::PlanStageData> root,
- const Collection* collection,
+ const CollectionPtr& collection,
NamespaceString nss,
std::queue<std::pair<BSONObj, boost::optional<RecordId>>> stash,
std::unique_ptr<PlanYieldPolicySBE> yieldPolicy);
diff --git a/src/mongo/db/query/plan_executor_impl.cpp b/src/mongo/db/query/plan_executor_impl.cpp
index 7be8aa4ef87..915bc2ad34b 100644
--- a/src/mongo/db/query/plan_executor_impl.cpp
+++ b/src/mongo/db/query/plan_executor_impl.cpp
@@ -83,14 +83,15 @@ MONGO_FAIL_POINT_DEFINE(planExecutorHangBeforeShouldWaitForInserts);
* Constructs a PlanYieldPolicy based on 'policy'.
*/
std::unique_ptr<PlanYieldPolicy> makeYieldPolicy(PlanExecutorImpl* exec,
- PlanYieldPolicy::YieldPolicy policy) {
+ PlanYieldPolicy::YieldPolicy policy,
+ const Yieldable* yieldable) {
switch (policy) {
case PlanYieldPolicy::YieldPolicy::YIELD_AUTO:
case PlanYieldPolicy::YieldPolicy::YIELD_MANUAL:
case PlanYieldPolicy::YieldPolicy::NO_YIELD:
case PlanYieldPolicy::YieldPolicy::WRITE_CONFLICT_RETRY_ONLY:
case PlanYieldPolicy::YieldPolicy::INTERRUPT_ONLY: {
- return std::make_unique<PlanYieldPolicyImpl>(exec, policy);
+ return std::make_unique<PlanYieldPolicyImpl>(exec, policy, yieldable);
}
case PlanYieldPolicy::YieldPolicy::ALWAYS_TIME_OUT: {
return std::make_unique<AlwaysTimeOutYieldPolicy>(exec);
@@ -130,7 +131,7 @@ PlanExecutorImpl::PlanExecutorImpl(OperationContext* opCtx,
unique_ptr<QuerySolution> qs,
unique_ptr<CanonicalQuery> cq,
const boost::intrusive_ptr<ExpressionContext>& expCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
NamespaceString nss,
PlanYieldPolicy::YieldPolicy yieldPolicy)
: _opCtx(opCtx),
@@ -141,8 +142,10 @@ PlanExecutorImpl::PlanExecutorImpl(OperationContext* opCtx,
_root(std::move(rt)),
_nss(std::move(nss)),
// There's no point in yielding if the collection doesn't exist.
- _yieldPolicy(makeYieldPolicy(
- this, collection ? yieldPolicy : PlanYieldPolicy::YieldPolicy::NO_YIELD)) {
+ _yieldPolicy(
+ makeYieldPolicy(this,
+ collection ? yieldPolicy : PlanYieldPolicy::YieldPolicy::NO_YIELD,
+ collection ? &collection : nullptr)) {
invariant(!_expCtx || _expCtx->opCtx == _opCtx);
invariant(!_cq || !_expCtx || _cq->getExpCtx() == _expCtx);
@@ -243,12 +246,13 @@ void PlanExecutorImpl::saveState() {
if (!isMarkedAsKilled()) {
_root->saveState();
}
+ _yieldPolicy->setYieldable(nullptr);
_currentState = kSaved;
}
-void PlanExecutorImpl::restoreState() {
+void PlanExecutorImpl::restoreState(const Yieldable* yieldable) {
try {
- restoreStateWithoutRetrying();
+ restoreStateWithoutRetrying(yieldable);
} catch (const WriteConflictException&) {
if (!_yieldPolicy->canAutoYield())
throw;
@@ -258,9 +262,10 @@ void PlanExecutorImpl::restoreState() {
}
}
-void PlanExecutorImpl::restoreStateWithoutRetrying() {
+void PlanExecutorImpl::restoreStateWithoutRetrying(const Yieldable* yieldable) {
invariant(_currentState == kSaved);
+ _yieldPolicy->setYieldable(yieldable);
if (!isMarkedAsKilled()) {
_root->restoreState();
}
diff --git a/src/mongo/db/query/plan_executor_impl.h b/src/mongo/db/query/plan_executor_impl.h
index 865a20fc515..651937eeb3f 100644
--- a/src/mongo/db/query/plan_executor_impl.h
+++ b/src/mongo/db/query/plan_executor_impl.h
@@ -59,7 +59,7 @@ public:
std::unique_ptr<QuerySolution> qs,
std::unique_ptr<CanonicalQuery> cq,
const boost::intrusive_ptr<ExpressionContext>& expCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
NamespaceString nss,
PlanYieldPolicy::YieldPolicy yieldPolicy);
@@ -68,7 +68,7 @@ public:
const NamespaceString& nss() const final;
OperationContext* getOpCtx() const final;
void saveState() final;
- void restoreState() final;
+ void restoreState(const Yieldable* yieldable) final;
void detachFromOperationContext() final;
void reattachToOperationContext(OperationContext* opCtx) final;
ExecState getNextDocument(Document* objOut, RecordId* dlOut) final;
@@ -96,7 +96,7 @@ public:
*
* This is only public for PlanYieldPolicy. DO NOT CALL ANYWHERE ELSE.
*/
- void restoreStateWithoutRetrying();
+ void restoreStateWithoutRetrying(const Yieldable* yieldable);
/**
* Return a pointer to this executor's MultiPlanStage, or nullptr if it does not have one.
diff --git a/src/mongo/db/query/plan_executor_sbe.cpp b/src/mongo/db/query/plan_executor_sbe.cpp
index 3e65c0c46e7..4e8931a00f1 100644
--- a/src/mongo/db/query/plan_executor_sbe.cpp
+++ b/src/mongo/db/query/plan_executor_sbe.cpp
@@ -42,7 +42,7 @@ PlanExecutorSBE::PlanExecutorSBE(
OperationContext* opCtx,
std::unique_ptr<CanonicalQuery> cq,
std::pair<std::unique_ptr<sbe::PlanStage>, stage_builder::PlanStageData> root,
- const Collection* collection,
+ const CollectionPtr& collection,
NamespaceString nss,
bool isOpen,
boost::optional<std::queue<std::pair<BSONObj, boost::optional<RecordId>>>> stash,
@@ -105,7 +105,7 @@ void PlanExecutorSBE::saveState() {
_root->saveState();
}
-void PlanExecutorSBE::restoreState() {
+void PlanExecutorSBE::restoreState(const Yieldable* yieldable) {
invariant(_root);
_root->restoreState();
}
diff --git a/src/mongo/db/query/plan_executor_sbe.h b/src/mongo/db/query/plan_executor_sbe.h
index 680f76c578e..0e3ebb3505c 100644
--- a/src/mongo/db/query/plan_executor_sbe.h
+++ b/src/mongo/db/query/plan_executor_sbe.h
@@ -43,7 +43,7 @@ public:
OperationContext* opCtx,
std::unique_ptr<CanonicalQuery> cq,
std::pair<std::unique_ptr<sbe::PlanStage>, stage_builder::PlanStageData> root,
- const Collection* collection,
+ const CollectionPtr& collection,
NamespaceString nss,
bool isOpen,
boost::optional<std::queue<std::pair<BSONObj, boost::optional<RecordId>>>> stash,
@@ -62,7 +62,7 @@ public:
}
void saveState();
- void restoreState();
+ void restoreState(const Yieldable* yieldable);
void detachFromOperationContext();
void reattachToOperationContext(OperationContext* opCtx);
diff --git a/src/mongo/db/query/plan_yield_policy.h b/src/mongo/db/query/plan_yield_policy.h
index 1a10961baa5..8fe09adb8e2 100644
--- a/src/mongo/db/query/plan_yield_policy.h
+++ b/src/mongo/db/query/plan_yield_policy.h
@@ -38,6 +38,7 @@
namespace mongo {
class ClockSource;
+class Yieldable;
class PlanYieldPolicy {
public:
@@ -238,6 +239,11 @@ public:
return _policy;
}
+ /**
+ * Set new yieldable instance if policy supports it.
+ */
+ virtual void setYieldable(const Yieldable* yieldable) {}
+
private:
/**
* Yields locks and calls 'abandonSnapshot()'. Calls 'whileYieldingFn()', if provided, while
diff --git a/src/mongo/db/query/plan_yield_policy_impl.cpp b/src/mongo/db/query/plan_yield_policy_impl.cpp
index 4fc3af37052..a88378d58f3 100644
--- a/src/mongo/db/query/plan_yield_policy_impl.cpp
+++ b/src/mongo/db/query/plan_yield_policy_impl.cpp
@@ -45,20 +45,24 @@ MONGO_FAIL_POINT_DEFINE(setInterruptOnlyPlansCheckForInterruptHang);
} // namespace
PlanYieldPolicyImpl::PlanYieldPolicyImpl(PlanExecutorImpl* exec,
- PlanYieldPolicy::YieldPolicy policy)
+ PlanYieldPolicy::YieldPolicy policy,
+ const Yieldable* yieldable)
: PlanYieldPolicy(exec->getOpCtx()->lockState()->isGlobalLockedRecursively()
? PlanYieldPolicy::YieldPolicy::NO_YIELD
: policy,
exec->getOpCtx()->getServiceContext()->getFastClockSource(),
internalQueryExecYieldIterations.load(),
Milliseconds{internalQueryExecYieldPeriodMS.load()}),
- _planYielding(exec) {}
+ _planYielding(exec),
+ _yieldable(yieldable) {}
Status PlanYieldPolicyImpl::yield(OperationContext* opCtx, std::function<void()> whileYieldingFn) {
// Can't use writeConflictRetry since we need to call saveState before reseting the
// transaction.
for (int attempt = 1; true; attempt++) {
try {
+ // Saving and restoring state modifies _yieldable so make a copy before we start
+ const Yieldable* yieldable = _yieldable;
try {
_planYielding->saveState();
} catch (const WriteConflictException&) {
@@ -70,10 +74,10 @@ Status PlanYieldPolicyImpl::yield(OperationContext* opCtx, std::function<void()>
opCtx->recoveryUnit()->abandonSnapshot();
} else {
// Release and reacquire locks.
- _yieldAllLocks(opCtx, whileYieldingFn, _planYielding->nss());
+ _yieldAllLocks(opCtx, yieldable, whileYieldingFn, _planYielding->nss());
}
- _planYielding->restoreStateWithoutRetrying();
+ _planYielding->restoreStateWithoutRetrying(yieldable);
return Status::OK();
} catch (const WriteConflictException&) {
CurOp::get(opCtx)->debug().additiveMetrics.incrementWriteConflicts(1);
@@ -89,6 +93,7 @@ Status PlanYieldPolicyImpl::yield(OperationContext* opCtx, std::function<void()>
}
void PlanYieldPolicyImpl::_yieldAllLocks(OperationContext* opCtx,
+ const Yieldable* yieldable,
std::function<void()> whileYieldingFn,
const NamespaceString& planExecNS) {
// Things have to happen here in a specific order:
@@ -101,6 +106,10 @@ void PlanYieldPolicyImpl::_yieldAllLocks(OperationContext* opCtx,
Locker::LockSnapshot snapshot;
+ if (yieldable) {
+ yieldable->yield();
+ }
+
auto unlocked = locker->saveLockStateAndUnlock(&snapshot);
// Attempt to check for interrupt while locks are not held, in order to discourage the
@@ -129,6 +138,10 @@ void PlanYieldPolicyImpl::_yieldAllLocks(OperationContext* opCtx,
locker->restoreLockState(opCtx, snapshot);
+ if (yieldable) {
+ yieldable->restore();
+ }
+
// After yielding and reacquiring locks, the preconditions that were used to select our
// ReadSource initially need to be checked again. Queries hold an AutoGetCollectionForRead RAII
// lock for their lifetime, which may select a ReadSource based on state (e.g. replication
diff --git a/src/mongo/db/query/plan_yield_policy_impl.h b/src/mongo/db/query/plan_yield_policy_impl.h
index be4163eedec..812c17638d0 100644
--- a/src/mongo/db/query/plan_yield_policy_impl.h
+++ b/src/mongo/db/query/plan_yield_policy_impl.h
@@ -31,14 +31,20 @@
#include "mongo/db/query/plan_executor_impl.h"
#include "mongo/db/query/plan_yield_policy.h"
+#include "mongo/db/yieldable.h"
namespace mongo {
class PlanYieldPolicyImpl final : public PlanYieldPolicy {
public:
- PlanYieldPolicyImpl(PlanExecutorImpl* exec, PlanYieldPolicy::YieldPolicy policy);
+ PlanYieldPolicyImpl(PlanExecutorImpl* exec,
+ PlanYieldPolicy::YieldPolicy policy,
+ const Yieldable* yieldable);
private:
+ void setYieldable(const Yieldable* yieldable) override {
+ _yieldable = yieldable;
+ }
Status yield(OperationContext* opCtx, std::function<void()> whileYieldingFn = nullptr) override;
void preCheckInterruptOnly(OperationContext* opCtx) override;
@@ -52,12 +58,14 @@ private:
* The whileYieldingFn will be executed after unlocking the locks and before re-acquiring them.
*/
void _yieldAllLocks(OperationContext* opCtx,
+ const Yieldable* yieldable,
std::function<void()> whileYieldingFn,
const NamespaceString& planExecNS);
// The plan executor which this yield policy is responsible for yielding. Must not outlive the
// plan executor.
PlanExecutorImpl* const _planYielding;
+ const Yieldable* _yieldable;
};
} // namespace mongo
diff --git a/src/mongo/db/query/planner_analysis.h b/src/mongo/db/query/planner_analysis.h
index ba1e6a8ac47..e5700483d30 100644
--- a/src/mongo/db/query/planner_analysis.h
+++ b/src/mongo/db/query/planner_analysis.h
@@ -36,6 +36,7 @@
namespace mongo {
class Collection;
+class CollectionPtr;
class QueryPlannerAnalysis {
public:
diff --git a/src/mongo/db/query/query_planner.cpp b/src/mongo/db/query/query_planner.cpp
index 18d7f3543a7..13a9fe6129b 100644
--- a/src/mongo/db/query/query_planner.cpp
+++ b/src/mongo/db/query/query_planner.cpp
@@ -1124,7 +1124,7 @@ StatusWith<std::vector<std::unique_ptr<QuerySolution>>> QueryPlanner::plan(
StatusWith<QueryPlanner::SubqueriesPlanningResult> QueryPlanner::planSubqueries(
OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
const PlanCache* planCache,
const CanonicalQuery& query,
const QueryPlannerParams& params) {
diff --git a/src/mongo/db/query/query_planner.h b/src/mongo/db/query/query_planner.h
index e9d27bea0f5..236ec4f0269 100644
--- a/src/mongo/db/query/query_planner.h
+++ b/src/mongo/db/query/query_planner.h
@@ -38,6 +38,7 @@ namespace mongo {
class CachedSolution;
class Collection;
+class CollectionPtr;
/**
* QueryPlanner's job is to provide an entry point to the query planning and optimization
@@ -106,7 +107,7 @@ public:
* lists of query solutions in 'SubqueriesPlanningResult'.
*/
static StatusWith<SubqueriesPlanningResult> planSubqueries(OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
const PlanCache* planCache,
const CanonicalQuery& query,
const QueryPlannerParams& params);
diff --git a/src/mongo/db/query/sbe_cached_solution_planner.h b/src/mongo/db/query/sbe_cached_solution_planner.h
index 264ddfbbbfa..9474cca0073 100644
--- a/src/mongo/db/query/sbe_cached_solution_planner.h
+++ b/src/mongo/db/query/sbe_cached_solution_planner.h
@@ -43,7 +43,7 @@ namespace mongo::sbe {
class CachedSolutionPlanner final : public BaseRuntimePlanner {
public:
CachedSolutionPlanner(OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
const CanonicalQuery& cq,
const QueryPlannerParams& queryParams,
size_t decisionReads,
diff --git a/src/mongo/db/query/sbe_multi_planner.h b/src/mongo/db/query/sbe_multi_planner.h
index 48dca7081bf..80ac325c3b3 100644
--- a/src/mongo/db/query/sbe_multi_planner.h
+++ b/src/mongo/db/query/sbe_multi_planner.h
@@ -43,7 +43,7 @@ namespace mongo::sbe {
class MultiPlanner final : public BaseRuntimePlanner {
public:
MultiPlanner(OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
const CanonicalQuery& cq,
PlanCachingMode cachingMode,
PlanYieldPolicySBE* yieldPolicy)
diff --git a/src/mongo/db/query/sbe_runtime_planner.cpp b/src/mongo/db/query/sbe_runtime_planner.cpp
index 254cfeb84de..1da89caf8e1 100644
--- a/src/mongo/db/query/sbe_runtime_planner.cpp
+++ b/src/mongo/db/query/sbe_runtime_planner.cpp
@@ -30,6 +30,7 @@
#include "mongo/db/query/sbe_runtime_planner.h"
+#include "mongo/db/catalog/collection.h"
#include "mongo/db/exec/sbe/expressions/expression.h"
#include "mongo/db/exec/trial_period_utils.h"
#include "mongo/db/query/plan_executor_sbe.h"
diff --git a/src/mongo/db/query/sbe_runtime_planner.h b/src/mongo/db/query/sbe_runtime_planner.h
index d399b096877..c7dbfbd73d2 100644
--- a/src/mongo/db/query/sbe_runtime_planner.h
+++ b/src/mongo/db/query/sbe_runtime_planner.h
@@ -60,7 +60,7 @@ public:
class BaseRuntimePlanner : public RuntimePlanner {
public:
BaseRuntimePlanner(OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
const CanonicalQuery& cq,
PlanYieldPolicySBE* yieldPolicy)
: _opCtx(opCtx), _collection(collection), _cq(cq), _yieldPolicy(yieldPolicy) {
@@ -95,7 +95,7 @@ protected:
std::vector<std::pair<std::unique_ptr<PlanStage>, stage_builder::PlanStageData>> roots);
OperationContext* const _opCtx;
- const Collection* const _collection;
+ const CollectionPtr& _collection;
const CanonicalQuery& _cq;
PlanYieldPolicySBE* const _yieldPolicy;
};
diff --git a/src/mongo/db/query/sbe_stage_builder.h b/src/mongo/db/query/sbe_stage_builder.h
index 203b04ef8ff..568f45d2b3f 100644
--- a/src/mongo/db/query/sbe_stage_builder.h
+++ b/src/mongo/db/query/sbe_stage_builder.h
@@ -89,7 +89,7 @@ struct PlanStageData {
class SlotBasedStageBuilder final : public StageBuilder<sbe::PlanStage> {
public:
SlotBasedStageBuilder(OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
const CanonicalQuery& cq,
const QuerySolution& solution,
PlanYieldPolicySBE* yieldPolicy,
diff --git a/src/mongo/db/query/sbe_stage_builder_coll_scan.cpp b/src/mongo/db/query/sbe_stage_builder_coll_scan.cpp
index 8b44fb09c89..bf099dee54d 100644
--- a/src/mongo/db/query/sbe_stage_builder_coll_scan.cpp
+++ b/src/mongo/db/query/sbe_stage_builder_coll_scan.cpp
@@ -54,13 +54,13 @@ namespace {
* Checks whether a callback function should be created for a ScanStage and returns it, if so. The
* logic in the provided callback will be executed when the ScanStage is opened or reopened.
*/
-sbe::ScanOpenCallback makeOpenCallbackIfNeeded(const Collection* collection,
+sbe::ScanOpenCallback makeOpenCallbackIfNeeded(const CollectionPtr& collection,
const CollectionScanNode* csn) {
if (csn->direction == CollectionScanParams::FORWARD && csn->shouldWaitForOplogVisibility) {
invariant(!csn->tailable);
invariant(collection->ns().isOplog());
- return [](OperationContext* opCtx, const Collection* collection, bool reOpen) {
+ return [](OperationContext* opCtx, const CollectionPtr& collection, bool reOpen) {
if (!reOpen) {
// Forward, non-tailable scans from the oplog need to wait until all oplog entries
// before the read begins to be visible. This isn't needed for reverse scans because
@@ -87,7 +87,7 @@ sbe::ScanOpenCallback makeOpenCallbackIfNeeded(const Collection* collection,
* of the same SlotId (the latter is returned purely for convenience purposes).
*/
std::tuple<std::vector<std::string>, sbe::value::SlotVector, boost::optional<sbe::value::SlotId>>
-makeOplogTimestampSlotsIfNeeded(const Collection* collection,
+makeOplogTimestampSlotsIfNeeded(const CollectionPtr& collection,
sbe::value::SlotIdGenerator* slotIdGenerator,
bool shouldTrackLatestOplogTimestamp) {
if (shouldTrackLatestOplogTimestamp) {
@@ -118,7 +118,7 @@ std::tuple<sbe::value::SlotId,
boost::optional<sbe::value::SlotId>,
std::unique_ptr<sbe::PlanStage>>
generateOptimizedOplogScan(OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
const CollectionScanNode* csn,
sbe::value::SlotIdGenerator* slotIdGenerator,
sbe::value::FrameIdGenerator* frameIdGenerator,
@@ -300,7 +300,7 @@ std::tuple<sbe::value::SlotId,
boost::optional<sbe::value::SlotId>,
std::unique_ptr<sbe::PlanStage>>
generateGenericCollScan(OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
const CollectionScanNode* csn,
sbe::value::SlotIdGenerator* slotIdGenerator,
sbe::value::FrameIdGenerator* frameIdGenerator,
@@ -447,7 +447,7 @@ std::tuple<sbe::value::SlotId,
boost::optional<sbe::value::SlotId>,
std::unique_ptr<sbe::PlanStage>>
generateCollScan(OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
const CollectionScanNode* csn,
sbe::value::SlotIdGenerator* slotIdGenerator,
sbe::value::FrameIdGenerator* frameIdGenerator,
diff --git a/src/mongo/db/query/sbe_stage_builder_coll_scan.h b/src/mongo/db/query/sbe_stage_builder_coll_scan.h
index 0fff4cf6212..338c5cff894 100644
--- a/src/mongo/db/query/sbe_stage_builder_coll_scan.h
+++ b/src/mongo/db/query/sbe_stage_builder_coll_scan.h
@@ -53,7 +53,7 @@ std::tuple<sbe::value::SlotId,
boost::optional<sbe::value::SlotId>,
std::unique_ptr<sbe::PlanStage>>
generateCollScan(OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
const CollectionScanNode* csn,
sbe::value::SlotIdGenerator* slotIdGenerator,
sbe::value::FrameIdGenerator* frameIdGenerator,
diff --git a/src/mongo/db/query/sbe_stage_builder_index_scan.cpp b/src/mongo/db/query/sbe_stage_builder_index_scan.cpp
index b7da05ca14b..2e98673bb93 100644
--- a/src/mongo/db/query/sbe_stage_builder_index_scan.cpp
+++ b/src/mongo/db/query/sbe_stage_builder_index_scan.cpp
@@ -266,7 +266,7 @@ makeIntervalsFromIndexBounds(const IndexBounds& bounds,
*/
std::pair<sbe::value::SlotId, std::unique_ptr<sbe::PlanStage>>
generateOptimizedMultiIntervalIndexScan(
- const Collection* collection,
+ const CollectionPtr& collection,
const std::string& indexName,
bool forward,
std::vector<std::pair<std::unique_ptr<KeyString::Value>, std::unique_ptr<KeyString::Value>>>
@@ -386,7 +386,7 @@ std::pair<sbe::value::SlotId, std::unique_ptr<sbe::PlanStage>> makeAnchorBranchF
* consisting of valid recordId's and index seek keys to restart the index scan from.
*/
std::pair<sbe::value::SlotId, std::unique_ptr<sbe::PlanStage>>
-makeRecursiveBranchForGenericIndexScan(const Collection* collection,
+makeRecursiveBranchForGenericIndexScan(const CollectionPtr& collection,
const std::string& indexName,
const sbe::CheckBoundsParams& params,
sbe::SpoolId spoolId,
@@ -513,7 +513,7 @@ makeRecursiveBranchForGenericIndexScan(const Collection* collection,
* - The recursion is terminated when the sspool becomes empty.
*/
std::pair<sbe::value::SlotId, std::unique_ptr<sbe::PlanStage>>
-generateGenericMultiIntervalIndexScan(const Collection* collection,
+generateGenericMultiIntervalIndexScan(const CollectionPtr& collection,
const IndexScanNode* ixn,
KeyString::Version version,
Ordering ordering,
@@ -614,7 +614,7 @@ generateGenericMultiIntervalIndexScan(const Collection* collection,
} // namespace
std::pair<sbe::value::SlotId, std::unique_ptr<sbe::PlanStage>> generateSingleIntervalIndexScan(
- const Collection* collection,
+ const CollectionPtr& collection,
const std::string& indexName,
bool forward,
std::unique_ptr<KeyString::Value> lowKey,
@@ -673,7 +673,7 @@ std::pair<sbe::value::SlotId, std::unique_ptr<sbe::PlanStage>> generateSingleInt
std::pair<sbe::value::SlotId, std::unique_ptr<sbe::PlanStage>> generateIndexScan(
OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
const IndexScanNode* ixn,
boost::optional<sbe::value::SlotId> returnKeySlot,
sbe::value::SlotIdGenerator* slotIdGenerator,
diff --git a/src/mongo/db/query/sbe_stage_builder_index_scan.h b/src/mongo/db/query/sbe_stage_builder_index_scan.h
index beb1d983482..538e54dff77 100644
--- a/src/mongo/db/query/sbe_stage_builder_index_scan.h
+++ b/src/mongo/db/query/sbe_stage_builder_index_scan.h
@@ -40,7 +40,7 @@ namespace mongo::stage_builder {
*/
std::pair<sbe::value::SlotId, std::unique_ptr<sbe::PlanStage>> generateIndexScan(
OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
const IndexScanNode* ixn,
boost::optional<sbe::value::SlotId> returnKeySlot,
sbe::value::SlotIdGenerator* slotIdGenerator,
@@ -67,7 +67,7 @@ std::pair<sbe::value::SlotId, std::unique_ptr<sbe::PlanStage>> generateIndexScan
* in the index.
*/
std::pair<sbe::value::SlotId, std::unique_ptr<sbe::PlanStage>> generateSingleIntervalIndexScan(
- const Collection* collection,
+ const CollectionPtr& collection,
const std::string& indexName,
bool forward,
std::unique_ptr<KeyString::Value> lowKey,
diff --git a/src/mongo/db/query/sbe_sub_planner.h b/src/mongo/db/query/sbe_sub_planner.h
index 1bb465df0f4..5f708a2cd4d 100644
--- a/src/mongo/db/query/sbe_sub_planner.h
+++ b/src/mongo/db/query/sbe_sub_planner.h
@@ -43,7 +43,7 @@ namespace mongo::sbe {
class SubPlanner final : public BaseRuntimePlanner {
public:
SubPlanner(OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
const CanonicalQuery& cq,
const QueryPlannerParams& queryParams,
PlanYieldPolicySBE* yieldPolicy)
diff --git a/src/mongo/db/query/stage_builder.h b/src/mongo/db/query/stage_builder.h
index dbee0b6b8b6..7e20618cd83 100644
--- a/src/mongo/db/query/stage_builder.h
+++ b/src/mongo/db/query/stage_builder.h
@@ -41,7 +41,7 @@ template <typename PlanStageType>
class StageBuilder {
public:
StageBuilder(OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
const CanonicalQuery& cq,
const QuerySolution& solution)
: _opCtx(opCtx), _collection(collection), _cq(cq), _solution(solution) {}
@@ -56,7 +56,7 @@ public:
protected:
OperationContext* _opCtx;
- const Collection* _collection;
+ const CollectionPtr& _collection;
const CanonicalQuery& _cq;
const QuerySolution& _solution;
};
diff --git a/src/mongo/db/query/stage_builder_util.cpp b/src/mongo/db/query/stage_builder_util.cpp
index 9af708df67b..9b535c20b17 100644
--- a/src/mongo/db/query/stage_builder_util.cpp
+++ b/src/mongo/db/query/stage_builder_util.cpp
@@ -37,7 +37,7 @@
namespace mongo::stage_builder {
std::unique_ptr<PlanStage> buildClassicExecutableTree(OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
const CanonicalQuery& cq,
const QuerySolution& solution,
WorkingSet* ws) {
@@ -54,7 +54,7 @@ std::unique_ptr<PlanStage> buildClassicExecutableTree(OperationContext* opCtx,
std::pair<std::unique_ptr<sbe::PlanStage>, stage_builder::PlanStageData>
buildSlotBasedExecutableTree(OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
const CanonicalQuery& cq,
const QuerySolution& solution,
PlanYieldPolicy* yieldPolicy,
diff --git a/src/mongo/db/query/stage_builder_util.h b/src/mongo/db/query/stage_builder_util.h
index aa6c0abfad2..cd1f77594eb 100644
--- a/src/mongo/db/query/stage_builder_util.h
+++ b/src/mongo/db/query/stage_builder_util.h
@@ -45,14 +45,14 @@ namespace mongo::stage_builder {
* will consist of.
*/
std::unique_ptr<PlanStage> buildClassicExecutableTree(OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
const CanonicalQuery& cq,
const QuerySolution& solution,
WorkingSet* ws);
std::pair<std::unique_ptr<sbe::PlanStage>, stage_builder::PlanStageData>
buildSlotBasedExecutableTree(OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
const CanonicalQuery& cq,
const QuerySolution& solution,
PlanYieldPolicy* yieldPolicy,
diff --git a/src/mongo/db/rebuild_indexes.cpp b/src/mongo/db/rebuild_indexes.cpp
index ea35ad418b8..52962679162 100644
--- a/src/mongo/db/rebuild_indexes.cpp
+++ b/src/mongo/db/rebuild_indexes.cpp
@@ -92,7 +92,7 @@ StatusWith<IndexNameObjs> getIndexNameObjs(OperationContext* opCtx,
}
Status rebuildIndexesOnCollection(OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
const std::vector<BSONObj>& indexSpecs,
RepairData repair) {
// Skip the rest if there are no indexes to rebuild.
diff --git a/src/mongo/db/rebuild_indexes.h b/src/mongo/db/rebuild_indexes.h
index 20ef0e7aff6..ea6c0cc2a94 100644
--- a/src/mongo/db/rebuild_indexes.h
+++ b/src/mongo/db/rebuild_indexes.h
@@ -37,6 +37,7 @@
namespace mongo {
class Collection;
+class CollectionPtr;
class OperationContext;
typedef std::pair<std::vector<std::string>, std::vector<BSONObj>> IndexNameObjs;
@@ -61,7 +62,7 @@ StatusWith<IndexNameObjs> getIndexNameObjs(OperationContext* opCtx,
*/
enum class RepairData { kYes, kNo };
Status rebuildIndexesOnCollection(OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
const std::vector<BSONObj>& indexSpecs,
RepairData repair);
@@ -70,7 +71,7 @@ Status rebuildIndexesOnCollection(OperationContext* opCtx,
* One example usage is when a 'dropIndex' command is rolled back. The dropped index must be remade.
*/
Status rebuildIndexesOnCollection(OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
const std::vector<BSONObj>& indexSpecs);
} // namespace mongo
diff --git a/src/mongo/db/repair.cpp b/src/mongo/db/repair.cpp
index 950e0b8d9aa..44bba37e1a0 100644
--- a/src/mongo/db/repair.cpp
+++ b/src/mongo/db/repair.cpp
@@ -87,7 +87,7 @@ Status rebuildIndexesForNamespace(OperationContext* opCtx,
}
namespace {
-Status dropUnfinishedIndexes(OperationContext* opCtx, const Collection* collection) {
+Status dropUnfinishedIndexes(OperationContext* opCtx, const CollectionPtr& collection) {
std::vector<std::string> indexNames;
auto durableCatalog = DurableCatalog::get(opCtx);
durableCatalog->getAllIndexes(opCtx, collection->getCatalogId(), &indexNames);
diff --git a/src/mongo/db/repl/SConscript b/src/mongo/db/repl/SConscript
index de85cf9021e..bff884e7844 100644
--- a/src/mongo/db/repl/SConscript
+++ b/src/mongo/db/repl/SConscript
@@ -21,6 +21,7 @@ env.Library(
'local_oplog_info.cpp',
],
LIBDEPS_PRIVATE=[
+ '$BUILD_DIR/mongo/db/catalog/collection',
'$BUILD_DIR/mongo/db/logical_time',
'$BUILD_DIR/mongo/db/storage/flow_control',
'$BUILD_DIR/mongo/db/vector_clock_mutable',
diff --git a/src/mongo/db/repl/apply_ops.cpp b/src/mongo/db/repl/apply_ops.cpp
index d9c8565507f..8643f55ffff 100644
--- a/src/mongo/db/repl/apply_ops.cpp
+++ b/src/mongo/db/repl/apply_ops.cpp
@@ -315,7 +315,7 @@ Status _checkPrecondition(OperationContext* opCtx,
if (!database) {
return {ErrorCodes::NamespaceNotFound, "database in ns does not exist: " + nss.ns()};
}
- const Collection* collection =
+ CollectionPtr collection =
CollectionCatalog::get(opCtx).lookupCollectionByNamespace(opCtx, nss);
if (!collection) {
return {ErrorCodes::NamespaceNotFound, "collection in ns does not exist: " + nss.ns()};
diff --git a/src/mongo/db/repl/collection_bulk_loader.h b/src/mongo/db/repl/collection_bulk_loader.h
index e58e262a674..7fc018f6a6a 100644
--- a/src/mongo/db/repl/collection_bulk_loader.h
+++ b/src/mongo/db/repl/collection_bulk_loader.h
@@ -39,6 +39,7 @@
namespace mongo {
class Collection;
+class CollectionPtr;
class OperationContext;
namespace repl {
diff --git a/src/mongo/db/repl/dbcheck.cpp b/src/mongo/db/repl/dbcheck.cpp
index 7da0b9c64a9..34127bb5e95 100644
--- a/src/mongo/db/repl/dbcheck.cpp
+++ b/src/mongo/db/repl/dbcheck.cpp
@@ -172,7 +172,7 @@ std::unique_ptr<HealthLogEntry> dbCheckBatchEntry(const NamespaceString& nss,
}
DbCheckHasher::DbCheckHasher(OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
const BSONKey& start,
const BSONKey& end,
int64_t maxCount,
@@ -233,7 +233,7 @@ std::string hashCollectionInfo(const DbCheckCollectionInformation& info) {
}
std::pair<boost::optional<UUID>, boost::optional<UUID>> getPrevAndNextUUIDs(
- OperationContext* opCtx, const Collection* collection) {
+ OperationContext* opCtx, const CollectionPtr& collection) {
const CollectionCatalog& catalog = CollectionCatalog::get(opCtx);
const UUID uuid = collection->uuid();
@@ -350,7 +350,7 @@ bool DbCheckHasher::_canHash(const BSONObj& obj) {
return true;
}
-std::vector<BSONObj> collectionIndexInfo(OperationContext* opCtx, const Collection* collection) {
+std::vector<BSONObj> collectionIndexInfo(OperationContext* opCtx, const CollectionPtr& collection) {
std::vector<BSONObj> result;
std::vector<std::string> names;
@@ -370,7 +370,7 @@ std::vector<BSONObj> collectionIndexInfo(OperationContext* opCtx, const Collecti
return result;
}
-BSONObj collectionOptions(OperationContext* opCtx, const Collection* collection) {
+BSONObj collectionOptions(OperationContext* opCtx, const CollectionPtr& collection) {
return DurableCatalog::get(opCtx)
->getCollectionOptions(opCtx, collection->getCatalogId())
.toBSON();
@@ -407,8 +407,7 @@ namespace {
Status dbCheckBatchOnSecondary(OperationContext* opCtx,
const repl::OpTime& optime,
const DbCheckOplogBatch& entry) {
- AutoGetCollectionForDbCheck agc(opCtx, entry.getNss(), entry.getType());
- const Collection* collection = agc.getCollection();
+ AutoGetCollectionForDbCheck collection(opCtx, entry.getNss(), entry.getType());
std::string msg = "replication consistency check";
if (!collection) {
@@ -419,7 +418,7 @@ Status dbCheckBatchOnSecondary(OperationContext* opCtx,
Status status = Status::OK();
boost::optional<DbCheckHasher> hasher;
try {
- hasher.emplace(opCtx, collection, entry.getMinKey(), entry.getMaxKey());
+ hasher.emplace(opCtx, collection.getCollection(), entry.getMinKey(), entry.getMaxKey());
} catch (const DBException& exception) {
auto logEntry = dbCheckErrorHealthLogEntry(
entry.getNss(), msg, OplogEntriesEnum::Batch, exception.toStatus());
diff --git a/src/mongo/db/repl/dbcheck.h b/src/mongo/db/repl/dbcheck.h
index 99c28b4be59..2a5b2433cf8 100644
--- a/src/mongo/db/repl/dbcheck.h
+++ b/src/mongo/db/repl/dbcheck.h
@@ -41,6 +41,7 @@ namespace mongo {
// Forward declarations.
class Collection;
+class CollectionPtr;
class OperationContext;
namespace repl {
@@ -83,7 +84,7 @@ struct DbCheckCollectionInformation {
* previous or next UUID, return boost::none respectively.
*/
std::pair<boost::optional<UUID>, boost::optional<UUID>> getPrevAndNextUUIDs(
- OperationContext* opCtx, const Collection* collection);
+ OperationContext* opCtx, const CollectionPtr& collection);
/**
* Get a HealthLogEntry for a dbCheck collection.
@@ -118,7 +119,7 @@ public:
* @param maxBytes The maximum number of bytes to hash.
*/
DbCheckHasher(OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
const BSONKey& start,
const BSONKey& end,
int64_t maxCount = std::numeric_limits<int64_t>::max(),
@@ -191,26 +192,34 @@ public:
AutoGetCollectionForDbCheck(OperationContext* opCtx,
const NamespaceString& nss,
const OplogEntriesEnum& type);
- const Collection* getCollection(void) {
+ explicit operator bool() const {
+ return static_cast<bool>(getCollection());
+ }
+
+ const Collection* operator->() const {
+ return getCollection().get();
+ }
+
+ const CollectionPtr& getCollection() const {
return _collection;
}
private:
AutoGetDbForDbCheck _agd;
Lock::CollectionLock _collLock;
- const Collection* _collection;
+ CollectionPtr _collection;
};
/**
* Gather the index information for a collection.
*/
-std::vector<BSONObj> collectionIndexInfo(OperationContext* opCtx, const Collection* collection);
+std::vector<BSONObj> collectionIndexInfo(OperationContext* opCtx, const CollectionPtr& collection);
/**
* Gather other information for a collection.
*/
-BSONObj collectionOptions(OperationContext* opCtx, const Collection* collection);
+BSONObj collectionOptions(OperationContext* opCtx, const CollectionPtr& collection);
namespace repl {
diff --git a/src/mongo/db/repl/idempotency_test_fixture.cpp b/src/mongo/db/repl/idempotency_test_fixture.cpp
index ca996de2692..571b5abedfe 100644
--- a/src/mongo/db/repl/idempotency_test_fixture.cpp
+++ b/src/mongo/db/repl/idempotency_test_fixture.cpp
@@ -324,7 +324,7 @@ OplogEntry IdempotencyTest::partialTxn(LogicalSessionId lsid,
prevOpTime);
}
-std::string IdempotencyTest::computeDataHash(const Collection* collection) {
+std::string IdempotencyTest::computeDataHash(const CollectionPtr& collection) {
auto desc = collection->getIndexCatalog()->findIdIndex(_opCtx.get());
ASSERT_TRUE(desc);
auto exec = InternalPlanner::indexScan(_opCtx.get(),
@@ -375,7 +375,7 @@ std::vector<CollectionState> IdempotencyTest::validateAllCollections() {
CollectionState IdempotencyTest::validate(const NamespaceString& nss) {
auto collUUID = [&]() -> OptionalCollectionUUID {
AutoGetCollectionForReadCommand autoColl(_opCtx.get(), nss);
- if (auto collection = autoColl.getCollection()) {
+ if (const auto& collection = autoColl.getCollection()) {
return collection->uuid();
}
return boost::none;
@@ -388,8 +388,7 @@ CollectionState IdempotencyTest::validate(const NamespaceString& nss) {
}
{
- AutoGetCollectionForReadCommand autoColl(_opCtx.get(), nss);
- auto collection = autoColl.getCollection();
+ AutoGetCollectionForReadCommand collection(_opCtx.get(), nss);
if (!collection) {
// Return a mostly default initialized CollectionState struct with exists set to false
@@ -412,10 +411,9 @@ CollectionState IdempotencyTest::validate(const NamespaceString& nss) {
ASSERT_TRUE(validateResults.valid);
}
- AutoGetCollectionForReadCommand autoColl(_opCtx.get(), nss);
- auto collection = autoColl.getCollection();
+ AutoGetCollectionForReadCommand collection(_opCtx.get(), nss);
- std::string dataHash = computeDataHash(collection);
+ std::string dataHash = computeDataHash(collection.getCollection());
auto durableCatalog = DurableCatalog::get(_opCtx.get());
auto collectionOptions =
diff --git a/src/mongo/db/repl/idempotency_test_fixture.h b/src/mongo/db/repl/idempotency_test_fixture.h
index e871517e9f5..654e9c87ddd 100644
--- a/src/mongo/db/repl/idempotency_test_fixture.h
+++ b/src/mongo/db/repl/idempotency_test_fixture.h
@@ -49,6 +49,7 @@
namespace mongo {
class Collection;
+class CollectionPtr;
namespace repl {
@@ -151,7 +152,7 @@ protected:
return obj;
};
- std::string computeDataHash(const Collection* collection);
+ std::string computeDataHash(const CollectionPtr& collection);
virtual std::string getStatesString(const std::vector<CollectionState>& state1,
const std::vector<CollectionState>& state2,
const std::vector<OplogEntry>& ops);
diff --git a/src/mongo/db/repl/local_oplog_info.cpp b/src/mongo/db/repl/local_oplog_info.cpp
index 01f48ac47b5..e73199c00db 100644
--- a/src/mongo/db/repl/local_oplog_info.cpp
+++ b/src/mongo/db/repl/local_oplog_info.cpp
@@ -81,16 +81,16 @@ void LocalOplogInfo::setOplogCollectionName(ServiceContext* service) {
}
}
-const Collection* LocalOplogInfo::getCollection() const {
+const CollectionPtr& LocalOplogInfo::getCollection() const {
return _oplog;
}
-void LocalOplogInfo::setCollection(const Collection* oplog) {
- _oplog = oplog;
+void LocalOplogInfo::setCollection(const CollectionPtr& oplog) {
+ _oplog = oplog.detached();
}
void LocalOplogInfo::resetCollection() {
- _oplog = nullptr;
+ _oplog = CollectionPtr();
}
void LocalOplogInfo::setNewTimestamp(ServiceContext* service, const Timestamp& newTime) {
diff --git a/src/mongo/db/repl/local_oplog_info.h b/src/mongo/db/repl/local_oplog_info.h
index 417901e4f4f..880e6bb6b0e 100644
--- a/src/mongo/db/repl/local_oplog_info.h
+++ b/src/mongo/db/repl/local_oplog_info.h
@@ -66,8 +66,8 @@ public:
*/
void setOplogCollectionName(ServiceContext* service);
- const Collection* getCollection() const;
- void setCollection(const Collection* oplog);
+ const CollectionPtr& getCollection() const;
+ void setCollection(const CollectionPtr& oplog);
void resetCollection();
/**
@@ -88,7 +88,7 @@ private:
// The "oplog" pointer is always valid (or null) because an operation must take the global
// exclusive lock to set the pointer to null when the Collection instance is destroyed. See
// "oplogCheckCloseDatabase".
- const Collection* _oplog = nullptr;
+ CollectionPtr _oplog;
// Synchronizes the section where a new Timestamp is generated and when it is registered in the
// storage engine.
diff --git a/src/mongo/db/repl/mock_repl_coord_server_fixture.cpp b/src/mongo/db/repl/mock_repl_coord_server_fixture.cpp
index 09d79862c07..e6f426933e4 100644
--- a/src/mongo/db/repl/mock_repl_coord_server_fixture.cpp
+++ b/src/mongo/db/repl/mock_repl_coord_server_fixture.cpp
@@ -94,9 +94,8 @@ void MockReplCoordServerFixture::setUp() {
}
void MockReplCoordServerFixture::insertOplogEntry(const repl::OplogEntry& entry) {
- AutoGetCollection autoColl(opCtx(), NamespaceString::kRsOplogNamespace, MODE_IX);
- auto coll = autoColl.getCollection();
- ASSERT_TRUE(coll != nullptr);
+ AutoGetCollection coll(opCtx(), NamespaceString::kRsOplogNamespace, MODE_IX);
+ ASSERT_TRUE(coll);
WriteUnitOfWork wuow(opCtx());
auto status = coll->insertDocument(opCtx(),
diff --git a/src/mongo/db/repl/oplog.cpp b/src/mongo/db/repl/oplog.cpp
index 8b0626fa926..23c148b7f75 100644
--- a/src/mongo/db/repl/oplog.cpp
+++ b/src/mongo/db/repl/oplog.cpp
@@ -213,7 +213,7 @@ void _logOpsInner(OperationContext* opCtx,
const NamespaceString& nss,
std::vector<Record>* records,
const std::vector<Timestamp>& timestamps,
- const Collection* oplogCollection,
+ const CollectionPtr& oplogCollection,
OpTime finalOpTime,
Date_t wallTime) {
auto replCoord = ReplicationCoordinator::get(opCtx);
@@ -333,7 +333,7 @@ OpTime logOp(OperationContext* opCtx, MutableOplogEntry* oplogEntry) {
oplogEntry->setOpTime(slot);
}
- auto oplog = oplogInfo->getCollection();
+ const auto& oplog = oplogInfo->getCollection();
auto wallClockTime = oplogEntry->getWallClockTime();
auto bsonOplogEntry = oplogEntry->toBSON();
@@ -425,7 +425,7 @@ std::vector<OpTime> logInsertOps(OperationContext* opCtx,
invariant(!opTimes.empty());
auto lastOpTime = opTimes.back();
invariant(!lastOpTime.isNull());
- auto oplog = oplogInfo->getCollection();
+ const auto& oplog = oplogInfo->getCollection();
auto wallClockTime = oplogEntryTemplate->getWallClockTime();
_logOpsInner(opCtx, nss, &records, timestamps, oplog, lastOpTime, wallClockTime);
wuow.commit();
@@ -536,7 +536,7 @@ void createOplog(OperationContext* opCtx,
const ReplSettings& replSettings = ReplicationCoordinator::get(opCtx)->getSettings();
OldClientContext ctx(opCtx, oplogCollectionName.ns());
- const Collection* collection =
+ CollectionPtr collection =
CollectionCatalog::get(opCtx).lookupCollectionByNamespace(opCtx, oplogCollectionName);
if (collection) {
@@ -981,7 +981,7 @@ Status applyOperation_inlock(OperationContext* opCtx,
}
NamespaceString requestNss;
- const Collection* collection = nullptr;
+ CollectionPtr collection = nullptr;
if (auto uuid = op.getUuid()) {
CollectionCatalog& catalog = CollectionCatalog::get(opCtx);
collection = catalog.lookupCollectionByUUID(opCtx, uuid.get());
@@ -1728,14 +1728,14 @@ void acquireOplogCollectionForLogging(OperationContext* opCtx) {
}
}
-void establishOplogCollectionForLogging(OperationContext* opCtx, const Collection* oplog) {
+void establishOplogCollectionForLogging(OperationContext* opCtx, const CollectionPtr& oplog) {
invariant(opCtx->lockState()->isW());
invariant(oplog);
LocalOplogInfo::get(opCtx)->setCollection(oplog);
}
void signalOplogWaiters() {
- auto oplog = LocalOplogInfo::get(getGlobalServiceContext())->getCollection();
+ const auto& oplog = LocalOplogInfo::get(getGlobalServiceContext())->getCollection();
if (oplog) {
oplog->getCappedCallback()->notifyCappedWaitersIfNeeded();
}
diff --git a/src/mongo/db/repl/oplog.h b/src/mongo/db/repl/oplog.h
index 17781db4df3..74e607d477e 100644
--- a/src/mongo/db/repl/oplog.h
+++ b/src/mongo/db/repl/oplog.h
@@ -45,6 +45,7 @@
namespace mongo {
class Collection;
+class CollectionPtr;
class Database;
class NamespaceString;
class OperationContext;
@@ -148,7 +149,7 @@ void acquireOplogCollectionForLogging(OperationContext* opCtx);
* Called by catalog::openCatalog() to re-establish the oplog collection pointer while holding onto
* the global lock in exclusive mode.
*/
-void establishOplogCollectionForLogging(OperationContext* opCtx, const Collection* oplog);
+void establishOplogCollectionForLogging(OperationContext* opCtx, const CollectionPtr& oplog);
using IncrementOpsAppliedStatsFn = std::function<void()>;
diff --git a/src/mongo/db/repl/oplog_applier_impl_test.cpp b/src/mongo/db/repl/oplog_applier_impl_test.cpp
index 9862126d7e2..f56011c0105 100644
--- a/src/mongo/db/repl/oplog_applier_impl_test.cpp
+++ b/src/mongo/db/repl/oplog_applier_impl_test.cpp
@@ -349,7 +349,7 @@ TEST_F(OplogApplierImplTest, applyOplogEntryOrGroupedInsertsCommand) {
<< BSON("create" << nss.coll()) << "ts" << Timestamp(1, 1) << "ui" << UUID::gen());
bool applyCmdCalled = false;
_opObserver->onCreateCollectionFn = [&](OperationContext* opCtx,
- const Collection*,
+ const CollectionPtr&,
const NamespaceString& collNss,
const CollectionOptions&,
const BSONObj&) {
diff --git a/src/mongo/db/repl/oplog_applier_impl_test_fixture.cpp b/src/mongo/db/repl/oplog_applier_impl_test_fixture.cpp
index d75b6469b4a..72f996976c2 100644
--- a/src/mongo/db/repl/oplog_applier_impl_test_fixture.cpp
+++ b/src/mongo/db/repl/oplog_applier_impl_test_fixture.cpp
@@ -89,7 +89,7 @@ void OplogApplierImplOpObserver::onUpdate(OperationContext* opCtx,
}
void OplogApplierImplOpObserver::onCreateCollection(OperationContext* opCtx,
- const Collection* coll,
+ const CollectionPtr& coll,
const NamespaceString& collectionName,
const CollectionOptions& options,
const BSONObj& idIndex,
diff --git a/src/mongo/db/repl/oplog_applier_impl_test_fixture.h b/src/mongo/db/repl/oplog_applier_impl_test_fixture.h
index 1a6c414d182..28fec503692 100644
--- a/src/mongo/db/repl/oplog_applier_impl_test_fixture.h
+++ b/src/mongo/db/repl/oplog_applier_impl_test_fixture.h
@@ -99,7 +99,7 @@ public:
* Called when OplogApplierImpl creates a collection.
*/
void onCreateCollection(OperationContext* opCtx,
- const Collection* coll,
+ const CollectionPtr& coll,
const NamespaceString& collectionName,
const CollectionOptions& options,
const BSONObj& idIndex,
@@ -121,7 +121,7 @@ public:
std::function<void(OperationContext*, const OplogUpdateEntryArgs&)> onUpdateFn;
std::function<void(OperationContext*,
- const Collection*,
+ const CollectionPtr&,
const NamespaceString&,
const CollectionOptions&,
const BSONObj&)>
diff --git a/src/mongo/db/repl/primary_only_service_op_observer.h b/src/mongo/db/repl/primary_only_service_op_observer.h
index 7b176eb663e..f0314ab9231 100644
--- a/src/mongo/db/repl/primary_only_service_op_observer.h
+++ b/src/mongo/db/repl/primary_only_service_op_observer.h
@@ -108,7 +108,7 @@ public:
const boost::optional<OplogSlot> slot) final {}
void onCreateCollection(OperationContext* opCtx,
- const Collection* coll,
+ const CollectionPtr& coll,
const NamespaceString& collectionName,
const CollectionOptions& options,
const BSONObj& idIndex,
diff --git a/src/mongo/db/repl/replication_coordinator_external_state_impl.cpp b/src/mongo/db/repl/replication_coordinator_external_state_impl.cpp
index 8e2badd998f..8daa5f92aba 100644
--- a/src/mongo/db/repl/replication_coordinator_external_state_impl.cpp
+++ b/src/mongo/db/repl/replication_coordinator_external_state_impl.cpp
@@ -715,8 +715,7 @@ Timestamp ReplicationCoordinatorExternalStateImpl::getGlobalTimestamp(ServiceCon
}
bool ReplicationCoordinatorExternalStateImpl::oplogExists(OperationContext* opCtx) {
- auto oplog = LocalOplogInfo::get(opCtx)->getCollection();
- return oplog != nullptr;
+ return static_cast<bool>(LocalOplogInfo::get(opCtx)->getCollection());
}
StatusWith<OpTimeAndWallTime> ReplicationCoordinatorExternalStateImpl::loadLastOpTimeAndWallTime(
diff --git a/src/mongo/db/repl/replication_coordinator_impl.cpp b/src/mongo/db/repl/replication_coordinator_impl.cpp
index a5f5d199b2d..766d69ffbc2 100644
--- a/src/mongo/db/repl/replication_coordinator_impl.cpp
+++ b/src/mongo/db/repl/replication_coordinator_impl.cpp
@@ -2303,7 +2303,7 @@ StatusWith<OpTime> ReplicationCoordinatorImpl::getLatestWriteOpTime(OperationCon
if (!canAcceptNonLocalWrites()) {
return {ErrorCodes::NotWritablePrimary, "Not primary so can't get latest write optime"};
}
- auto oplog = LocalOplogInfo::get(opCtx)->getCollection();
+ const auto& oplog = LocalOplogInfo::get(opCtx)->getCollection();
if (!oplog) {
return {ErrorCodes::NamespaceNotFound, "oplog collection does not exist"};
}
@@ -2836,7 +2836,7 @@ bool ReplicationCoordinatorImpl::canAcceptWritesFor_UNSAFE(OperationContext* opC
if (!ns->isOplog()) {
return true;
}
- } else if (auto oplogCollection = LocalOplogInfo::get(opCtx)->getCollection()) {
+ } else if (const auto& oplogCollection = LocalOplogInfo::get(opCtx)->getCollection()) {
auto uuid = nsOrUUID.uuid();
invariant(uuid, nsOrUUID.toString());
if (oplogCollection->uuid() != *uuid) {
diff --git a/src/mongo/db/repl/rollback_impl.cpp b/src/mongo/db/repl/rollback_impl.cpp
index 365410970ad..a696a57966b 100644
--- a/src/mongo/db/repl/rollback_impl.cpp
+++ b/src/mongo/db/repl/rollback_impl.cpp
@@ -603,12 +603,12 @@ void RollbackImpl::_correctRecordStoreCounts(OperationContext* opCtx) {
"Scanning collection to fix collection count",
"namespace"_attr = nss.ns(),
"uuid"_attr = uuid.toString());
- AutoGetCollectionForRead autoCollToScan(opCtx, nss);
- auto collToScan = autoCollToScan.getCollection();
- invariant(coll == collToScan,
+ AutoGetCollectionForRead collToScan(opCtx, nss);
+ invariant(coll == collToScan.getCollection(),
str::stream() << "Catalog returned invalid collection: " << nss.ns() << " ("
<< uuid.toString() << ")");
auto exec = collToScan->makePlanExecutor(opCtx,
+ collToScan.getCollection(),
PlanYieldPolicy::YieldPolicy::INTERRUPT_ONLY,
Collection::ScanDirection::kForward);
long long countFromScan = 0;
diff --git a/src/mongo/db/repl/rollback_test_fixture.cpp b/src/mongo/db/repl/rollback_test_fixture.cpp
index 862ba41e289..91a995fc466 100644
--- a/src/mongo/db/repl/rollback_test_fixture.cpp
+++ b/src/mongo/db/repl/rollback_test_fixture.cpp
@@ -233,17 +233,20 @@ void RollbackTest::_insertDocument(OperationContext* opCtx,
const NamespaceString& nss,
const BSONObj& doc) {
- AutoGetCollection autoColl(opCtx, nss, MODE_X);
- auto collection = autoColl.getCollection();
- if (!collection) {
+ auto insertDoc = [opCtx, &doc](const CollectionPtr& collection) {
+ WriteUnitOfWork wuow(opCtx);
+ OpDebug* const opDebug = nullptr;
+ ASSERT_OK(collection->insertDocument(opCtx, InsertStatement(doc), opDebug));
+ wuow.commit();
+ };
+ AutoGetCollection collection(opCtx, nss, MODE_X);
+ if (collection) {
+ insertDoc(collection.getCollection());
+ } else {
CollectionOptions options;
options.uuid = UUID::gen();
- collection = _createCollection(opCtx, nss, options);
+ insertDoc(_createCollection(opCtx, nss, options));
}
- WriteUnitOfWork wuow(opCtx);
- OpDebug* const opDebug = nullptr;
- ASSERT_OK(collection->insertDocument(opCtx, InsertStatement(doc), opDebug));
- wuow.commit();
}
Status RollbackTest::_insertOplogEntry(const BSONObj& doc) {
diff --git a/src/mongo/db/repl/rs_rollback.cpp b/src/mongo/db/repl/rs_rollback.cpp
index fa6b07c6696..0689bab6384 100644
--- a/src/mongo/db/repl/rs_rollback.cpp
+++ b/src/mongo/db/repl/rs_rollback.cpp
@@ -971,7 +971,7 @@ void rollbackDropIndexes(OperationContext* opCtx,
invariant(nss);
Lock::DBLock dbLock(opCtx, nss->db(), MODE_IX);
Lock::CollectionLock collLock(opCtx, *nss, MODE_X);
- const Collection* collection =
+ CollectionPtr collection =
CollectionCatalog::get(opCtx).lookupCollectionByNamespace(opCtx, *nss);
// If we cannot find the collection, we skip over dropping the index.
@@ -1016,7 +1016,7 @@ void rollbackDropIndexes(OperationContext* opCtx,
*/
void dropCollection(OperationContext* opCtx,
NamespaceString nss,
- const Collection* collection,
+ const CollectionPtr& collection,
Database* db) {
if (RollbackImpl::shouldCreateDataFiles()) {
RemoveSaver removeSaver("rollback", "", collection->uuid().toString());
@@ -1499,7 +1499,7 @@ void rollback_internal::syncFixUp(OperationContext* opCtx,
Database* db = dbLock.getDb();
if (db) {
- const Collection* collection =
+ CollectionPtr collection =
CollectionCatalog::get(opCtx).lookupCollectionByUUID(opCtx, uuid);
dropCollection(opCtx, *nss, collection, db);
LOGV2_DEBUG(21698,
diff --git a/src/mongo/db/repl/rs_rollback_test.cpp b/src/mongo/db/repl/rs_rollback_test.cpp
index b785eadeaa5..d7a14c13a35 100644
--- a/src/mongo/db/repl/rs_rollback_test.cpp
+++ b/src/mongo/db/repl/rs_rollback_test.cpp
@@ -79,7 +79,7 @@ OplogInterfaceMock::Operation makeNoopOplogEntryAndRecordId(Seconds seconds) {
return std::make_pair(BSON("ts" << ts.getTimestamp()), RecordId(1));
}
-OplogInterfaceMock::Operation makeDropIndexOplogEntry(const Collection* collection,
+OplogInterfaceMock::Operation makeDropIndexOplogEntry(const CollectionPtr& collection,
BSONObj key,
std::string indexName,
int time) {
@@ -96,7 +96,7 @@ OplogInterfaceMock::Operation makeDropIndexOplogEntry(const Collection* collecti
RecordId(time));
}
-OplogInterfaceMock::Operation makeStartIndexBuildOplogEntry(const Collection* collection,
+OplogInterfaceMock::Operation makeStartIndexBuildOplogEntry(const CollectionPtr& collection,
UUID buildUUID,
BSONObj spec,
int time) {
@@ -112,7 +112,7 @@ OplogInterfaceMock::Operation makeStartIndexBuildOplogEntry(const Collection* co
RecordId(time));
}
-OplogInterfaceMock::Operation makeCommitIndexBuildOplogEntry(const Collection* collection,
+OplogInterfaceMock::Operation makeCommitIndexBuildOplogEntry(const CollectionPtr& collection,
UUID buildUUID,
BSONObj spec,
int time) {
@@ -128,7 +128,7 @@ OplogInterfaceMock::Operation makeCommitIndexBuildOplogEntry(const Collection* c
RecordId(time));
}
-OplogInterfaceMock::Operation makeAbortIndexBuildOplogEntry(const Collection* collection,
+OplogInterfaceMock::Operation makeAbortIndexBuildOplogEntry(const CollectionPtr& collection,
UUID buildUUID,
BSONObj spec,
int time) {
@@ -150,7 +150,7 @@ OplogInterfaceMock::Operation makeAbortIndexBuildOplogEntry(const Collection* co
RecordId(time));
}
-OplogInterfaceMock::Operation makeCreateIndexOplogEntry(const Collection* collection,
+OplogInterfaceMock::Operation makeCreateIndexOplogEntry(const CollectionPtr& collection,
BSONObj key,
std::string indexName,
int time) {
@@ -847,14 +847,14 @@ BSONObj idxSpec(NamespaceString nss, std::string id) {
}
// Returns the number of indexes that exist on the given collection.
-int numIndexesOnColl(OperationContext* opCtx, NamespaceString nss, const Collection* coll) {
+int numIndexesOnColl(OperationContext* opCtx, NamespaceString nss, const CollectionPtr& coll) {
Lock::DBLock dbLock(opCtx, nss.db(), MODE_X);
auto indexCatalog = coll->getIndexCatalog();
ASSERT(indexCatalog);
return indexCatalog->numIndexesReady(opCtx);
}
-int numIndexesInProgress(OperationContext* opCtx, NamespaceString nss, const Collection* coll) {
+int numIndexesInProgress(OperationContext* opCtx, NamespaceString nss, const CollectionPtr& coll) {
Lock::DBLock dbLock(opCtx, nss.db(), MODE_X);
auto indexCatalog = coll->getIndexCatalog();
ASSERT(indexCatalog);
@@ -1738,7 +1738,7 @@ OpTime getOpTimeFromOplogEntry(const BSONObj& entry) {
TEST_F(RSRollbackTest, RollbackApplyOpsCommand) {
createOplog(_opCtx.get());
- const Collection* coll = nullptr;
+ CollectionPtr coll;
CollectionOptions options;
options.uuid = UUID::gen();
{
diff --git a/src/mongo/db/repl/storage_interface.h b/src/mongo/db/repl/storage_interface.h
index ef8af4ac2c1..098df44021d 100644
--- a/src/mongo/db/repl/storage_interface.h
+++ b/src/mongo/db/repl/storage_interface.h
@@ -47,6 +47,7 @@
namespace mongo {
class Collection;
+class CollectionPtr;
struct CollectionOptions;
class OperationContext;
@@ -326,7 +327,7 @@ public:
* matches are found.
*/
virtual boost::optional<BSONObj> findOplogEntryLessThanOrEqualToTimestamp(
- OperationContext* opCtx, const Collection* oplog, const Timestamp& timestamp) = 0;
+ OperationContext* opCtx, const CollectionPtr& oplog, const Timestamp& timestamp) = 0;
/**
* Calls findOplogEntryLessThanOrEqualToTimestamp with endless WriteConflictException retries.
@@ -337,7 +338,7 @@ public:
* fail, say for correctness.
*/
virtual boost::optional<BSONObj> findOplogEntryLessThanOrEqualToTimestampRetryOnWCE(
- OperationContext* opCtx, const Collection* oplog, const Timestamp& timestamp) = 0;
+ OperationContext* opCtx, const CollectionPtr& oplog, const Timestamp& timestamp) = 0;
/**
* Fetches the latest oplog entry's timestamp. Bypasses the oplog visibility rules.
diff --git a/src/mongo/db/repl/storage_interface_impl.cpp b/src/mongo/db/repl/storage_interface_impl.cpp
index f9b6945b259..926cc60efcb 100644
--- a/src/mongo/db/repl/storage_interface_impl.cpp
+++ b/src/mongo/db/repl/storage_interface_impl.cpp
@@ -299,28 +299,27 @@ Status StorageInterfaceImpl::insertDocument(OperationContext* opCtx,
namespace {
/**
- * Returns const Collection* from database RAII object.
+ * Returns const CollectionPtr& from database RAII object.
* Returns NamespaceNotFound if the database or collection does not exist.
*/
template <typename AutoGetCollectionType>
-StatusWith<decltype(std::declval<AutoGetCollectionType>().getCollection())> getCollection(
- const AutoGetCollectionType& autoGetCollection,
- const NamespaceStringOrUUID& nsOrUUID,
- const std::string& message) {
+StatusWith<const CollectionPtr*> getCollection(const AutoGetCollectionType& autoGetCollection,
+ const NamespaceStringOrUUID& nsOrUUID,
+ const std::string& message) {
if (!autoGetCollection.getDb()) {
StringData dbName = nsOrUUID.nss() ? nsOrUUID.nss()->db() : nsOrUUID.dbname();
return {ErrorCodes::NamespaceNotFound,
str::stream() << "Database [" << dbName << "] not found. " << message};
}
- auto collection = autoGetCollection.getCollection();
+ const auto& collection = autoGetCollection.getCollection();
if (!collection) {
return {ErrorCodes::NamespaceNotFound,
str::stream() << "Collection [" << nsOrUUID.toString() << "] not found. "
<< message};
}
- return collection;
+ return &collection;
}
Status insertDocumentsSingleBatch(OperationContext* opCtx,
@@ -329,14 +328,14 @@ Status insertDocumentsSingleBatch(OperationContext* opCtx,
std::vector<InsertStatement>::const_iterator end) {
boost::optional<AutoGetCollection> autoColl;
boost::optional<AutoGetOplog> autoOplog;
- const Collection* collection;
+ const CollectionPtr* collection;
auto nss = nsOrUUID.nss();
if (nss && nss->isOplog()) {
// Simplify locking rules for oplog collection.
autoOplog.emplace(opCtx, OplogAccessMode::kWrite);
- collection = autoOplog->getCollection();
- if (!collection) {
+ collection = &autoOplog->getCollection();
+ if (!*collection) {
return {ErrorCodes::NamespaceNotFound, "Oplog collection does not exist"};
}
} else {
@@ -351,7 +350,7 @@ Status insertDocumentsSingleBatch(OperationContext* opCtx,
WriteUnitOfWork wunit(opCtx);
OpDebug* const nullOpDebug = nullptr;
- auto status = collection->insertDocuments(opCtx, begin, end, nullOpDebug, false);
+ auto status = (*collection)->insertDocuments(opCtx, begin, end, nullOpDebug, false);
if (!status.isOK()) {
return status;
}
@@ -454,7 +453,7 @@ StatusWith<size_t> StorageInterfaceImpl::getOplogMaxSize(OperationContext* opCtx
NamespaceString::kRsOplogNamespace.ns(),
[&]() -> StatusWith<size_t> {
AutoGetOplog oplogRead(opCtx, OplogAccessMode::kRead);
- auto oplog = oplogRead.getCollection();
+ const auto& oplog = oplogRead.getCollection();
if (!oplog) {
return {ErrorCodes::NamespaceNotFound, "Your oplog doesn't exist."};
}
@@ -602,7 +601,7 @@ Status StorageInterfaceImpl::setIndexIsMultikey(OperationContext* opCtx,
if (!collectionResult.isOK()) {
return collectionResult.getStatus();
}
- auto collection = collectionResult.getValue();
+ const auto& collection = *collectionResult.getValue();
WriteUnitOfWork wunit(opCtx);
auto tsResult = opCtx->recoveryUnit()->setTimestamp(ts);
@@ -667,7 +666,7 @@ StatusWith<std::vector<BSONObj>> _findOrDeleteDocuments(
if (!collectionResult.isOK()) {
return Result(collectionResult.getStatus());
}
- auto collection = collectionResult.getValue();
+ const auto& collection = *collectionResult.getValue();
auto isForward = scanDirection == StorageInterface::ScanDirection::kForward;
auto direction = isForward ? InternalPlanner::FORWARD : InternalPlanner::BACKWARD;
@@ -922,7 +921,7 @@ Status _updateWithQuery(OperationContext* opCtx,
if (!collectionResult.isOK()) {
return collectionResult.getStatus();
}
- auto collection = collectionResult.getValue();
+ const auto& collection = *collectionResult.getValue();
WriteUnitOfWork wuow(opCtx);
if (!ts.isNull()) {
uassertStatusOK(opCtx->recoveryUnit()->setTimestamp(ts));
@@ -970,7 +969,7 @@ Status StorageInterfaceImpl::upsertById(OperationContext* opCtx,
if (!collectionResult.isOK()) {
return collectionResult.getStatus();
}
- auto collection = collectionResult.getValue();
+ const auto& collection = *collectionResult.getValue();
// We can create an UpdateRequest now that the collection's namespace has been resolved, in
// the event it was specified as a UUID.
@@ -1080,7 +1079,7 @@ Status StorageInterfaceImpl::deleteByFilter(OperationContext* opCtx,
if (!collectionResult.isOK()) {
return collectionResult.getStatus();
}
- auto collection = collectionResult.getValue();
+ const auto& collection = *collectionResult.getValue();
auto planExecutorResult = mongo::getExecutorDelete(
nullptr, collection, &parsedDelete, boost::none /* verbosity */);
@@ -1103,7 +1102,7 @@ Status StorageInterfaceImpl::deleteByFilter(OperationContext* opCtx,
}
boost::optional<BSONObj> StorageInterfaceImpl::findOplogEntryLessThanOrEqualToTimestamp(
- OperationContext* opCtx, const Collection* oplog, const Timestamp& timestamp) {
+ OperationContext* opCtx, const CollectionPtr& oplog, const Timestamp& timestamp) {
invariant(oplog);
invariant(opCtx->lockState()->isLocked());
@@ -1134,7 +1133,7 @@ boost::optional<BSONObj> StorageInterfaceImpl::findOplogEntryLessThanOrEqualToTi
}
boost::optional<BSONObj> StorageInterfaceImpl::findOplogEntryLessThanOrEqualToTimestampRetryOnWCE(
- OperationContext* opCtx, const Collection* oplogCollection, const Timestamp& timestamp) {
+ OperationContext* opCtx, const CollectionPtr& oplogCollection, const Timestamp& timestamp) {
// Oplog reads are specially done under only MODE_IS global locks, without database or
// collection level intent locks. Therefore, reads can run concurrently with validate cmds that
// take collection MODE_X locks. Validate with {full:true} set calls WT::verify on the
@@ -1209,7 +1208,7 @@ StatusWith<StorageInterface::CollectionSize> StorageInterfaceImpl::getCollection
if (!collectionResult.isOK()) {
return collectionResult.getStatus();
}
- auto collection = collectionResult.getValue();
+ const auto& collection = *collectionResult.getValue();
return collection->dataSize(opCtx);
}
@@ -1223,7 +1222,7 @@ StatusWith<StorageInterface::CollectionCount> StorageInterfaceImpl::getCollectio
if (!collectionResult.isOK()) {
return collectionResult.getStatus();
}
- auto collection = collectionResult.getValue();
+ const auto& collection = *collectionResult.getValue();
return collection->numRecords(opCtx);
}
@@ -1238,7 +1237,7 @@ Status StorageInterfaceImpl::setCollectionCount(OperationContext* opCtx,
if (!collectionResult.isOK()) {
return collectionResult.getStatus();
}
- auto collection = collectionResult.getValue();
+ const auto& collection = *collectionResult.getValue();
auto rs = collection->getRecordStore();
// We cannot fix the data size correctly, so we just get the current cached value and keep it
@@ -1257,7 +1256,7 @@ StatusWith<OptionalCollectionUUID> StorageInterfaceImpl::getCollectionUUID(
if (!collectionResult.isOK()) {
return collectionResult.getStatus();
}
- auto collection = collectionResult.getValue();
+ const auto& collection = *collectionResult.getValue();
return collection->uuid();
}
@@ -1340,12 +1339,11 @@ Status StorageInterfaceImpl::isAdminDbValid(OperationContext* opCtx) {
return Status::OK();
}
- const Collection* const usersCollection =
- CollectionCatalog::get(opCtx).lookupCollectionByNamespace(
- opCtx, AuthorizationManager::usersCollectionNamespace);
+ CollectionPtr usersCollection = CollectionCatalog::get(opCtx).lookupCollectionByNamespace(
+ opCtx, AuthorizationManager::usersCollectionNamespace);
const bool hasUsers =
usersCollection && !Helpers::findOne(opCtx, usersCollection, BSONObj(), false).isNull();
- const Collection* const adminVersionCollection =
+ CollectionPtr adminVersionCollection =
CollectionCatalog::get(opCtx).lookupCollectionByNamespace(
opCtx, AuthorizationManager::versionCollectionNamespace);
BSONObj authSchemaVersionDocument;
@@ -1398,7 +1396,7 @@ void StorageInterfaceImpl::waitForAllEarlierOplogWritesToBeVisible(OperationCont
if (primaryOnly &&
!repl::ReplicationCoordinator::get(opCtx)->canAcceptWritesForDatabase(opCtx, "admin"))
return;
- auto oplog = oplogRead.getCollection();
+ const auto& oplog = oplogRead.getCollection();
uassert(ErrorCodes::NotYetInitialized, "The oplog does not exist", oplog);
oplog->getRecordStore()->waitForAllEarlierOplogWritesToBeVisible(opCtx);
}
diff --git a/src/mongo/db/repl/storage_interface_impl.h b/src/mongo/db/repl/storage_interface_impl.h
index 2cddfaa4719..0e13614d443 100644
--- a/src/mongo/db/repl/storage_interface_impl.h
+++ b/src/mongo/db/repl/storage_interface_impl.h
@@ -148,10 +148,10 @@ public:
const BSONObj& filter) override;
boost::optional<BSONObj> findOplogEntryLessThanOrEqualToTimestamp(
- OperationContext* opCtx, const Collection* oplog, const Timestamp& timestamp) override;
+ OperationContext* opCtx, const CollectionPtr& oplog, const Timestamp& timestamp) override;
boost::optional<BSONObj> findOplogEntryLessThanOrEqualToTimestampRetryOnWCE(
- OperationContext* opCtx, const Collection* oplog, const Timestamp& timestamp) override;
+ OperationContext* opCtx, const CollectionPtr& oplog, const Timestamp& timestamp) override;
Timestamp getLatestOplogTimestamp(OperationContext* opCtx) override;
diff --git a/src/mongo/db/repl/storage_interface_impl_test.cpp b/src/mongo/db/repl/storage_interface_impl_test.cpp
index 3efd6bf1bcb..e78f89427ab 100644
--- a/src/mongo/db/repl/storage_interface_impl_test.cpp
+++ b/src/mongo/db/repl/storage_interface_impl_test.cpp
@@ -573,8 +573,7 @@ TEST_F(StorageInterfaceImplTest, CreateCollectionWithIDIndexCommits) {
ASSERT_OK(loader->insertDocuments(docs.begin(), docs.end()));
ASSERT_OK(loader->commit());
- AutoGetCollectionForReadCommand autoColl(opCtx, nss);
- auto coll = autoColl.getCollection();
+ AutoGetCollectionForReadCommand coll(opCtx, nss);
ASSERT(coll);
ASSERT_EQ(coll->getRecordStore()->numRecords(opCtx), 2LL);
auto collIdxCat = coll->getIndexCatalog();
@@ -601,8 +600,7 @@ void _testDestroyUncommitedCollectionBulkLoader(
// Collection and ID index should not exist after 'loader' is destroyed.
destroyLoaderFn(std::move(loader));
- AutoGetCollectionForReadCommand autoColl(opCtx, nss);
- auto coll = autoColl.getCollection();
+ AutoGetCollectionForReadCommand coll(opCtx, nss);
// Bulk loader is used to create indexes. The collection is not dropped when the bulk loader is
// destroyed.
diff --git a/src/mongo/db/repl/storage_interface_mock.h b/src/mongo/db/repl/storage_interface_mock.h
index 074f520ef62..9af77afaa55 100644
--- a/src/mongo/db/repl/storage_interface_mock.h
+++ b/src/mongo/db/repl/storage_interface_mock.h
@@ -273,12 +273,12 @@ public:
}
boost::optional<BSONObj> findOplogEntryLessThanOrEqualToTimestamp(
- OperationContext* opCtx, const Collection* oplog, const Timestamp& timestamp) override {
+ OperationContext* opCtx, const CollectionPtr& oplog, const Timestamp& timestamp) override {
return boost::none;
}
boost::optional<BSONObj> findOplogEntryLessThanOrEqualToTimestampRetryOnWCE(
- OperationContext* opCtx, const Collection* oplog, const Timestamp& timestamp) override {
+ OperationContext* opCtx, const CollectionPtr& oplog, const Timestamp& timestamp) override {
return boost::none;
}
diff --git a/src/mongo/db/repl/tenant_migration_donor_op_observer.h b/src/mongo/db/repl/tenant_migration_donor_op_observer.h
index 302ee5bfaef..d317a518498 100644
--- a/src/mongo/db/repl/tenant_migration_donor_op_observer.h
+++ b/src/mongo/db/repl/tenant_migration_donor_op_observer.h
@@ -106,7 +106,7 @@ public:
const boost::optional<OplogSlot> slot) final {}
void onCreateCollection(OperationContext* opCtx,
- const Collection* coll,
+ const CollectionPtr& coll,
const NamespaceString& collectionName,
const CollectionOptions& options,
const BSONObj& idIndex,
diff --git a/src/mongo/db/repl/tenant_migration_recipient_entry_helpers.cpp b/src/mongo/db/repl/tenant_migration_recipient_entry_helpers.cpp
index 357d38ae466..de656c59ca6 100644
--- a/src/mongo/db/repl/tenant_migration_recipient_entry_helpers.cpp
+++ b/src/mongo/db/repl/tenant_migration_recipient_entry_helpers.cpp
@@ -52,9 +52,9 @@ namespace {
* Creates the tenant migration recipients collection if it doesn't exist.
* Note: Throws WriteConflictException if the collection already exist.
*/
-const Collection* ensureTenantMigrationRecipientsCollectionExists(OperationContext* opCtx,
- Database* db,
- const NamespaceString& nss) {
+CollectionPtr ensureTenantMigrationRecipientsCollectionExists(OperationContext* opCtx,
+ Database* db,
+ const NamespaceString& nss) {
// Sanity checks.
invariant(db);
invariant(opCtx->lockState()->isCollectionLockedForMode(nss, MODE_IX));
@@ -129,9 +129,8 @@ StatusWith<TenantMigrationRecipientDocument> getStateDoc(OperationContext* opCtx
const UUID& migrationUUID) {
// Read the most up to date data.
ReadSourceScope readSourceScope(opCtx, RecoveryUnit::ReadSource::kNoTimestamp);
- AutoGetCollectionForRead autoCollection(opCtx,
- NamespaceString::kTenantMigrationRecipientsNamespace);
- const Collection* collection = autoCollection.getCollection();
+ AutoGetCollectionForRead collection(opCtx,
+ NamespaceString::kTenantMigrationRecipientsNamespace);
if (!collection) {
return Status(ErrorCodes::NamespaceNotFound,
@@ -140,8 +139,11 @@ StatusWith<TenantMigrationRecipientDocument> getStateDoc(OperationContext* opCtx
}
BSONObj result;
- auto foundDoc = Helpers::findOne(
- opCtx, collection, BSON("_id" << migrationUUID), result, /*requireIndex=*/true);
+ auto foundDoc = Helpers::findOne(opCtx,
+ collection.getCollection(),
+ BSON("_id" << migrationUUID),
+ result,
+ /*requireIndex=*/true);
if (!foundDoc) {
return Status(ErrorCodes::NoMatchingDocument,
str::stream() << "No matching state doc found with tenant migration UUID: "
diff --git a/src/mongo/db/repl/tenant_oplog_applier_test.cpp b/src/mongo/db/repl/tenant_oplog_applier_test.cpp
index 39a07d3d0b7..15efc7052b9 100644
--- a/src/mongo/db/repl/tenant_oplog_applier_test.cpp
+++ b/src/mongo/db/repl/tenant_oplog_applier_test.cpp
@@ -578,7 +578,7 @@ TEST_F(TenantOplogApplierTest, ApplyCommand_Success) {
<< BSON("create" << nss.coll()) << "ts" << Timestamp(1, 1) << "ui" << UUID::gen());
bool applyCmdCalled = false;
_opObserver->onCreateCollectionFn = [&](OperationContext* opCtx,
- const Collection*,
+ const CollectionPtr&,
const NamespaceString& collNss,
const CollectionOptions&,
const BSONObj&) {
@@ -609,7 +609,7 @@ TEST_F(TenantOplogApplierTest, ApplyCommand_WrongNSS) {
<< BSON("create" << nss.coll()) << "ts" << Timestamp(1, 1) << "ui" << UUID::gen());
bool applyCmdCalled = false;
_opObserver->onCreateCollectionFn = [&](OperationContext* opCtx,
- const Collection*,
+ const CollectionPtr&,
const NamespaceString& collNss,
const CollectionOptions&,
const BSONObj&) { applyCmdCalled = true; };
diff --git a/src/mongo/db/s/check_sharding_index_command.cpp b/src/mongo/db/s/check_sharding_index_command.cpp
index 64f07ebcccf..af6aca46aff 100644
--- a/src/mongo/db/s/check_sharding_index_command.cpp
+++ b/src/mongo/db/s/check_sharding_index_command.cpp
@@ -87,8 +87,7 @@ public:
return true;
}
- AutoGetCollectionForReadCommand autoColl(opCtx, nss);
- auto collection = autoColl.getCollection();
+ AutoGetCollectionForReadCommand collection(opCtx, nss);
if (!collection) {
errmsg = "ns not found";
return false;
diff --git a/src/mongo/db/s/config/sharding_catalog_manager_config_initialization_test.cpp b/src/mongo/db/s/config/sharding_catalog_manager_config_initialization_test.cpp
index 0f28c3fc1bb..19b0fc0b720 100644
--- a/src/mongo/db/s/config/sharding_catalog_manager_config_initialization_test.cpp
+++ b/src/mongo/db/s/config/sharding_catalog_manager_config_initialization_test.cpp
@@ -244,8 +244,7 @@ TEST_F(ConfigInitializationTest, ReRunsIfDocRolledBackThenReElected) {
repl::UnreplicatedWritesBlock uwb(opCtx);
auto nss = VersionType::ConfigNS;
writeConflictRetry(opCtx, "removeConfigDocuments", nss.ns(), [&] {
- AutoGetCollection autoColl(opCtx, nss, MODE_IX);
- auto coll = autoColl.getCollection();
+ AutoGetCollection coll(opCtx, nss, MODE_IX);
ASSERT_TRUE(coll);
auto cursor = coll->getCursor(opCtx);
std::vector<RecordId> recordIds;
diff --git a/src/mongo/db/s/config_server_op_observer.h b/src/mongo/db/s/config_server_op_observer.h
index f3c7b61fdd1..e45ee8d30d0 100644
--- a/src/mongo/db/s/config_server_op_observer.h
+++ b/src/mongo/db/s/config_server_op_observer.h
@@ -108,7 +108,7 @@ public:
const boost::optional<OplogSlot> slot) final{};
void onCreateCollection(OperationContext* opCtx,
- const Collection* coll,
+ const CollectionPtr& coll,
const NamespaceString& collectionName,
const CollectionOptions& options,
const BSONObj& idIndex,
diff --git a/src/mongo/db/s/migration_chunk_cloner_source_legacy.cpp b/src/mongo/db/s/migration_chunk_cloner_source_legacy.cpp
index 40d2853424e..85b91e96903 100644
--- a/src/mongo/db/s/migration_chunk_cloner_source_legacy.cpp
+++ b/src/mongo/db/s/migration_chunk_cloner_source_legacy.cpp
@@ -586,7 +586,7 @@ void MigrationChunkClonerSourceLegacy::_decrementOutstandingOperationTrackReques
}
void MigrationChunkClonerSourceLegacy::_nextCloneBatchFromIndexScan(OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
BSONArrayBuilder* arrBuilder) {
ElapsedTracker tracker(opCtx->getServiceContext()->getFastClockSource(),
internalQueryExecYieldIterations.load(),
@@ -597,7 +597,7 @@ void MigrationChunkClonerSourceLegacy::_nextCloneBatchFromIndexScan(OperationCon
_jumboChunkCloneState->clonerExec = std::move(exec);
} else {
_jumboChunkCloneState->clonerExec->reattachToOperationContext(opCtx);
- _jumboChunkCloneState->clonerExec->restoreState();
+ _jumboChunkCloneState->clonerExec->restoreState(&collection);
}
PlanExecutor::ExecState execState;
@@ -655,7 +655,7 @@ void MigrationChunkClonerSourceLegacy::_nextCloneBatchFromIndexScan(OperationCon
}
void MigrationChunkClonerSourceLegacy::_nextCloneBatchFromCloneLocs(OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
BSONArrayBuilder* arrBuilder) {
ElapsedTracker tracker(opCtx->getServiceContext()->getFastClockSource(),
internalQueryExecYieldIterations.load(),
@@ -705,7 +705,7 @@ uint64_t MigrationChunkClonerSourceLegacy::getCloneBatchBufferAllocationSize() {
}
Status MigrationChunkClonerSourceLegacy::nextCloneBatch(OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
BSONArrayBuilder* arrBuilder) {
dassert(opCtx->lockState()->isCollectionLockedForMode(_args.getNss(), MODE_IS));
@@ -802,7 +802,7 @@ StatusWith<BSONObj> MigrationChunkClonerSourceLegacy::_callRecipient(const BSONO
StatusWith<std::unique_ptr<PlanExecutor, PlanExecutor::Deleter>>
MigrationChunkClonerSourceLegacy::_getIndexScanExecutor(OperationContext* opCtx,
- const Collection* const collection) {
+ const CollectionPtr& collection) {
// Allow multiKey based on the invariant that shard keys must be single-valued. Therefore, any
// multi-key index prefixed by shard key cannot be multikey over the shard key fields.
const IndexDescriptor* idx =
@@ -833,15 +833,13 @@ MigrationChunkClonerSourceLegacy::_getIndexScanExecutor(OperationContext* opCtx,
}
Status MigrationChunkClonerSourceLegacy::_storeCurrentLocs(OperationContext* opCtx) {
- AutoGetCollection autoColl(opCtx, _args.getNss(), MODE_IS);
-
- const Collection* const collection = autoColl.getCollection();
+ AutoGetCollection collection(opCtx, _args.getNss(), MODE_IS);
if (!collection) {
return {ErrorCodes::NamespaceNotFound,
str::stream() << "Collection " << _args.getNss().ns() << " does not exist."};
}
- auto swExec = _getIndexScanExecutor(opCtx, collection);
+ auto swExec = _getIndexScanExecutor(opCtx, collection.getCollection());
if (!swExec.isOK()) {
return swExec.getStatus();
}
diff --git a/src/mongo/db/s/migration_chunk_cloner_source_legacy.h b/src/mongo/db/s/migration_chunk_cloner_source_legacy.h
index a5c1bdab2c1..181bc15b6ce 100644
--- a/src/mongo/db/s/migration_chunk_cloner_source_legacy.h
+++ b/src/mongo/db/s/migration_chunk_cloner_source_legacy.h
@@ -52,6 +52,7 @@ namespace mongo {
class BSONArrayBuilder;
class BSONObjBuilder;
class Collection;
+class CollectionPtr;
class Database;
class RecordId;
@@ -159,7 +160,7 @@ public:
* NOTE: Must be called with the collection lock held in at least IS mode.
*/
Status nextCloneBatch(OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
BSONArrayBuilder* arrBuilder);
/**
@@ -221,14 +222,14 @@ private:
StatusWith<BSONObj> _callRecipient(const BSONObj& cmdObj);
StatusWith<std::unique_ptr<PlanExecutor, PlanExecutor::Deleter>> _getIndexScanExecutor(
- OperationContext* opCtx, const Collection* const collection);
+ OperationContext* opCtx, const CollectionPtr& collection);
void _nextCloneBatchFromIndexScan(OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
BSONArrayBuilder* arrBuilder);
void _nextCloneBatchFromCloneLocs(OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
BSONArrayBuilder* arrBuilder);
/**
diff --git a/src/mongo/db/s/migration_chunk_cloner_source_legacy_commands.cpp b/src/mongo/db/s/migration_chunk_cloner_source_legacy_commands.cpp
index 017851f43e9..2f255b68fc2 100644
--- a/src/mongo/db/s/migration_chunk_cloner_source_legacy_commands.cpp
+++ b/src/mongo/db/s/migration_chunk_cloner_source_legacy_commands.cpp
@@ -108,7 +108,7 @@ public:
return _autoColl->getDb();
}
- const Collection* getColl() const {
+ const CollectionPtr& getColl() const {
invariant(_autoColl);
return _autoColl->getCollection();
}
diff --git a/src/mongo/db/s/migration_destination_manager.cpp b/src/mongo/db/s/migration_destination_manager.cpp
index e6e4de4ac75..fe1952a8ffc 100644
--- a/src/mongo/db/s/migration_destination_manager.cpp
+++ b/src/mongo/db/s/migration_destination_manager.cpp
@@ -717,7 +717,7 @@ void MigrationDestinationManager::cloneCollectionIndexesAndOptions(
// missing (auto-heal indexes).
// Checks that the collection's UUID matches the donor's.
- auto checkUUIDsMatch = [&](const Collection* collection) {
+ auto checkUUIDsMatch = [&](const CollectionPtr& collection) {
uassert(ErrorCodes::NotWritablePrimary,
str::stream() << "Unable to create collection " << nss.ns()
<< " because the node is not primary",
@@ -737,7 +737,7 @@ void MigrationDestinationManager::cloneCollectionIndexesAndOptions(
// Gets the missing indexes and checks if the collection is empty (auto-healing is
// possible).
- auto checkEmptyOrGetMissingIndexesFromDonor = [&](const Collection* collection) {
+ auto checkEmptyOrGetMissingIndexesFromDonor = [&](const CollectionPtr& collection) {
auto indexCatalog = collection->getIndexCatalog();
auto indexSpecs = indexCatalog->removeExistingIndexesNoChecks(
opCtx, collectionOptionsAndIndexes.indexSpecs);
@@ -754,12 +754,12 @@ void MigrationDestinationManager::cloneCollectionIndexesAndOptions(
};
{
- AutoGetCollection autoGetCollection(opCtx, nss, MODE_IS);
+ AutoGetCollection collection(opCtx, nss, MODE_IS);
- auto collection = autoGetCollection.getCollection();
if (collection) {
- checkUUIDsMatch(collection);
- auto indexSpecs = checkEmptyOrGetMissingIndexesFromDonor(collection);
+ checkUUIDsMatch(collection.getCollection());
+ auto indexSpecs =
+ checkEmptyOrGetMissingIndexesFromDonor(collection.getCollection());
if (indexSpecs.empty()) {
return;
}
diff --git a/src/mongo/db/s/migration_util.cpp b/src/mongo/db/s/migration_util.cpp
index 7d289fb979e..1e5011a6472 100644
--- a/src/mongo/db/s/migration_util.cpp
+++ b/src/mongo/db/s/migration_util.cpp
@@ -537,7 +537,7 @@ void submitOrphanRangesForCleanup(OperationContext* opCtx) {
if (dbName == NamespaceString::kLocalDb)
continue;
- for (auto collIt = catalog.begin(dbName); collIt != catalog.end(); ++collIt) {
+ for (auto collIt = catalog.begin(opCtx, dbName); collIt != catalog.end(opCtx); ++collIt) {
auto uuid = collIt.uuid().get();
auto nss = catalog.lookupNSSByUUID(opCtx, uuid).get();
LOGV2_DEBUG(22034,
diff --git a/src/mongo/db/s/range_deletion_util.cpp b/src/mongo/db/s/range_deletion_util.cpp
index 5f904e488ad..ec61ce0d47c 100644
--- a/src/mongo/db/s/range_deletion_util.cpp
+++ b/src/mongo/db/s/range_deletion_util.cpp
@@ -83,7 +83,7 @@ MONGO_FAIL_POINT_DEFINE(throwInternalErrorInDeleteRange);
* enqueued for deletion.
*/
bool collectionUuidHasChanged(const NamespaceString& nss,
- const Collection* currentCollection,
+ const CollectionPtr& currentCollection,
UUID expectedCollectionUuid) {
if (!currentCollection) {
@@ -121,11 +121,11 @@ bool collectionUuidHasChanged(const NamespaceString& nss,
* the range failed.
*/
StatusWith<int> deleteNextBatch(OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
BSONObj const& keyPattern,
ChunkRange const& range,
int numDocsToRemovePerBatch) {
- invariant(collection != nullptr);
+ invariant(collection);
auto const& nss = collection->ns();
@@ -303,18 +303,21 @@ ExecutorFuture<void> deleteRangeInBatches(const std::shared_ptr<executor::TaskEx
ensureRangeDeletionTaskStillExists(opCtx, *migrationId);
}
- AutoGetCollection autoColl(opCtx, nss, MODE_IX);
- auto* const collection = autoColl.getCollection();
+ AutoGetCollection collection(opCtx, nss, MODE_IX);
// Ensure the collection exists and has not been dropped or dropped and
// recreated.
- uassert(ErrorCodes::RangeDeletionAbandonedBecauseCollectionWithUUIDDoesNotExist,
- "Collection has been dropped since enqueuing this range "
- "deletion task. No need to delete documents.",
- !collectionUuidHasChanged(nss, collection, collectionUuid));
-
- auto numDeleted = uassertStatusOK(deleteNextBatch(
- opCtx, collection, keyPattern, range, numDocsToRemovePerBatch));
+ uassert(
+ ErrorCodes::RangeDeletionAbandonedBecauseCollectionWithUUIDDoesNotExist,
+ "Collection has been dropped since enqueuing this range "
+ "deletion task. No need to delete documents.",
+ !collectionUuidHasChanged(nss, collection.getCollection(), collectionUuid));
+
+ auto numDeleted = uassertStatusOK(deleteNextBatch(opCtx,
+ collection.getCollection(),
+ keyPattern,
+ range,
+ numDocsToRemovePerBatch));
LOGV2_DEBUG(
23769,
diff --git a/src/mongo/db/s/resharding/resharding_op_observer.h b/src/mongo/db/s/resharding/resharding_op_observer.h
index 0a6cfc3ad1f..7b5eb7108a6 100644
--- a/src/mongo/db/s/resharding/resharding_op_observer.h
+++ b/src/mongo/db/s/resharding/resharding_op_observer.h
@@ -108,7 +108,7 @@ public:
const boost::optional<OplogSlot> slot) override {}
void onCreateCollection(OperationContext* opCtx,
- const Collection* coll,
+ const CollectionPtr& coll,
const NamespaceString& collectionName,
const CollectionOptions& options,
const BSONObj& idIndex,
diff --git a/src/mongo/db/s/resharding_util.cpp b/src/mongo/db/s/resharding_util.cpp
index 5fc47faee38..849e99535d6 100644
--- a/src/mongo/db/s/resharding_util.cpp
+++ b/src/mongo/db/s/resharding_util.cpp
@@ -363,7 +363,7 @@ void createSlimOplogView(OperationContext* opCtx, Database* db) {
{
// Create 'system.views' in a separate WUOW if it does not exist.
WriteUnitOfWork wuow(opCtx);
- const Collection* coll = CollectionCatalog::get(opCtx).lookupCollectionByNamespace(
+ CollectionPtr coll = CollectionCatalog::get(opCtx).lookupCollectionByNamespace(
opCtx, NamespaceString(db->getSystemViewsName()));
if (!coll) {
coll = db->createCollection(opCtx, NamespaceString(db->getSystemViewsName()));
diff --git a/src/mongo/db/s/shard_local.cpp b/src/mongo/db/s/shard_local.cpp
index 9b432100426..8b293435bfb 100644
--- a/src/mongo/db/s/shard_local.cpp
+++ b/src/mongo/db/s/shard_local.cpp
@@ -127,9 +127,11 @@ Status ShardLocal::createIndexOnConfig(OperationContext* opCtx,
invariant(ns.db() == "config" || ns.db() == "admin");
try {
+ // TODO SERVER-50983: Create abstraction for creating collection when using
+ // AutoGetCollection
AutoGetOrCreateDb autoDb(opCtx, ns.db(), MODE_IX);
AutoGetCollection autoColl(opCtx, ns, MODE_X);
- auto collection = autoColl.getCollection();
+ const Collection* collection = autoColl.getCollection().get();
if (!collection) {
CollectionOptions options;
options.uuid = UUID::gen();
diff --git a/src/mongo/db/s/shard_server_op_observer.cpp b/src/mongo/db/s/shard_server_op_observer.cpp
index 3cef6d2aebd..9075740f1a8 100644
--- a/src/mongo/db/s/shard_server_op_observer.cpp
+++ b/src/mongo/db/s/shard_server_op_observer.cpp
@@ -453,7 +453,7 @@ void ShardServerOpObserver::onDelete(OperationContext* opCtx,
}
void ShardServerOpObserver::onCreateCollection(OperationContext* opCtx,
- const Collection* coll,
+ const CollectionPtr& coll,
const NamespaceString& collectionName,
const CollectionOptions& options,
const BSONObj& idIndex,
diff --git a/src/mongo/db/s/shard_server_op_observer.h b/src/mongo/db/s/shard_server_op_observer.h
index d608611570f..822cc291943 100644
--- a/src/mongo/db/s/shard_server_op_observer.h
+++ b/src/mongo/db/s/shard_server_op_observer.h
@@ -106,7 +106,7 @@ public:
const boost::optional<OplogSlot> slot) final{};
void onCreateCollection(OperationContext* opCtx,
- const Collection* coll,
+ const CollectionPtr& coll,
const NamespaceString& collectionName,
const CollectionOptions& options,
const BSONObj& idIndex,
diff --git a/src/mongo/db/s/shardsvr_shard_collection.cpp b/src/mongo/db/s/shardsvr_shard_collection.cpp
index a311110cc98..5b9e4c5dd7d 100644
--- a/src/mongo/db/s/shardsvr_shard_collection.cpp
+++ b/src/mongo/db/s/shardsvr_shard_collection.cpp
@@ -189,7 +189,7 @@ void checkCollation(OperationContext* opCtx, const ShardsvrShardCollectionReques
AutoGetCollectionViewMode::kViewsForbidden);
const auto actualCollator = [&]() -> const CollatorInterface* {
- const auto* const coll = autoColl.getCollection();
+ const auto& coll = autoColl.getCollection();
if (coll) {
uassert(
ErrorCodes::InvalidOptions, "can't shard a capped collection", !coll->isCapped());
diff --git a/src/mongo/db/s/split_chunk.cpp b/src/mongo/db/s/split_chunk.cpp
index b46885c3f1b..4efdc2e8656 100644
--- a/src/mongo/db/s/split_chunk.cpp
+++ b/src/mongo/db/s/split_chunk.cpp
@@ -58,7 +58,7 @@ namespace {
const ReadPreferenceSetting kPrimaryOnlyReadPreference{ReadPreference::PrimaryOnly};
bool checkIfSingleDoc(OperationContext* opCtx,
- const Collection* collection,
+ const CollectionPtr& collection,
const IndexDescriptor* idx,
const ChunkType* chunk) {
KeyPattern kp(idx->keyPattern());
@@ -208,9 +208,7 @@ StatusWith<boost::optional<ChunkRange>> splitChunk(OperationContext* opCtx,
}
}
- AutoGetCollection autoColl(opCtx, nss, MODE_IS);
-
- const Collection* const collection = autoColl.getCollection();
+ AutoGetCollection collection(opCtx, nss, MODE_IS);
if (!collection) {
LOGV2_WARNING(
23778,
@@ -237,10 +235,10 @@ StatusWith<boost::optional<ChunkRange>> splitChunk(OperationContext* opCtx,
KeyPattern shardKeyPattern(keyPatternObj);
if (shardKeyPattern.globalMax().woCompare(backChunk.getMax()) == 0 &&
- checkIfSingleDoc(opCtx, collection, idx, &backChunk)) {
+ checkIfSingleDoc(opCtx, collection.getCollection(), idx, &backChunk)) {
return boost::optional<ChunkRange>(ChunkRange(backChunk.getMin(), backChunk.getMax()));
} else if (shardKeyPattern.globalMin().woCompare(frontChunk.getMin()) == 0 &&
- checkIfSingleDoc(opCtx, collection, idx, &frontChunk)) {
+ checkIfSingleDoc(opCtx, collection.getCollection(), idx, &frontChunk)) {
return boost::optional<ChunkRange>(ChunkRange(frontChunk.getMin(), frontChunk.getMax()));
}
diff --git a/src/mongo/db/s/split_vector.cpp b/src/mongo/db/s/split_vector.cpp
index 67daf15550f..7879027e91c 100644
--- a/src/mongo/db/s/split_vector.cpp
+++ b/src/mongo/db/s/split_vector.cpp
@@ -76,9 +76,8 @@ std::vector<BSONObj> splitVector(OperationContext* opCtx,
}
{
- AutoGetCollection autoColl(opCtx, nss, MODE_IS);
+ AutoGetCollection collection(opCtx, nss, MODE_IS);
- const Collection* const collection = autoColl.getCollection();
uassert(ErrorCodes::NamespaceNotFound, "ns not found", collection);
// Allow multiKey based on the invariant that shard keys must be single-valued. Therefore,
@@ -164,7 +163,7 @@ std::vector<BSONObj> splitVector(OperationContext* opCtx,
long long numChunks = 0;
auto exec = InternalPlanner::indexScan(opCtx,
- collection,
+ collection.getCollection(),
idx,
minKey,
maxKey,
@@ -182,7 +181,7 @@ std::vector<BSONObj> splitVector(OperationContext* opCtx,
BSONObj maxKeyInChunk;
{
auto exec = InternalPlanner::indexScan(opCtx,
- collection,
+ collection.getCollection(),
idx,
maxKey,
minKey,
@@ -299,7 +298,7 @@ std::vector<BSONObj> splitVector(OperationContext* opCtx,
"keyCount"_attr = keyCount);
exec = InternalPlanner::indexScan(opCtx,
- collection,
+ collection.getCollection(),
idx,
minKey,
maxKey,
diff --git a/src/mongo/db/session_catalog_mongod.cpp b/src/mongo/db/session_catalog_mongod.cpp
index 7ae2190fe77..a8a8ff9d7d6 100644
--- a/src/mongo/db/session_catalog_mongod.cpp
+++ b/src/mongo/db/session_catalog_mongod.cpp
@@ -270,9 +270,8 @@ void MongoDSessionCatalog::onStepUp(OperationContext* opCtx) {
}
boost::optional<UUID> MongoDSessionCatalog::getTransactionTableUUID(OperationContext* opCtx) {
- AutoGetCollection autoColl(opCtx, NamespaceString::kSessionTransactionsTableNamespace, MODE_IS);
+ AutoGetCollection coll(opCtx, NamespaceString::kSessionTransactionsTableNamespace, MODE_IS);
- const auto coll = autoColl.getCollection();
if (!coll) {
return boost::none;
}
diff --git a/src/mongo/db/startup_recovery.cpp b/src/mongo/db/startup_recovery.cpp
index 7c96c3919f3..fbaaef9637f 100644
--- a/src/mongo/db/startup_recovery.cpp
+++ b/src/mongo/db/startup_recovery.cpp
@@ -105,7 +105,7 @@ Status restoreMissingFeatureCompatibilityVersionDocument(OperationContext* opCtx
createCollection(opCtx, fcvNss.db().toString(), BSON("create" << fcvNss.coll())));
}
- const Collection* fcvColl = CollectionCatalog::get(opCtx).lookupCollectionByNamespace(
+ const CollectionPtr& fcvColl = CollectionCatalog::get(opCtx).lookupCollectionByNamespace(
opCtx, NamespaceString::kServerConfigurationNamespace);
invariant(fcvColl);
@@ -323,7 +323,7 @@ bool hasReplSetConfigDoc(OperationContext* opCtx) {
void assertCappedOplog(OperationContext* opCtx, Database* db) {
const NamespaceString oplogNss(NamespaceString::kRsOplogNamespace);
invariant(opCtx->lockState()->isDbLockedForMode(oplogNss.db(), MODE_IS));
- const Collection* oplogCollection =
+ const CollectionPtr& oplogCollection =
CollectionCatalog::get(opCtx).lookupCollectionByNamespace(opCtx, oplogNss);
if (oplogCollection && !oplogCollection->isCapped()) {
LOGV2_FATAL_NOTRACE(
@@ -436,7 +436,7 @@ void setReplSetMemberInStandaloneMode(OperationContext* opCtx) {
}
invariant(opCtx->lockState()->isW());
- const Collection* collection = CollectionCatalog::get(opCtx).lookupCollectionByNamespace(
+ CollectionPtr collection = CollectionCatalog::get(opCtx).lookupCollectionByNamespace(
opCtx, NamespaceString::kSystemReplSetNamespace);
if (collection && !collection->isEmpty(opCtx)) {
setReplSetMemberInStandaloneMode(opCtx->getServiceContext(), true);
diff --git a/src/mongo/db/stats/storage_stats.cpp b/src/mongo/db/stats/storage_stats.cpp
index b942daf3dff..4e3eee4e846 100644
--- a/src/mongo/db/stats/storage_stats.cpp
+++ b/src/mongo/db/stats/storage_stats.cpp
@@ -70,7 +70,7 @@ Status appendCollectionStorageStats(OperationContext* opCtx,
return Status::OK();
}
- const Collection* collection = autoColl->getCollection(); // Will be set if present
+ const auto& collection = autoColl->getCollection(); // Will be set if present
if (!autoColl->getDb() || !collection) {
result->appendNumber("size", 0);
result->appendNumber("count", 0);
@@ -145,13 +145,12 @@ Status appendCollectionStorageStats(OperationContext* opCtx,
Status appendCollectionRecordCount(OperationContext* opCtx,
const NamespaceString& nss,
BSONObjBuilder* result) {
- AutoGetCollectionForReadCommand ctx(opCtx, nss);
- if (!ctx.getDb()) {
+ AutoGetCollectionForReadCommand collection(opCtx, nss);
+ if (!collection.getDb()) {
return {ErrorCodes::BadValue,
str::stream() << "Database [" << nss.db().toString() << "] not found."};
}
- const Collection* collection = ctx.getCollection();
if (!collection) {
return {ErrorCodes::BadValue,
str::stream() << "Collection [" << nss.toString() << "] not found."};
diff --git a/src/mongo/db/storage/oplog_cap_maintainer_thread.cpp b/src/mongo/db/storage/oplog_cap_maintainer_thread.cpp
index fefa3744e6b..53b359ec0d4 100644
--- a/src/mongo/db/storage/oplog_cap_maintainer_thread.cpp
+++ b/src/mongo/db/storage/oplog_cap_maintainer_thread.cpp
@@ -69,7 +69,7 @@ bool OplogCapMaintainerThread::_deleteExcessDocuments() {
// interruptions such as restartCatalog. PBWM, database lock or collection lock is not
// needed. This improves concurrency if oplog truncation takes long time.
AutoGetOplog oplogWrite(opCtx.get(), OplogAccessMode::kWrite);
- auto oplog = oplogWrite.getCollection();
+ const auto& oplog = oplogWrite.getCollection();
if (!oplog) {
LOGV2_DEBUG(4562600, 2, "oplog collection does not exist");
return false;
diff --git a/src/mongo/db/storage/record_store.h b/src/mongo/db/storage/record_store.h
index a6a88bc8403..ffcf0106e30 100644
--- a/src/mongo/db/storage/record_store.h
+++ b/src/mongo/db/storage/record_store.h
@@ -43,6 +43,7 @@ namespace mongo {
class CappedCallback;
class Collection;
+class CollectionPtr;
class MAdvise;
class OperationContext;
diff --git a/src/mongo/db/storage/storage_engine_impl.cpp b/src/mongo/db/storage/storage_engine_impl.cpp
index c8c87173421..f90d2ea6415 100644
--- a/src/mongo/db/storage/storage_engine_impl.cpp
+++ b/src/mongo/db/storage/storage_engine_impl.cpp
@@ -1192,7 +1192,7 @@ void StorageEngineImpl::TimestampMonitor::removeListener(TimestampListener* list
int64_t StorageEngineImpl::sizeOnDiskForDb(OperationContext* opCtx, StringData dbName) {
int64_t size = 0;
- catalog::forEachCollectionFromDb(opCtx, dbName, MODE_IS, [&](const Collection* collection) {
+ catalog::forEachCollectionFromDb(opCtx, dbName, MODE_IS, [&](const CollectionPtr& collection) {
size += collection->getRecordStore()->storageSize(opCtx);
std::vector<std::string> indexNames;
diff --git a/src/mongo/db/storage/storage_engine_test_fixture.h b/src/mongo/db/storage/storage_engine_test_fixture.h
index cada701556d..c6ad8880e77 100644
--- a/src/mongo/db/storage/storage_engine_test_fixture.h
+++ b/src/mongo/db/storage/storage_engine_test_fixture.h
@@ -157,7 +157,7 @@ public:
}
BSONObj spec = builder.append("name", key).append("v", 2).done();
- const Collection* collection =
+ CollectionPtr collection =
CollectionCatalog::get(opCtx).lookupCollectionByNamespace(opCtx, collNs);
auto descriptor =
std::make_unique<IndexDescriptor>(collection, IndexNames::findPluginName(spec), spec);
@@ -171,13 +171,13 @@ public:
}
void indexBuildSuccess(OperationContext* opCtx, NamespaceString collNs, std::string key) {
- const Collection* collection =
+ CollectionPtr collection =
CollectionCatalog::get(opCtx).lookupCollectionByNamespace(opCtx, collNs);
DurableCatalog::get(opCtx)->indexBuildSuccess(opCtx, collection->getCatalogId(), key);
}
Status removeEntry(OperationContext* opCtx, StringData collNs, DurableCatalog* catalog) {
- const Collection* collection = CollectionCatalog::get(opCtx).lookupCollectionByNamespace(
+ CollectionPtr collection = CollectionCatalog::get(opCtx).lookupCollectionByNamespace(
opCtx, NamespaceString(collNs));
return dynamic_cast<DurableCatalogImpl*>(catalog)->_removeEntry(opCtx,
collection->getCatalogId());
diff --git a/src/mongo/db/storage/wiredtiger/oplog_stones_server_status_section.cpp b/src/mongo/db/storage/wiredtiger/oplog_stones_server_status_section.cpp
index 71d2421f5e5..e92d6b169e2 100644
--- a/src/mongo/db/storage/wiredtiger/oplog_stones_server_status_section.cpp
+++ b/src/mongo/db/storage/wiredtiger/oplog_stones_server_status_section.cpp
@@ -55,7 +55,7 @@ public:
return builder.obj();
}
AutoGetOplog oplogRead(opCtx, OplogAccessMode::kRead);
- auto oplog = oplogRead.getCollection();
+ const auto& oplog = oplogRead.getCollection();
if (oplog) {
const auto localDb =
DatabaseHolder::get(opCtx)->getDb(opCtx, NamespaceString::kLocalDb);
diff --git a/src/mongo/db/system_index.cpp b/src/mongo/db/system_index.cpp
index 8bd0cfbd422..09521feda5a 100644
--- a/src/mongo/db/system_index.cpp
+++ b/src/mongo/db/system_index.cpp
@@ -199,7 +199,7 @@ Status verifySystemIndexes(OperationContext* opCtx) {
return Status::OK();
}
-void createSystemIndexes(OperationContext* opCtx, const Collection* collection) {
+void createSystemIndexes(OperationContext* opCtx, const CollectionPtr& collection) {
invariant(collection);
const NamespaceString& ns = collection->ns();
BSONObj indexSpec;
diff --git a/src/mongo/db/system_index.h b/src/mongo/db/system_index.h
index 02eb4d26b4a..ce341e8b3b9 100644
--- a/src/mongo/db/system_index.h
+++ b/src/mongo/db/system_index.h
@@ -32,6 +32,7 @@
namespace mongo {
class Collection;
+class CollectionPtr;
class OperationContext;
class Status;
@@ -39,7 +40,7 @@ class Status;
* Creates the appropriate indexes on _new_ system collections for authentication,
* authorization, and sessions.
*/
-void createSystemIndexes(OperationContext* opCtx, const Collection* collection);
+void createSystemIndexes(OperationContext* opCtx, const CollectionPtr& collection);
/**
* Verifies that only the appropriate indexes to support authentication, authorization, and
diff --git a/src/mongo/db/transaction_participant.cpp b/src/mongo/db/transaction_participant.cpp
index de5874ae3a6..5284c8c2300 100644
--- a/src/mongo/db/transaction_participant.cpp
+++ b/src/mongo/db/transaction_participant.cpp
@@ -206,18 +206,18 @@ void updateSessionEntry(OperationContext* opCtx, const UpdateRequest& updateRequ
// Current code only supports replacement update.
dassert(UpdateDriver::isDocReplacement(updateRequest.getUpdateModification()));
- AutoGetCollection autoColl(opCtx, NamespaceString::kSessionTransactionsTableNamespace, MODE_IX);
+ AutoGetCollection collection(
+ opCtx, NamespaceString::kSessionTransactionsTableNamespace, MODE_IX);
uassert(40527,
str::stream() << "Unable to persist transaction state because the session transaction "
"collection is missing. This indicates that the "
<< NamespaceString::kSessionTransactionsTableNamespace.ns()
<< " collection has been manually deleted.",
- autoColl.getCollection());
+ collection.getCollection());
WriteUnitOfWork wuow(opCtx);
- auto collection = autoColl.getCollection();
auto idIndex = collection->getIndexCatalog()->findIdIndex(opCtx);
uassert(40672,
diff --git a/src/mongo/db/views/durable_view_catalog.cpp b/src/mongo/db/views/durable_view_catalog.cpp
index d27b4384a59..25b0c2a28a6 100644
--- a/src/mongo/db/views/durable_view_catalog.cpp
+++ b/src/mongo/db/views/durable_view_catalog.cpp
@@ -111,7 +111,7 @@ void DurableViewCatalogImpl::_iterate(OperationContext* opCtx,
ViewCatalogLookupBehavior lookupBehavior) {
invariant(opCtx->lockState()->isCollectionLockedForMode(_db->getSystemViewsName(), MODE_IS));
- const Collection* systemViews =
+ const CollectionPtr& systemViews =
CollectionCatalog::get(opCtx).lookupCollectionByNamespace(opCtx, _db->getSystemViewsName());
if (!systemViews) {
return;
@@ -186,7 +186,7 @@ void DurableViewCatalogImpl::upsert(OperationContext* opCtx,
NamespaceString systemViewsNs(_db->getSystemViewsName());
dassert(opCtx->lockState()->isCollectionLockedForMode(systemViewsNs, MODE_X));
- const Collection* systemViews =
+ const CollectionPtr& systemViews =
CollectionCatalog::get(opCtx).lookupCollectionByNamespace(opCtx, systemViewsNs);
invariant(systemViews);
@@ -218,7 +218,7 @@ void DurableViewCatalogImpl::remove(OperationContext* opCtx, const NamespaceStri
dassert(opCtx->lockState()->isDbLockedForMode(_db->name(), MODE_IX));
dassert(opCtx->lockState()->isCollectionLockedForMode(name, MODE_IX));
- const Collection* systemViews =
+ const CollectionPtr& systemViews =
CollectionCatalog::get(opCtx).lookupCollectionByNamespace(opCtx, _db->getSystemViewsName());
dassert(opCtx->lockState()->isCollectionLockedForMode(systemViews->ns(), MODE_X));
diff --git a/src/mongo/db/yieldable.h b/src/mongo/db/yieldable.h
new file mode 100644
index 00000000000..d420789933d
--- /dev/null
+++ b/src/mongo/db/yieldable.h
@@ -0,0 +1,39 @@
+/**
+ * Copyright (C) 2018-present MongoDB, Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the Server Side Public License, version 1,
+ * as published by MongoDB, Inc.
+ *
+ * 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
+ * Server Side Public License for more details.
+ *
+ * You should have received a copy of the Server Side Public License
+ * along with this program. If not, see
+ * <http://www.mongodb.com/licensing/server-side-public-license>.
+ *
+ * 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 Server Side 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
+
+namespace mongo {
+class Yieldable {
+public:
+ virtual ~Yieldable() {}
+ virtual void yield() const = 0;
+ virtual void restore() const = 0;
+};
+} // namespace mongo