Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
RFieldSoA.hxx
Go to the documentation of this file.
1/// \file ROOT/RField/RFieldSoA.hxx
2/// \author Jakob Blomer <jblomer@cern.ch>
3/// \date 2026-03-03
4
5/*************************************************************************
6 * Copyright (C) 1995-2026, 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_SoA
14#define ROOT_RField_SoA
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
23#include <cstddef>
24#include <functional>
25#include <memory>
26#include <mutex>
27#include <string_view>
28#include <typeinfo>
29#include <vector>
30
31class TClass;
32
33namespace ROOT {
34
35namespace Experimental {
36
37/// The SoA field provides I/O for an in-memory SoA layout linked to an on-disk collection of the underlying record.
38/// As a concrete example, for an underlying record type
39/// \code{.cpp}
40/// struct PointRecord {
41/// float px, py;
42/// };
43/// \endcode
44/// a corresponding SoA layout will look like
45/// \code{.cpp}
46/// struct PointSoA {
47/// ROOT::RVec<float> px;
48/// ROOT::RVec<float> py;
49/// };
50/// \endcode
51///
52/// The SoA type has to be marked in the dictionary with the rntupleSoARecord attribute.
53///
54/// Since the on-disk representation is a collection of record type, the class version and checksum of the SoA type
55/// itself is ignored.
56class RSoAField : public RFieldBase {
57 class RSoADeleter : public RDeleter {
58 private:
60
61 public:
62 explicit RSoADeleter(TClass *cl);
63 void operator()(void *objPtr, bool dtorOnly) final;
64 };
65
66 TClass *fSoAClass = nullptr;
67 /// Direct access to the member fields of the underlying record. In case of a nested SoA type, this vector
68 /// contains the contents of the inner fRecordMemberFields, too. Effectively, this record will contain all the
69 /// fields of the underlying record type that correspond to terminal RVec members in a nested SoA type.
70 /// Pointers in this vector point into the field hierarchy owned by fSubfields[0].
71 std::vector<RFieldBase *> fRecordMemberFields;
72 /// The offset of the RVec members in the SoA type in the same order as fRecordMemberFields.
73 std::vector<std::size_t> fSoAMemberOffsets;
74 ///< A deleter returned by each record member's GetDeleter()
75 std::vector<std::unique_ptr<RDeleter>> fRecordMemberDeleters;
77
78 /// For reading and writing, the RVecs of the SoA class do not have a dedicated field. The in-memory RVecs of the
79 /// SoA object are used directly with the subfields of the underlying record type. For splitting a SoA class object
80 /// (SplitValue()), however, we need actual RRVecFields so that we can recursively split the in-memory SoA value.
81 /// The split fields are created only when SplitField() is called.
82 /// In general, the number of split fields is different from the number of record member fields because there is
83 /// one split field for every _direct_ member of the SoA class. Because nested SoA structs can have transient
84 /// members, we can also not reuse fSoAMemberOffsets but we need to store the data member offsets.
85 mutable std::unique_ptr<std::vector<std::unique_ptr<ROOT::RFieldBase>>> fSplitFields;
86 mutable std::unique_ptr<std::vector<std::size_t>> fSplitOffsets;
87 mutable std::unique_ptr<std::mutex> fLockSplitFields; ///< protects the fSplitFields member.
88
89 RSoAField(std::string_view fieldName, const RSoAField &source); ///< Used by CloneImpl
90 RSoAField(std::string_view fieldName, TClass *clSoA);
91
92 /// Called during construction, picks up the (nested) member fields of the underlying record type(s) and its
93 /// base classes.
95 /// For a nested SoA struct (either as a member of as a base class), use their fRecordMemberFields in this class,
96 /// i.e. "unroll" the vectors in the nested SoA struct into the SoA base class.
98 std::function<RFieldBase *(const std::string &)> fnRecordFieldFinder);
99
100 void ReconstructSplitFields() const;
101
102protected:
103 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final;
104
106 void GenerateColumns() final;
108
109 void ConstructValue(void *where) const final;
110 std::unique_ptr<RDeleter> GetDeleter() const final { return std::make_unique<RSoADeleter>(fSoAClass); }
111
112 std::size_t AppendImpl(const void *from) final;
113 void ReadGlobalImpl(ROOT::NTupleSize_t globalIndex, void *to) final;
114
116
117public:
118 RSoAField(std::string_view fieldName, std::string_view className);
121 ~RSoAField() override = default;
122
123 std::vector<RValue> SplitValue(const RValue &value) const final;
124 size_t GetValueSize() const final;
125 size_t GetAlignment() const final;
126 std::uint32_t GetTypeVersion() const final;
127 std::uint32_t GetTypeChecksum() const final;
128 /// For polymorphic classes (that declare or inherit at least one virtual method), return the expected dynamic type
129 /// of any user object. If the class is not polymorphic, return nullptr.
130 /// TODO(jblomer): use information in unique pointer field
133
134 TClass *GetSoAClass() const { return fSoAClass; }
135};
136
137} // namespace Experimental
138} // namespace ROOT
139
140#endif // ROOT_RField_SoA
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
Abstract base class for classes implementing the visitor design pattern.
void operator()(void *objPtr, bool dtorOnly) final
The SoA field provides I/O for an in-memory SoA layout linked to an on-disk collection of the underly...
Definition RFieldSoA.hxx:56
void ConstructValue(void *where) const final
Constructs value in a given location of size at least GetValueSize(). Called by the base class' Creat...
~RSoAField() override=default
void ReadGlobalImpl(ROOT::NTupleSize_t globalIndex, void *to) final
void GraftNestedMemberFields(const RSoAField &nestedSoA, std::size_t offsetInParent, std::function< RFieldBase *(const std::string &)> fnRecordFieldFinder)
For a nested SoA struct (either as a member of as a base class), use their fRecordMemberFields in thi...
std::vector< std::size_t > fSoAMemberOffsets
The offset of the RVec members in the SoA type in the same order as fRecordMemberFields.
Definition RFieldSoA.hxx:73
void AcceptVisitor(ROOT::Detail::RFieldVisitor &visitor) const final
const std::type_info * GetPolymorphicTypeInfo() const
For polymorphic classes (that declare or inherit at least one virtual method), return the expected dy...
size_t GetValueSize() const final
What sizeof(T) for this type returns.
std::vector< std::unique_ptr< RDeleter > > fRecordMemberDeleters
Definition RFieldSoA.hxx:75
RSoAField & operator=(RSoAField &&other)=default
void CollectRecordMemberFields()
Called during construction, picks up the (nested) member fields of the underlying record type(s) and ...
std::vector< RValue > SplitValue(const RValue &value) const final
Creates the list of direct child values given an existing value for this field.
size_t GetAlignment() const final
What alignof(T) for this type returns.
std::unique_ptr< std::vector< std::size_t > > fSplitOffsets
Definition RFieldSoA.hxx:86
std::vector< RFieldBase * > fRecordMemberFields
Direct access to the member fields of the underlying record.
Definition RFieldSoA.hxx:71
RSoAField(std::string_view fieldName, const RSoAField &source)
Used by CloneImpl.
std::uint32_t GetTypeVersion() const final
Indicates an evolution of the C++ type itself.
std::unique_ptr< RDeleter > GetDeleter() const final
std::uint32_t GetTypeChecksum() const final
Return the current TClass reported checksum of this class. Only valid if kTraitTypeChecksum is set.
RSoAField(RSoAField &&other)=default
std::unique_ptr< std::vector< std::unique_ptr< ROOT::RFieldBase > > > fSplitFields
For reading and writing, the RVecs of the SoA class do not have a dedicated field.
Definition RFieldSoA.hxx:85
const RColumnRepresentations & GetColumnRepresentations() const final
Implementations in derived classes should return a static RColumnRepresentations object.
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 GenerateColumns() final
Implementations in derived classes should create the backing columns corresponding to the field type ...
ROOT::Internal::RColumnIndex fNWritten
Definition RFieldSoA.hxx:76
std::unique_ptr< std::mutex > fLockSplitFields
protects the fSplitFields member.
Definition RFieldSoA.hxx:87
The in-memory representation of a 32bit or 64bit on-disk index column.
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.
The on-storage metadata of an RNTuple.
TClass instances represent classes, structs and namespaces in the ROOT type system.
Definition TClass.h:84
std::uint64_t NTupleSize_t
Integer type long enough to hold the maximum number of entries in a column.