Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
RFieldSequenceContainer.hxx
Go to the documentation of this file.
1/// \file ROOT/RField/SequenceContainer.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_RField_SequenceContainer
14#define ROOT_RField_SequenceContainer
15
16#ifndef ROOT_RField
17#error "Please include RField.hxx!"
18#endif
19
20#include <ROOT/RFieldBase.hxx>
21#include <ROOT/RNTupleTypes.hxx>
22#include <ROOT/RVec.hxx>
23
24#include <array>
25#include <memory>
26#include <vector>
27
28namespace ROOT {
29
30namespace Detail {
31class RFieldVisitor;
32} // namespace Detail
33
34namespace Experimental {
35class RSoAField;
36}
37
38namespace Internal {
39std::unique_ptr<RFieldBase> CreateEmulatedVectorField(std::string_view fieldName, std::unique_ptr<RFieldBase> itemField,
40 std::string_view emulatedFromType);
41}
42
43////////////////////////////////////////////////////////////////////////////////
44/// Template specializations for C++ std::array and C-style arrays
45////////////////////////////////////////////////////////////////////////////////
46
47/// The generic field for fixed size arrays, which do not need an offset column
48class RArrayField : public RFieldBase {
49private:
50 class RArrayDeleter : public RDeleter {
51 private:
52 std::size_t fItemSize = 0;
53 std::size_t fArrayLength = 0;
54 std::unique_ptr<RDeleter> fItemDeleter;
55
56 public:
57 RArrayDeleter(std::size_t itemSize, std::size_t arrayLength, std::unique_ptr<RDeleter> itemDeleter)
59 {
60 }
61 void operator()(void *objPtr, bool dtorOnly) final;
62 };
63
64 std::size_t fItemSize;
65 std::size_t fArrayLength;
66
67protected:
68 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final;
69
70 void ConstructValue(void *where) const final;
71 std::unique_ptr<RDeleter> GetDeleter() const final;
72
73 std::size_t AppendImpl(const void *from) final;
77
79
80public:
81 RArrayField(std::string_view fieldName, std::unique_ptr<RFieldBase> itemField, std::size_t arrayLength);
85
87 size_t GetLength() const { return fArrayLength; }
89 size_t GetAlignment() const final { return fSubfields[0]->GetAlignment(); }
91};
92
93template <typename ItemT, std::size_t N>
94class RField<std::array<ItemT, N>> : public RArrayField {
95public:
96 static std::string TypeName() { return "std::array<" + RField<ItemT>::TypeName() + "," + std::to_string(N) + ">"; }
97 explicit RField(std::string_view name) : RArrayField(name, std::make_unique<RField<ItemT>>("_0"), N) {}
98 RField(RField &&other) = default;
99 RField &operator=(RField &&other) = default;
100 ~RField() override = default;
101};
102
103template <typename ItemT, std::size_t N>
104class RField<ItemT[N]> final : public RField<std::array<ItemT, N>> {
105public:
106 explicit RField(std::string_view name) : RField<std::array<ItemT, N>>(name) {}
107 RField(RField &&other) = default;
110};
111
112////////////////////////////////////////////////////////////////////////////////
113/// Template specializations for ROOT's RVec
114////////////////////////////////////////////////////////////////////////////////
115
116/// The type-erased field for a RVec<Type>
118 friend class RArrayAsRVecField; // to use the RRVecDeleter and to call ResizeRVec()
119 friend class ROOT::Experimental::RSoAField; // to call ResizeRVec()
120
121 // Ensures that the RVec pointed to by rvec has at least nItems valid elements
122 // Returns the possibly new "begin pointer" of the RVec, i.e. the pointer to the data area.
123 static unsigned char *
124 ResizeRVec(void *rvec, std::size_t nItems, std::size_t itemSize, const RFieldBase *itemField, RDeleter *itemDeleter);
125
126 class RRVecDeleter : public RDeleter {
127 private:
128 std::size_t fItemAlignment;
129 std::size_t fItemSize = 0;
130 std::unique_ptr<RDeleter> fItemDeleter;
131
132 public:
133 explicit RRVecDeleter(std::size_t itemAlignment) : fItemAlignment(itemAlignment) {}
134 RRVecDeleter(std::size_t itemAlignment, std::size_t itemSize, std::unique_ptr<RDeleter> itemDeleter)
135 : fItemAlignment(itemAlignment), fItemSize(itemSize), fItemDeleter(std::move(itemDeleter))
136 {
137 }
138 void operator()(void *objPtr, bool dtorOnly) final;
139 };
140
141 std::unique_ptr<RDeleter> fItemDeleter;
142
143protected:
144 std::size_t fItemSize;
146 std::size_t fValueSize;
147
148 // For bulk read optimzation
149 std::size_t fBulkNRepetition = 1;
150 /// May be a direct PoD subfield or a sub-subfield of a fixed-size array of PoD
151 RFieldBase *fBulkSubfield = nullptr;
152
153 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final;
155 void GenerateColumns() final;
157
158 void ConstructValue(void *where) const final;
159 std::unique_ptr<RDeleter> GetDeleter() const final;
160
161 std::size_t AppendImpl(const void *from) final;
164
167
168 void CommitClusterImpl() final { fNWritten = 0; }
169
170public:
171 RRVecField(std::string_view fieldName, std::unique_ptr<RFieldBase> itemField);
172 RRVecField(RRVecField &&) = default;
174 RRVecField(const RRVecField &) = delete;
176 ~RRVecField() override = default;
177
178 std::vector<RValue> SplitValue(const RValue &value) const final;
179 size_t GetValueSize() const final;
180 size_t GetAlignment() const final;
182};
183
186public:
187 RField(std::string_view fieldName, std::unique_ptr<RFieldBase> itemField)
189 {
190 }
191
192 explicit RField(std::string_view name) : RField(name, std::make_unique<RField<ItemT>>("_0")) {}
193 RField(RField &&other) = default;
196
197 static std::string TypeName() { return "ROOT::VecOps::RVec<" + RField<ItemT>::TypeName() + ">"; }
198};
199
200////////////////////////////////////////////////////////////////////////////////
201/// Template specializations for C++ std::vector
202////////////////////////////////////////////////////////////////////////////////
203
204/// The generic field for a (nested) `std::vector<Type>` except for `std::vector<bool>`
205/// The field can be constructed as untyped collection through CreateUntyped().
206class RVectorField : public RFieldBase {
207 friend class RArrayAsVectorField; // to get access to the RVectorDeleter
208 friend std::unique_ptr<RFieldBase> Internal::CreateEmulatedVectorField(std::string_view fieldName,
209 std::unique_ptr<RFieldBase> itemField,
210 std::string_view emulatedFromType);
211
212 class RVectorDeleter : public RDeleter {
213 private:
214 std::size_t fItemSize = 0;
215 std::unique_ptr<RDeleter> fItemDeleter;
216
217 public:
218 RVectorDeleter() = default;
219 RVectorDeleter(std::size_t itemSize, std::unique_ptr<RDeleter> itemDeleter)
220 : fItemSize(itemSize), fItemDeleter(std::move(itemDeleter))
221 {
222 }
223 void operator()(void *objPtr, bool dtorOnly) final;
224 };
225
226 std::size_t fItemSize;
228 std::unique_ptr<RDeleter> fItemDeleter;
229
230 // Ensures that the std::vector pointed to by vec has at least nItems valid elements.
231 static void ResizeVector(void *vec, std::size_t nItems, std::size_t itemSize, const RFieldBase &itemField,
233
234protected:
235 /// Creates a possibly-untyped VectorField.
236 /// If `emulatedFromType` is not nullopt, the field is untyped. If the string is empty, it is a "regular"
237 /// untyped vector field; otherwise, it was created as an emulated field from the given type name.
238 RVectorField(std::string_view fieldName, std::unique_ptr<RFieldBase> itemField,
239 std::optional<std::string_view> emulatedFromType);
240
241 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final;
242
243 const RColumnRepresentations &GetColumnRepresentations() const final;
244 void GenerateColumns() final;
245 void GenerateColumns(const ROOT::RNTupleDescriptor &desc) final;
246
247 void ConstructValue(void *where) const final { new (where) std::vector<char>(); }
248 std::unique_ptr<RDeleter> GetDeleter() const final;
249
250 std::size_t AppendImpl(const void *from) final;
251 void ReadGlobalImpl(ROOT::NTupleSize_t globalIndex, void *to) final;
252
253 std::unique_ptr<RFieldBase> BeforeConnectPageSource(ROOT::Internal::RPageSource &pageSource) final;
254 void ReconcileOnDiskField(const RNTupleDescriptor &desc) final;
255
256 void CommitClusterImpl() final { fNWritten = 0; }
257
258public:
259 RVectorField(std::string_view fieldName, std::unique_ptr<RFieldBase> itemField);
262 ~RVectorField() override = default;
263
264 static std::unique_ptr<RVectorField>
265 CreateUntyped(std::string_view fieldName, std::unique_ptr<RFieldBase> itemField);
266
267 std::vector<RValue> SplitValue(const RValue &value) const final;
268 size_t GetValueSize() const final { return sizeof(std::vector<char>); }
269 size_t GetAlignment() const final { return std::alignment_of<std::vector<char>>(); }
270 void AcceptVisitor(ROOT::Detail::RFieldVisitor &visitor) const final;
271};
272
273template <typename ItemT>
274class RField<std::vector<ItemT>> final : public RVectorField {
275public:
276 static std::string TypeName() { return "std::vector<" + RField<ItemT>::TypeName() + ">"; }
277 explicit RField(std::string_view name) : RVectorField(name, std::make_unique<RField<ItemT>>("_0")) {}
278 RField(RField &&other) = default;
279 RField &operator=(RField &&other) = default;
281};
282
283// `std::vector<bool>` is a template specialization and needs special treatment
284template <>
285class RField<std::vector<bool>> final : public RFieldBase {
286private:
287 ROOT::Internal::RColumnIndex fNWritten{0};
288 /// If schema-evolved from an std::array, fOnDiskNRepetition is > 0 and there will be no
289 /// principal column.
290 std::size_t fOnDiskNRepetitions = 0;
291
292protected:
293 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final
294 {
295 return std::make_unique<RField>(newName);
296 }
297
298 const RColumnRepresentations &GetColumnRepresentations() const final;
299 void GenerateColumns() final;
300 void GenerateColumns(const ROOT::RNTupleDescriptor &desc) final;
301
302 void ConstructValue(void *where) const final { new (where) std::vector<bool>(); }
303 std::unique_ptr<RDeleter> GetDeleter() const final { return std::make_unique<RTypedDeleter<std::vector<bool>>>(); }
304
305 std::size_t AppendImpl(const void *from) final;
306 void ReadGlobalImpl(ROOT::NTupleSize_t globalIndex, void *to) final;
308
309 void ReconcileOnDiskField(const RNTupleDescriptor &desc) final;
310
311 void CommitClusterImpl() final { fNWritten = 0; }
312
313public:
314 static std::string TypeName() { return "std::vector<bool>"; }
315 explicit RField(std::string_view name);
316 RField(RField &&other) = default;
317 RField &operator=(RField &&other) = default;
319
320 std::vector<RValue> SplitValue(const RValue &value) const final;
321
322 size_t GetValueSize() const final { return sizeof(std::vector<bool>); }
323 size_t GetAlignment() const final { return std::alignment_of<std::vector<bool>>(); }
325};
326
327////////////////////////////////////////////////////////////////////////////////
328/// Additional classes related to sequence containers
329////////////////////////////////////////////////////////////////////////////////
330
331/**
332\class ROOT::RArrayAsRVecField
333\brief A field for fixed-size arrays that are represented as RVecs in memory.
334\ingroup NTuple
335This class is used only for reading. In particular, it helps exposing
336arbitrarily-nested `std::array` on-disk fields as RVecs for usage in RDataFrame.
337*/
339private:
340 std::unique_ptr<RDeleter> fItemDeleter; /// Sub field deleter or nullptr for simple fields
341 std::size_t fItemSize; /// The size of a child field's item
342 std::size_t fArrayLength; /// The length of the arrays in this field
343 std::size_t fValueSize; /// The size of a value of this field, i.e. an RVec
344
345protected:
346 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final;
347
348 void GenerateColumns() final { throw RException(R__FAIL("RArrayAsRVec fields must only be used for reading")); }
349 using RFieldBase::GenerateColumns;
350
351 void ConstructValue(void *where) const final;
352 /// Returns an RRVecField::RRVecDeleter
353 std::unique_ptr<RDeleter> GetDeleter() const final;
354
355 void ReadGlobalImpl(ROOT::NTupleSize_t globalIndex, void *to) final;
356 void ReadInClusterImpl(RNTupleLocalIndex localIndex, void *to) final;
357
358 void ReconcileOnDiskField(const RNTupleDescriptor &desc) final;
359
360public:
361 /**
362 Constructor of the field. The `itemField` argument represents the inner
363 item of the on-disk array, i.e. for an `std::array<float>` it is the `float`
364 field and not the `std::array` itself.
365 */
366 RArrayAsRVecField(std::string_view fieldName, std::unique_ptr<RFieldBase> itemField, std::size_t arrayLength);
372
373 std::size_t GetValueSize() const final { return fValueSize; }
374 std::size_t GetAlignment() const final;
375
376 std::vector<RFieldBase::RValue> SplitValue(const RFieldBase::RValue &value) const final;
377 void AcceptVisitor(ROOT::Detail::RFieldVisitor &visitor) const final;
378};
379
380/**
381\class ROOT::RArrayAsVectorField
382\brief A field for fixed-size arrays that are represented as std::vector in memory.
383\ingroup NTuple
384This class is used only for reading. In particular, it helps for schema evolution of fixed-size arrays into vectors.
385*/
387private:
388 std::unique_ptr<RDeleter> fItemDeleter; /// Sub field deleter or nullptr for simple fields
389 std::size_t fItemSize; /// The size of a child field's item
390 std::size_t fArrayLength; /// The length of the arrays in this field
391
392protected:
393 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final;
394
395 void GenerateColumns() final;
396 using RFieldBase::GenerateColumns;
397
398 void ConstructValue(void *where) const final { new (where) std::vector<char>(); }
399 /// Returns an RVectorField::RVectorDeleter
400 std::unique_ptr<RDeleter> GetDeleter() const final;
401
402 void ReadGlobalImpl(ROOT::NTupleSize_t globalIndex, void *to) final;
403 void ReadInClusterImpl(RNTupleLocalIndex localIndex, void *to) final;
404
405 void ReconcileOnDiskField(const RNTupleDescriptor &desc) final;
406
407public:
408 /// The `itemField` argument represents the inner item of the on-disk array,
409 /// i.e. for an `std::array<float>` it is the `float`
410 RArrayAsVectorField(std::string_view fieldName, std::unique_ptr<RFieldBase> itemField, std::size_t arrayLength);
416
417 size_t GetValueSize() const final { return sizeof(std::vector<char>); }
418 size_t GetAlignment() const final { return std::alignment_of<std::vector<char>>(); }
419
420 std::vector<RFieldBase::RValue> SplitValue(const RFieldBase::RValue &value) const final;
421 void AcceptVisitor(ROOT::Detail::RFieldVisitor &visitor) const final;
422};
423
424} // namespace ROOT
425
426#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:299
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:148
TRObject operator()(const T1 &t1) const
Abstract base class for classes implementing the visitor design pattern.
The SoA field provides I/O for an in-memory SoA layout linked to an on-disk collection of the underly...
Definition RFieldSoA.hxx:55
The in-memory representation of a 32bit or 64bit on-disk index column.
Abstract interface to read data from an ntuple.
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.
A field for fixed-size arrays that are represented as std::vector in memory.
std::unique_ptr< RDeleter > fItemDeleter
size_t GetAlignment() const final
As a rule of thumb, the alignment is equal to the size of the type.
std::size_t fArrayLength
The size of a child field's item.
std::size_t fItemSize
Sub field deleter or nullptr for simple fields.
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.
std::size_t ReadBulkImpl(const RBulkSpec &bulkSpec) final
General implementation of bulk read.
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::unique_ptr< RFieldBase > BeforeConnectPageSource(ROOT::Internal::RPageSource &pageSource) final
Called by ConnectPageSource() before connecting; derived classes may override this as appropriate,...
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:223
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
void ReadInClusterImpl(RNTupleLocalIndex localIndex, void *to) 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:206
Base class for all ROOT issued exceptions.
Definition RError.hxx:78
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.
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:320
~RField() final=default
RField & operator=(RField &&other)=default
static std::string TypeName()
Definition RField.hxx:322
RField(std::string_view name)
Definition RField.hxx:323
The on-storage metadata of an RNTuple.
Addresses a column element or field item relative to a particular cluster, instead of a global NTuple...
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
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
~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:1525
std::unique_ptr< RFieldBase > CreateEmulatedVectorField(std::string_view fieldName, std::unique_ptr< RFieldBase > itemField, std::string_view emulatedFromType)
Definition RField.cxx:598
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().