49 clone.fFieldId = fFieldId;
50 clone.fFieldVersion = fFieldVersion;
51 clone.fTypeVersion = fTypeVersion;
52 clone.fFieldName = fFieldName;
53 clone.fFieldDescription = fFieldDescription;
55 clone.fTypeAlias = fTypeAlias;
56 clone.fNRepetitions = fNRepetitions;
57 clone.fStructure = fStructure;
58 clone.fParentId = fParentId;
59 clone.fLinkIds = fLinkIds;
60 clone.fLogicalColumnIds = fLogicalColumnIds;
64std::unique_ptr<ROOT::Experimental::RFieldBase>
68 return std::make_unique<RUnsplitField>(GetFieldName(), GetTypeName());
71 if (GetTypeName().empty()) {
75 std::vector<std::unique_ptr<RFieldBase>> memberFields;
76 for (
auto id : fLinkIds) {
78 memberFields.emplace_back(memberDesc.CreateField(ntplDesc));
81 auto recordField = std::make_unique<RRecordField>(GetFieldName(), memberFields);
82 recordField->SetOnDiskId(fFieldId);
85 auto recordField = std::make_unique<RRecordField>(
"_0", memberFields);
86 auto collectionField = std::make_unique<RVectorField>(GetFieldName(), std::move(recordField));
87 collectionField->SetOnDiskId(fFieldId);
88 return collectionField;
90 throw RException(
R__FAIL(
"unknown field type for field \"" + GetFieldName() +
"\""));
94 auto field =
RFieldBase::Create(GetFieldName(), GetTypeAlias().empty() ? GetTypeName() : GetTypeAlias()).Unwrap();
95 field->SetOnDiskId(fFieldId);
96 for (
auto &
f : *field)
97 f.SetOnDiskId(ntplDesc.
FindFieldId(
f.GetFieldName(),
f.GetParent()->GetOnDiskId()));
116 clone.fLogicalColumnId = fLogicalColumnId;
117 clone.fPhysicalColumnId = fPhysicalColumnId;
118 clone.fModel = fModel;
119 clone.fFieldId = fFieldId;
120 clone.fIndex = fIndex;
121 clone.fFirstElementIndex = fFirstElementIndex;
133 decltype(idxInCluster) firstInPage = 0;
135 for (
const auto &pi : fPageInfos) {
136 if (firstInPage + pi.fNElements > idxInCluster) {
151 std::size_t pageSize)
155 const auto nElements = std::accumulate(fPageInfos.begin(), fPageInfos.end(), 0U,
156 [](std::size_t
n,
const auto &
PI) { return n + PI.fNElements; });
157 const auto nElementsRequired =
static_cast<std::uint64_t
>(columnRange.
fNElements);
159 if (nElementsRequired == nElements)
161 R__ASSERT((nElementsRequired > nElements) &&
"invalid attempt to shrink RPageRange");
163 std::vector<RPageInfo> pageInfos;
165 const std::uint64_t nElementsPerPage = pageSize / element.
GetSize();
167 for (
auto nRemainingElements = nElementsRequired - nElements; nRemainingElements > 0;) {
169 PI.
fNElements = std::min(nElementsPerPage, nRemainingElements);
172 pageInfos.emplace_back(
PI);
173 nRemainingElements -=
PI.fNElements;
176 pageInfos.insert(pageInfos.end(), std::make_move_iterator(fPageInfos.begin()),
177 std::make_move_iterator(fPageInfos.end()));
178 std::swap(fPageInfos, pageInfos);
179 return nElementsRequired - nElements;
191 std::unordered_set<DescriptorId_t>
result;
192 for (
const auto &
x : fColumnRanges)
199 std::uint64_t nbytes = 0;
200 for (
const auto &pr : fPageRanges) {
201 for (
const auto &pi : pr.second.fPageInfos) {
202 nbytes += pi.fLocator.fBytesOnStorage;
211 clone.fClusterId = fClusterId;
212 clone.fFirstEntryIndex = fFirstEntryIndex;
213 clone.fNEntries = fNEntries;
214 clone.fColumnRanges = fColumnRanges;
215 for (
const auto &
d : fPageRanges)
216 clone.fPageRanges.emplace(
d.first,
d.second.Clone());
231 clone.fContentId = fContentId;
232 clone.fTypeVersionFrom = fTypeVersionFrom;
233 clone.fTypeVersionTo = fTypeVersionTo;
235 clone.fContent = fContent;
244 return fName == other.
fName &&
260 for (
const auto &cd : fClusterDescriptors) {
261 if (!cd.second.ContainsColumn(physicalColumnId))
263 auto columnRange = cd.second.GetColumnRange(physicalColumnId);
264 result = std::max(
result, columnRange.fFirstElementIndex + columnRange.fNElements);
273 std::string leafName(fieldName);
274 auto posDot = leafName.find_last_of(
'.');
275 if (posDot != std::string::npos) {
276 auto parentName = leafName.substr(0, posDot);
277 leafName = leafName.substr(posDot + 1);
278 parentId = FindFieldId(parentName, parentId);
280 auto itrFieldDesc = fFieldDescriptors.find(parentId);
281 if (itrFieldDesc == fFieldDescriptors.end())
283 for (
const auto linkId : itrFieldDesc->second.GetLinkIds()) {
284 if (fFieldDescriptors.at(linkId).GetFieldName() == leafName)
296 const auto &fieldDescriptor = fFieldDescriptors.at(fieldId);
297 auto prefix = GetQualifiedFieldName(fieldDescriptor.GetParentId());
299 return fieldDescriptor.GetFieldName();
300 return prefix +
"." + fieldDescriptor.GetFieldName();
306 return FindFieldId(fieldName, GetFieldZeroId());
312 auto itr = fFieldDescriptors.find(fieldId);
313 if (itr == fFieldDescriptors.cend())
315 if (itr->second.GetLogicalColumnIds().size() <= columnIndex)
317 return itr->second.GetLogicalColumnIds().at(columnIndex);
323 auto logicalId = FindLogicalColumnId(fieldId, columnIndex);
326 return GetColumnDescriptor(logicalId).GetPhysicalId();
333 for (
const auto &cd : fClusterDescriptors) {
334 if (!cd.second.ContainsColumn(physicalColumnId))
336 auto columnRange = cd.second.GetColumnRange(physicalColumnId);
337 if (columnRange.Contains(
index))
338 return cd.second.GetId();
348 const auto &clusterDesc = GetClusterDescriptor(clusterId);
349 auto firstEntryInNextCluster = clusterDesc.GetFirstEntryIndex() + clusterDesc.GetNEntries();
351 for (
const auto &cd : fClusterDescriptors) {
352 if (cd.second.GetFirstEntryIndex() == firstEntryInNextCluster)
353 return cd.second.GetId();
363 const auto &clusterDesc = GetClusterDescriptor(clusterId);
365 for (
const auto &cd : fClusterDescriptors) {
366 if (cd.second.GetFirstEntryIndex() + cd.second.GetNEntries() == clusterDesc.GetFirstEntryIndex())
367 return cd.second.GetId();
372std::vector<ROOT::Experimental::DescriptorId_t>
377 std::vector<DescriptorId_t> fields;
380 fields.emplace_back(fieldId);
386 for (
unsigned int i = 0;
true; ++i) {
387 auto logicalId = fNTuple.FindLogicalColumnId(fieldId, i);
390 fColumns.emplace_back(logicalId);
407 while (!fieldIdQueue.empty()) {
408 auto currFieldId = fieldIdQueue.front();
409 fieldIdQueue.pop_front();
414 auto fieldId = field.GetId();
415 fieldIdQueue.push_back(fieldId);
422 std::vector<std::uint64_t>
result;
423 unsigned int base = 0;
424 std::uint64_t flags = 0;
426 if ((
f > 0) && ((
f % 64) == 0))
428 while (
f > base + 64) {
429 result.emplace_back(flags);
436 result.emplace_back(flags);
442 std::vector<RClusterDescriptor> &clusterDescs)
446 return R__FAIL(
"invalid attempt to add details of unknown cluster group");
447 if (iter->second.HasClusterDetails())
448 return R__FAIL(
"invalid attempt to re-populate cluster group details");
449 if (iter->second.GetNClusters() != clusterDescs.size())
450 return R__FAIL(
"mismatch of number of clusters");
452 std::vector<DescriptorId_t> clusterIds;
453 for (
unsigned i = 0; i < clusterDescs.size(); ++i) {
454 clusterIds.emplace_back(clusterDescs[i].GetId());
457 return R__FAIL(
"invalid attempt to re-populate existing cluster");
461 cgBuilder.AddClusters(clusterIds);
462 iter->second = cgBuilder.MoveDescriptor().Unwrap();
471 return R__FAIL(
"invalid attempt to drop cluster details of unknown cluster group");
472 if (!iter->second.HasClusterDetails())
473 return R__FAIL(
"invalid attempt to drop details of cluster group summary");
475 for (
auto clusterId : iter->second.GetClusterIds())
477 iter->second = iter->second.CloneSummary();
483 auto fieldZero = std::make_unique<RFieldZero>();
487 model->AddField(topDesc.CreateField(*
this));
494 auto clone = std::make_unique<RNTupleDescriptor>();
506 clone->fFieldDescriptors.emplace(
d.first,
d.second.Clone());
508 clone->fColumnDescriptors.emplace(
d.first,
d.second.Clone());
510 clone->fClusterGroupDescriptors.emplace(
d.first,
d.second.Clone());
512 clone->fClusterDescriptors.emplace(
d.first,
d.second.Clone());
514 clone->fExtraTypeInfoDescriptors.emplace_back(
d.Clone());
538 clone.fClusterGroupId = fClusterGroupId;
539 clone.fPageListLocator = fPageListLocator;
540 clone.fPageListLength = fPageListLength;
541 clone.fMinEntry = fMinEntry;
542 clone.fEntrySpan = fEntrySpan;
550 clone.fClusterIds = fClusterIds;
557 DescriptorId_t physicalId, std::uint64_t firstElementIndex, std::uint32_t compressionSettings,
561 return R__FAIL(
"column ID mismatch");
562 if (fCluster.fPageRanges.count(physicalId) > 0)
563 return R__FAIL(
"column ID conflict");
565 columnRange.fCompressionSettings = compressionSettings;
567 columnRange.fNElements += pi.fNElements;
569 fCluster.fPageRanges[physicalId] = pageRange.
Clone();
570 fCluster.fColumnRanges[physicalId] = columnRange;
580 auto fnTraverseSubtree = [&](
DescriptorId_t rootFieldId, std::uint64_t nRepetitionsAtThisLevel,
581 const auto &visitField,
const auto &enterSubtree) ->
void {
582 visitField(rootFieldId, nRepetitionsAtThisLevel);
584 const std::uint64_t nRepetitions = std::max(
f.GetNRepetitions(), std::uint64_t{1U}) * nRepetitionsAtThisLevel;
585 enterSubtree(
f.GetId(), nRepetitions, visitField, enterSubtree);
595 for (
const auto &topLevelFieldId : xHeader->GetTopLevelFields(desc)) {
599 for (const auto &c : desc.GetColumnIterable(fieldId)) {
600 const DescriptorId_t physicalId = c.GetPhysicalId();
601 auto &columnRange = fCluster.fColumnRanges[physicalId];
602 auto &pageRange = fCluster.fPageRanges[physicalId];
606 if (columnRange.fPhysicalColumnId == kInvalidDescriptorId) {
607 columnRange.fPhysicalColumnId = physicalId;
608 columnRange.fFirstElementIndex = 0;
609 columnRange.fNElements = 0;
611 pageRange.fPhysicalColumnId = physicalId;
619 if (c.IsDeferredColumn()) {
620 columnRange.fFirstElementIndex = fCluster.GetFirstEntryIndex() * nRepetitions;
621 columnRange.fNElements = fCluster.GetNEntries() * nRepetitions;
622 const auto element = Internal::RColumnElementBase::Generate<void>(c.GetModel().GetType());
623 pageRange.ExtendToFitColumnRange(columnRange, *element, Internal::RPage::kPageZeroSize);
636 return R__FAIL(
"unset cluster ID");
637 if (fCluster.fNEntries == 0)
638 return R__FAIL(
"empty cluster");
639 for (
const auto &pr : fCluster.fPageRanges) {
640 if (fCluster.fColumnRanges.count(pr.first) == 0) {
641 return R__FAIL(
"missing column range");
645 std::swap(
result, fCluster);
669 return R__FAIL(
"unset cluster group ID");
671 std::swap(
result, fClusterGroup);
681 return R__FAIL(
"unset column group ID");
683 std::swap(
result, fColumnGroup);
695 std::swap(
result, fExtraTypeInfo);
704 if (fDescriptor.fFieldDescriptors.count(fieldId) == 0)
705 return R__FAIL(
"field with id '" + std::to_string(fieldId) +
"' doesn't exist");
717 for (
const auto& key_val: fDescriptor.fFieldDescriptors) {
718 const auto&
id = key_val.first;
719 const auto& desc = key_val.second;
722 return R__FAIL(
"field with id '" + std::to_string(
id) +
"' has an invalid parent id");
731 std::swap(
result, fDescriptor);
736 const std::string_view description)
738 fDescriptor.fName = std::string(
name);
739 fDescriptor.fDescription = std::string(description);
746 fDescriptor.fFeatureFlags.insert(flag);
753 return R__FAIL(
"invalid logical column id");
755 return R__FAIL(
"invalid physical column id");
757 return R__FAIL(
"invalid column model");
759 return R__FAIL(
"invalid field id, dangling column");
760 return fColumn.Clone();
764 : fField(fieldDesc.
Clone())
789 return R__FAIL(
"invalid field id");
792 return R__FAIL(
"invalid field structure");
801 return fField.Clone();
806 fDescriptor.fFieldDescriptors.emplace(fieldDesc.
GetId(), fieldDesc.
Clone());
807 if (fDescriptor.fHeaderExtension)
808 fDescriptor.fHeaderExtension->AddFieldId(fieldDesc.
GetId());
810 fDescriptor.fFieldZeroId = fieldDesc.
GetId();
818 if (!(fieldExists = EnsureFieldExists(fieldId)))
820 if (!(fieldExists = EnsureFieldExists(linkId)))
821 return R__FAIL(
"child field with id '" + std::to_string(linkId) +
"' doesn't exist in NTuple");
823 if (linkId == fDescriptor.GetFieldZeroId()) {
824 return R__FAIL(
"cannot make FieldZero a child field");
827 auto parentId = fDescriptor.fFieldDescriptors.at(linkId).GetParentId();
829 return R__FAIL(
"field '" + std::to_string(linkId) +
"' already has a parent ('" +
830 std::to_string(parentId) +
")");
832 if (fieldId == linkId) {
833 return R__FAIL(
"cannot make field '" + std::to_string(fieldId) +
"' a child of itself");
835 fDescriptor.fFieldDescriptors.at(linkId).fParentId = fieldId;
836 fDescriptor.fFieldDescriptors.at(fieldId).fLinkIds.push_back(linkId);
843 std::uint32_t
index, std::uint64_t firstElementIdx)
847 c.fPhysicalColumnId = physicalId;
848 c.fFieldId = fieldId;
851 c.fFirstElementIndex = firstElementIdx;
853 auto res = AttachColumn(fieldId,
c);
857 if (!
c.IsAliasColumn())
858 fDescriptor.fNPhysicalColumns++;
859 if (fDescriptor.fHeaderExtension)
860 fDescriptor.fHeaderExtension->AddColumn(
c.IsAliasColumn());
861 fDescriptor.fColumnDescriptors.emplace(logicalId, std::move(
c));
869 const auto fieldId = columnDesc.GetFieldId();
870 const auto index = columnDesc.GetIndex();
872 auto fieldExists = EnsureFieldExists(fieldId);
876 return R__FAIL(
"column index clash");
880 return R__FAIL(
"out of bounds column index");
882 if (columnDesc.IsAliasColumn()) {
883 if (columnDesc.GetModel() != fDescriptor.GetColumnDescriptor(columnDesc.GetPhysicalId()).GetModel())
884 return R__FAIL(
"alias column type mismatch");
886 auto res = AttachColumn(fieldId, columnDesc);
890 auto logicalId = columnDesc.GetLogicalId();
891 if (!columnDesc.IsAliasColumn())
892 fDescriptor.fNPhysicalColumns++;
893 fDescriptor.fColumnDescriptors.emplace(logicalId, std::move(columnDesc));
894 if (fDescriptor.fHeaderExtension)
895 fDescriptor.fHeaderExtension->AddColumn(columnDesc.IsAliasColumn());
904 auto itrFieldDesc = fDescriptor.fFieldDescriptors.find(fieldId);
905 if (itrFieldDesc == fDescriptor.fFieldDescriptors.end()) {
906 return R__FAIL(
"AttachColumn: invalid field ID");
908 auto &logicalColumnIds = itrFieldDesc->second.fLogicalColumnIds;
909 for (std::size_t i = logicalColumnIds.size(); i <= columnDesc.
GetIndex(); ++i) {
920 const auto id = clusterGroup.GetId();
921 if (fDescriptor.fClusterGroupDescriptors.count(
id) > 0)
922 return R__FAIL(
"cluster group id clash");
923 fDescriptor.fNEntries = std::max(fDescriptor.fNEntries, clusterGroup.GetMinEntry() + clusterGroup.GetEntrySpan());
924 fDescriptor.fNClusters += clusterGroup.GetNClusters();
925 fDescriptor.fClusterGroupDescriptors.emplace(
id, std::move(clusterGroup));
931 fDescriptor.fName =
"";
932 fDescriptor.fDescription =
"";
933 fDescriptor.fFieldDescriptors.clear();
934 fDescriptor.fColumnDescriptors.clear();
935 fDescriptor.fClusterDescriptors.clear();
936 fDescriptor.fClusterGroupDescriptors.clear();
937 fDescriptor.fHeaderExtension.reset();
942 if (!fDescriptor.fHeaderExtension)
943 fDescriptor.fHeaderExtension = std::make_unique<RNTupleDescriptor::RHeaderExtension>();
949 auto clusterId = clusterDesc.GetId();
950 if (fDescriptor.fClusterDescriptors.count(clusterId) > 0)
951 return R__FAIL(
"cluster id clash");
952 fDescriptor.fClusterDescriptors.emplace(clusterId, std::move(clusterDesc));
960 if (std::find(fDescriptor.fExtraTypeInfoDescriptors.begin(), fDescriptor.fExtraTypeInfoDescriptors.end(),
961 extraTypeInfoDesc) != fDescriptor.fExtraTypeInfoDescriptors.end()) {
962 return R__FAIL(
"extra type info duplicates");
964 fDescriptor.fExtraTypeInfoDescriptors.emplace_back(std::move(extraTypeInfoDesc));
#define R__FORWARD_ERROR(res)
Short-hand to return an RResult<T> in an error state (i.e. after checking)
#define R__FAIL(msg)
Short-hand to return an RResult<T> in an error state; the RError is implicitly converted into RResult...
TObject * clone(const char *newname) const override
#define R__ASSERT(e)
Checks condition e and reports a fatal error if it's false.
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
A helper class for piece-wise construction of an RClusterDescriptor.
RResult< RClusterDescriptor > MoveDescriptor()
Move out the full cluster descriptor including page locations.
RClusterDescriptorBuilder & AddExtendedColumnRanges(const RNTupleDescriptor &desc)
Add column and page ranges for columns created during late model extension missing in this cluster.
RResult< void > CommitColumnRange(DescriptorId_t physicalId, std::uint64_t firstElementIndex, std::uint32_t compressionSettings, const RClusterDescriptor::RPageRange &pageRange)
A helper class for piece-wise construction of an RClusterGroupDescriptor.
RClusterGroupDescriptorBuilder & PageListLocator(const RNTupleLocator &pageListLocator)
RClusterGroupDescriptorBuilder & MinEntry(std::uint64_t minEntry)
RClusterGroupDescriptorBuilder & ClusterGroupId(DescriptorId_t clusterGroupId)
RClusterGroupDescriptorBuilder & EntrySpan(std::uint64_t entrySpan)
RClusterGroupDescriptorBuilder & NClusters(std::uint32_t nClusters)
RClusterGroupDescriptorBuilder & PageListLength(std::uint64_t pageListLength)
RResult< RClusterGroupDescriptor > MoveDescriptor()
static RClusterGroupDescriptorBuilder FromSummary(const RClusterGroupDescriptor &clusterGroupDesc)
RResult< RColumnDescriptor > MakeDescriptor() const
Attempt to make a column descriptor.
A column element encapsulates the translation between basic C++ types and their column representation...
std::size_t GetSize() const
std::size_t GetPackedSize(std::size_t nElements=1U) const
RResult< RColumnGroupDescriptor > MoveDescriptor()
A helper class for piece-wise construction of an RFieldDescriptor.
RFieldDescriptorBuilder & TypeVersion(std::uint32_t typeVersion)
RFieldDescriptorBuilder & NRepetitions(std::uint64_t nRepetitions)
RFieldDescriptorBuilder & FieldVersion(std::uint32_t fieldVersion)
RFieldDescriptorBuilder & Structure(const ENTupleStructure &structure)
RFieldDescriptorBuilder & TypeName(const std::string &typeName)
static RFieldDescriptorBuilder FromField(const RFieldBase &field)
Make a new RFieldDescriptorBuilder based off a live NTuple field.
RResult< RFieldDescriptor > MakeDescriptor() const
Attempt to make a field descriptor.
RFieldDescriptorBuilder & FieldName(const std::string &fieldName)
RFieldDescriptorBuilder()=default
Make an empty dangling field descriptor.
RFieldDescriptorBuilder & TypeAlias(const std::string &typeAlias)
RFieldDescriptorBuilder & FieldDescription(const std::string &fieldDescription)
RResult< void > AttachColumn(DescriptorId_t fieldId, const RColumnDescriptor &columnDesc)
void BeginHeaderExtension()
Mark the beginning of the header extension; any fields and columns added after a call to this functio...
RResult< void > EnsureFieldExists(DescriptorId_t fieldId) const
RResult< void > AddFieldLink(DescriptorId_t fieldId, DescriptorId_t linkId)
RResult< void > EnsureValidDescriptor() const
Checks whether invariants hold:
RResult< void > AddCluster(RClusterDescriptor &&clusterDesc)
void SetNTuple(const std::string_view name, const std::string_view description)
RResult< void > AddClusterGroup(RClusterGroupDescriptor &&clusterGroup)
void SetFeature(unsigned int flag)
void AddField(const RFieldDescriptor &fieldDesc)
RResult< void > AddColumn(DescriptorId_t logicalId, DescriptorId_t physicalId, DescriptorId_t fieldId, const RColumnModel &model, std::uint32_t index, std::uint64_t firstElementIdx=0U)
RNTupleDescriptor MoveDescriptor()
void Reset()
Clears so-far stored clusters, fields, and columns and return to a pristine ntuple descriptor.
RResult< void > AddExtraTypeInfo(RExtraTypeInfoDescriptor &&extraTypeInfoDesc)
Meta-data for a set of ntuple clusters.
std::unordered_map< DescriptorId_t, RPageRange > fPageRanges
NTupleSize_t fFirstEntryIndex
Clusters can be swapped by adjusting the entry offsets.
DescriptorId_t fClusterId
std::unordered_set< DescriptorId_t > GetColumnIds() const
RClusterDescriptor Clone() const
std::unordered_map< DescriptorId_t, RColumnRange > fColumnRanges
bool operator==(const RClusterDescriptor &other) const
std::uint64_t GetBytesOnStorage() const
Clusters are bundled in cluster groups.
std::uint64_t fMinEntry
The minimum first entry number of the clusters in the cluster group.
RClusterGroupDescriptor Clone() const
std::uint64_t fEntrySpan
Number of entries that are (partially for sharded clusters) covered by this cluster group.
std::uint64_t GetMinEntry() const
std::uint64_t GetPageListLength() const
RClusterGroupDescriptor CloneSummary() const
std::uint32_t fNClusters
Number of clusters is always known even if the cluster IDs are not (yet) populated.
std::uint32_t GetNClusters() const
DescriptorId_t fClusterGroupId
bool operator==(const RClusterGroupDescriptor &other) const
RNTupleLocator GetPageListLocator() const
std::vector< DescriptorId_t > fClusterIds
The cluster IDs can be empty if the corresponding page list is not loaded.
std::uint64_t GetEntrySpan() const
DescriptorId_t GetId() const
Meta-data stored for every column of an ntuple.
DescriptorId_t fPhysicalColumnId
Usually identical to the logical column ID, except for alias columns where it references the shadowed...
DescriptorId_t fLogicalColumnId
The actual column identifier, which is the link to the corresponding field.
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.
DescriptorId_t GetLogicalId() const
std::uint32_t GetIndex() const
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
Meta-data for a sets of columns; non-trivial column groups are used for sharded clusters.
std::unordered_set< DescriptorId_t > fPhysicalColumnIds
bool operator==(const RColumnGroupDescriptor &other) const
DescriptorId_t fColumnGroupId
Holds the static meta-data of an RNTuple column.
Base class for all ROOT issued exceptions.
A field translates read and write calls from/to underlying columns to/from tree values.
std::string GetFieldName() const
ENTupleStructure GetStructure() const
std::string GetTypeName() const
virtual std::uint32_t GetTypeVersion() const
Indicates an evolution of the C++ type itself.
virtual std::uint32_t GetFieldVersion() const
Indicates an evolution of the mapping scheme from C++ type to columns.
static RResult< std::unique_ptr< RFieldBase > > Create(const std::string &fieldName, const std::string &canonicalType, const std::string &typeAlias, bool fContinueOnError=false)
Factory method to resurrect a field from the stored on-disk type information.
std::string GetDescription() const
Get the field's description.
std::size_t GetNRepetitions() const
std::string GetTypeAlias() const
static RResult< void > EnsureValidFieldName(std::string_view fieldName)
Check whether a given string is a valid field name.
Meta-data stored for every field of an ntuple.
std::vector< DescriptorId_t > fLinkIds
The pointers in the other direction from parent to children.
DescriptorId_t GetParentId() const
std::unique_ptr< RFieldBase > CreateField(const RNTupleDescriptor &ntplDesc) const
In general, we create a field simply from the C++ type name.
std::uint32_t fTypeVersion
The version of the C++ type itself.
std::string GetFieldName() const
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.
std::vector< DescriptorId_t > fLogicalColumnIds
The ordered list of columns attached to this field.
DescriptorId_t GetId() const
DescriptorId_t fParentId
Establishes sub field relationships, such as classes and collections.
std::uint64_t GetNRepetitions() const
RFieldDescriptor Clone() const
Get a copy of the descriptor.
bool operator==(const RFieldDescriptor &other) const
std::string fTypeAlias
A typedef or using directive that resolved to the type name during field creation.
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.
RColumnDescriptorIterable(const RNTupleDescriptor &ntuple, const RFieldDescriptor &field)
void CollectColumnIds(DescriptorId_t fieldId)
The on-storage meta-data of an ntuple.
std::uint64_t fNPhysicalColumns
Updated by the descriptor builder when columns are added.
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 fOnDiskFooterSize
Like fOnDiskHeaderSize, contains both cluster summaries and page locations.
std::uint64_t fNEntries
Updated by the descriptor builder when the cluster groups are added.
DescriptorId_t FindPhysicalColumnId(DescriptorId_t fieldId, std::uint32_t columnIndex) const
std::set< unsigned int > fFeatureFlags
std::vector< RExtraTypeInfoDescriptor > fExtraTypeInfoDescriptors
NTupleSize_t GetNElements(DescriptorId_t physicalColumnId) const
DescriptorId_t FindLogicalColumnId(DescriptorId_t fieldId, std::uint32_t columnIndex) const
std::unordered_map< DescriptorId_t, RClusterGroupDescriptor > fClusterGroupDescriptors
DescriptorId_t FindNextClusterId(DescriptorId_t clusterId) const
DescriptorId_t FindPrevClusterId(DescriptorId_t clusterId) const
std::unordered_map< DescriptorId_t, RColumnDescriptor > fColumnDescriptors
std::unique_ptr< RNTupleDescriptor > Clone() const
DescriptorId_t FindClusterId(DescriptorId_t physicalColumnId, NTupleSize_t index) const
std::uint64_t fNClusters
Updated by the descriptor builder when the cluster groups are added.
std::string fName
The ntuple name needs to be unique in a given storage location (file)
RFieldDescriptorIterable GetTopLevelFields() const
std::unordered_map< DescriptorId_t, RFieldDescriptor > fFieldDescriptors
RFieldDescriptorIterable GetFieldIterable(const RFieldDescriptor &fieldDesc) const
DescriptorId_t GetFieldZeroId() const
Returns the logical parent of all top-level NTuple data fields.
std::uint64_t fOnDiskHeaderXxHash3
Set by the descriptor builder when deserialized.
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 ...
RResult< void > AddClusterGroupDetails(DescriptorId_t clusterGroupId, std::vector< RClusterDescriptor > &clusterDescs)
Methods to load and drop cluster group details (cluster IDs and page locations)
DescriptorId_t FindFieldId(std::string_view fieldName, DescriptorId_t parentId) const
const RFieldDescriptor & GetFieldDescriptor(DescriptorId_t fieldId) const
std::unique_ptr< RNTupleModel > CreateModel() const
Re-create the C++ model from the stored meta-data.
RResult< void > DropClusterGroupDetails(DescriptorId_t clusterGroupId)
std::unique_ptr< RHeaderExtension > fHeaderExtension
std::string fDescription
Free text from the user.
DescriptorId_t fFieldZeroId
Set by the descriptor builder.
const RHeaderExtension * GetHeaderExtension() const
Return header extension information; if the descriptor does not have a header extension,...
std::uint64_t fOnDiskHeaderSize
Set by the descriptor builder when deserialized.
std::vector< std::uint64_t > GetFeatureFlags() 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...
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.
ClusterSize_t fNElements
The number of column elements in the cluster.
DescriptorId_t fPhysicalColumnId
Wrap the integer in a struct in order to avoid template specialization clash with std::uint64_t.