Logo ROOT  
Reference Guide
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 
19 #include <ROOT/RColumnElement.hxx>
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 
29 namespace ROOT {
30 namespace Experimental {
31 namespace 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 
39 On the primitives data layer, the RColumn and RColumnElement are the equivalents to RField and RTreeValue on the
40 logical data layer.
41 */
42 // clang-format on
43 class RColumn {
44 private:
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 
68 public:
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 {
136  ClusterSize_t::ValueType nBatch = fCurrentPage.GetNElements() - idxInPage;
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 {
154  ClusterSize_t::ValueType nBatch = fCurrentPage.GetNElements() - idxInPage;
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; }
235  RPageSource *GetPageSource() const { return fPageSource; }
239 };
240 
241 } // namespace Detail
242 
243 } // namespace Experimental
244 } // namespace ROOT
245 
246 #endif
ROOT::Experimental::Detail::RColumn::GetClusterIndex
RClusterIndex GetClusterIndex(NTupleSize_t globalIndex)
Definition: RColumn.hxx:188
ROOT::Experimental::Detail::RColumn::Create
static RColumn * Create(const RColumnModel &model, std::uint32_t index)
Definition: RColumn.hxx:70
ROOT::Experimental::Detail::RColumn::fCurrentPage
RPage fCurrentPage
The currently mapped page for reading.
Definition: RColumn.hxx:60
ROOT::Experimental::Detail::RColumn::Connect
void Connect(DescriptorId_t fieldId, RPageStorage *pageStorage)
Definition: RColumn.cxx:43
ROOT::Experimental::Detail::RColumn::GetModel
const RColumnModel & GetModel() const
Definition: RColumn.hxx:232
ROOT::Experimental::Detail::RColumn::fHandleSource
RPageStorage::ColumnHandle_t fHandleSource
Definition: RColumn.hxx:54
ROOT::Experimental::Detail::RPage
A page is a slice of a column that is mapped into memory.
Definition: RPage.hxx:41
ROOT::Experimental::Detail::RColumn::GetCollectionInfo
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
ROOT::Experimental::Detail::RColumn::Map
CppT * Map(const NTupleSize_t globalIndex)
Definition: RColumn.hxx:162
ROOT::Experimental::Detail::RPage::TryGrow
void * TryGrow(ClusterSize_t::ValueType nElements)
Return a pointer after the last element that has space for nElements new elements.
Definition: RPage.hxx:107
ROOT::Experimental::DescriptorId_t
std::uint64_t DescriptorId_t
Distriniguishes elements of the same type within a descriptor, e.g. different fields.
Definition: RNTupleUtil.hxx:91
ROOT::Experimental::Detail::RPageStorage
Common functionality of an ntuple storage for both reading and writing.
Definition: RPageStorage.hxx:61
RPage.hxx
ROOT::Experimental::Detail::RColumnElementBase::GetSize
std::size_t GetSize() const
Definition: RColumnElement.hxx:102
ROOT::Experimental::Detail::RColumn::fIndex
std::uint32_t fIndex
Columns belonging to the same field are distinguished by their order.
Definition: RColumn.hxx:50
ROOT::Experimental::Detail::RColumn::GetIndex
std::uint32_t GetIndex() const
Definition: RColumn.hxx:233
ROOT::Experimental::Detail::RColumn::GetNElements
NTupleSize_t GetNElements() const
Definition: RColumn.hxx:230
ROOT::Experimental::NTupleSize_t
std::uint64_t NTupleSize_t
Integer type long enough to hold the maximum number of entries in a column.
Definition: RNTupleUtil.hxx:55
ROOT::Experimental::Detail::RPageSource
Abstract interface to read data from an ntuple.
Definition: RPageStorage.hxx:193
ROOT::Experimental::Detail::RPage::RClusterInfo::GetId
NTupleSize_t GetId() const
Definition: RPage.hxx:55
ROOT::Experimental::Detail::RColumn::fHandleSink
RPageStorage::ColumnHandle_t fHandleSink
Definition: RColumn.hxx:53
ROOT::Experimental::Detail::RColumn::GetColumnIdSource
ColumnId_t GetColumnIdSource() const
Definition: RColumn.hxx:234
ROOT::Experimental::Detail::RColumn::GetSwitchInfo
void GetSwitchInfo(NTupleSize_t globalIndex, RClusterIndex *varIndex, std::uint32_t *tag)
Get the currently active cluster id.
Definition: RColumn.hxx:221
ROOT::Experimental::Detail::RColumn::AppendV
void AppendV(const RColumnElementBase &elemArray, std::size_t count)
Definition: RColumn.hxx:94
ROOT::Experimental::Detail::RColumn::Append
void Append(const RColumnElementBase &element)
Definition: RColumn.hxx:83
ROOT::Experimental::Detail::RColumn::Flush
void Flush()
Definition: RColumn.cxx:62
ROOT::Experimental::RClusterIndex::GetIndex
ClusterSize_t::ValueType GetIndex() const
Definition: RNTupleUtil.hxx:116
ROOT::Experimental::Detail::RColumn::operator=
RColumn & operator=(const RColumn &)=delete
RPageStorage.hxx
ROOT::Experimental::Detail::RColumn::ReadV
void ReadV(const NTupleSize_t globalIndex, const ClusterSize_t::ValueType count, RColumnElementBase *elemArray)
Definition: RColumn.hxx:125
ROOT::Experimental::RNTupleVersion
For forward and backward compatibility, attach version information to the consitituents of the file f...
Definition: RNTupleUtil.hxx:127
ROOT::Experimental::Detail::RColumn::GetGlobalIndex
NTupleSize_t GetGlobalIndex(const RClusterIndex &clusterIndex)
Definition: RColumn.hxx:181
ROOT::Experimental::RClusterSize::ValueType
std::uint32_t ValueType
Definition: RNTupleUtil.hxx:59
ROOT::Experimental::Detail::RPage::GetClusterInfo
const RClusterInfo & GetClusterInfo() const
Definition: RPage.hxx:90
ROOT::Experimental::Detail::RColumn::fNElements
NTupleSize_t fNElements
The number of elements written resp. available in the column.
Definition: RColumn.hxx:58
ROOT::Experimental::Detail::RColumnElement
Pairs of C++ type and column type, like float and EColumnType::kReal32.
Definition: RColumnElement.hxx:109
ROOT::Experimental::Detail::RColumn::fElement
std::unique_ptr< RColumnElementBase > fElement
Used to pack and unpack pages on writing/reading.
Definition: RColumn.hxx:64
ROOT::Experimental::Detail::RPage::GetBuffer
void * GetBuffer() const
Definition: RPage.hxx:104
ROOT::Experimental::Detail::RColumn::GetVersion
RNTupleVersion GetVersion() const
Definition: RColumn.hxx:238
ROOT::Experimental::Detail::RColumn::fModel
RColumnModel fModel
Definition: RColumn.hxx:45
RColumnModel.hxx
ROOT::Experimental::Detail::RPage::GetGlobalRangeFirst
NTupleSize_t GetGlobalRangeFirst() const
Definition: RPage.hxx:84
ROOT::Experimental::Detail::RColumn::Read
void Read(const RClusterIndex &clusterIndex, RColumnElementBase *element)
Definition: RColumn.hxx:116
ROOT::Experimental::RClusterIndex::GetClusterId
DescriptorId_t GetClusterId() const
Definition: RNTupleUtil.hxx:115
ROOT::Experimental::Detail::RColumnElementBase::ReadFrom
void ReadFrom(void *source, std::size_t count)
Set the column element or an array of elements from the memory location source.
Definition: RColumnElement.hxx:81
ROOT::Experimental::Detail::RColumn::fColumnIdSource
ColumnId_t fColumnIdSource
The column id is used to find matching pages with content when reading.
Definition: RColumn.hxx:62
ROOT::Experimental::Detail::RPageStorage::RColumnHandle
Definition: RPageStorage.hxx:90
ROOT::Experimental::Detail::RColumn::RColumn
RColumn(const RColumnModel &model, std::uint32_t index)
Definition: RColumn.cxx:24
ROOT::Experimental::Detail::RPage::GetClusterRangeLast
ClusterSize_t::ValueType GetClusterRangeLast() const
Definition: RPage.hxx:87
ROOT::Experimental::RColumnModel
Holds the static meta-data of a column in a tree.
Definition: RColumnModel.hxx:61
ROOT::Experimental::Detail::RPageSink
Abstract interface to write data into an ntuple.
Definition: RPageStorage.hxx:129
ROOT::Experimental::Detail::RColumn::fPageSink
RPageSink * fPageSink
Definition: RColumn.hxx:51
ROOT::Experimental::Detail::RPage::Contains
bool Contains(NTupleSize_t globalIndex) const
Definition: RPage.hxx:92
ROOT::Experimental::Detail::RPage::RClusterInfo::GetIndexOffset
NTupleSize_t GetIndexOffset() const
Definition: RPage.hxx:56
RNTupleUtil.hxx
ROOT::Experimental::RClusterIndex
Addresses a column element or field item relative to a particular cluster, instead of a global NTuple...
Definition: RNTupleUtil.hxx:95
ROOT::Experimental::Detail::RColumn::~RColumn
~RColumn()
Definition: RColumn.cxx:31
ROOT::Experimental::RClusterSize
Wrap the 32bit integer in a struct in order to avoid template specialization clash with std::uint32_t...
Definition: RNTupleUtil.hxx:58
ROOT::Experimental::Detail::RColumn::GetHandleSource
RPageStorage::ColumnHandle_t GetHandleSource() const
Definition: RColumn.hxx:236
ROOT::Experimental::Detail::RPage::GetGlobalRangeLast
NTupleSize_t GetGlobalRangeLast() const
Definition: RPage.hxx:85
RColumnElement.hxx
R__ASSERT
#define R__ASSERT(e)
Definition: TError.h:120
ROOT::Experimental::Detail::RColumn::MapPage
void MapPage(const NTupleSize_t index)
Definition: RColumn.cxx:70
ROOT::Experimental::Detail::RColumn::GetPageSource
RPageSource * GetPageSource() const
Definition: RColumn.hxx:235
ROOT::Experimental::Detail::RColumn
Definition: RColumn.hxx:43
ROOT::Experimental::Detail::RPage::GetClusterRangeFirst
ClusterSize_t::ValueType GetClusterRangeFirst() const
Definition: RPage.hxx:86
ROOT::Experimental::Detail::RColumn::Read
void Read(const NTupleSize_t globalIndex, RColumnElementBase *element)
Definition: RColumn.hxx:106
ROOT::Experimental::Detail::RColumn::fHeadPage
RPage fHeadPage
Open page into which new elements are being written.
Definition: RColumn.hxx:56
ROOT::Experimental::Detail::RColumn::GetHandleSink
RPageStorage::ColumnHandle_t GetHandleSink() const
Definition: RColumn.hxx:237
make_cnn_model.model
model
Definition: make_cnn_model.py:6
ROOT::Experimental::Detail::RColumn::GetElement
RColumnElementBase * GetElement() const
Definition: RColumn.hxx:231
ROOT::Experimental::Detail::RPage::GetNElements
ClusterSize_t::ValueType GetNElements() const
Definition: RPage.hxx:83
ROOT::Experimental::Detail::RColumnElementBase
Definition: RColumnElement.hxx:48
ROOT::Experimental::Detail::RColumn::RColumn
RColumn(const RColumn &)=delete
ROOT::Experimental::ColumnId_t
std::int64_t ColumnId_t
Uniquely identifies a physical column within the scope of the current process, used to tag pages.
Definition: RNTupleUtil.hxx:87
ROOT::Experimental::Detail::RColumn::Map
CppT * Map(const RClusterIndex &clusterIndex)
Definition: RColumn.hxx:172
ROOT
tbb::task_arena is an alias of tbb::interface7::task_arena, which doesn't allow to forward declare tb...
Definition: EExecutionPolicy.hxx:4
ROOT::Experimental::Detail::RColumnElementBase::WriteTo
void WriteTo(void *destination, std::size_t count) const
Write one or multiple column elements into destination.
Definition: RColumnElement.hxx:76
ROOT::Experimental::Detail::RColumn::GetCollectionInfo
void GetCollectionInfo(const RClusterIndex &clusterIndex, RClusterIndex *collectionStart, ClusterSize_t *collectionSize)
Definition: RColumn.hxx:210
TError.h
ROOT::Experimental::Detail::RColumn::ReadV
void ReadV(const RClusterIndex &clusterIndex, const ClusterSize_t::ValueType count, RColumnElementBase *elemArray)
Definition: RColumn.hxx:143
ROOT::Experimental::Detail::RColumn::fPageSource
RPageSource * fPageSource
Definition: RColumn.hxx:52