Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:12:26

0001 // @(#)root/io:$Id$
0002 // Author: Philippe Canal 05/2010
0003 
0004 /*************************************************************************
0005  * Copyright (C) 1995-2004, Rene Brun and Fons Rademakers.               *
0006  * All rights reserved.                                                  *
0007  *                                                                       *
0008  * For the licensing terms see $ROOTSYS/LICENSE.                         *
0009  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
0010  *************************************************************************/
0011 
0012 #ifndef ROOT_TStreamerInfoActions
0013 #define ROOT_TStreamerInfoActions
0014 
0015 #include <memory>
0016 #include <vector>
0017 
0018 #include "TStreamerInfo.h"
0019 #include "TVirtualArray.h"
0020 
0021 /**
0022 \class TStreamerInfoActions::TConfiguration
0023 \ingroup IO
0024 */
0025 
0026 namespace TStreamerInfoActions {
0027 
0028    /// Base class of the Configurations.
0029    class TConfiguration {
0030    protected:
0031    public:
0032       typedef TStreamerInfo::TCompInfo_t TCompInfo_t;
0033       TVirtualStreamerInfo *fInfo;    ///< TStreamerInfo form which the action is derived
0034       UInt_t                fElemId;  ///< Identifier of the TStreamerElement
0035       TCompInfo_t          *fCompInfo;///< Access to compiled information (for legacy code)
0036       Int_t                 fOffset;  ///< Offset within the object
0037       UInt_t                fLength;  ///< Number of element in a fixed length array.
0038    public:
0039       TConfiguration(TVirtualStreamerInfo *info, UInt_t id, TCompInfo_t *compinfo, Int_t offset) : fInfo(info), fElemId(id), fCompInfo(compinfo), fOffset(offset),fLength(1) {};
0040       TConfiguration(TVirtualStreamerInfo *info, UInt_t id, TCompInfo_t *compinfo, Int_t offset, UInt_t length) : fInfo(info), fElemId(id), fCompInfo(compinfo), fOffset(offset),fLength(length) {};
0041       virtual ~TConfiguration() {};
0042 
0043       virtual void AddToOffset(Int_t delta);
0044       virtual void SetMissing();
0045 
0046       virtual TConfiguration *Copy() { return new TConfiguration(*this); }
0047 
0048       virtual void Print() const;
0049       virtual void PrintDebug(TBuffer &buffer, void *object) const;
0050    };
0051 
0052    /// Base class of the Configurations for the member wise looping routines.
0053    class TLoopConfiguration {
0054    public:
0055       TVirtualCollectionProxy *fProxy = nullptr;
0056    public:
0057       TLoopConfiguration() = default;
0058       TLoopConfiguration(TVirtualCollectionProxy *proxy) : fProxy(proxy) {}
0059 
0060       // virtual void PrintDebug(TBuffer &buffer, void *object) const;
0061       virtual ~TLoopConfiguration() {};
0062       virtual void Print() const;
0063       virtual void *GetFirstAddress(void *start, const void *end) const = 0;
0064       virtual TLoopConfiguration* Copy() const = 0; // { return new TLoopConfiguration(*this); }
0065       virtual TVirtualCollectionProxy* GetCollectionProxy() const { return fProxy; }
0066    };
0067 
0068    typedef TVirtualCollectionProxy::Next_t Next_t;
0069 
0070    typedef Int_t (*TStreamerInfoAction_t)(TBuffer &buf, void *obj, const TConfiguration *conf);
0071    typedef Int_t (*TStreamerInfoVecPtrLoopAction_t)(TBuffer &buf, void *iter, const void *end, const TConfiguration *conf);
0072    typedef Int_t (*TStreamerInfoLoopAction_t)(TBuffer &buf, void *iter, const void *end, const TLoopConfiguration *loopconf, const TConfiguration *conf);
0073 
0074    class TConfiguredAction : public TObject {
0075    public:
0076       union {
0077          TStreamerInfoAction_t           fAction;
0078          TStreamerInfoVecPtrLoopAction_t fVecPtrLoopAction;
0079          TStreamerInfoLoopAction_t       fLoopAction;
0080       };
0081       TConfiguration              *fConfiguration;
0082    private:
0083       // assignment operator must be the default because the 'copy' constructor is actually a move constructor and must be used.
0084    public:
0085       TConfiguredAction() : fAction(nullptr), fConfiguration(nullptr) {}
0086       TConfiguredAction(const TConfiguredAction &rval) : TObject(rval), fAction(rval.fAction), fConfiguration(rval.fConfiguration)
0087       {
0088          // WARNING: Technically this is a move constructor ...
0089          const_cast<TConfiguredAction&>(rval).fConfiguration = nullptr;
0090       }
0091       TConfiguredAction &operator=(const TConfiguredAction &rval)
0092       {
0093          // WARNING: Technically this is a move assignment!.
0094 
0095          TConfiguredAction tmp(rval); // this does a move.
0096          TObject::operator=(tmp);     // we are missing TObject::Swap
0097          std::swap(fAction,tmp.fAction);
0098          std::swap(fConfiguration,tmp.fConfiguration);
0099          return *this;
0100       };
0101 
0102       TConfiguredAction(TStreamerInfoAction_t action, TConfiguration *conf) : fAction(action), fConfiguration(conf)
0103       {
0104          // Usual constructor.
0105       }
0106       TConfiguredAction(TStreamerInfoVecPtrLoopAction_t action, TConfiguration *conf) : fVecPtrLoopAction(action), fConfiguration(conf)
0107       {
0108          // Usual constructor.
0109       }
0110       TConfiguredAction(TStreamerInfoLoopAction_t action, TConfiguration *conf) : fLoopAction(action), fConfiguration(conf)
0111       {
0112          // Usual constructor.
0113       }
0114       ~TConfiguredAction() override {
0115          // Usual destructor.
0116          // Idea: the configuration ownership might be moved to a single list so that
0117          // we can shared them between the optimized and non-optimized list of actions.
0118          delete fConfiguration;
0119       }
0120       void PrintDebug(TBuffer &buffer, void *object) const;
0121 
0122       inline Int_t operator()(TBuffer &buffer, void *object) const {
0123          return fAction(buffer, object, fConfiguration);
0124       }
0125 
0126       inline Int_t operator()(TBuffer &buffer, void *start_collection, const void *end_collection) const {
0127          return fVecPtrLoopAction(buffer, start_collection, end_collection, fConfiguration);
0128       }
0129 
0130       inline Int_t operator()(TBuffer &buffer, void *start_collection, const void *end_collection, const TLoopConfiguration *loopconf) const {
0131          return fLoopAction(buffer, start_collection, end_collection, loopconf, fConfiguration);
0132       }
0133 
0134       ClassDefOverride(TConfiguredAction,0); // A configured action
0135    };
0136 
0137    struct TIDNode;
0138    using TIDs = std::vector<TIDNode>;
0139 
0140    // Hold information about unfolded/extracted StreamerElement for
0141    // a sub-object
0142    struct TNestedIDs {
0143       TNestedIDs() = default;
0144       TNestedIDs(TStreamerInfo *info, Int_t offset);
0145       ~TNestedIDs();
0146 
0147       TStreamerInfo *fInfo = nullptr; ///< Not owned.
0148       TVirtualArray *fOnfileObject = nullptr;
0149       Bool_t         fOwnOnfileObject = kFALSE;
0150       Int_t          fOffset;
0151       TIDs           fIDs;
0152    };
0153 
0154    // A 'node' in the list of StreamerElement ID, either
0155    // the index of the element in the current streamerInfo
0156    // or a set of unfolded/extracted StreamerElement for a sub-object.
0157    struct TIDNode {
0158       TIDNode() = default;
0159       TIDNode(Int_t id) : fElemID(id), fElement(nullptr), fInfo(nullptr) {}
0160       TIDNode(TStreamerInfo *info, Int_t offset) : fElemID(-1), fElement(nullptr), fInfo(nullptr)  {
0161          fNestedIDs = std::make_unique<TNestedIDs>(info, offset);
0162       }
0163       Int_t fElemID = -1;
0164       TStreamerElement *fElement = nullptr;
0165       TStreamerInfo *fInfo = nullptr;
0166       std::unique_ptr<TNestedIDs> fNestedIDs;
0167    };
0168 
0169    inline TNestedIDs::TNestedIDs(TStreamerInfo *info, Int_t offset) : fInfo(info), fOffset(offset) {}
0170    inline TNestedIDs::~TNestedIDs() {
0171          if (fOwnOnfileObject)
0172             delete fOnfileObject;
0173       }
0174 
0175 
0176    typedef std::vector<TConfiguredAction> ActionContainer_t;
0177    class TActionSequence : public TObject {
0178       TActionSequence() {};
0179    public:
0180       enum class EStatusBits {
0181          kVectorPtrLooper = BIT(14)
0182       };
0183 
0184       struct SequencePtr;
0185       using SequenceGetter_t = SequencePtr(*)(TStreamerInfo *info, TVirtualCollectionProxy *collectionProxy, TClass *originalClass);
0186 
0187       TActionSequence(TVirtualStreamerInfo *info, UInt_t maxdata, Bool_t isForVecPtr = kFALSE)
0188          : fStreamerInfo(info), fLoopConfig(nullptr)
0189       {
0190          if (isForVecPtr)
0191             SetBit((UInt_t)EStatusBits::kVectorPtrLooper);
0192          fActions.reserve(maxdata);
0193       };
0194       ~TActionSequence() override {
0195          delete fLoopConfig;
0196       }
0197 
0198       template <typename action_t>
0199       void AddAction( action_t action, TConfiguration *conf ) {
0200          fActions.emplace_back( action, conf );
0201       }
0202       void AddAction(const TConfiguredAction &action ) {
0203          fActions.push_back( action );
0204       }
0205 
0206       Bool_t IsForVectorPtrLooper() const {
0207          return TestBit((UInt_t)EStatusBits::kVectorPtrLooper);
0208       }
0209 
0210       TVirtualStreamerInfo *fStreamerInfo; ///< StreamerInfo used to derive these actions.
0211       TLoopConfiguration   *fLoopConfig;   ///< If this is a bundle of memberwise streaming action, this configures the looping
0212       ActionContainer_t     fActions;
0213 
0214       void AddToOffset(Int_t delta);
0215       void SetMissing();
0216 
0217       TActionSequence *CreateCopy();
0218       static TActionSequence *CreateReadMemberWiseActions(TVirtualStreamerInfo *info, TVirtualCollectionProxy &proxy);
0219       static TActionSequence *CreateWriteMemberWiseActions(TVirtualStreamerInfo *info, TVirtualCollectionProxy &proxy);
0220       TActionSequence *CreateSubSequence(const std::vector<Int_t> &element_ids, size_t offset);
0221 
0222       TActionSequence *CreateSubSequence(const TIDs &element_ids, size_t offset, SequenceGetter_t create);
0223       void AddToSubSequence(TActionSequence *sequence, const TIDs &element_ids, Int_t offset, SequenceGetter_t create);
0224 
0225       void Print(Option_t * = "") const override;
0226 
0227       // Maybe owner unique_ptr
0228       struct SequencePtr {
0229          TStreamerInfoActions::TActionSequence *fSequence = nullptr;
0230          Bool_t fOwner = kFALSE;
0231 
0232          SequencePtr() = default;
0233 
0234          SequencePtr(SequencePtr &&from) : fSequence(from.fSequence), fOwner(from.fOwner) {
0235             from.fOwner = false;
0236          }
0237 
0238          SequencePtr(TStreamerInfoActions::TActionSequence *sequence,  Bool_t owner) : fSequence(sequence), fOwner(owner) {}
0239 
0240          ~SequencePtr() {
0241             if (fOwner) delete fSequence;
0242          }
0243 
0244          // Accessor to the pointee.
0245          TStreamerInfoActions::TActionSequence &operator*() const {
0246             return *fSequence;
0247          }
0248 
0249          // Accessor to the pointee
0250          TStreamerInfoActions::TActionSequence *operator->() const {
0251             return fSequence;
0252          }
0253 
0254          // Return true is the pointee is not nullptr.
0255          operator bool() {
0256             return fSequence != nullptr;
0257          }
0258       };
0259 
0260       // SequenceGetter_t implementations
0261 
0262       static SequencePtr ReadMemberWiseActionsCollectionGetter(TStreamerInfo *info, TVirtualCollectionProxy * /* collectionProxy */, TClass * /* originalClass */) {
0263          auto seq = info->GetReadMemberWiseActions(kTRUE);
0264          return {seq, kFALSE};
0265       }
0266       static SequencePtr ConversionReadMemberWiseActionsViaProxyGetter(TStreamerInfo *info, TVirtualCollectionProxy *collectionProxy, TClass *originalClass) {
0267          auto seq = collectionProxy->GetConversionReadMemberWiseActions(originalClass, info->GetClassVersion());
0268          return {seq, kFALSE};
0269       }
0270       static SequencePtr ReadMemberWiseActionsViaProxyGetter(TStreamerInfo *info, TVirtualCollectionProxy *collectionProxy, TClass * /* originalClass */) {
0271          auto seq = collectionProxy->GetReadMemberWiseActions(info->GetClassVersion());
0272          return {seq, kFALSE};
0273       }
0274       static SequencePtr ReadMemberWiseActionsCollectionCreator(TStreamerInfo *info, TVirtualCollectionProxy *collectionProxy, TClass * /* originalClass */) {
0275          auto seq = TStreamerInfoActions::TActionSequence::CreateReadMemberWiseActions(info,*collectionProxy);
0276          return {seq, kTRUE};
0277       }
0278       // Creator5() = Creator1;
0279       static SequencePtr ReadMemberWiseActionsGetter(TStreamerInfo *info, TVirtualCollectionProxy * /* collectionProxy */, TClass * /* originalClass */) {
0280          auto seq = info->GetReadMemberWiseActions(kFALSE);
0281          return {seq, kFALSE};
0282       }
0283 
0284       static SequencePtr WriteMemberWiseActionsCollectionGetter(TStreamerInfo *info, TVirtualCollectionProxy * /* collectionProxy */, TClass * /* originalClass */) {
0285          auto seq = info->GetWriteMemberWiseActions(kTRUE);
0286          return {seq, kFALSE};
0287       }
0288       static SequencePtr WriteMemberWiseActionsViaProxyGetter(TStreamerInfo *, TVirtualCollectionProxy *collectionProxy, TClass * /* originalClass */) {
0289          auto seq = collectionProxy->GetWriteMemberWiseActions();
0290          return {seq, kFALSE};
0291       }
0292       static SequencePtr WriteMemberWiseActionsCollectionCreator(TStreamerInfo *info, TVirtualCollectionProxy *collectionProxy, TClass * /* originalClass */) {
0293          auto seq = TStreamerInfoActions::TActionSequence::CreateWriteMemberWiseActions(info,*collectionProxy);
0294          return {seq, kTRUE};
0295       }
0296       // Creator5() = Creator1;
0297       static SequencePtr WriteMemberWiseActionsGetter(TStreamerInfo *info, TVirtualCollectionProxy * /* collectionProxy */, TClass * /* originalClass */) {
0298          auto seq = info->GetWriteMemberWiseActions(kFALSE);
0299          return {seq, kFALSE};
0300       }
0301       ClassDefOverride(TActionSequence,0);
0302    };
0303 
0304 }
0305 
0306 #endif // ROOT_TStreamerInfoActions
0307 
0308