Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
RColumn.hxx
Go to the documentation of this file.
1/// \file ROOT/RColumn.hxx
2/// \ingroup NTuple ROOT7
3/// \author Jakob Blomer <jblomer@cern.ch>
4/// \date 2018-10-09
5/// \warning This is part of the ROOT 7 prototype! It will change without notice. It might trigger earthquakes. Feedback
6/// is welcome!
7
8/*************************************************************************
9 * Copyright (C) 1995-2019, Rene Brun and Fons Rademakers. *
10 * All rights reserved. *
11 * *
12 * For the licensing terms see $ROOTSYS/LICENSE. *
13 * For the list of contributors see $ROOTSYS/README/CREDITS. *
14 *************************************************************************/
15
16#ifndef ROOT7_RColumn
17#define ROOT7_RColumn
18
20#include <ROOT/RColumnModel.hxx>
21#include <ROOT/RNTupleUtil.hxx>
22#include <ROOT/RPage.hxx>
23#include <ROOT/RPageStorage.hxx>
24
25#include <TError.h>
26
27#include <memory>
28
29namespace ROOT {
30namespace Experimental {
31namespace Detail {
32
33// clang-format off
34/**
35\class ROOT::Experimental::RColumn
36\ingroup NTuple
37\brief A column is a storage-backed array of a simple, fixed-size type, from which pages can be mapped into memory.
38
39On the primitives data layer, the RColumn and RColumnElement are the equivalents to RField and RTreeValue on the
40logical data layer.
41*/
42// clang-format on
43class RColumn {
44private:
46 /**
47 * Columns belonging to the same field are distinguished by their order. E.g. for an std::string field, there is
48 * the offset column with index 0 and the character value column with index 1.
49 */
50 std::uint32_t fIndex;
55 /// Open page into which new elements are being written
57 /// The number of elements written resp. available in the column
59 /// The currently mapped page for reading
61 /// The column id is used to find matching pages with content when reading
63 /// Used to pack and unpack pages on writing/reading
64 std::unique_ptr<RColumnElementBase> fElement;
65
66 RColumn(const RColumnModel &model, std::uint32_t index);
67
68public:
69 template <typename CppT, EColumnType ColumnT>
70 static RColumn *Create(const RColumnModel &model, std::uint32_t index) {
71 R__ASSERT(model.GetType() == ColumnT);
72 auto column = new RColumn(model, index);
73 column->fElement = std::unique_ptr<RColumnElementBase>(new RColumnElement<CppT, ColumnT>(nullptr));
74 return column;
75 }
76
77 RColumn(const RColumn&) = delete;
78 RColumn &operator =(const RColumn&) = delete;
79 ~RColumn();
80
81 void Connect(DescriptorId_t fieldId, RPageStorage *pageStorage);
82
83 void Append(const RColumnElementBase &element) {
84 void *dst = fHeadPage.TryGrow(1);
85 if (dst == nullptr) {
86 Flush();
87 dst = fHeadPage.TryGrow(1);
88 R__ASSERT(dst != nullptr);
89 }
90 element.WriteTo(dst, 1);
91 fNElements++;
92 }
93
94 void AppendV(const RColumnElementBase &elemArray, std::size_t count) {
95 void *dst = fHeadPage.TryGrow(count);
96 if (dst == nullptr) {
97 for (unsigned i = 0; i < count; ++i) {
98 Append(RColumnElementBase(elemArray, i));
99 }
100 return;
101 }
102 elemArray.WriteTo(dst, count);
103 fNElements += count;
104 }
105
106 void Read(const NTupleSize_t globalIndex, RColumnElementBase *element) {
107 if (!fCurrentPage.Contains(globalIndex)) {
108 MapPage(globalIndex);
109 R__ASSERT(fCurrentPage.Contains(globalIndex));
110 }
111 void *src = static_cast<unsigned char *>(fCurrentPage.GetBuffer()) +
112 (globalIndex - fCurrentPage.GetGlobalRangeFirst()) * element->GetSize();
113 element->ReadFrom(src, 1);
114 }
115
116 void Read(const RClusterIndex &clusterIndex, RColumnElementBase *element) {
117 if (!fCurrentPage.Contains(clusterIndex)) {
118 MapPage(clusterIndex);
119 }
120 void *src = static_cast<unsigned char *>(fCurrentPage.GetBuffer()) +
121 (clusterIndex.GetIndex() - fCurrentPage.GetClusterRangeFirst()) * element->GetSize();
122 element->ReadFrom(src, 1);
123 }
124
125 void ReadV(const NTupleSize_t globalIndex, const ClusterSize_t::ValueType count, RColumnElementBase *elemArray) {
126 R__ASSERT(count > 0);
127 if (!fCurrentPage.Contains(globalIndex)) {
128 MapPage(globalIndex);
129 }
130 NTupleSize_t idxInPage = globalIndex - fCurrentPage.GetGlobalRangeFirst();
131
132 void *src = static_cast<unsigned char *>(fCurrentPage.GetBuffer()) + idxInPage * elemArray->GetSize();
133 if (globalIndex + count <= fCurrentPage.GetGlobalRangeLast() + 1) {
134 elemArray->ReadFrom(src, count);
135 } else {
137 elemArray->ReadFrom(src, nBatch);
138 RColumnElementBase elemTail(*elemArray, nBatch);
139 ReadV(globalIndex + nBatch, count - nBatch, &elemTail);
140 }
141 }
142
143 void ReadV(const RClusterIndex &clusterIndex, const ClusterSize_t::ValueType count, RColumnElementBase *elemArray)
144 {
145 if (!fCurrentPage.Contains(clusterIndex)) {
146 MapPage(clusterIndex);
147 }
148 NTupleSize_t idxInPage = clusterIndex.GetIndex() - fCurrentPage.GetClusterRangeFirst();
149
150 void* src = static_cast<unsigned char *>(fCurrentPage.GetBuffer()) + idxInPage * elemArray->GetSize();
151 if (clusterIndex.GetIndex() + count <= fCurrentPage.GetClusterRangeLast() + 1) {
152 elemArray->ReadFrom(src, count);
153 } else {
155 elemArray->ReadFrom(src, nBatch);
156 RColumnElementBase elemTail(*elemArray, nBatch);
157 ReadV(RClusterIndex(clusterIndex.GetClusterId(), clusterIndex.GetIndex() + nBatch), count - nBatch, &elemTail);
158 }
159 }
160
161 template <typename CppT, EColumnType ColumnT>
162 CppT *Map(const NTupleSize_t globalIndex) {
163 if (!fCurrentPage.Contains(globalIndex)) {
164 MapPage(globalIndex);
165 }
166 return reinterpret_cast<CppT*>(
167 static_cast<unsigned char *>(fCurrentPage.GetBuffer()) +
169 }
170
171 template <typename CppT, EColumnType ColumnT>
172 CppT *Map(const RClusterIndex &clusterIndex) {
173 if (!fCurrentPage.Contains(clusterIndex)) {
174 MapPage(clusterIndex);
175 }
176 return reinterpret_cast<CppT*>(
177 static_cast<unsigned char *>(fCurrentPage.GetBuffer()) +
179 }
180
182 if (!fCurrentPage.Contains(clusterIndex)) {
183 MapPage(clusterIndex);
184 }
185 return fCurrentPage.GetClusterInfo().GetIndexOffset() + clusterIndex.GetIndex();
186 }
187
189 if (!fCurrentPage.Contains(globalIndex)) {
190 MapPage(globalIndex);
191 }
193 globalIndex - fCurrentPage.GetClusterInfo().GetIndexOffset());
194 }
195
196 /// For offset columns only, look at the two adjacent values that define a collection's coordinates
197 void GetCollectionInfo(const NTupleSize_t globalIndex, RClusterIndex *collectionStart, ClusterSize_t *collectionSize)
198 {
199 auto idxStart = (globalIndex == 0) ? 0 : *Map<ClusterSize_t, EColumnType::kIndex>(globalIndex - 1);
200 auto idxEnd = *Map<ClusterSize_t, EColumnType::kIndex>(globalIndex);
201 auto selfOffset = fCurrentPage.GetClusterInfo().GetIndexOffset();
202 if (globalIndex == selfOffset) {
203 // Passed cluster boundary
204 idxStart = 0;
205 }
206 *collectionSize = idxEnd - idxStart;
207 *collectionStart = RClusterIndex(fCurrentPage.GetClusterInfo().GetId(), idxStart);
208 }
209
210 void GetCollectionInfo(const RClusterIndex &clusterIndex,
211 RClusterIndex *collectionStart, ClusterSize_t *collectionSize)
212 {
213 auto index = clusterIndex.GetIndex();
214 auto idxStart = (index == 0) ? 0 : *Map<ClusterSize_t, EColumnType::kIndex>(clusterIndex - 1);
215 auto idxEnd = *Map<ClusterSize_t, EColumnType::kIndex>(clusterIndex);
216 *collectionSize = idxEnd - idxStart;
217 *collectionStart = RClusterIndex(clusterIndex.GetClusterId(), idxStart);
218 }
219
220 /// Get the currently active cluster id
221 void GetSwitchInfo(NTupleSize_t globalIndex, RClusterIndex *varIndex, std::uint32_t *tag) {
222 auto varSwitch = Map<RColumnSwitch, EColumnType::kSwitch>(globalIndex);
223 *varIndex = RClusterIndex(fCurrentPage.GetClusterInfo().GetId(), varSwitch->GetIndex());
224 *tag = varSwitch->GetTag();
225 }
226
227 void Flush();
228 void MapPage(const NTupleSize_t index);
229 void MapPage(const RClusterIndex &clusterIndex);
231 RColumnElementBase *GetElement() const { return fElement.get(); }
232 const RColumnModel &GetModel() const { return fModel; }
233 std::uint32_t GetIndex() const { return fIndex; }
239};
240
241} // namespace Detail
242
243} // namespace Experimental
244} // namespace ROOT
245
246#endif
#define R__ASSERT(e)
Definition TError.h:120
void WriteTo(void *destination, std::size_t count) const
Write one or multiple column elements into destination.
void ReadFrom(void *source, std::size_t count)
Set the column element or an array of elements from the memory location source.
Pairs of C++ type and column type, like float and EColumnType::kReal32.
static RColumn * Create(const RColumnModel &model, std::uint32_t index)
Definition RColumn.hxx:70
RPageStorage::ColumnHandle_t GetHandleSource() const
Definition RColumn.hxx:236
void ReadV(const NTupleSize_t globalIndex, const ClusterSize_t::ValueType count, RColumnElementBase *elemArray)
Definition RColumn.hxx:125
RColumn & operator=(const RColumn &)=delete
void GetCollectionInfo(const RClusterIndex &clusterIndex, RClusterIndex *collectionStart, ClusterSize_t *collectionSize)
Definition RColumn.hxx:210
const RColumnModel & GetModel() const
Definition RColumn.hxx:232
RPage fHeadPage
Open page into which new elements are being written.
Definition RColumn.hxx:56
ColumnId_t GetColumnIdSource() const
Definition RColumn.hxx:234
std::uint32_t GetIndex() const
Definition RColumn.hxx:233
void AppendV(const RColumnElementBase &elemArray, std::size_t count)
Definition RColumn.hxx:94
RColumnElementBase * GetElement() const
Definition RColumn.hxx:231
void Append(const RColumnElementBase &element)
Definition RColumn.hxx:83
RNTupleVersion GetVersion() const
Definition RColumn.hxx:238
CppT * Map(const NTupleSize_t globalIndex)
Definition RColumn.hxx:162
void Connect(DescriptorId_t fieldId, RPageStorage *pageStorage)
Definition RColumn.cxx:43
void MapPage(const NTupleSize_t index)
Definition RColumn.cxx:70
void GetSwitchInfo(NTupleSize_t globalIndex, RClusterIndex *varIndex, std::uint32_t *tag)
Get the currently active cluster id.
Definition RColumn.hxx:221
void Read(const NTupleSize_t globalIndex, RColumnElementBase *element)
Definition RColumn.hxx:106
NTupleSize_t GetGlobalIndex(const RClusterIndex &clusterIndex)
Definition RColumn.hxx:181
std::unique_ptr< RColumnElementBase > fElement
Used to pack and unpack pages on writing/reading.
Definition RColumn.hxx:64
NTupleSize_t GetNElements() const
Definition RColumn.hxx:230
RColumn(const RColumn &)=delete
RPage fCurrentPage
The currently mapped page for reading.
Definition RColumn.hxx:60
std::uint32_t fIndex
Columns belonging to the same field are distinguished by their order.
Definition RColumn.hxx:50
RPageStorage::ColumnHandle_t GetHandleSink() const
Definition RColumn.hxx:237
RPageSource * GetPageSource() const
Definition RColumn.hxx:235
NTupleSize_t fNElements
The number of elements written resp. available in the column.
Definition RColumn.hxx:58
ColumnId_t fColumnIdSource
The column id is used to find matching pages with content when reading.
Definition RColumn.hxx:62
CppT * Map(const RClusterIndex &clusterIndex)
Definition RColumn.hxx:172
void ReadV(const RClusterIndex &clusterIndex, const ClusterSize_t::ValueType count, RColumnElementBase *elemArray)
Definition RColumn.hxx:143
RPageStorage::ColumnHandle_t fHandleSink
Definition RColumn.hxx:53
void Read(const RClusterIndex &clusterIndex, RColumnElementBase *element)
Definition RColumn.hxx:116
RPageStorage::ColumnHandle_t fHandleSource
Definition RColumn.hxx:54
void GetCollectionInfo(const NTupleSize_t globalIndex, RClusterIndex *collectionStart, ClusterSize_t *collectionSize)
For offset columns only, look at the two adjacent values that define a collection's coordinates.
Definition RColumn.hxx:197
RClusterIndex GetClusterIndex(NTupleSize_t globalIndex)
Definition RColumn.hxx:188
Abstract interface to write data into an ntuple.
Abstract interface to read data from an ntuple.
Common functionality of an ntuple storage for both reading and writing.
A page is a slice of a column that is mapped into memory.
Definition RPage.hxx:41
ClusterSize_t::ValueType GetClusterRangeLast() const
Definition RPage.hxx:87
ClusterSize_t::ValueType GetNElements() const
Definition RPage.hxx:83
bool Contains(NTupleSize_t globalIndex) const
Definition RPage.hxx:92
const RClusterInfo & GetClusterInfo() const
Definition RPage.hxx:90
NTupleSize_t GetGlobalRangeFirst() const
Definition RPage.hxx:84
NTupleSize_t GetGlobalRangeLast() const
Definition RPage.hxx:85
void * TryGrow(ClusterSize_t::ValueType nElements)
Return a pointer after the last element that has space for nElements new elements.
Definition RPage.hxx:107
ClusterSize_t::ValueType GetClusterRangeFirst() const
Definition RPage.hxx:86
Addresses a column element or field item relative to a particular cluster, instead of a global NTuple...
DescriptorId_t GetClusterId() const
ClusterSize_t::ValueType GetIndex() const
Holds the static meta-data of a column in a tree.
For forward and backward compatibility, attach version information to the consitituents of the file f...
std::uint64_t NTupleSize_t
Integer type long enough to hold the maximum number of entries in a column.
std::uint64_t DescriptorId_t
Distriniguishes elements of the same type within a descriptor, e.g. different fields.
std::int64_t ColumnId_t
Uniquely identifies a physical column within the scope of the current process, used to tag pages.
tbb::task_arena is an alias of tbb::interface7::task_arena, which doesn't allow to forward declare tb...
Wrap the 32bit integer in a struct in order to avoid template specialization clash with std::uint32_t...