diff options
| author | ijon <[email protected]> | 2023-03-28 16:34:01 +0300 | 
|---|---|---|
| committer | ijon <[email protected]> | 2023-03-28 16:34:01 +0300 | 
| commit | 0e6ffae60c698b05a5d4d086260319c32b7a5568 (patch) | |
| tree | 9c4b0816c938567ae0282c529fa5408f1df388ed | |
| parent | c6cb670ad64833f1478698f88c022bc3d0a26aae (diff) | |
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 975e515928c..ac5dfee7859 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 7f3046f3e76..75a3701fd80 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 dfb3bdcedfb..e2dfbe42c99 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; | 
