Logo ROOT  
Reference Guide
Loading...
Searching...
No Matches
RPage.hxx
Go to the documentation of this file.
1/// \file ROOT/RPage.hxx
2/// \author Jakob Blomer <jblomer@cern.ch>
3/// \date 2018-10-09
4
5/*************************************************************************
6 * Copyright (C) 1995-2019, Rene Brun and Fons Rademakers. *
7 * All rights reserved. *
8 * *
9 * For the licensing terms see $ROOTSYS/LICENSE. *
10 * For the list of contributors see $ROOTSYS/README/CREDITS. *
11 *************************************************************************/
12
13#ifndef ROOT_RPage
14#define ROOT_RPage
15
16#include <ROOT/RNTupleTypes.hxx>
17
18#include <cassert>
19#include <cstddef>
20#include <cstdint>
21#include <memory>
22
23namespace ROOT {
24namespace Internal {
25
26class RPageAllocator;
27class RPageRef;
28
29// clang-format off
30/**
31\class ROOT::Internal::RPage
32\ingroup NTuple
33\brief A page is a slice of a column that is mapped into memory
34
35The page provides an opaque memory buffer for uncompressed, unpacked data. It does not interpret
36the contents but it does now about the size (and thus the number) of the elements inside as well as the element
37number range within the backing column/cluster.
38For reading, pages are allocated and filled by the page source and then registered with the page pool.
39For writing, the page sink allocates uninitialized pages of a given size.
40The page has a pointer to its memory allocator so that it can release itself.
41*/
42// clang-format on
43class RPage {
44 friend class RPageRef;
45
46public:
47 static constexpr size_t kPageZeroSize = 64 * 1024;
48
49 /**
50 * Stores information about the cluster in which this page resides.
51 */
53 private:
54 /// The cluster number
56 /// The first element index of the column in this cluster
58
59 public:
60 RClusterInfo() = default;
62 ROOT::DescriptorId_t GetId() const { return fId; }
64 };
65
66private:
67 void *fBuffer = nullptr;
68 /// The allocator used to allocate fBuffer. Can be null if the buffer doesn't need to be freed.
70 std::uint32_t fElementSize = 0;
71 std::uint32_t fNElements = 0;
72 /// The capacity of the page in number of elements
73 std::uint32_t fMaxElements = 0;
76
77public:
78 RPage() = default;
79 RPage(void *buffer, RPageAllocator *pageAllocator, std::uint32_t elementSize, std::uint32_t maxElements)
80 : fBuffer(buffer), fPageAllocator(pageAllocator), fElementSize(elementSize), fMaxElements(maxElements)
81 {}
82 RPage(const RPage &) = delete;
83 RPage &operator=(const RPage &) = delete;
84 RPage(RPage &&other)
85 {
86 fBuffer = other.fBuffer;
87 fPageAllocator = other.fPageAllocator;
88 fElementSize = other.fElementSize;
89 fNElements = other.fNElements;
90 fMaxElements = other.fMaxElements;
91 fRangeFirst = other.fRangeFirst;
92 fClusterInfo = other.fClusterInfo;
93 other.fPageAllocator = nullptr;
94 }
96 {
97 if (this != &other) {
98 std::swap(fBuffer, other.fBuffer);
99 std::swap(fPageAllocator, other.fPageAllocator);
100 std::swap(fElementSize, other.fElementSize);
101 std::swap(fNElements, other.fNElements);
102 std::swap(fMaxElements, other.fMaxElements);
103 std::swap(fRangeFirst, other.fRangeFirst);
104 std::swap(fClusterInfo, other.fClusterInfo);
105 }
106 return *this;
107 }
108 ~RPage();
109
110 /// The space taken by column elements in the buffer
111 std::size_t GetNBytes() const
112 {
113 return static_cast<std::size_t>(fElementSize) * static_cast<std::size_t>(fNElements);
114 }
115 std::size_t GetCapacity() const
116 {
117 return static_cast<std::size_t>(fElementSize) * static_cast<std::size_t>(fMaxElements);
118 }
119 std::uint32_t GetElementSize() const { return fElementSize; }
120 std::uint32_t GetNElements() const { return fNElements; }
121 std::uint32_t GetMaxElements() const { return fMaxElements; }
124 ROOT::NTupleSize_t GetLocalRangeFirst() const { return fRangeFirst - fClusterInfo.GetIndexOffset(); }
126 const RClusterInfo& GetClusterInfo() const { return fClusterInfo; }
127
128 bool Contains(ROOT::NTupleSize_t globalIndex) const
129 {
130 return (globalIndex >= fRangeFirst) && (globalIndex < fRangeFirst + ROOT::NTupleSize_t(fNElements));
131 }
132
133 bool Contains(RNTupleLocalIndex localIndex) const
134 {
135 if (fClusterInfo.GetId() != localIndex.GetClusterId())
136 return false;
137 auto clusterRangeFirst = fRangeFirst - fClusterInfo.GetIndexOffset();
138 return (localIndex.GetIndexInCluster() >= clusterRangeFirst) &&
139 (localIndex.GetIndexInCluster() < clusterRangeFirst + fNElements);
140 }
141
142 void* GetBuffer() const { return fBuffer; }
143 /// Increases the number elements in the page. The caller is responsible to respect the page capacity,
144 /// i.e. to ensure that fNElements + nElements <= fMaxElements.
145 /// Returns a pointer after the last element, which is used during writing in anticipation of the caller filling
146 /// nElements in the page.
147 /// When reading a page from disk, GrowUnchecked is used to set the actual number of elements. In this case, the
148 /// return value is ignored.
149 void *GrowUnchecked(std::uint32_t nElements)
150 {
151 assert(fNElements + nElements <= fMaxElements);
152 auto offset = GetNBytes();
153 fNElements += nElements;
154 return static_cast<unsigned char *>(fBuffer) + offset;
155 }
156 /// Seek the page to a certain position of the column
157 void SetWindow(const ROOT::NTupleSize_t rangeFirst, const RClusterInfo &clusterInfo)
158 {
159 fClusterInfo = clusterInfo;
160 fRangeFirst = rangeFirst;
161 }
162 /// Forget all currently stored elements (size == 0) and set a new starting index.
163 void Reset(ROOT::NTupleSize_t rangeFirst)
164 {
165 fNElements = 0;
166 fRangeFirst = rangeFirst;
167 }
168 void ResetCluster(const RClusterInfo &clusterInfo) { fNElements = 0; fClusterInfo = clusterInfo; }
169
170 /// Return a pointer to the page zero buffer used if there is no on-disk data for a particular deferred column
171 static const void *GetPageZeroBuffer();
172
173 bool IsNull() const { return fBuffer == nullptr; }
174 bool IsEmpty() const { return fNElements == 0; }
175 bool operator ==(const RPage &other) const { return fBuffer == other.fBuffer; }
176 bool operator !=(const RPage &other) const { return !(*this == other); }
177}; // class RPage
178
179} // namespace Internal
180} // namespace ROOT
181
182#endif
XFontStruct * id
Definition TGX11.cxx:147
Abstract interface to allocate and release pages.
Reference to a page stored in the page pool.
Stores information about the cluster in which this page resides.
Definition RPage.hxx:52
ROOT::NTupleSize_t GetIndexOffset() const
Definition RPage.hxx:63
ROOT::NTupleSize_t fIndexOffset
The first element index of the column in this cluster.
Definition RPage.hxx:57
RClusterInfo(ROOT::DescriptorId_t id, ROOT::NTupleSize_t indexOffset)
Definition RPage.hxx:61
ROOT::DescriptorId_t GetId() const
Definition RPage.hxx:62
ROOT::DescriptorId_t fId
The cluster number.
Definition RPage.hxx:55
bool IsNull() const
Definition RPage.hxx:173
ROOT::NTupleSize_t GetGlobalRangeLast() const
Definition RPage.hxx:123
RPage(void *buffer, RPageAllocator *pageAllocator, std::uint32_t elementSize, std::uint32_t maxElements)
Definition RPage.hxx:79
std::uint32_t GetNElements() const
Definition RPage.hxx:120
RClusterInfo fClusterInfo
Definition RPage.hxx:75
std::size_t GetNBytes() const
The space taken by column elements in the buffer.
Definition RPage.hxx:111
void * GrowUnchecked(std::uint32_t nElements)
Increases the number elements in the page.
Definition RPage.hxx:149
RPage & operator=(RPage &&other)
Definition RPage.hxx:95
bool operator==(const RPage &other) const
Definition RPage.hxx:175
RPage(RPage &&other)
Definition RPage.hxx:84
friend class RPageRef
Definition RPage.hxx:44
std::uint32_t fNElements
Definition RPage.hxx:71
void Reset(ROOT::NTupleSize_t rangeFirst)
Forget all currently stored elements (size == 0) and set a new starting index.
Definition RPage.hxx:163
void * GetBuffer() const
Definition RPage.hxx:142
ROOT::NTupleSize_t GetLocalRangeLast() const
Definition RPage.hxx:125
static constexpr size_t kPageZeroSize
Definition RPage.hxx:47
std::uint32_t GetElementSize() const
Definition RPage.hxx:119
static const void * GetPageZeroBuffer()
Return a pointer to the page zero buffer used if there is no on-disk data for a particular deferred c...
Definition RPage.cxx:22
std::uint32_t GetMaxElements() const
Definition RPage.hxx:121
std::size_t GetCapacity() const
Definition RPage.hxx:115
RPageAllocator * fPageAllocator
The allocator used to allocate fBuffer. Can be null if the buffer doesn't need to be freed.
Definition RPage.hxx:69
std::uint32_t fMaxElements
The capacity of the page in number of elements.
Definition RPage.hxx:73
RPage & operator=(const RPage &)=delete
bool Contains(ROOT::NTupleSize_t globalIndex) const
Definition RPage.hxx:128
ROOT::NTupleSize_t fRangeFirst
Definition RPage.hxx:74
bool operator!=(const RPage &other) const
Definition RPage.hxx:176
RPage(const RPage &)=delete
void SetWindow(const ROOT::NTupleSize_t rangeFirst, const RClusterInfo &clusterInfo)
Seek the page to a certain position of the column.
Definition RPage.hxx:157
std::uint32_t fElementSize
Definition RPage.hxx:70
const RClusterInfo & GetClusterInfo() const
Definition RPage.hxx:126
ROOT::NTupleSize_t GetGlobalRangeFirst() const
Definition RPage.hxx:122
ROOT::NTupleSize_t GetLocalRangeFirst() const
Definition RPage.hxx:124
bool Contains(RNTupleLocalIndex localIndex) const
Definition RPage.hxx:133
bool IsEmpty() const
Definition RPage.hxx:174
void ResetCluster(const RClusterInfo &clusterInfo)
Definition RPage.hxx:168
Addresses a column element or field item relative to a particular cluster, instead of a global NTuple...
ROOT::NTupleSize_t GetIndexInCluster() const
ROOT::DescriptorId_t GetClusterId() const
std::uint64_t DescriptorId_t
Distriniguishes elements of the same type within a descriptor, e.g. different fields.
std::uint64_t NTupleSize_t
Integer type long enough to hold the maximum number of entries in a column.