diff options
author | Uladzimir Makouski <uladzimir.makouski@mongodb.com> | 2021-04-22 06:22:08 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2021-04-22 09:18:21 +0000 |
commit | aa2bbde8810ae9de83d6d0f1adbd364ed52cde32 (patch) | |
tree | 1024b095f0e0b5b8302d83c60242a25b93ce7f5c | |
parent | 1bc449e8d7626639900cfddb19df4d974bdb7532 (diff) | |
download | mongo-aa2bbde8810ae9de83d6d0f1adbd364ed52cde32.tar.gz |
Revert "SERVER-43964 UUID etc need not befriend IDL types"
This reverts commit 8f4dbd6889eb9534da7af27729aa0c2edea532f0.
-rw-r--r-- | buildscripts/idl/idl/cpp_types.py | 18 | ||||
-rw-r--r-- | buildscripts/idl/idl/generator.py | 24 | ||||
-rw-r--r-- | src/mongo/db/s/migration_destination_manager.cpp | 32 | ||||
-rw-r--r-- | src/mongo/db/s/migration_destination_manager.h | 2 | ||||
-rw-r--r-- | src/mongo/idl/idl_parser.h | 64 | ||||
-rw-r--r-- | src/mongo/s/catalog/type_chunk.h | 12 | ||||
-rw-r--r-- | src/mongo/util/uuid.h | 84 |
7 files changed, 128 insertions, 108 deletions
diff --git a/buildscripts/idl/idl/cpp_types.py b/buildscripts/idl/idl/cpp_types.py index bb7ec7d0a22..d4066af197f 100644 --- a/buildscripts/idl/idl/cpp_types.py +++ b/buildscripts/idl/idl/cpp_types.py @@ -56,6 +56,24 @@ def is_primitive_scalar_type(cpp_type): ] +def get_primitive_scalar_type_default_value(cpp_type): + # type: (str) -> str + """ + Return a default value for a primitive scalar type. + + Assumes the IDL generated code verifies the user sets the value before serialization. + """ + # pylint: disable=invalid-name + assert is_primitive_scalar_type(cpp_type) + if cpp_type == 'bool': + return 'false' + # TODO (SERVER-50101): Remove 'FeatureCompatibility::Version' once IDL supports a command + # cpp_type of C++ enum. + if cpp_type == 'ServerGlobalParams::FeatureCompatibility::Version': + return 'ServerGlobalParams::FeatureCompatibility::Version::kUnsetDefault44Behavior' + return '-1' + + def is_primitive_type(cpp_type): # type: (str) -> bool """Return True if a cpp_type is a primitive type and should not be returned as reference.""" diff --git a/buildscripts/idl/idl/generator.py b/buildscripts/idl/idl/generator.py index 3dc643b5075..34747fd6d24 100644 --- a/buildscripts/idl/idl/generator.py +++ b/buildscripts/idl/idl/generator.py @@ -1580,12 +1580,13 @@ class _CppSourceFileWriter(_CppFileWriterBase): if default_init: for field in struct.fields: needs_init = (field.type and field.type.cpp_type and not field.type.is_array - and _is_required_serializer_field(field) - and field.cpp_name != 'dbName') - if needs_init: + and cpp_types.is_primitive_scalar_type(field.type.cpp_type)) + + if _is_required_serializer_field(field) and needs_init: initializers.append( - '%s(mongo::idl::preparsedValue<decltype(%s)>())' % - (_get_field_member_name(field), _get_field_member_name(field))) + '%s(%s)' % (_get_field_member_name(field), + cpp_types.get_primitive_scalar_type_default_value( + field.type.cpp_type))) # Serialize the _dbName field second initializes_db_name = False @@ -1759,13 +1760,13 @@ class _CppSourceFileWriter(_CppFileWriterBase): if struct.command_field.type.cpp_type and cpp_types.is_primitive_scalar_type( struct.command_field.type.cpp_type): - self._writer.write_line( - 'auto localCmdType = mongo::idl::preparsedValue<%s>();' % - (cpp_type_info.get_storage_type())) + self._writer.write_line('%s localCmdType(%s);' % + (cpp_type_info.get_storage_type(), + cpp_types.get_primitive_scalar_type_default_value( + struct.command_field.type.cpp_type))) else: self._writer.write_line( - 'auto localCmdType = mongo::idl::preparsedValue<%s>();' % - (cpp_type_info.get_storage_type())) + '%s localCmdType;' % (cpp_type_info.get_storage_type())) self._writer.write_line( '%s object(localCmdType);' % (common.title_case(struct.cpp_name))) elif struct.namespace in (common.COMMAND_NAMESPACE_CONCATENATE_WITH_DB, @@ -1776,8 +1777,7 @@ class _CppSourceFileWriter(_CppFileWriterBase): else: assert False, "Missing case" else: - self._writer.write_line('auto object = mongo::idl::preparsedValue<%s>();' % - common.title_case(struct.cpp_name)) + self._writer.write_line('%s object;' % common.title_case(struct.cpp_name)) self._writer.write_line(method_info.get_call('object')) self._writer.write_line('return object;') diff --git a/src/mongo/db/s/migration_destination_manager.cpp b/src/mongo/db/s/migration_destination_manager.cpp index 3c62eaa932d..7e5a9fbe72f 100644 --- a/src/mongo/db/s/migration_destination_manager.cpp +++ b/src/mongo/db/s/migration_destination_manager.cpp @@ -701,7 +701,7 @@ MigrationDestinationManager::getCollectionOptions(OperationContext* opCtx, fromOptionsBob.append(info["uuid"]); fromOptions = fromOptionsBob.obj(); - return {fromOptions, UUID::fromCDR(fromUUID)}; + return {fromOptions, fromUUID}; } void MigrationDestinationManager::_dropLocalIndexesIfNecessary( @@ -918,7 +918,7 @@ void MigrationDestinationManager::_migrateDriver(OperationContext* outerOpCtx) { "fromShard"_attr = _fromShard, "epoch"_attr = _epoch, "sessionId"_attr = *_sessionId, - "migrationId"_attr = _migrationId->toBSON()); + "migrationId"_attr = _migrationId.toBSON()); MoveTimingHelper timing( outerOpCtx, "to", _nss.ns(), _min, _max, 6 /* steps */, &_errmsg, _toShard, _fromShard); @@ -928,7 +928,7 @@ void MigrationDestinationManager::_migrateDriver(OperationContext* outerOpCtx) { if (initialState == ABORT) { LOGV2_ERROR(22013, "Migration abort requested before the migration started", - "migrationId"_attr = _migrationId->toBSON()); + "migrationId"_attr = _migrationId.toBSON()); return; } @@ -965,7 +965,7 @@ void MigrationDestinationManager::_migrateDriver(OperationContext* outerOpCtx) { "scheduled for deletion", "namespace"_attr = _nss.ns(), "range"_attr = redact(range.toString()), - "migrationId"_attr = _migrationId->toBSON()); + "migrationId"_attr = _migrationId.toBSON()); auto status = CollectionShardingRuntime::waitForClean( outerOpCtx, _nss, donorCollectionOptionsAndIndexes.uuid, range); @@ -979,7 +979,7 @@ void MigrationDestinationManager::_migrateDriver(OperationContext* outerOpCtx) { } // Insert a pending range deletion task for the incoming range. - RangeDeletionTask recipientDeletionTask(*_migrationId, + RangeDeletionTask recipientDeletionTask(_migrationId, _nss, donorCollectionOptionsAndIndexes.uuid, _fromShard, @@ -1099,7 +1099,7 @@ void MigrationDestinationManager::_migrateDriver(OperationContext* outerOpCtx) { LOGV2_WARNING( 22011, "secondaryThrottle on, but doc insert timed out; continuing", - "migrationId"_attr = _migrationId->toBSON()); + "migrationId"_attr = _migrationId.toBSON()); } else { uassertStatusOK(replStatus.status); } @@ -1177,7 +1177,7 @@ void MigrationDestinationManager::_migrateDriver(OperationContext* outerOpCtx) { if (getState() == ABORT) { LOGV2(22002, "Migration aborted while waiting for replication at catch up stage", - "migrationId"_attr = _migrationId->toBSON()); + "migrationId"_attr = _migrationId.toBSON()); return; } @@ -1190,7 +1190,7 @@ void MigrationDestinationManager::_migrateDriver(OperationContext* outerOpCtx) { if (i > 100) { LOGV2(22003, "secondaries having hard time keeping up with migrate", - "migrationId"_attr = _migrationId->toBSON()); + "migrationId"_attr = _migrationId.toBSON()); } sleepmillis(20); @@ -1212,12 +1212,12 @@ void MigrationDestinationManager::_migrateDriver(OperationContext* outerOpCtx) { LOGV2(22004, "Waiting for replication to catch up before entering critical section", - "migrationId"_attr = _migrationId->toBSON()); + "migrationId"_attr = _migrationId.toBSON()); LOGV2_DEBUG_OPTIONS(4817411, 2, {logv2::LogComponent::kShardMigrationPerf}, "Starting majority commit wait on recipient", - "migrationId"_attr = _migrationId->toBSON()); + "migrationId"_attr = _migrationId.toBSON()); runWithoutSession(outerOpCtx, [&] { auto awaitReplicationResult = @@ -1229,12 +1229,12 @@ void MigrationDestinationManager::_migrateDriver(OperationContext* outerOpCtx) { LOGV2(22005, "Chunk data replicated successfully.", - "migrationId"_attr = _migrationId->toBSON()); + "migrationId"_attr = _migrationId.toBSON()); LOGV2_DEBUG_OPTIONS(4817412, 2, {logv2::LogComponent::kShardMigrationPerf}, "Finished majority commit wait on recipient", - "migrationId"_attr = _migrationId->toBSON()); + "migrationId"_attr = _migrationId.toBSON()); } { @@ -1274,7 +1274,7 @@ void MigrationDestinationManager::_migrateDriver(OperationContext* outerOpCtx) { if (getState() == ABORT) { LOGV2(22006, "Migration aborted while transferring mods", - "migrationId"_attr = _migrationId->toBSON()); + "migrationId"_attr = _migrationId.toBSON()); return; } @@ -1407,7 +1407,7 @@ bool MigrationDestinationManager::_applyMigrateOp(OperationContext* opCtx, "reloaded remote document", "localDoc"_attr = redact(localDoc), "remoteDoc"_attr = redact(updatedDoc), - "migrationId"_attr = _migrationId->toBSON()); + "migrationId"_attr = _migrationId.toBSON()); } // We are in write lock here, so sure we aren't killing @@ -1438,7 +1438,7 @@ bool MigrationDestinationManager::_flushPendingWrites(OperationContext* opCtx, "chunkMin"_attr = redact(_min), "chunkMax"_attr = redact(_max), "lastOpApplied"_attr = op, - "migrationId"_attr = _migrationId->toBSON()); + "migrationId"_attr = _migrationId.toBSON()); } return false; } @@ -1449,7 +1449,7 @@ bool MigrationDestinationManager::_flushPendingWrites(OperationContext* opCtx, "namespace"_attr = _nss.ns(), "chunkMin"_attr = redact(_min), "chunkMax"_attr = redact(_max), - "migrationId"_attr = _migrationId->toBSON()); + "migrationId"_attr = _migrationId.toBSON()); return true; } diff --git a/src/mongo/db/s/migration_destination_manager.h b/src/mongo/db/s/migration_destination_manager.h index b90a56f52f1..761f8c9c4ef 100644 --- a/src/mongo/db/s/migration_destination_manager.h +++ b/src/mongo/db/s/migration_destination_manager.h @@ -234,7 +234,7 @@ private: stdx::thread _migrateThreadHandle; - boost::optional<UUID> _migrationId; + UUID _migrationId; LogicalSessionId _lsid; TxnNumber _txnNumber{kUninitializedTxnNumber}; NamespaceString _nss; diff --git a/src/mongo/idl/idl_parser.h b/src/mongo/idl/idl_parser.h index 17d7c803586..316ccd06c7e 100644 --- a/src/mongo/idl/idl_parser.h +++ b/src/mongo/idl/idl_parser.h @@ -37,7 +37,6 @@ #include "mongo/bson/bsonobjbuilder.h" #include "mongo/bson/bsontypes.h" #include "mongo/db/namespace_string.h" -#include "mongo/stdx/type_traits.h" namespace mongo { @@ -71,69 +70,6 @@ void idlSerialize(BSONObjBuilder* builder, StringData fieldName, std::vector<T> } } -/** - * A few overloads of `idlPreparsedValue` are built into IDL. See - * `preparsedValue` below. They are placed into a tiny private - * namespace which defines no types to isolate them. - */ -namespace preparsed_value_adl_barrier { - -/** - * This is the fallback for `idlPreparsedValue`. It value-initializes a `T` - * with a forwarded argument list in the usual way. - */ -template <typename T, typename... A> -auto idlPreparsedValue(stdx::type_identity<T>, A&&... a) { - return T(std::forward<A>(a)...); -} - -/** - * The value -1 is a conspicuous "uninitialized" value for integers. - * The integral type `bool` is exempt from this convention, however. - */ -template <typename T, std::enable_if_t<std::is_integral_v<T> && !std::is_same_v<bool, T>, int> = 0> -auto idlPreparsedValue(stdx::type_identity<T>) { - return static_cast<T>(-1); -} - -/** - * Define a default Feature Compatibility Version enum value for use in parsed - * ServerGlobalParams. - * TODO(SERVER-50101): Remove 'FeatureCompatibility::Version' once IDL supports - * a command cpp_type of C++ enum. - */ -inline auto idlPreparsedValue( - stdx::type_identity<ServerGlobalParams::FeatureCompatibility::Version>) { - return ServerGlobalParams::FeatureCompatibility::Version::kUnsetDefault44Behavior; -} - -} // namespace preparsed_value_adl_barrier - -/** - * Constructs an instance of `T(args...)` for use in idl parsing. The way the - * IDL generator currently writes C++ parse functions, it makes an instance of - * a field of type `T` and then mutates it. `preparsedValue<T>()` is used to - * construct those objects. This convention allows an extension hook whereby a - * type can select a custom initializer for such pre-parsed objects, - * particularly for types that shouldn't have a public default constructor. - * - * The extension hook is implemented via ADL on the name `idlPreparsedValue`. - * - * `idlPreparsedValue` takes a `type_identity<T>` and then some forwarded - * constructor arguments optionally (the IDL generator doesn't currently - * provide any such arguments but could conceivably do so in the future). A - * type `T` is deduced from this `type_identity<T>` argument. - * - * There are other ways to implement this extension mechanism, but this - * phrasing allows argument-dependent lookup to search the namespaces - * associated with `T`, since `T` is a template parameter of the - * `type_identity<T>` argument. - */ -template <typename T, typename... A> -T preparsedValue(A&&... args) { - using preparsed_value_adl_barrier::idlPreparsedValue; - return idlPreparsedValue(stdx::type_identity<T>{}, std::forward<A>(args)...); -} } // namespace idl diff --git a/src/mongo/s/catalog/type_chunk.h b/src/mongo/s/catalog/type_chunk.h index 1de86691f20..425edb9c4e2 100644 --- a/src/mongo/s/catalog/type_chunk.h +++ b/src/mongo/s/catalog/type_chunk.h @@ -39,7 +39,6 @@ #include "mongo/s/chunk_version.h" #include "mongo/s/shard_id.h" #include "mongo/s/shard_key_pattern.h" -#include "mongo/stdx/type_traits.h" namespace mongo { @@ -124,14 +123,17 @@ public: ChunkRange unionWith(ChunkRange const& other) const; private: + // For use with IDL parsing - limited to friend access only. + ChunkRange() = default; + + // Make the IDL generated parser a friend + friend class RangeDeletionTask; + friend class MigrationCoordinatorDocument; + BSONObj _minKey; BSONObj _maxKey; }; -inline ChunkRange idlPreparsedValue(stdx::type_identity<ChunkRange>) { - return ChunkRange{{}, {}}; -} - class ChunkHistory : public ChunkHistoryBase { public: ChunkHistory() : ChunkHistoryBase() {} diff --git a/src/mongo/util/uuid.h b/src/mongo/util/uuid.h index eade27480d6..a5e259a3c9a 100644 --- a/src/mongo/util/uuid.h +++ b/src/mongo/util/uuid.h @@ -40,20 +40,83 @@ #include "mongo/bson/bsonmisc.h" #include "mongo/bson/bsonobj.h" #include "mongo/logv2/log_attr.h" -#include "mongo/stdx/type_traits.h" namespace mongo { +namespace repl { +class CollectionInfo; +class OplogEntryBase; +class DurableReplOperation; +class InitialSyncIdDocument; +} // namespace repl + +namespace idl { +namespace import { +class One_UUID; +} // namespace import +} // namespace idl + /** * A UUID is a 128-bit unique identifier, per RFC 4122, v4, using * a secure random number generator. */ class UUID { + using UUIDStorage = std::array<unsigned char, 16>; + + // Make the IDL generated parser a friend + friend class ConfigsvrShardCollectionResponse; + friend class CommonReshardingMetadata; + friend class DonorAbortMigration; + friend class DonorStartMigration; + friend class DonorWaitForMigrationToCommit; + friend class DonorForgetMigration; + friend class DonorStateMachine; + friend class DatabaseVersion; + friend class DbCheckOplogCollection; + friend class EncryptionPlaceholder; + friend class ExternalKeysCollectionDocument; + friend class idl::import::One_UUID; + friend class IndexBuildEntry; + friend class KeyStoreRecord; + friend class ListCollectionsReplyInfo; + friend class LogicalSessionId; + friend class LogicalSessionToClient; + friend class LogicalSessionIdToClient; + friend class LogicalSessionFromClient; + friend class MigrationCoordinatorDocument; + friend class MigrationDestinationManager; + friend class MigrationRecipientCommonData; + friend class RangeDeletionTask; + friend class ResolvedKeyId; + friend class repl::CollectionInfo; + friend class repl::OplogEntryBase; + friend class repl::DurableReplOperation; + friend class repl::InitialSyncIdDocument; + friend class RecipientForgetMigration; + friend class RecipientSyncData; + friend class ReshardingDonorDocument; + friend class ReshardingSourceId; + friend class ResumeIndexInfo; + friend class ResumeTokenInternal; + friend class ShardCollectionTypeBase; + friend class ShardsvrCleanupReshardCollection; + friend class ShardsvrShardCollectionResponse; + friend class ShardsvrRenameCollection; + friend class TenantMigrationDonorDocument; + friend class TenantMigrationRecipientDocument; + friend class TestReshardCloneCollection; + friend class TypeCollectionRecipientFields; + friend class TypeCollectionReshardingFields; + friend class VoteCommitIndexBuild; + friend class ImportCollectionOplogEntry; + friend class VoteCommitImportCollection; + + public: /** * The number of bytes contained in a UUID. */ - static constexpr int kNumBytes = 16; + static constexpr int kNumBytes = sizeof(UUIDStorage); /** * Generate a new random v4 UUID per RFC 4122. @@ -80,7 +143,7 @@ public: static UUID parse(const BSONObj& obj); static UUID fromCDR(ConstDataRange cdr) { - UUID uuid{UUIDStorage{}}; + UUID uuid; invariant(cdr.length() == uuid._uuid.size()); memcpy(uuid._uuid.data(), cdr.data(), uuid._uuid.size()); return uuid; @@ -179,18 +242,19 @@ public: } private: - using UUIDStorage = std::array<unsigned char, kNumBytes>; - UUID(const UUIDStorage& uuid) : _uuid(uuid) {} + /** + * Should never be used, as the resulting UUID will not be unique. + * The exception is in code generated by the IDL compiler, which itself ensures + * such an invalid value cannot propagate. + */ + friend class LogicalSessionId; + UUID() = default; + UUIDStorage _uuid{}; // UUID in network byte order }; -/** Allow IDL-generated parsers to define uninitialized UUID objects. */ -inline auto idlPreparsedValue(stdx::type_identity<UUID>) { - return UUID::fromCDR(std::array<unsigned char, 16>{}); -} - inline std::ostream& operator<<(std::ostream& s, const UUID& uuid) { return (s << uuid.toString()); } |