Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-08-16 09:21:11

0001 /// \file ROOT/RField/RFieldSoA.hxx
0002 /// \ingroup NTuple
0003 /// \author Jakob Blomer <jblomer@cern.ch>
0004 /// \date 2026-03-03
0005 
0006 /*************************************************************************
0007  * Copyright (C) 1995-2026, Rene Brun and Fons Rademakers.               *
0008  * All rights reserved.                                                  *
0009  *                                                                       *
0010  * For the licensing terms see $ROOTSYS/LICENSE.                         *
0011  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
0012  *************************************************************************/
0013 
0014 #ifndef ROOT_RField_SoA
0015 #define ROOT_RField_SoA
0016 
0017 #ifndef ROOT_RField
0018 #error "Please include RField.hxx!"
0019 #endif
0020 
0021 #include <ROOT/RFieldBase.hxx>
0022 #include <ROOT/RNTupleTypes.hxx>
0023 
0024 #include <cstddef>
0025 #include <memory>
0026 #include <string_view>
0027 #include <typeinfo>
0028 #include <vector>
0029 
0030 class TClass;
0031 
0032 namespace ROOT {
0033 
0034 namespace Experimental {
0035 
0036 /// The SoA field provides I/O for an in-memory SoA layout linked to an on-disk collection of the underlying record.
0037 /// As a concrete example, for an underlying record type
0038 /// \code{.cpp}
0039 /// struct PointRecord {
0040 ///    float px, py;
0041 /// };
0042 /// \endcode
0043 /// a corresponding SoA layout will look like
0044 /// \code{.cpp}
0045 /// struct PointSoA {
0046 ///    ROOT::RVec<float> px;
0047 ///    ROOT::RVec<float> py;
0048 /// };
0049 /// \endcode
0050 ///
0051 /// The SoA type has to be marked in the dictionary with the rntupleSoARecord attribute.
0052 ///
0053 /// Since the on-disk representation is a collection of record type, the class version and checksum of the SoA type
0054 /// itself is ignored.
0055 class RSoAField : public RFieldBase {
0056    class RSoADeleter : public RDeleter {
0057    private:
0058       TClass *fSoAClass;
0059 
0060    public:
0061       explicit RSoADeleter(TClass *cl) : fSoAClass(cl) {}
0062       void operator()(void *objPtr, bool dtorOnly) final;
0063    };
0064 
0065    TClass *fSoAClass = nullptr;
0066    std::vector<RFieldBase *> fRecordMemberFields; ///< Direct access to the member fields of the underlying record
0067    /// The offset of the RVec members in the SoA type in the order of subfields of the underlying record type.
0068    /// In particular, the order is not necessarily the same then the order of RVec members in the SoA class.
0069    std::vector<std::size_t> fSoAMemberOffsets;
0070    std::size_t fMaxAlignment = 1;
0071    ROOT::Internal::RColumnIndex fNWritten;
0072 
0073    RSoAField(std::string_view fieldName, const RSoAField &source); ///< Used by CloneImpl
0074    RSoAField(std::string_view fieldName, TClass *clSoA);
0075 
0076 protected:
0077    std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final;
0078 
0079    const RColumnRepresentations &GetColumnRepresentations() const final;
0080    void GenerateColumns() final;
0081    void GenerateColumns(const ROOT::RNTupleDescriptor &desc) final;
0082 
0083    void ConstructValue(void *where) const final;
0084    std::unique_ptr<RDeleter> GetDeleter() const final { return std::make_unique<RSoADeleter>(fSoAClass); }
0085 
0086    std::size_t AppendImpl(const void *from) final;
0087    void ReadGlobalImpl(ROOT::NTupleSize_t globalIndex, void *to) final;
0088 
0089    void ReconcileOnDiskField(const RNTupleDescriptor &) final {}
0090 
0091    void CommitClusterImpl() final { fNWritten = 0; }
0092 
0093 public:
0094    RSoAField(std::string_view fieldName, std::string_view className);
0095    RSoAField(RSoAField &&other) = default;
0096    RSoAField &operator=(RSoAField &&other) = default;
0097    ~RSoAField() override = default;
0098 
0099    std::vector<RValue> SplitValue(const RValue &value) const final;
0100    size_t GetValueSize() const final;
0101    size_t GetAlignment() const final { return fMaxAlignment; }
0102    std::uint32_t GetTypeVersion() const final;
0103    std::uint32_t GetTypeChecksum() const final;
0104    /// For polymorphic classes (that declare or inherit at least one virtual method), return the expected dynamic type
0105    /// of any user object. If the class is not polymorphic, return nullptr.
0106    /// TODO(jblomer): use information in unique pointer field
0107    const std::type_info *GetPolymorphicTypeInfo() const;
0108    // TODO(jblomer)
0109    // void AcceptVisitor(ROOT::Detail::RFieldVisitor &visitor) const final;
0110 
0111    TClass *GetSoAClass() const { return fSoAClass; }
0112 };
0113 
0114 } // namespace Experimental
0115 } // namespace ROOT
0116 
0117 #endif // ROOT_RField_SoA