Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
RNTupleDescriptor.cxx
Go to the documentation of this file.
1/// \file RNTupleDescriptor.cxx
2/// \ingroup NTuple ROOT7
3/// \author Jakob Blomer <jblomer@cern.ch>
4/// \date 2018-10-04
5/// \warning This is part of the ROOT 7 prototype! It will change without notice. It might trigger earthquakes. Feedback
6/// is welcome!
7
8/*************************************************************************
9 * Copyright (C) 1995-2019, Rene Brun and Fons Rademakers. *
10 * All rights reserved. *
11 * *
12 * For the licensing terms see $ROOTSYS/LICENSE. *
13 * For the list of contributors see $ROOTSYS/README/CREDITS. *
14 *************************************************************************/
15
16#include <ROOT/RError.hxx>
17#include <ROOT/RField.hxx>
19#include <ROOT/RNTupleModel.hxx>
20#include <ROOT/RNTupleUtil.hxx>
21#include <ROOT/RStringView.hxx>
22
23#include <RZip.h>
24#include <TError.h>
25
26#include <algorithm>
27#include <cstdint>
28#include <deque>
29#include <iostream>
30#include <set>
31#include <utility>
32
33
35{
36 return fFieldId == other.fFieldId &&
38 fTypeVersion == other.fTypeVersion &&
39 fFieldName == other.fFieldName &&
41 fTypeName == other.fTypeName &&
43 fStructure == other.fStructure &&
44 fParentId == other.fParentId &&
45 fLinkIds == other.fLinkIds;
46}
47
50{
51 RFieldDescriptor clone;
52 clone.fFieldId = fFieldId;
53 clone.fFieldVersion = fFieldVersion;
54 clone.fTypeVersion = fTypeVersion;
55 clone.fFieldName = fFieldName;
56 clone.fFieldDescription = fFieldDescription;
57 clone.fTypeName = fTypeName;
58 clone.fNRepetitions = fNRepetitions;
59 clone.fStructure = fStructure;
60 clone.fParentId = fParentId;
61 clone.fLinkIds = fLinkIds;
62 return clone;
63}
64
65std::unique_ptr<ROOT::Experimental::Detail::RFieldBase>
67{
68 if (GetTypeName().empty() && GetStructure() == ENTupleStructure::kCollection) {
69 // For untyped collections, we have no class available to collect all the sub fields.
70 // Therefore, we create an untyped record field as an artifical binder for the collection items.
71 std::vector<std::unique_ptr<Detail::RFieldBase>> memberFields;
72 for (auto id : fLinkIds) {
73 const auto &memberDesc = ntplDesc.GetFieldDescriptor(id);
74 memberFields.emplace_back(memberDesc.CreateField(ntplDesc));
75 }
76 auto recordField = std::make_unique<RRecordField>("_0", memberFields);
77 auto collectionField = std::make_unique<RVectorField>(GetFieldName(), std::move(recordField));
78 collectionField->SetOnDiskId(fFieldId);
79 return collectionField;
80 }
81
82 auto field = Detail::RFieldBase::Create(GetFieldName(), GetTypeName()).Unwrap();
83 field->SetOnDiskId(fFieldId);
84 for (auto &f : *field)
85 f.SetOnDiskId(ntplDesc.FindFieldId(f.GetName(), f.GetParent()->GetOnDiskId()));
86 return field;
87}
88
89
90////////////////////////////////////////////////////////////////////////////////
91
92
94{
95 return fColumnId == other.fColumnId &&
96 fModel == other.fModel &&
97 fFieldId == other.fFieldId &&
98 fIndex == other.fIndex;
99}
100
101
104{
105 RColumnDescriptor clone;
106 clone.fColumnId = fColumnId;
107 clone.fModel = fModel;
108 clone.fFieldId = fFieldId;
109 clone.fIndex = fIndex;
110 return clone;
111}
112
113
114////////////////////////////////////////////////////////////////////////////////
115
116
119{
120 // TODO(jblomer): binary search
121 RPageInfo pageInfo;
122 decltype(idxInCluster) firstInPage = 0;
123 NTupleSize_t pageNo = 0;
124 for (const auto &pi : fPageInfos) {
125 if (firstInPage + pi.fNElements > idxInCluster) {
126 pageInfo = pi;
127 break;
128 }
129 firstInPage += pi.fNElements;
130 ++pageNo;
131 }
132 R__ASSERT(firstInPage <= idxInCluster);
133 R__ASSERT((firstInPage + pageInfo.fNElements) > idxInCluster);
134 return RPageInfoExtended{pageInfo, firstInPage, pageNo};
135}
136
137
139{
140 return fClusterId == other.fClusterId && fFirstEntryIndex == other.fFirstEntryIndex &&
141 fNEntries == other.fNEntries && fHasPageLocations == other.fHasPageLocations &&
142 fColumnRanges == other.fColumnRanges && fPageRanges == other.fPageRanges;
143}
144
145
146std::unordered_set<ROOT::Experimental::DescriptorId_t> ROOT::Experimental::RClusterDescriptor::GetColumnIds() const
147{
148 EnsureHasPageLocations();
149 std::unordered_set<DescriptorId_t> result;
150 for (const auto &x : fColumnRanges)
151 result.emplace(x.first);
152 return result;
153}
154
155
157{
158 EnsureHasPageLocations();
159 return fColumnRanges.find(columnId) != fColumnRanges.end();
160}
161
162
164{
165 EnsureHasPageLocations();
166 std::uint64_t nbytes = 0;
167 for (const auto &pr : fPageRanges) {
168 for (const auto &pi : pr.second.fPageInfos) {
169 nbytes += pi.fLocator.fBytesOnStorage;
170 }
171 }
172 return nbytes;
173}
174
176{
177 if (!fHasPageLocations)
178 throw RException(R__FAIL("invalid attempt to access page locations of summary-only cluster descriptor"));
179}
180
182{
183 RClusterDescriptor clone;
184 clone.fClusterId = fClusterId;
185 clone.fFirstEntryIndex = fFirstEntryIndex;
186 clone.fNEntries = fNEntries;
187 clone.fHasPageLocations = fHasPageLocations;
188 clone.fColumnRanges = fColumnRanges;
189 for (const auto &d : fPageRanges)
190 clone.fPageRanges.emplace(d.first, d.second.Clone());
191 return clone;
192}
193
194////////////////////////////////////////////////////////////////////////////////
195
196
198{
199 return fName == other.fName && fDescription == other.fDescription && fNEntries == other.fNEntries &&
200 fGeneration == other.fGeneration && fFieldDescriptors == other.fFieldDescriptors &&
201 fColumnDescriptors == other.fColumnDescriptors &&
202 fClusterGroupDescriptors == other.fClusterGroupDescriptors &&
203 fClusterDescriptors == other.fClusterDescriptors;
204}
205
206
208{
210 for (const auto &cd : fClusterDescriptors) {
211 if (!cd.second.ContainsColumn(columnId))
212 continue;
213 auto columnRange = cd.second.GetColumnRange(columnId);
214 result = std::max(result, columnRange.fFirstElementIndex + columnRange.fNElements);
215 }
216 return result;
217}
218
219
222{
223 std::string leafName(fieldName);
224 auto posDot = leafName.find_last_of('.');
225 if (posDot != std::string::npos) {
226 auto parentName = leafName.substr(0, posDot);
227 leafName = leafName.substr(posDot + 1);
228 parentId = FindFieldId(parentName, parentId);
229 }
230 for (const auto &fd : fFieldDescriptors) {
231 if (fd.second.GetParentId() == parentId && fd.second.GetFieldName() == leafName)
232 return fd.second.GetId();
233 }
235}
236
237
239{
240 if (fieldId == kInvalidDescriptorId)
241 return "";
242
243 const auto &fieldDescriptor = fFieldDescriptors.at(fieldId);
244 auto prefix = GetQualifiedFieldName(fieldDescriptor.GetParentId());
245 if (prefix.empty())
246 return fieldDescriptor.GetFieldName();
247 return prefix + "." + fieldDescriptor.GetFieldName();
248}
249
250
253{
254 return FindFieldId("", kInvalidDescriptorId);
255}
256
257
260{
261 return FindFieldId(fieldName, GetFieldZeroId());
262}
263
264
267{
268 for (const auto &cd : fColumnDescriptors) {
269 if (cd.second.GetFieldId() == fieldId && cd.second.GetIndex() == columnIndex)
270 return cd.second.GetId();
271 }
273}
274
277{
278 // TODO(jblomer): binary search?
279 for (const auto &cd : fClusterDescriptors) {
280 if (!cd.second.ContainsColumn(columnId))
281 continue;
282 auto columnRange = cd.second.GetColumnRange(columnId);
283 if (columnRange.Contains(index))
284 return cd.second.GetId();
285 }
287}
288
289
290// TODO(jblomer): fix for cases of sharded clasters
293{
294 const auto &clusterDesc = GetClusterDescriptor(clusterId);
295 auto firstEntryInNextCluster = clusterDesc.GetFirstEntryIndex() + clusterDesc.GetNEntries();
296 // TODO(jblomer): binary search?
297 for (const auto &cd : fClusterDescriptors) {
298 if (cd.second.GetFirstEntryIndex() == firstEntryInNextCluster)
299 return cd.second.GetId();
300 }
302}
303
304
305// TODO(jblomer): fix for cases of sharded clasters
308{
309 const auto &clusterDesc = GetClusterDescriptor(clusterId);
310 // TODO(jblomer): binary search?
311 for (const auto &cd : fClusterDescriptors) {
312 if (cd.second.GetFirstEntryIndex() + cd.second.GetNEntries() == clusterDesc.GetFirstEntryIndex())
313 return cd.second.GetId();
314 }
316}
317
320{
321 auto iter = fClusterDescriptors.find(clusterDesc.GetId());
322 if (iter == fClusterDescriptors.end())
323 return R__FAIL("invalid attempt to add cluster details without known cluster summary");
324 if (iter->second.HasPageLocations())
325 return R__FAIL("invalid attempt to re-populate page list");
326 if (!clusterDesc.HasPageLocations())
327 return R__FAIL("provided cluster descriptor does not contain page locations");
328 iter->second = std::move(clusterDesc);
329 return RResult<void>::Success();
330}
331
333{
334 auto iter = fClusterDescriptors.find(clusterId);
335 if (iter == fClusterDescriptors.end())
336 return R__FAIL("invalid attempt to drop cluster details of unknown cluster");
337 if (!iter->second.HasPageLocations())
338 return R__FAIL("invalid attempt to drop details of cluster summary");
339 iter->second = RClusterDescriptor(clusterId, iter->second.GetFirstEntryIndex(), iter->second.GetNEntries());
340 return RResult<void>::Success();
341}
342
343std::unique_ptr<ROOT::Experimental::RNTupleModel> ROOT::Experimental::RNTupleDescriptor::GenerateModel() const
344{
345 auto model = RNTupleModel::Create();
346 model->GetFieldZero()->SetOnDiskId(GetFieldZeroId());
347 for (const auto &topDesc : GetTopLevelFields())
348 model->AddField(topDesc.CreateField(*this));
349 model->Freeze();
350 return model;
351}
352
353std::unique_ptr<ROOT::Experimental::RNTupleDescriptor> ROOT::Experimental::RNTupleDescriptor::Clone() const
354{
355 auto clone = std::make_unique<RNTupleDescriptor>();
356 clone->fName = fName;
357 clone->fDescription = fDescription;
358 clone->fOnDiskHeaderSize = fOnDiskHeaderSize;
359 clone->fOnDiskFooterSize = fOnDiskFooterSize;
360 clone->fNEntries = fNEntries;
361 clone->fGeneration = fGeneration;
362 for (const auto &d : fFieldDescriptors)
363 clone->fFieldDescriptors.emplace(d.first, d.second.Clone());
364 for (const auto &d : fColumnDescriptors)
365 clone->fColumnDescriptors.emplace(d.first, d.second.Clone());
366 for (const auto &d : fClusterGroupDescriptors)
367 clone->fClusterGroupDescriptors.emplace(d.first, d.second.Clone());
368 for (const auto &d : fClusterDescriptors)
369 clone->fClusterDescriptors.emplace(d.first, d.second.Clone());
370 return clone;
371}
372
373////////////////////////////////////////////////////////////////////////////////
374
376{
377 return fColumnGroupId == other.fColumnGroupId && fColumnIds == other.fColumnIds;
378}
379
380////////////////////////////////////////////////////////////////////////////////
381
383{
384 return fClusterGroupId == other.fClusterGroupId && fClusterIds == other.fClusterIds;
385}
386
388{
390 clone.fClusterGroupId = fClusterGroupId;
391 clone.fClusterIds = fClusterIds;
392 clone.fPageListLocator = fPageListLocator;
393 clone.fPageListLength = fPageListLength;
394 return clone;
395}
396
397////////////////////////////////////////////////////////////////////////////////
398
401 DescriptorId_t columnId, std::uint64_t firstElementIndex, std::uint32_t compressionSettings,
402 const RClusterDescriptor::RPageRange &pageRange)
403{
404 if (columnId != pageRange.fColumnId)
405 return R__FAIL("column ID mismatch");
406 if (fCluster.fPageRanges.count(columnId) > 0)
407 return R__FAIL("column ID conflict");
408 RClusterDescriptor::RColumnRange columnRange{columnId, firstElementIndex, RClusterSize(0)};
409 columnRange.fCompressionSettings = compressionSettings;
410 for (const auto &pi : pageRange.fPageInfos) {
411 columnRange.fNElements += pi.fNElements;
412 }
413 fCluster.fPageRanges[columnId] = pageRange.Clone();
414 fCluster.fColumnRanges[columnId] = columnRange;
415 return RResult<void>::Success();
416}
417
418
421{
422 if (fCluster.fClusterId == kInvalidDescriptorId)
423 return R__FAIL("unset cluster ID");
424 if (fCluster.fNEntries == 0)
425 return R__FAIL("empty cluster");
426 for (const auto &pr : fCluster.fPageRanges) {
427 if (fCluster.fColumnRanges.count(pr.first) == 0) {
428 return R__FAIL("missing column range");
429 }
430 }
431 fCluster.fHasPageLocations = true;
433 std::swap(result, fCluster);
434 return result;
435}
436
437std::vector<ROOT::Experimental::RClusterDescriptorBuilder>
439 DescriptorId_t clusterGroupId)
440{
441 const auto &clusterGroupDesc = ntplDesc.GetClusterGroupDescriptor(clusterGroupId);
442 std::vector<RClusterDescriptorBuilder> result;
443 for (auto clusterId : clusterGroupDesc.fClusterIds) {
444 const auto &cluster = ntplDesc.GetClusterDescriptor(clusterId);
445 result.emplace_back(RClusterDescriptorBuilder(clusterId, cluster.GetFirstEntryIndex(), cluster.GetNEntries()));
446 }
447 return result;
448}
449
450////////////////////////////////////////////////////////////////////////////////
451
454{
455 if (fClusterGroup.fClusterGroupId == kInvalidDescriptorId)
456 return R__FAIL("unset cluster group ID");
458 std::swap(result, fClusterGroup);
459 return result;
460}
461
462////////////////////////////////////////////////////////////////////////////////
463
466{
467 if (fColumnGroup.fColumnGroupId == kInvalidDescriptorId)
468 return R__FAIL("unset column group ID");
470 std::swap(result, fColumnGroup);
471 return result;
472}
473
474////////////////////////////////////////////////////////////////////////////////
475
478 if (fDescriptor.fFieldDescriptors.count(fieldId) == 0)
479 return R__FAIL("field with id '" + std::to_string(fieldId) + "' doesn't exist");
480 return RResult<void>::Success();
481}
482
485 // Reuse field name validity check
486 auto validName = Detail::RFieldBase::EnsureValidFieldName(fDescriptor.GetName());
487 if (!validName) {
488 return R__FORWARD_ERROR(validName);
489 }
490 // open-ended list of invariant checks
491 for (const auto& key_val: fDescriptor.fFieldDescriptors) {
492 const auto& id = key_val.first;
493 const auto& desc = key_val.second;
494 // parent not properly set
495 if (id != DescriptorId_t(0) && desc.GetParentId() == kInvalidDescriptorId) {
496 return R__FAIL("field with id '" + std::to_string(id) + "' has an invalid parent id");
497 }
498 }
499 return RResult<void>::Success();
500}
501
503{
505 std::swap(result, fDescriptor);
506 return result;
507}
508
510 const std::string_view description)
511{
512 fDescriptor.fName = std::string(name);
513 fDescriptor.fDescription = std::string(description);
514}
515
518{
519 if (fColumn.GetId() == kInvalidDescriptorId)
520 return R__FAIL("invalid column id");
521 if (fColumn.GetModel().GetType() == EColumnType::kUnknown)
522 return R__FAIL("invalid column model");
523 if (fColumn.GetFieldId() == kInvalidDescriptorId)
524 return R__FAIL("invalid field id, dangling column");
525 return fColumn.Clone();
526}
527
529 const RFieldDescriptor& fieldDesc) : fField(fieldDesc.Clone())
530{
532 fField.fLinkIds = {};
533}
534
537 RFieldDescriptorBuilder fieldDesc;
538 fieldDesc.FieldVersion(field.GetFieldVersion())
540 .FieldName(field.GetName())
542 .TypeName(field.GetType())
543 .Structure(field.GetStructure())
545 return fieldDesc;
546}
547
550 if (fField.GetId() == kInvalidDescriptorId) {
551 return R__FAIL("invalid field id");
552 }
553 if (fField.GetStructure() == ENTupleStructure::kInvalid) {
554 return R__FAIL("invalid field structure");
555 }
556 // FieldZero is usually named "" and would be a false positive here
557 if (fField.GetParentId() != kInvalidDescriptorId) {
558 auto validName = Detail::RFieldBase::EnsureValidFieldName(fField.GetFieldName());
559 if (!validName) {
560 return R__FORWARD_ERROR(validName);
561 }
562 }
563 return fField.Clone();
564}
565
567 fDescriptor.fFieldDescriptors.emplace(fieldDesc.GetId(), fieldDesc.Clone());
568}
569
572{
573 auto fieldExists = RResult<void>::Success();
574 if (!(fieldExists = EnsureFieldExists(fieldId)))
575 return R__FORWARD_ERROR(fieldExists);
576 if (!(fieldExists = EnsureFieldExists(linkId)))
577 return R__FAIL("child field with id '" + std::to_string(linkId) + "' doesn't exist in NTuple");
578
579 if (linkId == fDescriptor.GetFieldZeroId()) {
580 return R__FAIL("cannot make FieldZero a child field");
581 }
582 // fail if field already has another valid parent
583 auto parentId = fDescriptor.fFieldDescriptors.at(linkId).GetParentId();
584 if ((parentId != kInvalidDescriptorId) && (parentId != fieldId)) {
585 return R__FAIL("field '" + std::to_string(linkId) + "' already has a parent ('" +
586 std::to_string(parentId) + ")");
587 }
588 if (fieldId == linkId) {
589 return R__FAIL("cannot make field '" + std::to_string(fieldId) + "' a child of itself");
590 }
591 fDescriptor.fFieldDescriptors.at(linkId).fParentId = fieldId;
592 fDescriptor.fFieldDescriptors.at(fieldId).fLinkIds.push_back(linkId);
593 return RResult<void>::Success();
594}
595
597 const RColumnModel &model, std::uint32_t index)
598{
600 c.fColumnId = columnId;
601 c.fFieldId = fieldId;
602 c.fModel = model;
603 c.fIndex = index;
604 fDescriptor.fColumnDescriptors.emplace(columnId, std::move(c));
605}
606
607
610{
611 const auto fieldId = columnDesc.GetFieldId();
612 const auto index = columnDesc.GetIndex();
613
614 auto fieldExists = EnsureFieldExists(fieldId);
615 if (!fieldExists)
616 return R__FORWARD_ERROR(fieldExists);
617 if (fDescriptor.FindColumnId(fieldId, index) != kInvalidDescriptorId) {
618 return R__FAIL("column index clash");
619 }
620 if (index > 0) {
621 if (fDescriptor.FindColumnId(fieldId, index - 1) == kInvalidDescriptorId)
622 return R__FAIL("out of bounds column index");
623 }
624
625 auto columnId = columnDesc.GetId();
626 fDescriptor.fColumnDescriptors.emplace(columnId, std::move(columnDesc));
627
628 return RResult<void>::Success();
629}
630
633 std::uint64_t nEntries)
634{
635 if (fDescriptor.fClusterDescriptors.count(clusterId) > 0)
636 return R__FAIL("cluster id clash while adding cluster summary");
637 fDescriptor.fNEntries = std::max(fDescriptor.fNEntries, firstEntry + nEntries);
638 fDescriptor.fClusterDescriptors.emplace(clusterId, RClusterDescriptor(clusterId, firstEntry, nEntries));
639 return RResult<void>::Success();
640}
641
643{
644 auto id = clusterGroup.GetId();
645 fDescriptor.fClusterGroupDescriptors.emplace(id, clusterGroup.MoveDescriptor().Unwrap());
646}
647
649{
650 fDescriptor.fName = "";
651 fDescriptor.fDescription = "";
652 fDescriptor.fFieldDescriptors.clear();
653 fDescriptor.fColumnDescriptors.clear();
654 fDescriptor.fClusterDescriptors.clear();
655 fDescriptor.fClusterGroupDescriptors.clear();
656}
657
660{
661 auto clusterId = clusterDesc.GetId();
662 if (fDescriptor.fClusterDescriptors.count(clusterId) > 0)
663 return R__FAIL("cluster id clash");
664 fDescriptor.fNEntries =
665 std::max(fDescriptor.fNEntries, clusterDesc.GetFirstEntryIndex() + clusterDesc.GetNEntries());
666 fDescriptor.fClusterDescriptors.emplace(clusterId, std::move(clusterDesc));
667 return RResult<void>::Success();
668}
#define R__FORWARD_ERROR(res)
Short-hand to return an RResult<T> in an error state (i.e. after checking)
Definition RError.hxx:307
#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:303
#define d(i)
Definition RSha256.hxx:102
#define f(i)
Definition RSha256.hxx:104
#define c(i)
Definition RSha256.hxx:101
#define R__ASSERT(e)
Definition TError.h:117
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
char name[80]
Definition TGX11.cxx:110
virtual std::uint32_t GetFieldVersion() const
Indicates an evolution of the mapping scheme from C++ type to columns.
Definition RField.hxx:306
std::string GetDescription() const
Get the field's description.
Definition RField.hxx:294
std::size_t GetNRepetitions() const
Definition RField.hxx:288
virtual std::uint32_t GetTypeVersion() const
Indicates an evolution of the C++ type itself.
Definition RField.hxx:308
static RResult< void > EnsureValidFieldName(std::string_view fieldName)
Check whether a given string is a valid field name.
Definition RField.cxx:298
static RResult< std::unique_ptr< RFieldBase > > Create(const std::string &fieldName, const std::string &typeName)
Factory method to resurrect a field from the stored on-disk type information.
Definition RField.cxx:193
ENTupleStructure GetStructure() const
Definition RField.hxx:287
A helper class for piece-wise construction of an RClusterDescriptor.
RResult< void > CommitColumnRange(DescriptorId_t columnId, std::uint64_t firstElementIndex, std::uint32_t compressionSettings, const RClusterDescriptor::RPageRange &pageRange)
RResult< RClusterDescriptor > MoveDescriptor()
Move out the full cluster descriptor including page locations.
Meta-data for a set of ntuple clusters.
std::unordered_map< DescriptorId_t, RPageRange > fPageRanges
bool ContainsColumn(DescriptorId_t columnId) const
NTupleSize_t fFirstEntryIndex
Clusters can be swapped by adjusting the entry offsets.
std::unordered_set< DescriptorId_t > GetColumnIds() const
std::unordered_map< DescriptorId_t, RColumnRange > fColumnRanges
bool operator==(const RClusterDescriptor &other) const
A helper class for piece-wise construction of an RClusterGroupDescriptor.
RResult< RClusterGroupDescriptor > MoveDescriptor()
static std::vector< RClusterDescriptorBuilder > GetClusterSummaries(const RNTupleDescriptor &ntplDesc, DescriptorId_t clusterGroupId)
Used to prepare the cluster descriptor builders when loading the page locations for a certain cluster...
Clusters are stored in cluster groups.
std::uint32_t fPageListLength
Uncompressed size of the page list.
RNTupleLocator fPageListLocator
The page list that corresponds to the cluster group.
bool operator==(const RClusterGroupDescriptor &other) const
RResult< RColumnDescriptor > MakeDescriptor() const
Attempt to make a column descriptor.
Meta-data stored for every column of an ntuple.
RColumnDescriptor Clone() const
Get a copy of the descriptor.
DescriptorId_t fFieldId
Every column belongs to one and only one field.
RColumnModel fModel
Contains the column type and whether it is sorted.
std::uint32_t fIndex
A field can be serialized into several columns, which are numbered from zero to $n$.
bool operator==(const RColumnDescriptor &other) const
RResult< RColumnGroupDescriptor > MoveDescriptor()
Meta-data for a sets of columns; non-trivial column groups are used for sharded clusters.
bool operator==(const RColumnGroupDescriptor &other) const
std::unordered_set< DescriptorId_t > fColumnIds
Holds the static meta-data of a column in a tree.
Base class for all ROOT issued exceptions.
Definition RError.hxx:78
A helper class for piece-wise construction of an RFieldDescriptor.
RFieldDescriptorBuilder & FieldName(const std::string &fieldName)
RFieldDescriptorBuilder & NRepetitions(std::uint64_t nRepetitions)
static RFieldDescriptorBuilder FromField(const Detail::RFieldBase &field)
Make a new RFieldDescriptorBuilder based off a live NTuple field.
RFieldDescriptorBuilder & Structure(const ENTupleStructure &structure)
RResult< RFieldDescriptor > MakeDescriptor() const
Attempt to make a field descriptor.
RFieldDescriptorBuilder & TypeName(const std::string &typeName)
RFieldDescriptorBuilder & TypeVersion(std::uint32_t typeVersion)
RFieldDescriptorBuilder & FieldDescription(const std::string &fieldDescription)
RFieldDescriptorBuilder & FieldVersion(std::uint32_t fieldVersion)
RFieldDescriptorBuilder()=default
Make an empty dangling field descriptor.
Meta-data stored for every field of an ntuple.
std::vector< DescriptorId_t > fLinkIds
The pointers in the other direction from parent to children.
std::uint32_t fTypeVersion
The version of the C++ type itself.
std::unique_ptr< Detail::RFieldBase > CreateField(const RNTupleDescriptor &ntplDesc) const
In general, we create a field simply from the C++ type name.
std::string fFieldDescription
Free text set by the user.
std::string fFieldName
The leaf name, not including parent fields.
std::uint32_t fFieldVersion
The version of the C++-type-to-column translation mechanics.
DescriptorId_t fParentId
Establishes sub field relationships, such as classes and collections.
RFieldDescriptor Clone() const
Get a copy of the descriptor.
bool operator==(const RFieldDescriptor &other) const
ENTupleStructure fStructure
The structural information carried by this field in the data model tree.
std::string fTypeName
The C++ type that was used when writing the field.
std::uint64_t fNRepetitions
The number of elements per entry for fixed-size arrays.
RResult< void > EnsureValidDescriptor() const
Checks whether invariants hold:
void AddColumn(DescriptorId_t columnId, DescriptorId_t fieldId, const RColumnModel &model, std::uint32_t index)
RResult< void > AddClusterSummary(DescriptorId_t clusterId, std::uint64_t firstEntry, std::uint64_t nEntries)
RResult< void > EnsureFieldExists(DescriptorId_t fieldId) const
RResult< void > AddFieldLink(DescriptorId_t fieldId, DescriptorId_t linkId)
void SetNTuple(const std::string_view name, const std::string_view description)
void Reset()
Clears so-far stored clusters, fields, and columns and return to a pristine ntuple descriptor.
void AddClusterGroup(RClusterGroupDescriptorBuilder &&clusterGroup)
RResult< void > AddClusterWithDetails(RClusterDescriptor &&clusterDesc)
Used during writing.
void AddField(const RFieldDescriptor &fieldDesc)
The on-storage meta-data of an ntuple.
std::unordered_map< DescriptorId_t, RClusterDescriptor > fClusterDescriptors
May contain only a subset of all the available clusters, e.g.
std::uint64_t fGeneration
Once constructed by an RNTupleDescriptorBuilder, the descriptor is mostly immutable except for set of...
std::uint64_t fNEntries
Updated by the descriptor builder when the cluster summaries are added.
std::unique_ptr< RNTupleModel > GenerateModel() const
Re-create the C++ model from the stored meta-data.
std::unordered_map< DescriptorId_t, RClusterGroupDescriptor > fClusterGroupDescriptors
DescriptorId_t FindNextClusterId(DescriptorId_t clusterId) const
DescriptorId_t FindPrevClusterId(DescriptorId_t clusterId) const
RResult< void > DropClusterDetails(DescriptorId_t clusterId)
DescriptorId_t GetFieldZeroId() const
Returns the logical parent of all top-level NTuple data fields.
std::unordered_map< DescriptorId_t, RColumnDescriptor > fColumnDescriptors
std::unique_ptr< RNTupleDescriptor > Clone() const
std::string fName
The ntuple name needs to be unique in a given storage location (file)
const RClusterDescriptor & GetClusterDescriptor(DescriptorId_t clusterId) const
std::unordered_map< DescriptorId_t, RFieldDescriptor > fFieldDescriptors
bool operator==(const RNTupleDescriptor &other) const
std::string GetQualifiedFieldName(DescriptorId_t fieldId) const
Walks up the parents of the field ID and returns a field name of the form a.b.c.d In case of invalid ...
DescriptorId_t FindFieldId(std::string_view fieldName, DescriptorId_t parentId) const
RResult< void > AddClusterDetails(RClusterDescriptor &&clusterDesc)
Methods to load and drop cluster details.
const RFieldDescriptor & GetFieldDescriptor(DescriptorId_t fieldId) const
DescriptorId_t FindColumnId(DescriptorId_t fieldId, std::uint32_t columnIndex) const
NTupleSize_t GetNElements(DescriptorId_t columnId) const
const RClusterGroupDescriptor & GetClusterGroupDescriptor(DescriptorId_t clusterGroupId) const
std::string fDescription
Free text from the user.
DescriptorId_t FindClusterId(DescriptorId_t columnId, NTupleSize_t index) const
static std::unique_ptr< RNTupleModel > Create()
The class is used as a return type for operations that can fail; wraps a value of type T or an RError...
Definition RError.hxx:207
struct void * fTypeName
Definition cppyy.h:9
Double_t x[n]
Definition legend1.C:17
std::uint64_t NTupleSize_t
Integer type long enough to hold the maximum number of entries in a column.
std::uint64_t DescriptorId_t
Distriniguishes elements of the same type within a descriptor, e.g. different fields.
constexpr DescriptorId_t kInvalidDescriptorId
The window of element indexes of a particular column in a particular cluster.
We do not need to store the element size / uncompressed page size because we know to which column the...
ClusterSize_t fNElements
The sum of the elements of all the pages must match the corresponding fNElements field in fColumnRang...
Records the parition of data into pages for a particular column in a particular cluster.
RPageInfoExtended Find(RClusterSize::ValueType idxInCluster) const
Find the page in the RPageRange that contains the given element. The element must exist.
Wrap the 32bit integer in a struct in order to avoid template specialization clash with std::uint32_t...