Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
RNTupleTypes.hxx
Go to the documentation of this file.
1/// \file ROOT/RNTupleTypes.hxx
2/// \author Jakob Blomer <jblomer@cern.ch>
3/// \date 2018-10-04
4
5/*************************************************************************
6 * Copyright (C) 1995-2020, 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_RNTupleTypes
14#define ROOT_RNTupleTypes
15
16#include <ROOT/RConfig.hxx>
17
18#include <cstddef>
19#include <cstdint>
20#include <limits>
21#include <ostream>
22#include <type_traits>
23#include <variant>
24
25class TDirectory; // For RNTupleInputSpec
26
27namespace ROOT {
28
29/// Helper types to present an offset column as array of collection sizes.
30/// See RField<RNTupleCardinality<SizeT>> for details.
31template <typename SizeT>
33 static_assert(std::is_same_v<SizeT, std::uint32_t> || std::is_same_v<SizeT, std::uint64_t>,
34 "RNTupleCardinality is only supported with std::uint32_t or std::uint64_t template parameters");
35
36 using ValueType = SizeT;
37
39 explicit constexpr RNTupleCardinality(ValueType value) : fValue(value) {}
41 {
42 fValue = value;
43 return *this;
44 }
45 operator ValueType() const { return fValue; }
46
48};
49
50// clang-format off
51/**
52\class ROOT::ENTupleColumnType
53\ingroup NTuple
54\brief The available trivial, native content types of a column
55
56More complex types, such as classes, get translated into columns of such simple types by the RField.
57When changed, remember to update
58 - RColumnElement::Generate()
59 - RColumnElement::GetTypeName()
60 - RColumnElement::GetValidBitRange()
61 - RColumnElement template specializations / packing & unpacking
62 - If necessary, endianess handling for the packing + unit test in ntuple_endian
63 - RNTupleSerializer::[Des|S]erializeColumnType
64*/
65// clang-format on
67 kUnknown = 0,
68 // type for root columns of (nested) collections; offsets are relative to the current cluster
71 // 96 bit column that is a pair of a kIndex64 and a 32bit dispatch tag to a column ID;
72 // used to serialize std::variant.
73 kSwitch,
74 kByte,
75 kChar,
76 kBit,
77 kReal64,
78 kReal32,
79 kReal16,
80 kInt64,
81 kUInt64,
82 kInt32,
83 kUInt32,
84 kInt16,
85 kUInt16,
86 kInt8,
87 kUInt8,
100 kMax,
101};
102
103/// The fields in the RNTuple data model tree can carry different structural information about the type system.
104/// Collection fields have an offset column and subfields with arbitrary cardinality, record fields have no
105/// materialization on the primitive column layer and an arbitrary number of subfields. Plain fields are either
106/// leafs (e.g., `float`) or "wrapper fields" with exactly one child that has the same cardinality
107/// (number of elements in the data set modulo field repetitions) as the parent (e.g., std::atomic<T>).
108// IMPORTANT: if you add members, remember to change the related `operator<<` below.
109enum class ENTupleStructure : std::uint16_t {
110 kInvalid,
111 kPlain,
113 kRecord,
114 kVariant,
115 kStreamer,
116 kUnknown,
117};
118
119inline std::ostream &operator<<(std::ostream &os, ENTupleStructure structure)
120{
121 static const char *const names[] = {"Invalid", "Plain", "Collection", "Record", "Variant", "Streamer", "Unknown"};
122 static_assert((std::size_t)ENTupleStructure::kUnknown + 1 == std::size(names));
123
124 if (R__likely(static_cast<std::size_t>(structure) <= std::size(names)))
125 os << names[static_cast<std::uint16_t>(structure)];
126 else
127 os << "(invalid)";
128 return os;
129}
130
131/// Integer type long enough to hold the maximum number of entries in a column
132using NTupleSize_t = std::uint64_t;
133constexpr NTupleSize_t kInvalidNTupleIndex = std::uint64_t(-1);
134
135/// Distriniguishes elements of the same type within a descriptor, e.g. different fields
136using DescriptorId_t = std::uint64_t;
137constexpr DescriptorId_t kInvalidDescriptorId = std::uint64_t(-1);
138
139/// Addresses a column element or field item relative to a particular cluster, instead of a global NTupleSize_t index
141private:
144
145public:
146 RNTupleLocalIndex() = default;
147 RNTupleLocalIndex(const RNTupleLocalIndex &other) = default;
149 constexpr RNTupleLocalIndex(ROOT::DescriptorId_t clusterId, ROOT::NTupleSize_t indexInCluster)
150 : fClusterId(clusterId), fIndexInCluster(indexInCluster)
151 {
152 }
153
158
163
165 {
166 return RNTupleLocalIndex(fClusterId, fIndexInCluster * repetitionFactor);
167 }
168
169 RNTupleLocalIndex operator++(int) /* postfix */
170 {
171 auto r = *this;
173 return r;
174 }
175
177 {
179 return *this;
180 }
181
183 {
184 return fClusterId == other.fClusterId && fIndexInCluster == other.fIndexInCluster;
185 }
186
187 bool operator!=(RNTupleLocalIndex other) const { return !(*this == other); }
188
191};
192
193/// RNTupleLocator payload that is common for object stores using 64bit location information.
194/// This might not contain the full location of the content. In particular, for page locators this information may be
195/// used in conjunction with the cluster and column ID.
197private:
198 std::uint64_t fLocation = 0;
199
200public:
202 explicit RNTupleLocatorObject64(std::uint64_t location) : fLocation(location) {}
203 bool operator==(const RNTupleLocatorObject64 &other) const { return fLocation == other.fLocation; }
204 std::uint64_t GetLocation() const { return fLocation; }
205};
206
207/// RNTupleLocator payload for the kTypeMulti locator (type 0x03). Used by storage
208/// backends that pack multiple pages into shared objects (e.g., S3 Mode A). The two
209/// 32-bit fields are written to disk as separate integers, so the on-disk layout is
210/// directly interpretable without any bit unpacking.
212private:
213 std::uint32_t fObjectId = 0;
214 std::uint32_t fOffset = 0;
215
216public:
218 RNTupleLocatorMulti(std::uint32_t objectId, std::uint32_t offset) : fObjectId(objectId), fOffset(offset) {}
219
220 bool operator==(const RNTupleLocatorMulti &other) const
221 {
222 return fObjectId == other.fObjectId && fOffset == other.fOffset;
223 }
224
225 std::uint32_t GetObjectId() const { return fObjectId; }
226 std::uint32_t GetOffset() const { return fOffset; }
227};
228
229// Workaround missing return type overloading
230class RNTupleLocator;
231namespace Internal {
232template <typename T>
234
235template <>
236struct RNTupleLocatorHelper<std::uint64_t> {
237 static std::uint64_t Get(const RNTupleLocator &loc);
238};
239
240template <>
244
245template <>
249} // namespace Internal
250
251/// Generic information about the physical location of data. Values depend on the concrete storage type. E.g.,
252/// for a local file `fPosition` is a 64bit file offset. Referenced objects on storage can be compressed
253/// and therefore we need to store their actual size.
254/// Note that we use a representation optimized for memory consumption that slightly differs from the on-disk
255/// representation.
257 friend struct Internal::RNTupleLocatorHelper<std::uint64_t>;
258 friend struct Internal::RNTupleLocatorHelper<RNTupleLocatorObject64>;
259 friend struct Internal::RNTupleLocatorHelper<RNTupleLocatorMulti>;
260
261public:
262 /// Values for the _Type_ field in non-disk locators. Serializable types must have the MSb == 0; see
263 /// `doc/BinaryFormatSpecification.md` for details
264 enum ELocatorType : std::uint8_t {
265 // The kTypeFile locator may translate to an on-disk standard locator (type 0x00) or a large locator (type 0x01),
266 // if the size of the referenced data block is >2GB
267 kTypeFile = 0x00,
268 // The following locators are experimental and are not defined in the binary format specification.
269 kTypeObject64 = 0x02,
270 kTypeMulti = 0x03,
271
272 kLastSerializableType = 0x7f,
273 kTypePageZero = kLastSerializableType + 1,
275 };
276
277private:
278 /// The 4 most significant bits of fFlagsAndNBytes carry the locator type (3 bits)
279 /// plus one bit for a reserved bit of an extended locator.
280 static constexpr std::uint64_t kMaskFlags = 0x0FULL << 60;
281 static constexpr std::uint64_t kMaskType = 0x07ULL << 61;
282 static constexpr std::uint64_t kMaskReservedBit = 1ull << 60;
283
284 /// To save memory, we use the most significant bits to store the locator type (file, Object64, zero page,
285 /// unkown, kTestLocatorType) as well as one "reserved bit" that can be used in future locators.
286 /// Consequently, we can only store sizes up to 60 bits (1 EB), which in practice won't be an issue.
287 std::uint64_t fFlagsAndNBytes = 0;
288 /// Simple on-disk locators consisting of a 64-bit offset use variant type `uint64_t`;
289 /// Object store locators use RNTupleLocatorObject64 but can still use the same 64 bit int for information storage.
290 std::uint64_t fPosition = 0;
291
292public:
293 RNTupleLocator() = default;
294
295 bool operator==(const RNTupleLocator &other) const
296 {
297 return fPosition == other.fPosition && fFlagsAndNBytes == other.fFlagsAndNBytes;
298 }
299
300 std::uint64_t GetNBytesOnStorage() const { return fFlagsAndNBytes & ~kMaskFlags; }
301 /// For non-disk locators, the value for the _Type_ field. This makes it possible to have different type values even
302 /// if the payload structure is identical.
303 ELocatorType GetType() const;
304 /// We currently only support one of the 8 available reserved bits (none are used so far).
305 std::uint8_t GetReserved() const { return (fFlagsAndNBytes & kMaskReservedBit) > 0; }
306
307 void SetNBytesOnStorage(std::uint64_t nBytesOnStorage);
309 void SetReserved(std::uint8_t reserved);
310
311 /// Note that for GetPosition() / SetPosition(), the locator type must correspond
312 /// (kTypeFile, kTypeObject64, ...).
313
314 template <typename T>
315 T GetPosition() const
316 {
318 }
319
320 void SetPosition(std::uint64_t position);
321 void SetPosition(RNTupleLocatorObject64 position);
322 void SetPosition(RNTupleLocatorMulti position);
323};
324
325namespace Internal {
326class RPageSource; // For RNTupleInputSpec
327}
328
329// clang-format off
330 /**
331 \class ROOT::Experimental::RNTupleInputSpec
332 \ingroup NTuple
333 \brief Specification of the name and location of an RNTuple, used for creating a new RNTupleProcessor.
334
335 An RNTupleInputSpec can be created by providing either a string with a path to the ROOT file or a pointer to the
336 TDirectory (or any of its subclasses) that contains the RNTuple.
337
338 Note that the RNTupleInputSpec is *write-only*, to prevent usability issues with Python.
339 */
340// clang-format on
342 friend class RNTupleProcessor;
344
345public:
346 using Storage_t = std::variant<std::string, TDirectory *>;
347
348private:
349 std::string fNTupleName;
351
352public:
353 RNTupleInputSpec(std::string_view n, TDirectory *s) : fNTupleName(n), fStorage(s) {}
354 RNTupleInputSpec(std::string_view n, const std::string &s) : fNTupleName(n), fStorage(s) {}
355
356 const std::string &GetNTupleName() const { return fNTupleName; }
357 const Storage_t &GetStorage() const { return fStorage; }
358};
359
360namespace Internal {
361
364 /// Uncompressed length of the anchor, including the checksum.
365 std::uint32_t fLength = 0;
366};
367
368/// The in-memory representation of a 32bit or 64bit on-disk index column. Wraps the integer in a
369/// named type so that templates can distinguish between integer data columns and index columns.
371public:
372 using ValueType = std::uint64_t;
373
374private:
376
377public:
378 RColumnIndex() = default;
379 explicit constexpr RColumnIndex(ValueType value) : fValue(value) {}
381 {
382 fValue = value;
383 return *this;
384 }
386 {
387 fValue += value;
388 return *this;
389 }
391 {
392 auto result = *this;
393 fValue++;
394 return result;
395 }
396 operator ValueType() const { return fValue; }
397};
398
399/// Holds the index and the tag of a kSwitch column
401private:
403 std::uint32_t fTag = 0;
404
405public:
406 RColumnSwitch() = default;
407 RColumnSwitch(ROOT::NTupleSize_t index, std::uint32_t tag) : fIndex(index), fTag(tag) {}
409 std::uint32_t GetTag() const { return fTag; }
410};
411
412inline constexpr ENTupleColumnType kTestFutureColumnType =
413 static_cast<ENTupleColumnType>(std::numeric_limits<std::underlying_type_t<ENTupleColumnType>>::max() - 1);
414
416 static_cast<ROOT::ENTupleStructure>(std::numeric_limits<std::underlying_type_t<ROOT::ENTupleStructure>>::max() - 1);
417
420
421} // namespace Internal
422} // namespace ROOT
423
424#endif
#define R__likely(expr)
Definition RConfig.hxx:569
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h offset
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t r
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t result
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t index
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t type
The in-memory representation of a 32bit or 64bit on-disk index column.
constexpr RColumnIndex(ValueType value)
RColumnIndex & operator=(const ValueType value)
RColumnIndex & operator+=(const ValueType value)
Holds the index and the tag of a kSwitch column.
std::uint32_t GetTag() const
ROOT::NTupleSize_t GetIndex() const
RColumnSwitch(ROOT::NTupleSize_t index, std::uint32_t tag)
const std::string & GetNTupleName() const
RNTupleInputSpec(std::string_view n, const std::string &s)
RNTupleInputSpec(std::string_view n, TDirectory *s)
const Storage_t & GetStorage() const
std::variant< std::string, TDirectory * > Storage_t
Addresses a column element or field item relative to a particular cluster, instead of a global NTuple...
RNTupleLocalIndex operator*(ROOT::NTupleSize_t repetitionFactor) const
RNTupleLocalIndex operator-(ROOT::NTupleSize_t off) const
ROOT::NTupleSize_t fIndexInCluster
RNTupleLocalIndex operator++(int)
bool operator==(RNTupleLocalIndex other) const
RNTupleLocalIndex operator+(ROOT::NTupleSize_t off) const
ROOT::NTupleSize_t GetIndexInCluster() const
constexpr RNTupleLocalIndex(ROOT::DescriptorId_t clusterId, ROOT::NTupleSize_t indexInCluster)
RNTupleLocalIndex & operator++()
RNTupleLocalIndex(const RNTupleLocalIndex &other)=default
RNTupleLocalIndex & operator=(const RNTupleLocalIndex &other)=default
bool operator!=(RNTupleLocalIndex other) const
ROOT::DescriptorId_t fClusterId
ROOT::DescriptorId_t GetClusterId() const
RNTupleLocator payload for the kTypeMulti locator (type 0x03).
RNTupleLocatorMulti(std::uint32_t objectId, std::uint32_t offset)
std::uint32_t GetOffset() const
std::uint32_t GetObjectId() const
bool operator==(const RNTupleLocatorMulti &other) const
RNTupleLocator payload that is common for object stores using 64bit location information.
bool operator==(const RNTupleLocatorObject64 &other) const
RNTupleLocatorObject64(std::uint64_t location)
std::uint64_t GetLocation() const
Generic information about the physical location of data.
std::uint64_t GetNBytesOnStorage() const
bool operator==(const RNTupleLocator &other) const
std::uint64_t fPosition
Simple on-disk locators consisting of a 64-bit offset use variant type uint64_t; Object store locator...
RNTupleLocator()=default
ELocatorType
Values for the Type field in non-disk locators.
std::uint64_t fFlagsAndNBytes
To save memory, we use the most significant bits to store the locator type (file, Object64,...
static constexpr std::uint64_t kMaskFlags
The 4 most significant bits of fFlagsAndNBytes carry the locator type (3 bits) plus one bit for a res...
ELocatorType GetType() const
For non-disk locators, the value for the Type field.
std::uint8_t GetReserved() const
We currently only support one of the 8 available reserved bits (none are used so far).
static constexpr std::uint64_t kMaskReservedBit
T GetPosition() const
Note that for GetPosition() / SetPosition(), the locator type must correspond (kTypeFile,...
void SetType(ELocatorType type)
void SetPosition(std::uint64_t position)
static constexpr std::uint64_t kMaskType
void SetReserved(std::uint8_t reserved)
See GetReserved(): we ignore the reserved flag since we don't use it anywhere currently.
void SetNBytesOnStorage(std::uint64_t nBytesOnStorage)
Interface for iterating over entries of vertically ("chained") and/or horizontally ("joined") combine...
Processor specialization for processing a single RNTuple.
Describe directory structure in memory.
Definition TDirectory.h:45
const Int_t n
Definition legend1.C:16
constexpr ROOT::ENTupleStructure kTestFutureFieldStructure
constexpr RNTupleLocator::ELocatorType kTestLocatorType
std::ostream & operator<<(std::ostream &os, const RConcurrentHashColl::HashValue &h)
std::uint64_t DescriptorId_t
Distriniguishes elements of the same type within a descriptor, e.g. different fields.
constexpr NTupleSize_t kInvalidNTupleIndex
std::uint64_t NTupleSize_t
Integer type long enough to hold the maximum number of entries in a column.
constexpr DescriptorId_t kInvalidDescriptorId
ENTupleStructure
The fields in the RNTuple data model tree can carry different structural information about the type s...
ENTupleColumnType
static RNTupleLocatorMulti Get(const RNTupleLocator &loc)
static RNTupleLocatorObject64 Get(const RNTupleLocator &loc)
Helper types to present an offset column as array of collection sizes.
RNTupleCardinality & operator=(const ValueType value)
constexpr RNTupleCardinality(ValueType value)