Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:10:46

0001 /// \file ROOT/RNTupleUtil.hxx
0002 /// \ingroup NTuple ROOT7
0003 /// \author Jakob Blomer <jblomer@cern.ch>
0004 /// \date 2018-10-04
0005 /// \warning This is part of the ROOT 7 prototype! It will change without notice. It might trigger earthquakes. Feedback
0006 /// is welcome!
0007 
0008 /*************************************************************************
0009  * Copyright (C) 1995-2020, Rene Brun and Fons Rademakers.               *
0010  * All rights reserved.                                                  *
0011  *                                                                       *
0012  * For the licensing terms see $ROOTSYS/LICENSE.                         *
0013  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
0014  *************************************************************************/
0015 
0016 #ifndef ROOT7_RNTupleUtil
0017 #define ROOT7_RNTupleUtil
0018 
0019 #include <cstdint>
0020 
0021 #include <string>
0022 #include <variant>
0023 
0024 #include <ROOT/RLogger.hxx>
0025 
0026 namespace ROOT {
0027 namespace Experimental {
0028 
0029 class RLogChannel;
0030 /// Log channel for RNTuple diagnostics.
0031 RLogChannel &NTupleLog();
0032 
0033 /**
0034  * The fields in the ntuple model tree can carry different structural information about the type system.
0035  * Leaf fields contain just data, collection fields resolve to offset columns, record fields have no
0036  * materialization on the primitive column layer.
0037  */
0038 enum ENTupleStructure {
0039    kLeaf,
0040    kCollection,
0041    kRecord,
0042    kVariant,
0043    kReference, // unimplemented so far
0044    kInvalid,
0045 };
0046 
0047 /// Integer type long enough to hold the maximum number of entries in a column
0048 using NTupleSize_t = std::uint64_t;
0049 constexpr NTupleSize_t kInvalidNTupleIndex = std::uint64_t(-1);
0050 /// Wrap the integer in a struct in order to avoid template specialization clash with std::uint64_t
0051 struct RClusterSize {
0052    using ValueType = std::uint64_t;
0053 
0054    RClusterSize() : fValue(0) {}
0055    explicit constexpr RClusterSize(ValueType value) : fValue(value) {}
0056    RClusterSize& operator =(const ValueType value) { fValue = value; return *this; }
0057    RClusterSize& operator +=(const ValueType value) { fValue += value; return *this; }
0058    RClusterSize operator++(int) { auto result = *this; fValue++; return result; }
0059    operator ValueType() const { return fValue; }
0060 
0061    ValueType fValue;
0062 };
0063 using ClusterSize_t = RClusterSize;
0064 constexpr ClusterSize_t kInvalidClusterIndex(std::uint64_t(-1));
0065 
0066 constexpr int kUnknownCompressionSettings = -1;
0067 
0068 /// Helper types to present an offset column as array of collection sizes.
0069 /// See RField<RNTupleCardinality<SizeT>> for details.
0070 template <typename SizeT>
0071 struct RNTupleCardinality {
0072    static_assert(std::is_same_v<SizeT, std::uint32_t> || std::is_same_v<SizeT, std::uint64_t>,
0073                  "RNTupleCardinality is only supported with std::uint32_t or std::uint64_t template parameters");
0074 
0075    using ValueType = SizeT;
0076 
0077    RNTupleCardinality() : fValue(0) {}
0078    explicit constexpr RNTupleCardinality(ValueType value) : fValue(value) {}
0079    RNTupleCardinality &operator=(const ValueType value)
0080    {
0081       fValue = value;
0082       return *this;
0083    }
0084    operator ValueType() const { return fValue; }
0085 
0086    ValueType fValue;
0087 };
0088 
0089 /// Holds the index and the tag of a kSwitch column
0090 class RColumnSwitch {
0091 private:
0092    ClusterSize_t fIndex;
0093    std::uint32_t fTag = 0;
0094 
0095 public:
0096    RColumnSwitch() = default;
0097    RColumnSwitch(ClusterSize_t index, std::uint32_t tag) : fIndex(index), fTag(tag) { }
0098    ClusterSize_t GetIndex() const { return fIndex; }
0099    std::uint32_t GetTag() const { return fTag; }
0100 };
0101 
0102 /// Uniquely identifies a physical column within the scope of the current process, used to tag pages
0103 using ColumnId_t = std::int64_t;
0104 constexpr ColumnId_t kInvalidColumnId = -1;
0105 
0106 /// Distriniguishes elements of the same type within a descriptor, e.g. different fields
0107 using DescriptorId_t = std::uint64_t;
0108 constexpr DescriptorId_t kInvalidDescriptorId = std::uint64_t(-1);
0109 
0110 /// Addresses a column element or field item relative to a particular cluster, instead of a global NTupleSize_t index
0111 class RClusterIndex {
0112 private:
0113    DescriptorId_t fClusterId = kInvalidDescriptorId;
0114    ClusterSize_t::ValueType fIndex = kInvalidClusterIndex;
0115 public:
0116    RClusterIndex() = default;
0117    RClusterIndex(const RClusterIndex &other) = default;
0118    RClusterIndex &operator =(const RClusterIndex &other) = default;
0119    constexpr RClusterIndex(DescriptorId_t clusterId, ClusterSize_t::ValueType index)
0120       : fClusterId(clusterId), fIndex(index) {}
0121 
0122    RClusterIndex  operator+(ClusterSize_t::ValueType off) const { return RClusterIndex(fClusterId, fIndex + off); }
0123    RClusterIndex  operator-(ClusterSize_t::ValueType off) const { return RClusterIndex(fClusterId, fIndex - off); }
0124    RClusterIndex  operator++(int) /* postfix */        { auto r = *this; fIndex++; return r; }
0125    RClusterIndex& operator++()    /* prefix */         { ++fIndex; return *this; }
0126    bool operator==(RClusterIndex other) const { return fClusterId == other.fClusterId && fIndex == other.fIndex; }
0127    bool operator!=(RClusterIndex other) const { return !(*this == other); }
0128 
0129    DescriptorId_t GetClusterId() const { return fClusterId; }
0130    ClusterSize_t::ValueType GetIndex() const { return fIndex; }
0131 };
0132 
0133 /// RNTupleLocator payload that is common for object stores using 64bit location information.
0134 /// This might not contain the full location of the content. In particular, for page locators this information may be
0135 /// used in conjunction with the cluster and column ID.
0136 struct RNTupleLocatorObject64 {
0137    std::uint64_t fLocation = 0;
0138    bool operator==(const RNTupleLocatorObject64 &other) const { return fLocation == other.fLocation; }
0139 };
0140 
0141 /// Generic information about the physical location of data. Values depend on the concrete storage type.  E.g.,
0142 /// for a local file `fPosition` might be a 64bit file offset. Referenced objects on storage can be compressed
0143 /// and therefore we need to store their actual size.
0144 /// TODO(jblomer): consider moving this to `RNTupleDescriptor`
0145 struct RNTupleLocator {
0146    /// Values for the _Type_ field in non-disk locators.  Serializable types must have the MSb == 0; see
0147    /// `doc/specifications.md` for details
0148    enum ELocatorType : std::uint8_t {
0149       kTypeFile = 0x00,
0150       kTypeURI = 0x01,
0151       kTypeDAOS = 0x02,
0152 
0153       kLastSerializableType = 0x7f,
0154       kTypePageZero = kLastSerializableType + 1,
0155    };
0156 
0157    /// Simple on-disk locators consisting of a 64-bit offset use variant type `uint64_t`; extended locators have
0158    /// `fPosition.index()` > 0
0159    std::variant<std::uint64_t, std::string, RNTupleLocatorObject64> fPosition;
0160    std::uint32_t fBytesOnStorage = 0;
0161    /// For non-disk locators, the value for the _Type_ field. This makes it possible to have different type values even
0162    /// if the payload structure is identical.
0163    ELocatorType fType = kTypeFile;
0164    /// Reserved for use by concrete storage backends
0165    std::uint8_t fReserved = 0;
0166 
0167    bool operator==(const RNTupleLocator &other) const {
0168       return fPosition == other.fPosition && fBytesOnStorage == other.fBytesOnStorage && fType == other.fType;
0169    }
0170    template <typename T>
0171    const T &GetPosition() const
0172    {
0173       return std::get<T>(fPosition);
0174    }
0175 };
0176 
0177 namespace Internal {
0178 template <typename T>
0179 auto MakeAliasedSharedPtr(T *rawPtr)
0180 {
0181    const static std::shared_ptr<T> fgRawPtrCtrlBlock;
0182    return std::shared_ptr<T>(fgRawPtrCtrlBlock, rawPtr);
0183 }
0184 } // namespace Internal
0185 
0186 } // namespace Experimental
0187 } // namespace ROOT
0188 
0189 #endif