diff options
author | ijon <ijon@yandex-team.com> | 2023-03-28 16:34:01 +0300 |
---|---|---|
committer | ijon <ijon@yandex-team.com> | 2023-03-28 16:34:01 +0300 |
commit | 0e6ffae60c698b05a5d4d086260319c32b7a5568 (patch) | |
tree | 9c4b0816c938567ae0282c529fa5408f1df388ed | |
parent | c6cb670ad64833f1478698f88c022bc3d0a26aae (diff) | |
download | ydb-0e6ffae60c698b05a5d4d086260319c32b7a5568.tar.gz |
schemeshard: replace TTxOperationReply generation-by-macro with proper templates
Let templates do their work.
Use SCHEMESHARD_INCOMING_EVENTS only to make explicit template instantiations
(for TTxOperationReply and CreateTxOperationReply()).
-rw-r--r-- | ydb/core/tx/schemeshard/schemeshard__operation.cpp | 160 | ||||
-rw-r--r-- | ydb/core/tx/schemeshard/schemeshard_impl.h | 8 | ||||
-rw-r--r-- | ydb/core/tx/schemeshard/schemeshard_types.h | 13 |
3 files changed, 102 insertions, 79 deletions
diff --git a/ydb/core/tx/schemeshard/schemeshard__operation.cpp b/ydb/core/tx/schemeshard/schemeshard__operation.cpp index 975e515928..ac5dfee785 100644 --- a/ydb/core/tx/schemeshard/schemeshard__operation.cpp +++ b/ydb/core/tx/schemeshard/schemeshard__operation.cpp @@ -385,75 +385,84 @@ void OutOfScopeEventHandler<TEvDataShard::TEvSchemaChanged>(const TEvDataShard:: template <class TEvType> -struct TSchemeShard::TTxOperationReply {}; - -#define DefineTTxOperationReply(TEvType, TxType) \ - template<> \ - struct TSchemeShard::TTxOperationReply<TEvType>: public NTabletFlatExecutor::TTransactionBase<TSchemeShard> { \ - TOperationId OperationId; \ - TEvType::TPtr EvReply; \ - TSideEffects OnComplete; \ - TMemoryChanges MemChanges; \ - TStorageChanges DbChanges; \ -\ - TTxType GetTxType() const override { return TxType; } \ -\ - TTxOperationReply(TSchemeShard* self, TOperationId id, TEvType::TPtr& ev) \ - : TBase(self) \ - , OperationId(id) \ - , EvReply(ev) \ - { \ - Y_VERIFY(TEvType::EventType != TEvPrivate::TEvOperationPlan::EventType); \ - Y_VERIFY(TEvType::EventType != TEvTxProcessing::TEvPlanStep::EventType); \ - } \ -\ - bool Execute(NTabletFlatExecutor::TTransactionContext& txc, const TActorContext& ctx) override { \ - LOG_DEBUG_S(ctx, NKikimrServices::FLAT_TX_SCHEMESHARD, \ - "TTxOperationReply<" #TEvType "> execute" \ - << ", operationId: " << OperationId \ - << ", at schemeshard: " << Self->TabletID() \ - << ", message: " << ISubOperationState::DebugReply(EvReply)); \ - if (!Self->Operations.contains(OperationId.GetTxId())) { \ - LOG_DEBUG_S(ctx, NKikimrServices::FLAT_TX_SCHEMESHARD, \ - "TTxOperationReply<" #TEvType "> execute" \ - << ", operationId: " << OperationId \ - << ", at schemeshard: " << Self->TabletID() \ - << ", operation unknown"); \ - TOperationContext context{Self, txc, ctx, OnComplete, MemChanges, DbChanges}; \ - OutOfScopeEventHandler<TEvType>(EvReply, context); \ - return true; \ - } \ - TOperation::TPtr operation = Self->Operations.at(OperationId.GetTxId()); \ - if (operation->DoneParts.contains(OperationId.GetSubTxId())) { \ - LOG_DEBUG_S(ctx, NKikimrServices::FLAT_TX_SCHEMESHARD, \ - "TTxOperationReply<" #TEvType "> execute" \ - << ", operationId: " << OperationId \ - << ", at schemeshard: " << Self->TabletID() \ - << ", operation part is already done"); \ - TOperationContext context{Self, txc, ctx, OnComplete, MemChanges, DbChanges}; \ - OutOfScopeEventHandler<TEvType>(EvReply, context); \ - return true; \ - } \ - ISubOperation::TPtr part = operation->Parts.at(ui64(OperationId.GetSubTxId())); \ - TOperationContext context{Self, txc, ctx, OnComplete, MemChanges, DbChanges}; \ - Y_VERIFY(EvReply); \ - part->HandleReply(EvReply, context); \ - OnComplete.ApplyOnExecute(Self, txc, ctx); \ - DbChanges.Apply(Self, txc, ctx); \ - return true; \ - } \ - \ - void Complete(const TActorContext& ctx) override { \ - LOG_DEBUG_S(ctx, NKikimrServices::FLAT_TX_SCHEMESHARD, "TTxOperationReply<" #TEvType "> complete" \ - << ", operationId: " << OperationId \ - << ", at schemeshard: " << Self->TabletID() \ - ); \ - OnComplete.ApplyOnComplete(Self, ctx); \ - } \ +struct TTxTypeFrom; + +#define DefineTxTypeFromSpecialization(TEvType, TxTypeValue) \ + template <> \ + struct TTxTypeFrom<TEvType> { \ + static constexpr TTxType TxType = TxTypeValue; \ }; - SCHEMESHARD_INCOMING_EVENTS(DefineTTxOperationReply) -#undef DefineTxOperationReply + SCHEMESHARD_INCOMING_EVENTS(DefineTxTypeFromSpecialization) +#undef DefineTxTypeFromSpecialization + + +template <class TEvType> +struct TTxOperationReply : public NTabletFlatExecutor::TTransactionBase<TSchemeShard> { + TOperationId OperationId; + typename TEvType::TPtr EvReply; + TSideEffects OnComplete; + TMemoryChanges MemChanges; + TStorageChanges DbChanges; + + TTxType GetTxType() const override { + return TTxTypeFrom<TEvType>::TxType; + } + + TTxOperationReply(TSchemeShard* self, TOperationId id, typename TEvType::TPtr& ev) + : TBase(self) + , OperationId(id) + , EvReply(ev) + { + Y_VERIFY(TEvType::EventType != TEvPrivate::TEvOperationPlan::EventType); + Y_VERIFY(TEvType::EventType != TEvTxProcessing::TEvPlanStep::EventType); + } + + bool Execute(NTabletFlatExecutor::TTransactionContext& txc, const TActorContext& ctx) override { + LOG_DEBUG_S(ctx, NKikimrServices::FLAT_TX_SCHEMESHARD, + "TTxOperationReply<" << EvReply->GetTypeName() << "> execute" + << ", operationId: " << OperationId + << ", at schemeshard: " << Self->TabletID() + << ", message: " << ISubOperationState::DebugReply(EvReply)); + if (!Self->Operations.contains(OperationId.GetTxId())) { + LOG_DEBUG_S(ctx, NKikimrServices::FLAT_TX_SCHEMESHARD, + "TTxOperationReply<" << EvReply->GetTypeName() << "> execute " + << ", operationId: " << OperationId + << ", at schemeshard: " << Self->TabletID() + << ", operation unknown"); + TOperationContext context{Self, txc, ctx, OnComplete, MemChanges, DbChanges}; + OutOfScopeEventHandler<TEvType>(EvReply, context); + return true; + } + TOperation::TPtr operation = Self->Operations.at(OperationId.GetTxId()); + if (operation->DoneParts.contains(OperationId.GetSubTxId())) { + LOG_DEBUG_S(ctx, NKikimrServices::FLAT_TX_SCHEMESHARD, + "TTxOperationReply<" << EvReply->GetTypeName() << "> execute" + << ", operationId: " << OperationId + << ", at schemeshard: " << Self->TabletID() + << ", operation part is already done"); + TOperationContext context{Self, txc, ctx, OnComplete, MemChanges, DbChanges}; + OutOfScopeEventHandler<TEvType>(EvReply, context); + return true; + } + ISubOperation::TPtr part = operation->Parts.at(ui64(OperationId.GetSubTxId())); + TOperationContext context{Self, txc, ctx, OnComplete, MemChanges, DbChanges}; + Y_VERIFY(EvReply); + part->HandleReply(EvReply, context); + OnComplete.ApplyOnExecute(Self, txc, ctx); + DbChanges.Apply(Self, txc, ctx); + return true; + } + + void Complete(const TActorContext& ctx) override { + LOG_DEBUG_S(ctx, NKikimrServices::FLAT_TX_SCHEMESHARD, "TTxOperationReply<" << EvReply->GetTypeName() << "> complete" + << ", operationId: " << OperationId + << ", at schemeshard: " << Self->TabletID() + ); + OnComplete.ApplyOnComplete(Self, ctx); + } +}; + struct TSchemeShard::TTxOperationPlanStep: public NTabletFlatExecutor::TTransactionBase<TSchemeShard> { TEvTxProcessing::TEvPlanStep::TPtr Ev; @@ -554,13 +563,18 @@ NTabletFlatExecutor::ITransaction* TSchemeShard::CreateTxOperationProgress(TOper return new TTxOperationProgress(this, opId); } -#define DefineCreateTxOperationReply(TEvType, TxType) \ - NTabletFlatExecutor::ITransaction* TSchemeShard::CreateTxOperationReply(TOperationId id, TEvType::TPtr& ev) { \ - return new TTxOperationReply<TEvType>(this, id, ev); \ - } +template <EventBasePtr TEvPtr> +NTabletFlatExecutor::ITransaction* TSchemeShard::CreateTxOperationReply(TOperationId id, TEvPtr& ev) { + using TEvType = typename EventTypeFromTEvPtr<TEvPtr>::type; + return new TTxOperationReply<TEvType>(this, id, ev); +} + +#define DefineCreateTxOperationReplyFunc(TEvType, ...) \ + template NTabletFlatExecutor::ITransaction* TSchemeShard::CreateTxOperationReply(TOperationId id, TEvType::TPtr& ev); + + SCHEMESHARD_INCOMING_EVENTS(DefineCreateTxOperationReplyFunc) +#undef DefineCreateTxOperationReplyFunc - SCHEMESHARD_INCOMING_EVENTS(DefineCreateTxOperationReply) -#undef DefineTxOperationReply TString JoinPath(const TString& workingDir, const TString& name) { Y_VERIFY(!name.StartsWith('/') && !name.EndsWith('/')); diff --git a/ydb/core/tx/schemeshard/schemeshard_impl.h b/ydb/core/tx/schemeshard/schemeshard_impl.h index 7f3046f3e7..75a3701fd8 100644 --- a/ydb/core/tx/schemeshard/schemeshard_impl.h +++ b/ydb/core/tx/schemeshard/schemeshard_impl.h @@ -875,12 +875,8 @@ public: struct TTxLogin; NTabletFlatExecutor::ITransaction* CreateTxLogin(TEvSchemeShard::TEvLogin::TPtr &ev); - - template<class T> struct TTxOperationReply; -#define DeclareCreateTxOperationReply(TEvType, TxType) \ - NTabletFlatExecutor::ITransaction* CreateTxOperationReply(TOperationId id, TEvType::TPtr& ev); - SCHEMESHARD_INCOMING_EVENTS(DeclareCreateTxOperationReply) -#undef DeclareCreateTxOperationReply + template <EventBasePtr TEvPtr> + NTabletFlatExecutor::ITransaction* CreateTxOperationReply(TOperationId id, TEvPtr& ev); void PublishToSchemeBoard(THashMap<TTxId, TDeque<TPathId>>&& paths, const TActorContext& ctx); void PublishToSchemeBoard(TTxId txId, TDeque<TPathId>&& paths, const TActorContext& ctx); diff --git a/ydb/core/tx/schemeshard/schemeshard_types.h b/ydb/core/tx/schemeshard/schemeshard_types.h index dfb3bdcedf..e2dfbe42c9 100644 --- a/ydb/core/tx/schemeshard/schemeshard_types.h +++ b/ydb/core/tx/schemeshard/schemeshard_types.h @@ -9,6 +9,19 @@ namespace NKikimr::NSchemeShard { +// Concept for TEventBase::TPtr +template <class TEvPtr> +concept EventBasePtr = requires { typename TEvPtr::TValueType; } && std::is_base_of_v<IEventHandle, typename TEvPtr::TValueType>; + +// Deduce TEventType from its own TEventType::TPtr. +template <EventBasePtr TEvPtr> +struct EventTypeFromTEvPtr { + // TEventType::TPtr is TAutoPtr<TEventHandle*<TEventType>>. + // Retrieve TEventType through return type of TEventHandle*::Get(). + using type = typename std::remove_pointer<decltype(std::declval<typename TEvPtr::TValueType>().Get())>::type; + // It would help if TEventHandle* had an explicit type alias to wrapped TEventType +}; + struct TSchemeLimits { // Used for backward compatability in case of old databases without explicit limits static constexpr ui64 MaxPathsCompat = 200*1000; |