Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
RFieldSequenceContainer.hxx
Go to the documentation of this file.
1/// \file ROOT/RField/SequenceContainer.hxx
2/// \ingroup NTuple
3/// \author Jakob Blomer <jblomer@cern.ch>
4/// \date 2018-10-09
5
6/*************************************************************************
7 * Copyright (C) 1995-2019, Rene Brun and Fons Rademakers. *
8 * All rights reserved. *
9 * *
10 * For the licensing terms see $ROOTSYS/LICENSE. *
11 * For the list of contributors see $ROOTSYS/README/CREDITS. *
12 *************************************************************************/
13
14#ifndef ROOT_RField_SequenceContainer
15#define ROOT_RField_SequenceContainer
16
17#ifndef ROOT_RField
18#error "Please include RField.hxx!"
19#endif
20
21#include <ROOT/RFieldBase.hxx>
22#include <ROOT/RNTupleTypes.hxx>
23#include <ROOT/RVec.hxx>
24
25#include <array>
26#include <memory>
27#include <vector>
28
29namespace ROOT {
30
31namespace Detail {
32class RFieldVisitor;
33} // namespace Detail
34
35namespace Internal {
36std::unique_ptr<RFieldBase> CreateEmulatedVectorField(std::string_view fieldName, std::unique_ptr<RFieldBase> itemField,
37 std::string_view emulatedFromType);
38}
39
40////////////////////////////////////////////////////////////////////////////////
41/// Template specializations for C++ std::array and C-style arrays
42////////////////////////////////////////////////////////////////////////////////
43
44/// The generic field for fixed size arrays, which do not need an offset column
45class RArrayField : public RFieldBase {
46private:
47 class RArrayDeleter : public RDeleter {
48 private:
49 std::size_t fItemSize = 0;
50 std::size_t fArrayLength = 0;
51 std::unique_ptr<RDeleter> fItemDeleter;
52
53 public:
54 RArrayDeleter(std::size_t itemSize, std::size_t arrayLength, std::unique_ptr<RDeleter> itemDeleter)
56 {
57 }
58 void operator()(void *objPtr, bool dtorOnly) final;
59 };
60
61 std::size_t fItemSize;
62 std::size_t fArrayLength;
63
64protected:
65 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final;
66
67 void ConstructValue(void *where) const final;
68 std::unique_ptr<RDeleter> GetDeleter() const final;
69
70 std::size_t AppendImpl(const void *from) final;
73
75
76public:
77 RArrayField(std::string_view fieldName, std::unique_ptr<RFieldBase> itemField, std::size_t arrayLength);
81
83 size_t GetLength() const { return fArrayLength; }
85 size_t GetAlignment() const final { return fSubfields[0]->GetAlignment(); }
87};
88
89template <typename ItemT, std::size_t N>
90class RField<std::array<ItemT, N>> : public RArrayField {
91public:
92 static std::string TypeName() { return "std::array<" + RField<ItemT>::TypeName() + "," + std::to_string(N) + ">"; }
93 explicit RField(std::string_view name) : RArrayField(name, std::make_unique<RField<ItemT>>("_0"), N) {}
94 RField(RField &&other) = default;
95 RField &operator=(RField &&other) = default;
96 ~RField() override = default;
97};
98
99template <typename ItemT, std::size_t N>
100class RField<ItemT[N]> final : public RField<std::array<ItemT, N>> {
101public:
102 explicit RField(std::string_view name) : RField<std::array<ItemT, N>>(name) {}
103 RField(RField &&other) = default;
106};
107
108////////////////////////////////////////////////////////////////////////////////
109/// Template specializations for ROOT's RVec
110////////////////////////////////////////////////////////////////////////////////
111
112/// The type-erased field for a RVec<Type>
114public:
115 /// the RRVecDeleter is also used by RArrayAsRVecField and therefore declared public
116 class RRVecDeleter : public RDeleter {
117 private:
118 std::size_t fItemAlignment;
119 std::size_t fItemSize = 0;
120 std::unique_ptr<RDeleter> fItemDeleter;
121
122 public:
123 explicit RRVecDeleter(std::size_t itemAlignment) : fItemAlignment(itemAlignment) {}
124 RRVecDeleter(std::size_t itemAlignment, std::size_t itemSize, std::unique_ptr<RDeleter> itemDeleter)
125 : fItemAlignment(itemAlignment), fItemSize(itemSize), fItemDeleter(std::move(itemDeleter))
126 {
127 }
128 void operator()(void *objPtr, bool dtorOnly) final;
129 };
130
131 std::unique_ptr<RDeleter> fItemDeleter;
132
133protected:
134 std::size_t fItemSize;
136 std::size_t fValueSize;
137
138 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final;
140 void GenerateColumns() final;
142
143 void ConstructValue(void *where) const final;
144 std::unique_ptr<RDeleter> GetDeleter() const final;
145
146 std::size_t AppendImpl(const void *from) final;
149
151
152 void CommitClusterImpl() final { fNWritten = 0; }
153
154public:
155 RRVecField(std::string_view fieldName, std::unique_ptr<RFieldBase> itemField);
156 RRVecField(RRVecField &&) = default;
158 RRVecField(const RRVecField &) = delete;
160 ~RRVecField() override = default;
161
162 std::vector<RValue> SplitValue(const RValue &value) const final;
163 size_t GetValueSize() const final;
164 size_t GetAlignment() const final;
166 void
171 void
176};
177
178template <typename ItemT>
179class RField<ROOT::VecOps::RVec<ItemT>> final : public RRVecField {
180public:
181 RField(std::string_view fieldName, std::unique_ptr<RFieldBase> itemField)
183 {
184 }
185
186 explicit RField(std::string_view name) : RField(name, std::make_unique<RField<ItemT>>("_0")) {}
187 RField(RField &&other) = default;
190
191 static std::string TypeName() { return "ROOT::VecOps::RVec<" + RField<ItemT>::TypeName() + ">"; }
192};
193
194////////////////////////////////////////////////////////////////////////////////
195/// Template specializations for C++ std::vector
196////////////////////////////////////////////////////////////////////////////////
197
198/// The generic field for a (nested) `std::vector<Type>` except for `std::vector<bool>`
199/// The field can be constructed as untyped collection through CreateUntyped().
200class RVectorField : public RFieldBase {
201 friend std::unique_ptr<RFieldBase> Internal::CreateEmulatedVectorField(std::string_view fieldName,
202 std::unique_ptr<RFieldBase> itemField,
203 std::string_view emulatedFromType);
204
205 class RVectorDeleter : public RDeleter {
206 private:
207 std::size_t fItemSize = 0;
208 std::unique_ptr<RDeleter> fItemDeleter;
209
210 public:
211 RVectorDeleter() = default;
212 RVectorDeleter(std::size_t itemSize, std::unique_ptr<RDeleter> itemDeleter)
213 : fItemSize(itemSize), fItemDeleter(std::move(itemDeleter))
214 {
215 }
216 void operator()(void *objPtr, bool dtorOnly) final;
217 };
218
219 std::size_t fItemSize;
221 std::unique_ptr<RDeleter> fItemDeleter;
222
223protected:
224 /// Creates a possibly-untyped VectorField.
225 /// If `emulatedFromType` is not nullopt, the field is untyped. If the string is empty, it is a "regular"
226 /// untyped vector field; otherwise, it was created as an emulated field from the given type name.
227 RVectorField(std::string_view fieldName, std::unique_ptr<RFieldBase> itemField,
228 std::optional<std::string_view> emulatedFromType);
229
230 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final;
231
232 const RColumnRepresentations &GetColumnRepresentations() const final;
233 void GenerateColumns() final;
234 void GenerateColumns(const ROOT::RNTupleDescriptor &desc) final;
235
236 void ConstructValue(void *where) const final { new (where) std::vector<char>(); }
237 std::unique_ptr<RDeleter> GetDeleter() const final;
238
239 std::size_t AppendImpl(const void *from) final;
240 void ReadGlobalImpl(ROOT::NTupleSize_t globalIndex, void *to) final;
241
242 void ReconcileOnDiskField(const RNTupleDescriptor &desc) final;
243
244 void CommitClusterImpl() final { fNWritten = 0; }
245
246public:
247 RVectorField(std::string_view fieldName, std::unique_ptr<RFieldBase> itemField);
250 ~RVectorField() override = default;
251
252 static std::unique_ptr<RVectorField>
253 CreateUntyped(std::string_view fieldName, std::unique_ptr<RFieldBase> itemField);
254
255 std::vector<RValue> SplitValue(const RValue &value) const final;
256 size_t GetValueSize() const final { return sizeof(std::vector<char>); }
257 size_t GetAlignment() const final { return std::alignment_of<std::vector<char>>(); }
258 void AcceptVisitor(ROOT::Detail::RFieldVisitor &visitor) const final;
259 void
264 void
269};
270
271template <typename ItemT>
272class RField<std::vector<ItemT>> final : public RVectorField {
273public:
274 static std::string TypeName() { return "std::vector<" + RField<ItemT>::TypeName() + ">"; }
275 explicit RField(std::string_view name) : RVectorField(name, std::make_unique<RField<ItemT>>("_0")) {}
276 RField(RField &&other) = default;
277 RField &operator=(RField &&other) = default;
279};
280
281// `std::vector<bool>` is a template specialization and needs special treatment
282template <>
283class RField<std::vector<bool>> final : public RFieldBase {
284private:
285 ROOT::Internal::RColumnIndex fNWritten{0};
286
287protected:
288 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final
289 {
290 return std::make_unique<RField>(newName);
291 }
292
293 const RColumnRepresentations &GetColumnRepresentations() const final;
294 void GenerateColumns() final;
295 void GenerateColumns(const ROOT::RNTupleDescriptor &desc) final;
296
297 void ConstructValue(void *where) const final { new (where) std::vector<bool>(); }
298 std::unique_ptr<RDeleter> GetDeleter() const final { return std::make_unique<RTypedDeleter<std::vector<bool>>>(); }
299
300 std::size_t AppendImpl(const void *from) final;
301 void ReadGlobalImpl(ROOT::NTupleSize_t globalIndex, void *to) final;
302
303 void ReconcileOnDiskField(const RNTupleDescriptor &desc) final;
304
305 void CommitClusterImpl() final { fNWritten = 0; }
306
307public:
308 static std::string TypeName() { return "std::vector<bool>"; }
309 explicit RField(std::string_view name);
310 RField(RField &&other) = default;
311 RField &operator=(RField &&other) = default;
313
314 std::vector<RValue> SplitValue(const RValue &value) const final;
315
316 size_t GetValueSize() const final { return sizeof(std::vector<bool>); }
317 size_t GetAlignment() const final { return std::alignment_of<std::vector<bool>>(); }
319 void
320 GetCollectionInfo(ROOT::NTupleSize_t globalIndex, RNTupleLocalIndex *collectionStart, ROOT::NTupleSize_t *size) const
321 {
323 }
324 void
325 GetCollectionInfo(RNTupleLocalIndex localIndex, RNTupleLocalIndex *collectionStart, ROOT::NTupleSize_t *size) const
326 {
328 }
329};
330
331////////////////////////////////////////////////////////////////////////////////
332/// Additional classes related to sequence containers
333////////////////////////////////////////////////////////////////////////////////
334
335/**
336\class ROOT::RArrayAsRVecField
337\brief A field for fixed-size arrays that are represented as RVecs in memory.
338\ingroup NTuple
339This class is used only for reading. In particular, it helps exposing
340arbitrarily-nested `std::array` on-disk fields as RVecs for usage in RDataFrame.
341*/
343private:
344 std::unique_ptr<RDeleter> fItemDeleter; /// Sub field deleter or nullptr for simple fields
345 std::size_t fItemSize; /// The size of a child field's item
346 std::size_t fArrayLength; /// The length of the arrays in this field
347 std::size_t fValueSize; /// The size of a value of this field, i.e. an RVec
348
349protected:
350 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final;
351
352 void GenerateColumns() final { throw RException(R__FAIL("RArrayAsRVec fields must only be used for reading")); }
353 using RFieldBase::GenerateColumns;
354
355 void ConstructValue(void *where) const final;
356 /// Returns an RRVecField::RRVecDeleter
357 std::unique_ptr<RDeleter> GetDeleter() const final;
358
359 void ReadGlobalImpl(ROOT::NTupleSize_t globalIndex, void *to) final;
360 void ReadInClusterImpl(RNTupleLocalIndex localIndex, void *to) final;
361
362 void ReconcileOnDiskField(const RNTupleDescriptor &desc) final;
363
364public:
365 /**
366 Constructor of the field. The `itemField` argument represents the inner
367 item of the on-disk array, i.e. for an `std::array<float>` it is the `float`
368 field and not the `std::array` itself.
369 */
370 RArrayAsRVecField(std::string_view fieldName, std::unique_ptr<RFieldBase> itemField, std::size_t arrayLength);
376
377 std::size_t GetValueSize() const final { return fValueSize; }
378 std::size_t GetAlignment() const final;
379
380 std::vector<RFieldBase::RValue> SplitValue(const RFieldBase::RValue &value) const final;
381 void AcceptVisitor(ROOT::Detail::RFieldVisitor &visitor) const final;
382};
383
384} // namespace ROOT
385
386#endif
size_t fValueSize
#define R__FAIL(msg)
Short-hand to return an RResult<T> in an error state; the RError is implicitly converted into RResult...
Definition RError.hxx:300
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
#define N
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
char name[80]
Definition TGX11.cxx:110
TRObject operator()(const T1 &t1) const
Abstract base class for classes implementing the visitor design pattern.
The in-memory representation of a 32bit or 64bit on-disk index column.
void GetCollectionInfo(const ROOT::NTupleSize_t globalIndex, RNTupleLocalIndex *collectionStart, ROOT::NTupleSize_t *collectionSize)
For offset columns only, look at the two adjacent values that define a collection's coordinates.
Definition RColumn.hxx:283
Additional classes related to sequence containers.
std::unique_ptr< RDeleter > fItemDeleter
std::size_t fArrayLength
The size of a child field's item.
std::size_t fItemSize
Sub field deleter or nullptr for simple fields.
void GenerateColumns() final
Implementations in derived classes should create the backing columns corresponding to the field type ...
std::size_t fValueSize
The length of the arrays in this field.
RArrayDeleter(std::size_t itemSize, std::size_t arrayLength, std::unique_ptr< RDeleter > itemDeleter)
std::unique_ptr< RDeleter > fItemDeleter
void operator()(void *objPtr, bool dtorOnly) final
Template specializations for C++ std::array and C-style arrays.
std::unique_ptr< RDeleter > GetDeleter() const final
void ReadGlobalImpl(ROOT::NTupleSize_t globalIndex, void *to) final
void AcceptVisitor(ROOT::Detail::RFieldVisitor &visitor) const final
size_t GetValueSize() const final
The number of bytes taken by a value of the appropriate type.
std::size_t AppendImpl(const void *from) final
Operations on values of complex types, e.g.
void ReadInClusterImpl(RNTupleLocalIndex localIndex, void *to) final
std::unique_ptr< RFieldBase > CloneImpl(std::string_view newName) const final
Called by Clone(), which additionally copies the on-disk ID.
size_t GetAlignment() const final
As a rule of thumb, the alignment is equal to the size of the type.
void ConstructValue(void *where) const final
Constructs value in a given location of size at least GetValueSize(). Called by the base class' Creat...
void ReconcileOnDiskField(const RNTupleDescriptor &desc) final
For non-artificial fields, check compatibility of the in-memory field and the on-disk field.
std::vector< RValue > SplitValue(const RValue &value) const final
Creates the list of direct child values given an existing value for this field.
std::size_t AppendImpl(const void *from) final
Operations on values of complex types, e.g.
std::unique_ptr< RFieldBase > CloneImpl(std::string_view newName) const final
Called by Clone(), which additionally copies the on-disk ID.
void ReconcileOnDiskField(const RNTupleDescriptor &desc) final
For non-artificial fields, check compatibility of the in-memory field and the on-disk field.
size_t GetAlignment() const final
As a rule of thumb, the alignment is equal to the size of the type.
Definition RField.hxx:201
void ReadGlobalImpl(ROOT::NTupleSize_t globalIndex, void *to) final
void ConstructValue(void *where) const final
Constructs value in a given location of size at least GetValueSize(). Called by the base class' Creat...
void AcceptVisitor(ROOT::Detail::RFieldVisitor &visitor) const final
size_t GetValueSize() const final
The number of bytes taken by a value of the appropriate type.
std::vector< RValue > SplitValue(const RValue &value) const final
Creates the list of direct child values given an existing value for this field.
std::unique_ptr< RDeleter > GetDeleter() const final
Definition RField.hxx:184
Base class for all ROOT issued exceptions.
Definition RError.hxx:79
The list of column representations a field can have.
A functor to release the memory acquired by CreateValue() (memory and constructor).
Points to an object with RNTuple I/O support and keeps a pointer to the corresponding field.
A field translates read and write calls from/to underlying columns to/from tree values.
ROOT::Internal::RColumn * fPrincipalColumn
All fields that have columns have a distinct main column.
std::vector< std::unique_ptr< RFieldBase > > fSubfields
Collections and classes own subfields.
virtual const RColumnRepresentations & GetColumnRepresentations() const
Implementations in derived classes should return a static RColumnRepresentations object.
virtual void GenerateColumns()
Implementations in derived classes should create the backing columns corresponding to the field type ...
virtual void CommitClusterImpl()
RFieldBase(std::string_view name, std::string_view type, ROOT::ENTupleStructure structure, bool isSimple, std::size_t nRepetitions=0)
The constructor creates the underlying column objects and connects them to either a sink or a source.
virtual std::size_t ReadBulkImpl(const RBulkSpec &bulkSpec)
General implementation of bulk read.
RField(RField &&other)=default
~RField() final=default
RField & operator=(RField &&other)=default
RField(std::string_view fieldName, std::unique_ptr< RFieldBase > itemField)
RField & operator=(RField &&other)=default
Classes with dictionaries that can be inspected by TClass.
Definition RField.hxx:292
~RField() final=default
RField & operator=(RField &&other)=default
static std::string TypeName()
Definition RField.hxx:294
RField(std::string_view name)
Definition RField.hxx:295
The on-storage metadata of an RNTuple.
Addresses a column element or field item relative to a particular cluster, instead of a global NTuple...
the RRVecDeleter is also used by RArrayAsRVecField and therefore declared public
RRVecDeleter(std::size_t itemAlignment, std::size_t itemSize, std::unique_ptr< RDeleter > itemDeleter)
std::unique_ptr< RDeleter > fItemDeleter
RRVecDeleter(std::size_t itemAlignment)
Template specializations for ROOT's RVec.
RRVecField & operator=(RRVecField &&)=default
~RRVecField() override=default
void GetCollectionInfo(RNTupleLocalIndex localIndex, RNTupleLocalIndex *collectionStart, ROOT::NTupleSize_t *size) const
RRVecField(const RRVecField &)=delete
ROOT::Internal::RColumnIndex fNWritten
std::unique_ptr< RDeleter > fItemDeleter
RRVecField(RRVecField &&)=default
RRVecField & operator=(RRVecField &)=delete
RVectorDeleter(std::size_t itemSize, std::unique_ptr< RDeleter > itemDeleter)
Template specializations for C++ std::vector.
RVectorField(RVectorField &&other)=default
void GetCollectionInfo(ROOT::NTupleSize_t globalIndex, RNTupleLocalIndex *collectionStart, ROOT::NTupleSize_t *size) const
void GetCollectionInfo(RNTupleLocalIndex localIndex, RNTupleLocalIndex *collectionStart, ROOT::NTupleSize_t *size) const
~RVectorField() override=default
size_t GetAlignment() const final
As a rule of thumb, the alignment is equal to the size of the type.
std::unique_ptr< RDeleter > fItemDeleter
ROOT::Internal::RColumnIndex fNWritten
size_t GetValueSize() const final
The number of bytes taken by a value of the appropriate type.
RVectorField & operator=(RVectorField &&other)=default
A "std::vector"-like collection of values implementing handy operation to analyse them.
Definition RVec.hxx:1526
std::unique_ptr< RFieldBase > CreateEmulatedVectorField(std::string_view fieldName, std::unique_ptr< RFieldBase > itemField, std::string_view emulatedFromType)
Definition RField.cxx:537
std::uint64_t NTupleSize_t
Integer type long enough to hold the maximum number of entries in a column.
Input parameter to RFieldBase::ReadBulk() and RFieldBase::ReadBulkImpl().