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
24namespace ROOT {
25
26/// Helper types to present an offset column as array of collection sizes.
27/// See RField<RNTupleCardinality<SizeT>> for details.
28template <typename SizeT>
30 static_assert(std::is_same_v<SizeT, std::uint32_t> || std::is_same_v<SizeT, std::uint64_t>,
31 "RNTupleCardinality is only supported with std::uint32_t or std::uint64_t template parameters");
32
33 using ValueType = SizeT;
34
36 explicit constexpr RNTupleCardinality(ValueType value) : fValue(value) {}
38 {
39 fValue = value;
40 return *this;
41 }
42 operator ValueType() const { return fValue; }
43
45};
46
47// clang-format off
48/**
49\class ROOT::ENTupleColumnType
50\ingroup NTuple
51\brief The available trivial, native content types of a column
52
53More complex types, such as classes, get translated into columns of such simple types by the RField.
54When changed, remember to update
55 - RColumnElement::Generate()
56 - RColumnElement::GetTypeName()
57 - RColumnElement::GetValidBitRange()
58 - RColumnElement template specializations / packing & unpacking
59 - If necessary, endianess handling for the packing + unit test in ntuple_endian
60 - RNTupleSerializer::[Des|S]erializeColumnType
61*/
62// clang-format on
64 kUnknown = 0,
65 // type for root columns of (nested) collections; offsets are relative to the current cluster
68 // 96 bit column that is a pair of a kIndex64 and a 32bit dispatch tag to a column ID;
69 // used to serialize std::variant.
70 kSwitch,
71 kByte,
72 kChar,
73 kBit,
74 kReal64,
75 kReal32,
76 kReal16,
77 kInt64,
78 kUInt64,
79 kInt32,
80 kUInt32,
81 kInt16,
82 kUInt16,
83 kInt8,
84 kUInt8,
97 kMax,
98};
99
100/// The fields in the RNTuple data model tree can carry different structural information about the type system.
101/// Collection fields have an offset column and subfields with arbitrary cardinality, record fields have no
102/// materialization on the primitive column layer and an arbitrary number of subfields. Plain fields are either
103/// leafs (e.g., `float`) or "wrapper fields" with exactly one child that has the same cardinality
104/// (number of elements in the data set modulo field repetitions) as the parent (e.g., std::atomic<T>).
105// IMPORTANT: if you add members, remember to change the related `operator<<` below.
106enum class ENTupleStructure : std::uint16_t {
107 kInvalid,
108 kPlain,
110 kRecord,
111 kVariant,
112 kStreamer,
113 kUnknown,
114};
115
116inline std::ostream &operator<<(std::ostream &os, ENTupleStructure structure)
117{
118 static const char *const names[] = {"Invalid", "Plain", "Collection", "Record", "Variant", "Streamer", "Unknown"};
119 static_assert((std::size_t)ENTupleStructure::kUnknown + 1 == std::size(names));
120
121 if (R__likely(static_cast<std::size_t>(structure) <= std::size(names)))
123 else
124 os << "(invalid)";
125 return os;
126}
127
128/// Integer type long enough to hold the maximum number of entries in a column
129using NTupleSize_t = std::uint64_t;
130constexpr NTupleSize_t kInvalidNTupleIndex = std::uint64_t(-1);
131
132/// Distriniguishes elements of the same type within a descriptor, e.g. different fields
133using DescriptorId_t = std::uint64_t;
134constexpr DescriptorId_t kInvalidDescriptorId = std::uint64_t(-1);
135
136/// Addresses a column element or field item relative to a particular cluster, instead of a global NTupleSize_t index
138private:
141
142public:
143 RNTupleLocalIndex() = default;
150
155
160
165
166 RNTupleLocalIndex operator++(int) /* postfix */
167 {
168 auto r = *this;
170 return r;
171 }
172
174 {
176 return *this;
177 }
178
180 {
181 return fClusterId == other.fClusterId && fIndexInCluster == other.fIndexInCluster;
182 }
183
184 bool operator!=(RNTupleLocalIndex other) const { return !(*this == other); }
185
188};
189
190/// RNTupleLocator payload that is common for object stores using 64bit location information.
191/// This might not contain the full location of the content. In particular, for page locators this information may be
192/// used in conjunction with the cluster and column ID.
194private:
195 std::uint64_t fLocation = 0;
196
197public:
199 explicit RNTupleLocatorObject64(std::uint64_t location) : fLocation(location) {}
200 bool operator==(const RNTupleLocatorObject64 &other) const { return fLocation == other.fLocation; }
201 std::uint64_t GetLocation() const { return fLocation; }
202};
203
204/// RNTupleLocator payload for the kTypeMulti locator (type 0x03). Used by storage
205/// backends that pack multiple pages into shared objects (e.g., S3 Mode A). The two
206/// 32-bit fields are written to disk as separate integers, so the on-disk layout is
207/// directly interpretable without any bit unpacking.
209private:
210 std::uint32_t fObjectId = 0;
211 std::uint32_t fOffset = 0;
212
213public:
215 RNTupleLocatorMulti(std::uint32_t objectId, std::uint32_t offset) : fObjectId(objectId), fOffset(offset) {}
216
218 {
219 return fObjectId == other.fObjectId && fOffset == other.fOffset;
220 }
221
222 std::uint32_t GetObjectId() const { return fObjectId; }
223 std::uint32_t GetOffset() const { return fOffset; }
224};
225
226// Workaround missing return type overloading
227class RNTupleLocator;
228namespace Internal {
229template <typename T>
231
232template <>
233struct RNTupleLocatorHelper<std::uint64_t> {
234 static std::uint64_t Get(const RNTupleLocator &loc);
235};
236
237template <>
241
242template <>
246} // namespace Internal
247
248/// Generic information about the physical location of data. Values depend on the concrete storage type. E.g.,
249/// for a local file `fPosition` is a 64bit file offset. Referenced objects on storage can be compressed
250/// and therefore we need to store their actual size.
251/// Note that we use a representation optimized for memory consumption that slightly differs from the on-disk
252/// representation.
254 friend struct Internal::RNTupleLocatorHelper<std::uint64_t>;
255 friend struct Internal::RNTupleLocatorHelper<RNTupleLocatorObject64>;
256 friend struct Internal::RNTupleLocatorHelper<RNTupleLocatorMulti>;
257
258public:
259 /// Values for the _Type_ field in non-disk locators. Serializable types must have the MSb == 0; see
260 /// `doc/BinaryFormatSpecification.md` for details
261 enum ELocatorType : std::uint8_t {
262 // The kTypeFile locator may translate to an on-disk standard locator (type 0x00) or a large locator (type 0x01),
263 // if the size of the referenced data block is >2GB
264 kTypeFile = 0x00,
265 // The following locators are experimental and are not defined in the binary format specification.
266 kTypeObject64 = 0x02,
267 kTypeMulti = 0x03,
268
269 kLastSerializableType = 0x7f,
270 kTypePageZero = kLastSerializableType + 1,
272 };
273
274private:
275 /// The 4 most significant bits of fFlagsAndNBytes carry the locator type (3 bits)
276 /// plus one bit for a reserved bit of an extended locator.
277 static constexpr std::uint64_t kMaskFlags = 0x0FULL << 60;
278 static constexpr std::uint64_t kMaskType = 0x07ULL << 61;
279 static constexpr std::uint64_t kMaskReservedBit = 1ull << 60;
280
281 /// To save memory, we use the most significant bits to store the locator type (file, Object64, zero page,
282 /// unkown, kTestLocatorType) as well as one "reserved bit" that can be used in future locators.
283 /// Consequently, we can only store sizes up to 60 bits (1 EB), which in practice won't be an issue.
284 std::uint64_t fFlagsAndNBytes = 0;
285 /// Simple on-disk locators consisting of a 64-bit offset use variant type `uint64_t`;
286 /// Object store locators use RNTupleLocatorObject64 but can still use the same 64 bit int for information storage.
287 std::uint64_t fPosition = 0;
288
289public:
290 RNTupleLocator() = default;
291
292 bool operator==(const RNTupleLocator &other) const
293 {
294 return fPosition == other.fPosition && fFlagsAndNBytes == other.fFlagsAndNBytes;
295 }
296
297 std::uint64_t GetNBytesOnStorage() const { return fFlagsAndNBytes & ~kMaskFlags; }
298 /// For non-disk locators, the value for the _Type_ field. This makes it possible to have different type values even
299 /// if the payload structure is identical.
300 ELocatorType GetType() const;
301 /// We currently only support one of the 8 available reserved bits (none are used so far).
302 std::uint8_t GetReserved() const { return (fFlagsAndNBytes & kMaskReservedBit) > 0; }
303
304 void SetNBytesOnStorage(std::uint64_t nBytesOnStorage);
306 void SetReserved(std::uint8_t reserved);
307
308 /// Note that for GetPosition() / SetPosition(), the locator type must correspond
309 /// (kTypeFile, kTypeObject64, ...).
310
311 template <typename T>
312 T GetPosition() const
313 {
315 }
316
317 void SetPosition(std::uint64_t position);
318 void SetPosition(RNTupleLocatorObject64 position);
319 void SetPosition(RNTupleLocatorMulti position);
320};
321
322namespace Internal {
323
326 /// Uncompressed length of the anchor, including the checksum.
327 std::uint32_t fLength = 0;
328};
329
330/// The in-memory representation of a 32bit or 64bit on-disk index column. Wraps the integer in a
331/// named type so that templates can distinguish between integer data columns and index columns.
333public:
334 using ValueType = std::uint64_t;
335
336private:
338
339public:
340 RColumnIndex() = default;
341 explicit constexpr RColumnIndex(ValueType value) : fValue(value) {}
343 {
344 fValue = value;
345 return *this;
346 }
348 {
349 fValue += value;
350 return *this;
351 }
353 {
354 auto result = *this;
355 fValue++;
356 return result;
357 }
358 operator ValueType() const { return fValue; }
359};
360
361/// Holds the index and the tag of a kSwitch column
363private:
365 std::uint32_t fTag = 0;
366
367public:
368 RColumnSwitch() = default;
369 RColumnSwitch(ROOT::NTupleSize_t index, std::uint32_t tag) : fIndex(index), fTag(tag) {}
371 std::uint32_t GetTag() const { return fTag; }
372};
373
374inline constexpr ENTupleColumnType kTestFutureColumnType =
375 static_cast<ENTupleColumnType>(std::numeric_limits<std::underlying_type_t<ENTupleColumnType>>::max() - 1);
376
378 static_cast<ROOT::ENTupleStructure>(std::numeric_limits<std::underlying_type_t<ROOT::ENTupleStructure>>::max() - 1);
379
382
383} // namespace Internal
384} // namespace ROOT
385
386#endif
#define R__likely(expr)
Definition RConfig.hxx:593
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
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)
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)
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)