Logo ROOT   6.18/05
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
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#include <vector>
29
30namespace ROOT {
31namespace Experimental {
32namespace Detail {
33
34// clang-format off
35/**
36\class ROOT::Experimental::RColumn
37\ingroup NTuple
38\brief A column is a storage-backed array of a simple, fixed-size type, from which pages can be mapped into memory.
39
40On the primitives data layer, the RColumn and RColumnElement are the equivalents to RField and RTreeValue on the
41logical data layer.
42*/
43// clang-format on
44class RColumn {
45private:
51 /// Open page into which new elements are being written
53 /// The number of elements written resp. available in the column
55 /// The currently mapped page for reading
57 /// The column id is used to find matching pages with content when reading
59 /// Optional link to a parent offset column that points into this column
61
62public:
63 explicit RColumn(const RColumnModel& model);
64 RColumn(const RColumn&) = delete;
65 RColumn& operator =(const RColumn&) = delete;
66 ~RColumn() = default;
67
68 void Connect(RPageStorage* pageStorage);
69
70 void Append(const RColumnElementBase& element) {
71 void* dst = fHeadPage.TryGrow(1);
72 if (dst == nullptr) {
73 Flush();
74 dst = fHeadPage.TryGrow(1);
75 R__ASSERT(dst != nullptr);
76 }
77 element.Serialize(dst, 1);
78 fNElements++;
79 }
80
81 void AppendV(const RColumnElementBase& elemArray, std::size_t count) {
82 void* dst = fHeadPage.TryGrow(count);
83 if (dst == nullptr) {
84 for (unsigned i = 0; i < count; ++i) {
85 Append(RColumnElementBase(elemArray, i));
86 }
87 return;
88 }
89 elemArray.Serialize(dst, count);
90 fNElements += count;
91 }
92
93 void Read(const NTupleSize_t index, RColumnElementBase* element) {
94 if (!fCurrentPage.Contains(index)) {
95 MapPage(index);
96 }
97 void* src = static_cast<unsigned char *>(fCurrentPage.GetBuffer()) +
98 (index - fCurrentPage.GetRangeFirst()) * element->GetSize();
99 element->Deserialize(src, 1);
100 }
101
102 void ReadV(const NTupleSize_t index, const NTupleSize_t count, RColumnElementBase* elemArray) {
103 if (!fCurrentPage.Contains(index)) {
104 MapPage(index);
105 }
106 NTupleSize_t idxInPage = index - fCurrentPage.GetRangeFirst();
107
108 void* src = static_cast<unsigned char *>(fCurrentPage.GetBuffer()) + idxInPage * elemArray->GetSize();
109 if (index + count <= fCurrentPage.GetRangeLast() + 1) {
110 elemArray->Deserialize(src, count);
111 } else {
112 NTupleSize_t nBatch = fCurrentPage.GetRangeLast() - idxInPage;
113 elemArray->Deserialize(src, nBatch);
114 RColumnElementBase elemTail(*elemArray, nBatch);
115 ReadV(index + nBatch, count - nBatch, &elemTail);
116 }
117 }
118
119 /// Map may fall back to Read() and therefore requires a valid element
120 template <typename CppT, EColumnType ColumnT>
121 CppT* Map(const NTupleSize_t index, RColumnElementBase* element) {
123 Read(index, element);
124 return static_cast<CppT*>(element->GetRawContent());
125 }
126
127 if (!fCurrentPage.Contains(index)) {
128 MapPage(index);
129 }
130 return reinterpret_cast<CppT*>(
131 static_cast<unsigned char *>(fCurrentPage.GetBuffer()) +
133 }
134
135 /// MapV may fail if there are less than count consecutive elements or if the type pair is not mappable
136 template <typename CppT, EColumnType ColumnT>
137 void* MapV(const NTupleSize_t index, const NTupleSize_t count) {
139 if (!fCurrentPage.Contains(index)) {
140 MapPage(index);
141 }
142 if (index + count > fCurrentPage.GetRangeLast() + 1) return nullptr;
143 return static_cast<unsigned char *>(fCurrentPage.GetBuffer()) +
144 (index - fCurrentPage.GetRangeFirst()) * kColumnElementSizes[static_cast<int>(ColumnT)];
145 }
146
147 /// For offset columns only, do index arithmetic from cluster-local to global indizes
148 void GetCollectionInfo(const NTupleSize_t index, NTupleSize_t* collectionStart, ClusterSize_t* collectionSize) {
151 auto idxStart = (index == 0) ? 0 : *Map<ClusterSize_t, EColumnType::kIndex>(index - 1, &elemDummy);
152 auto idxEnd = *Map<ClusterSize_t, EColumnType::kIndex>(index, &elemDummy);
153 auto selfOffset = fCurrentPage.GetClusterInfo().GetSelfOffset();
154 auto pointeeOffset = fCurrentPage.GetClusterInfo().GetPointeeOffset();
155 if (index == selfOffset) {
156 // Passed cluster boundary
157 idxStart = 0;
158 }
159 *collectionSize = idxEnd - idxStart;
160 *collectionStart = pointeeOffset + idxStart;
161 }
162
163 void Flush();
164 void MapPage(const NTupleSize_t index);
166 const RColumnModel& GetModel() const { return fModel; }
170 void SetOffsetColumn(RColumn* offsetColumn) { fOffsetColumn = offsetColumn; }
172};
173
174} // namespace Detail
175
176} // namespace Experimental
177} // namespace ROOT
178
179#endif
static RooMathCoreReg dummy
#define R__ASSERT(e)
Definition: TError.h:96
void Deserialize(void *source, std::size_t count)
void Serialize(void *destination, std::size_t count) const
Pairs of C++ type and column type, like float and EColumnType::kReal32.
RPageStorage::ColumnHandle_t GetHandleSource() const
Definition: RColumn.hxx:169
RColumn & operator=(const RColumn &)=delete
void SetOffsetColumn(RColumn *offsetColumn)
Definition: RColumn.hxx:170
const RColumnModel & GetModel() const
Definition: RColumn.hxx:166
RPage fHeadPage
Open page into which new elements are being written.
Definition: RColumn.hxx:52
ColumnId_t GetColumnIdSource() const
Definition: RColumn.hxx:167
RColumn * fOffsetColumn
Optional link to a parent offset column that points into this column.
Definition: RColumn.hxx:60
void AppendV(const RColumnElementBase &elemArray, std::size_t count)
Definition: RColumn.hxx:81
RColumn * GetOffsetColumn() const
Definition: RColumn.hxx:171
void Append(const RColumnElementBase &element)
Definition: RColumn.hxx:70
void MapPage(const NTupleSize_t index)
Definition: RColumn.cxx:59
CppT * Map(const NTupleSize_t index, RColumnElementBase *element)
Map may fall back to Read() and therefore requires a valid element.
Definition: RColumn.hxx:121
RColumn(const RColumnModel &model)
Definition: RColumn.cxx:24
void GetCollectionInfo(const NTupleSize_t index, NTupleSize_t *collectionStart, ClusterSize_t *collectionSize)
For offset columns only, do index arithmetic from cluster-local to global indizes.
Definition: RColumn.hxx:148
void Connect(RPageStorage *pageStorage)
Definition: RColumn.cxx:32
void Read(const NTupleSize_t index, RColumnElementBase *element)
Definition: RColumn.hxx:93
void * MapV(const NTupleSize_t index, const NTupleSize_t count)
MapV may fail if there are less than count consecutive elements or if the type pair is not mappable.
Definition: RColumn.hxx:137
RColumn(const RColumn &)=delete
RPage fCurrentPage
The currently mapped page for reading.
Definition: RColumn.hxx:56
void ReadV(const NTupleSize_t index, const NTupleSize_t count, RColumnElementBase *elemArray)
Definition: RColumn.hxx:102
RPageSource * GetPageSource() const
Definition: RColumn.hxx:168
NTupleSize_t fNElements
The number of elements written resp. available in the column.
Definition: RColumn.hxx:54
ColumnId_t fColumnIdSource
The column id is used to find matching pages with content when reading.
Definition: RColumn.hxx:58
RPageStorage::ColumnHandle_t fHandleSink
Definition: RColumn.hxx:49
RPageStorage::ColumnHandle_t fHandleSource
Definition: RColumn.hxx:50
Abstract interface to write data into a tree.
Abstract interface to read data from a tree.
Manages tree meta-data, which is common for sinks and sources.
A page is a fixed size slice of a column that is mapped into memory.
Definition: RPage.hxx:40
bool Contains(NTupleSize_t index) const
Definition: RPage.hxx:92
const RClusterInfo & GetClusterInfo() const
Definition: RPage.hxx:91
NTupleSize_t GetRangeFirst() const
Definition: RPage.hxx:89
NTupleSize_t GetRangeLast() const
Definition: RPage.hxx:90
void * TryGrow(std::size_t nElements)
Return a pointer after the last element that has space for nElements new elements.
Definition: RPage.hxx:98
Holds the static meta-data of a column in a tree.
std::uint64_t NTupleSize_t
Integer type long enough to hold the maximum number of entries in a column.
Definition: RNTupleUtil.hxx:44
std::int64_t ColumnId_t
Uniquely identifies a physical column within the scope of the current process, used to tag pages.
Definition: RNTupleUtil.hxx:61
constexpr std::size_t kColumnElementSizes[]
Lookup table for the element size in bytes for column types.
Namespace for new ROOT classes and functions.
Definition: StringConv.hxx:21
Wrap the 32bit integer in a struct in order to avoid template specialization clash with std::uint32_t...
Definition: RNTupleUtil.hxx:47