File indexing completed on 2025-09-15 09:11:45
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef ROOT_RPage
0015 #define ROOT_RPage
0016
0017 #include <ROOT/RNTupleUtil.hxx>
0018
0019 #include <cassert>
0020 #include <cstddef>
0021 #include <cstdint>
0022 #include <memory>
0023
0024 namespace ROOT {
0025 namespace Internal {
0026
0027 class RPageAllocator;
0028 class RPageRef;
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044 class RPage {
0045 friend class RPageRef;
0046
0047 public:
0048 static constexpr size_t kPageZeroSize = 64 * 1024;
0049
0050
0051
0052
0053 class RClusterInfo {
0054 private:
0055
0056 ROOT::DescriptorId_t fId = 0;
0057
0058 ROOT::NTupleSize_t fIndexOffset = 0;
0059
0060 public:
0061 RClusterInfo() = default;
0062 RClusterInfo(ROOT::NTupleSize_t id, ROOT::NTupleSize_t indexOffset) : fId(id), fIndexOffset(indexOffset) {}
0063 ROOT::NTupleSize_t GetId() const { return fId; }
0064 ROOT::NTupleSize_t GetIndexOffset() const { return fIndexOffset; }
0065 };
0066
0067 private:
0068 void *fBuffer = nullptr;
0069
0070 RPageAllocator *fPageAllocator = nullptr;
0071 std::uint32_t fElementSize = 0;
0072 std::uint32_t fNElements = 0;
0073
0074 std::uint32_t fMaxElements = 0;
0075 ROOT::NTupleSize_t fRangeFirst = 0;
0076 RClusterInfo fClusterInfo;
0077
0078 public:
0079 RPage() = default;
0080 RPage(void *buffer, RPageAllocator *pageAllocator, std::uint32_t elementSize, std::uint32_t maxElements)
0081 : fBuffer(buffer), fPageAllocator(pageAllocator), fElementSize(elementSize), fMaxElements(maxElements)
0082 {}
0083 RPage(const RPage &) = delete;
0084 RPage &operator=(const RPage &) = delete;
0085 RPage(RPage &&other)
0086 {
0087 fBuffer = other.fBuffer;
0088 fPageAllocator = other.fPageAllocator;
0089 fElementSize = other.fElementSize;
0090 fNElements = other.fNElements;
0091 fMaxElements = other.fMaxElements;
0092 fRangeFirst = other.fRangeFirst;
0093 fClusterInfo = other.fClusterInfo;
0094 other.fPageAllocator = nullptr;
0095 }
0096 RPage &operator=(RPage &&other)
0097 {
0098 if (this != &other) {
0099 std::swap(fBuffer, other.fBuffer);
0100 std::swap(fPageAllocator, other.fPageAllocator);
0101 std::swap(fElementSize, other.fElementSize);
0102 std::swap(fNElements, other.fNElements);
0103 std::swap(fMaxElements, other.fMaxElements);
0104 std::swap(fRangeFirst, other.fRangeFirst);
0105 std::swap(fClusterInfo, other.fClusterInfo);
0106 }
0107 return *this;
0108 }
0109 ~RPage();
0110
0111
0112 std::size_t GetNBytes() const
0113 {
0114 return static_cast<std::size_t>(fElementSize) * static_cast<std::size_t>(fNElements);
0115 }
0116 std::size_t GetCapacity() const
0117 {
0118 return static_cast<std::size_t>(fElementSize) * static_cast<std::size_t>(fMaxElements);
0119 }
0120 std::uint32_t GetElementSize() const { return fElementSize; }
0121 std::uint32_t GetNElements() const { return fNElements; }
0122 std::uint32_t GetMaxElements() const { return fMaxElements; }
0123 ROOT::NTupleSize_t GetGlobalRangeFirst() const { return fRangeFirst; }
0124 ROOT::NTupleSize_t GetGlobalRangeLast() const { return fRangeFirst + ROOT::NTupleSize_t(fNElements) - 1; }
0125 ROOT::NTupleSize_t GetLocalRangeFirst() const { return fRangeFirst - fClusterInfo.GetIndexOffset(); }
0126 ROOT::NTupleSize_t GetLocalRangeLast() const { return GetLocalRangeFirst() + ROOT::NTupleSize_t(fNElements) - 1; }
0127 const RClusterInfo& GetClusterInfo() const { return fClusterInfo; }
0128
0129 bool Contains(ROOT::NTupleSize_t globalIndex) const
0130 {
0131 return (globalIndex >= fRangeFirst) && (globalIndex < fRangeFirst + ROOT::NTupleSize_t(fNElements));
0132 }
0133
0134 bool Contains(RNTupleLocalIndex localIndex) const
0135 {
0136 if (fClusterInfo.GetId() != localIndex.GetClusterId())
0137 return false;
0138 auto clusterRangeFirst = fRangeFirst - fClusterInfo.GetIndexOffset();
0139 return (localIndex.GetIndexInCluster() >= clusterRangeFirst) &&
0140 (localIndex.GetIndexInCluster() < clusterRangeFirst + fNElements);
0141 }
0142
0143 void* GetBuffer() const { return fBuffer; }
0144
0145
0146
0147
0148
0149
0150 void *GrowUnchecked(std::uint32_t nElements)
0151 {
0152 assert(fNElements + nElements <= fMaxElements);
0153 auto offset = GetNBytes();
0154 fNElements += nElements;
0155 return static_cast<unsigned char *>(fBuffer) + offset;
0156 }
0157
0158 void SetWindow(const ROOT::NTupleSize_t rangeFirst, const RClusterInfo &clusterInfo)
0159 {
0160 fClusterInfo = clusterInfo;
0161 fRangeFirst = rangeFirst;
0162 }
0163
0164 void Reset(ROOT::NTupleSize_t rangeFirst)
0165 {
0166 fNElements = 0;
0167 fRangeFirst = rangeFirst;
0168 }
0169 void ResetCluster(const RClusterInfo &clusterInfo) { fNElements = 0; fClusterInfo = clusterInfo; }
0170
0171
0172 static const void *GetPageZeroBuffer();
0173
0174 bool IsNull() const { return fBuffer == nullptr; }
0175 bool IsEmpty() const { return fNElements == 0; }
0176 bool operator ==(const RPage &other) const { return fBuffer == other.fBuffer; }
0177 bool operator !=(const RPage &other) const { return !(*this == other); }
0178 };
0179
0180 }
0181 }
0182
0183 #endif