68std::unique_ptr<ROOT::Experimental::RFieldBase>
72 auto streamerField = std::make_unique<RStreamerField>(GetFieldName(), GetTypeName());
73 streamerField->SetOnDiskId(fFieldId);
80 if (continueOnError) {
81 auto invalidField = std::make_unique<RInvalidField>(GetFieldName(), GetTypeName(),
"");
82 invalidField->SetOnDiskId(fFieldId);
85 throw RException(
R__FAIL(
"unexpected on-disk field structure value for field \"" + GetFieldName() +
"\""));
89 if (GetTypeName().empty()) {
90 switch (GetStructure()) {
92 std::vector<std::unique_ptr<RFieldBase>> memberFields;
93 for (
auto id : fLinkIds) {
95 auto field = memberDesc.
CreateField(ntplDesc, continueOnError);
98 memberFields.emplace_back(std::move(field));
100 auto recordField = std::make_unique<RRecordField>(GetFieldName(), std::move(memberFields));
101 recordField->SetOnDiskId(fFieldId);
105 if (fLinkIds.size() != 1) {
106 throw RException(
R__FAIL(
"unsupported untyped collection for field \"" + GetFieldName() +
"\""));
112 collectionField->SetOnDiskId(fFieldId);
113 return collectionField;
115 default:
throw RException(
R__FAIL(
"unsupported untyped field structure for field \"" + GetFieldName() +
"\""));
120 auto field =
RFieldBase::Create(GetFieldName(), GetTypeAlias().empty() ? GetTypeName() : GetTypeAlias()).Unwrap();
121 field->SetOnDiskId(fFieldId);
122 for (
auto &
f : *field)
123 f.SetOnDiskId(ntplDesc.
FindFieldId(
f.GetFieldName(),
f.GetParent()->GetOnDiskId()));
127 return std::make_unique<RInvalidField>(GetFieldName(), GetTypeName(),
ex.GetError().GetReport());
143 if (
fTypeName.compare(0, 10,
"std::pair<") == 0)
145 if (
fTypeName.compare(0, 11,
"std::tuple<") == 0)
184 decltype(idxInCluster) firstInPage = 0;
186 for (
const auto &pi : fPageInfos) {
187 if (firstInPage + pi.fNElements > idxInCluster) {
202 std::size_t pageSize)
207 const auto nElements = std::accumulate(fPageInfos.begin(), fPageInfos.end(), 0U,
208 [](std::size_t
n,
const auto &
PI) { return n + PI.fNElements; });
209 const auto nElementsRequired =
static_cast<std::uint64_t
>(columnRange.
fNElements);
211 if (nElementsRequired == nElements)
213 R__ASSERT((nElementsRequired > nElements) &&
"invalid attempt to shrink RPageRange");
215 std::vector<RPageInfo> pageInfos;
217 const std::uint64_t nElementsPerPage = pageSize / element.
GetSize();
219 for (
auto nRemainingElements = nElementsRequired - nElements; nRemainingElements > 0;) {
221 PI.
fNElements = std::min(nElementsPerPage, nRemainingElements);
224 pageInfos.emplace_back(
PI);
225 nRemainingElements -=
PI.fNElements;
228 pageInfos.insert(pageInfos.end(), std::make_move_iterator(fPageInfos.begin()),
229 std::make_move_iterator(fPageInfos.end()));
230 std::swap(fPageInfos, pageInfos);
231 return nElementsRequired - nElements;
242 std::uint64_t nbytes = 0;
243 for (
const auto &pr : fPageRanges) {
244 for (
const auto &pi : pr.second.fPageInfos) {
245 nbytes += pi.fLocator.fBytesOnStorage;
258 for (
const auto &
d : fPageRanges)
285 return fName == other.
fName &&
301 for (
const auto &cd : fClusterDescriptors) {
302 if (!cd.second.ContainsColumn(physicalColumnId))
304 auto columnRange = cd.second.GetColumnRange(physicalColumnId);
305 result = std::max(
result, columnRange.fFirstElementIndex + columnRange.fNElements);
313 std::string leafName(fieldName);
314 auto posDot = leafName.find_last_of(
'.');
315 if (posDot != std::string::npos) {
316 auto parentName = leafName.substr(0, posDot);
317 leafName = leafName.substr(posDot + 1);
318 parentId = FindFieldId(parentName, parentId);
320 auto itrFieldDesc = fFieldDescriptors.find(parentId);
321 if (itrFieldDesc == fFieldDescriptors.end())
323 for (
const auto linkId : itrFieldDesc->second.GetLinkIds()) {
324 if (fFieldDescriptors.at(linkId).GetFieldName() == leafName)
335 const auto &fieldDescriptor = fFieldDescriptors.at(fieldId);
336 auto prefix = GetQualifiedFieldName(fieldDescriptor.GetParentId());
338 return fieldDescriptor.GetFieldName();
339 return prefix +
"." + fieldDescriptor.GetFieldName();
344 return FindFieldId(fieldName, GetFieldZeroId());
349 std::uint16_t representationIndex)
const
351 auto itr = fFieldDescriptors.find(fieldId);
352 if (itr == fFieldDescriptors.cend())
354 if (columnIndex >= itr->second.GetColumnCardinality())
356 const auto idx = representationIndex * itr->second.GetColumnCardinality() + columnIndex;
357 if (itr->second.GetLogicalColumnIds().size() <= idx)
359 return itr->second.GetLogicalColumnIds()[idx];
364 std::uint16_t representationIndex)
const
366 auto logicalId = FindLogicalColumnId(fieldId, columnIndex, representationIndex);
369 return GetColumnDescriptor(logicalId).GetPhysicalId();
376 for (
const auto &cd : fClusterDescriptors) {
377 if (!cd.second.ContainsColumn(physicalColumnId))
379 auto columnRange = cd.second.GetColumnRange(physicalColumnId);
380 if (columnRange.Contains(
index))
381 return cd.second.GetId();
390 const auto &clusterDesc = GetClusterDescriptor(clusterId);
391 auto firstEntryInNextCluster = clusterDesc.GetFirstEntryIndex() + clusterDesc.GetNEntries();
393 for (
const auto &cd : fClusterDescriptors) {
394 if (cd.second.GetFirstEntryIndex() == firstEntryInNextCluster)
395 return cd.second.GetId();
404 const auto &clusterDesc = GetClusterDescriptor(clusterId);
406 for (
const auto &cd : fClusterDescriptors) {
407 if (cd.second.GetFirstEntryIndex() + cd.second.GetNEntries() == clusterDesc.GetFirstEntryIndex())
408 return cd.second.GetId();
413std::vector<ROOT::Experimental::DescriptorId_t>
418 std::vector<DescriptorId_t> fields;
421 fields.emplace_back(fieldId);
428 : fNTuple(ntuple), fColumns(field.GetLogicalColumnIds())
438 while (!fieldIdQueue.empty()) {
439 auto currFieldId = fieldIdQueue.front();
440 fieldIdQueue.pop_front();
446 auto fieldId = field.GetId();
447 fieldIdQueue.push_back(fieldId);
454 std::vector<std::uint64_t>
result;
455 unsigned int base = 0;
456 std::uint64_t flags = 0;
458 if ((
f > 0) && ((
f % 64) == 0))
460 while (
f > base + 64) {
461 result.emplace_back(flags);
468 result.emplace_back(flags);
474 std::vector<RClusterDescriptor> &clusterDescs)
478 return R__FAIL(
"invalid attempt to add details of unknown cluster group");
479 if (iter->second.HasClusterDetails())
480 return R__FAIL(
"invalid attempt to re-populate cluster group details");
481 if (iter->second.GetNClusters() != clusterDescs.size())
482 return R__FAIL(
"mismatch of number of clusters");
484 std::vector<DescriptorId_t> clusterIds;
485 for (
unsigned i = 0; i < clusterDescs.size(); ++i) {
486 clusterIds.emplace_back(clusterDescs[i].GetId());
489 return R__FAIL(
"invalid attempt to re-populate existing cluster");
493 cgBuilder.AddClusters(clusterIds);
494 iter->second = cgBuilder.MoveDescriptor().Unwrap();
503 return R__FAIL(
"invalid attempt to drop cluster details of unknown cluster group");
504 if (!iter->second.HasClusterDetails())
505 return R__FAIL(
"invalid attempt to drop details of cluster group summary");
507 for (
auto clusterId : iter->second.GetClusterIds())
509 iter->second = iter->second.CloneSummary();
513std::unique_ptr<ROOT::Experimental::RNTupleModel>
516 auto fieldZero = std::make_unique<RFieldZero>();
522 auto field = topDesc.CreateField(*
this, continueOnError);
527 model->AddProjectedField(std::move(field), [
this](
const std::string &targetName) -> std::string {
531 model->AddField(std::move(field));
540 auto clone = std::make_unique<RNTupleDescriptor>();
541 clone->fName =
fName;
552 clone->fFieldDescriptors.emplace(
d.first,
d.second.Clone());
554 clone->fColumnDescriptors.emplace(
d.first,
d.second.Clone());
556 clone->fClusterGroupDescriptors.emplace(
d.first,
d.second.Clone());
558 clone->fClusterDescriptors.emplace(
d.first,
d.second.Clone());
560 clone->fExtraTypeInfoDescriptors.emplace_back(
d.Clone());
562 clone->fHeaderExtension = std::make_unique<RHeaderExtension>(*
fHeaderExtension);
596 DescriptorId_t physicalId, std::uint64_t firstElementIndex, std::uint32_t compressionSettings,
600 return R__FAIL(
"column ID mismatch");
601 if (fCluster.fColumnRanges.count(physicalId) > 0)
602 return R__FAIL(
"column ID conflict");
604 columnRange.fCompressionSettings = compressionSettings;
606 columnRange.fNElements += pi.fNElements;
608 fCluster.fPageRanges[physicalId] = pageRange.
Clone();
609 fCluster.fColumnRanges[physicalId] = columnRange;
616 if (fCluster.fColumnRanges.count(physicalId) > 0)
617 return R__FAIL(
"column ID conflict");
623 fCluster.fColumnRanges[physicalId] = columnRange;
630 for (
auto &[
_, columnRange] : fCluster.fColumnRanges) {
631 if (!columnRange.fIsSuppressed)
638 for (
const auto otherColumnLogicalId : fieldDesc.GetLogicalColumnIds()) {
640 if (otherColumnDesc.GetRepresentationIndex() == columnDesc.GetRepresentationIndex())
642 if (otherColumnDesc.GetIndex() != columnDesc.GetIndex())
646 const auto &otherColumnRange = fCluster.GetColumnRange(otherColumnDesc.GetPhysicalId());
647 if (otherColumnRange.fIsSuppressed)
651 columnRange.fNElements = otherColumnRange.fNElements;
656 return R__FAIL(std::string(
"cannot find non-suppressed column for column ID ") +
657 std::to_string(columnRange.fPhysicalColumnId) +
658 ", cluster ID: " + std::to_string(fCluster.GetId()));
670 auto fnTraverseSubtree = [&](
DescriptorId_t rootFieldId, std::uint64_t nRepetitionsAtThisLevel,
671 const auto &visitField,
const auto &enterSubtree) ->
void {
672 visitField(rootFieldId, nRepetitionsAtThisLevel);
674 const std::uint64_t nRepetitions = std::max(
f.GetNRepetitions(), std::uint64_t{1U}) * nRepetitionsAtThisLevel;
675 enterSubtree(
f.GetId(), nRepetitions, visitField, enterSubtree);
687 topLevelField.GetId(), std::max(topLevelField.GetNRepetitions(), std::uint64_t{1U}),
689 for (const auto &c : desc.GetColumnIterable(fieldId)) {
690 const DescriptorId_t physicalId = c.GetPhysicalId();
691 auto &columnRange = fCluster.fColumnRanges[physicalId];
696 if (columnRange.fPhysicalColumnId == kInvalidDescriptorId) {
697 columnRange.fPhysicalColumnId = physicalId;
698 columnRange.fFirstElementIndex = 0;
699 columnRange.fNElements = 0;
700 columnRange.fIsSuppressed = c.IsSuppressedDeferredColumn();
708 if (c.IsDeferredColumn()) {
709 columnRange.fFirstElementIndex = fCluster.GetFirstEntryIndex() * nRepetitions;
710 columnRange.fNElements = fCluster.GetNEntries() * nRepetitions;
711 if (!columnRange.fIsSuppressed) {
712 auto &pageRange = fCluster.fPageRanges[physicalId];
713 pageRange.fPhysicalColumnId = physicalId;
714 const auto element = Internal::RColumnElementBase::Generate<void>(c.GetType());
715 pageRange.ExtendToFitColumnRange(columnRange, *element, Internal::RPage::kPageZeroSize);
717 } else if (!columnRange.fIsSuppressed) {
718 fCluster.fPageRanges[physicalId].fPhysicalColumnId = physicalId;
731 return R__FAIL(
"unset cluster ID");
732 if (fCluster.fNEntries == 0)
733 return R__FAIL(
"empty cluster");
734 for (
const auto &pr : fCluster.fPageRanges) {
735 if (fCluster.fColumnRanges.count(pr.first) == 0) {
736 return R__FAIL(
"missing column range");
740 std::swap(
result, fCluster);
764 return R__FAIL(
"unset cluster group ID");
766 std::swap(
result, fClusterGroup);
778 std::swap(
result, fExtraTypeInfo);
787 if (fDescriptor.fFieldDescriptors.count(fieldId) == 0)
788 return R__FAIL(
"field with id '" + std::to_string(fieldId) +
"' doesn't exist");
800 for (
const auto &[fieldId, fieldDesc] : fDescriptor.fFieldDescriptors) {
802 if (fieldId != fDescriptor.GetFieldZeroId() && fieldDesc.GetParentId() ==
kInvalidDescriptorId) {
803 return R__FAIL(
"field with id '" + std::to_string(fieldId) +
"' has an invalid parent id");
807 const auto columnCardinality = fieldDesc.GetColumnCardinality();
808 if (columnCardinality == 0)
813 const auto &logicalColumnIds = fieldDesc.GetLogicalColumnIds();
814 const auto nColumns = logicalColumnIds.size();
816 if ((nColumns + 1) == columnCardinality)
819 const auto &lastColumn = fDescriptor.GetColumnDescriptor(logicalColumnIds.back());
820 if (lastColumn.GetIndex() + 1 != columnCardinality)
821 return R__FAIL(
"field with id '" + std::to_string(fieldId) +
"' has incomplete column representations");
829 EnsureValidDescriptor().ThrowOnError();
831 std::swap(
result, fDescriptor);
836 const std::string_view description)
838 fDescriptor.fName = std::string(
name);
839 fDescriptor.fDescription = std::string(description);
846 fDescriptor.fFeatureFlags.insert(flag);
853 return R__FAIL(
"invalid logical column id");
855 return R__FAIL(
"invalid physical column id");
857 return R__FAIL(
"invalid field id, dangling column");
865 const auto [minBits, maxBits] = RColumnElementBase::GetValidBitRange(fColumn.GetType());
866 if (fColumn.GetBitsOnStorage() < minBits || fColumn.GetBitsOnStorage() > maxBits)
867 return R__FAIL(
"invalid column bit width");
870 return fColumn.Clone();
874 : fField(fieldDesc.
Clone())
902 return R__FAIL(
"invalid field id");
905 return R__FAIL(
"invalid field structure");
913 if (fField.GetFieldName().empty()) {
914 return R__FAIL(
"name cannot be empty string \"\"");
917 return fField.Clone();
922 fDescriptor.fFieldDescriptors.emplace(fieldDesc.
GetId(), fieldDesc.
Clone());
923 if (fDescriptor.fHeaderExtension)
924 fDescriptor.fHeaderExtension->AddExtendedField(fieldDesc);
926 fDescriptor.fFieldZeroId = fieldDesc.
GetId();
934 if (!(fieldExists = EnsureFieldExists(fieldId)))
936 if (!(fieldExists = EnsureFieldExists(linkId)))
937 return R__FAIL(
"child field with id '" + std::to_string(linkId) +
"' doesn't exist in NTuple");
939 if (linkId == fDescriptor.GetFieldZeroId()) {
940 return R__FAIL(
"cannot make FieldZero a child field");
943 auto parentId = fDescriptor.fFieldDescriptors.at(linkId).GetParentId();
945 return R__FAIL(
"field '" + std::to_string(linkId) +
"' already has a parent ('" + std::to_string(parentId) +
")");
947 if (fieldId == linkId) {
948 return R__FAIL(
"cannot make field '" + std::to_string(fieldId) +
"' a child of itself");
950 fDescriptor.fFieldDescriptors.at(linkId).fParentId = fieldId;
951 fDescriptor.fFieldDescriptors.at(fieldId).fLinkIds.push_back(linkId);
960 if (!(fieldExists = EnsureFieldExists(sourceId)))
962 if (!(fieldExists = EnsureFieldExists(targetId)))
963 return R__FAIL(
"projected field with id '" + std::to_string(targetId) +
"' doesn't exist in NTuple");
965 if (targetId == fDescriptor.GetFieldZeroId()) {
966 return R__FAIL(
"cannot make FieldZero a projected field");
968 if (sourceId == targetId) {
969 return R__FAIL(
"cannot make field '" + std::to_string(targetId) +
"' a projection of itself");
971 if (fDescriptor.fFieldDescriptors.at(sourceId).IsProjectedField()) {
972 return R__FAIL(
"cannot make field '" + std::to_string(targetId) +
"' a projection of an already projected field");
975 auto &targetDesc = fDescriptor.fFieldDescriptors.at(targetId);
976 if (targetDesc.IsProjectedField() && targetDesc.GetProjectionSourceId() != sourceId) {
977 return R__FAIL(
"field '" + std::to_string(targetId) +
"' has already a projection source ('" +
978 std::to_string(targetDesc.GetProjectionSourceId()) +
")");
980 fDescriptor.fFieldDescriptors.at(targetId).fProjectionSourceId = sourceId;
987 const auto fieldId = columnDesc.GetFieldId();
988 const auto columnIndex = columnDesc.GetIndex();
989 const auto representationIndex = columnDesc.GetRepresentationIndex();
991 auto fieldExists = EnsureFieldExists(fieldId);
995 auto &fieldDesc = fDescriptor.fFieldDescriptors.find(fieldId)->second;
997 if (columnDesc.IsAliasColumn()) {
998 if (columnDesc.GetType() != fDescriptor.GetColumnDescriptor(columnDesc.GetPhysicalId()).GetType())
999 return R__FAIL(
"alias column type mismatch");
1001 if (fDescriptor.FindLogicalColumnId(fieldId, columnIndex, representationIndex) !=
kInvalidDescriptorId) {
1002 return R__FAIL(
"column index clash");
1004 if (columnIndex > 0) {
1005 if (fDescriptor.FindLogicalColumnId(fieldId, columnIndex - 1, representationIndex) ==
kInvalidDescriptorId)
1006 return R__FAIL(
"out of bounds column index");
1008 if (representationIndex > 0) {
1009 if (fDescriptor.FindLogicalColumnId(fieldId, 0, representationIndex - 1) ==
kInvalidDescriptorId) {
1010 return R__FAIL(
"out of bounds representation index");
1012 if (columnIndex == 0) {
1013 assert(fieldDesc.fColumnCardinality > 0);
1014 if (fDescriptor.FindLogicalColumnId(fieldId, fieldDesc.fColumnCardinality - 1, representationIndex - 1) ==
1016 return R__FAIL(
"incomplete column representations");
1019 if (columnIndex >= fieldDesc.fColumnCardinality)
1020 return R__FAIL(
"irregular column representations");
1024 fieldDesc.fColumnCardinality = columnIndex + 1;
1027 const auto logicalId = columnDesc.GetLogicalId();
1028 fieldDesc.fLogicalColumnIds.emplace_back(logicalId);
1030 if (!columnDesc.IsAliasColumn())
1031 fDescriptor.fNPhysicalColumns++;
1032 fDescriptor.fColumnDescriptors.emplace(logicalId, std::move(columnDesc));
1033 if (fDescriptor.fHeaderExtension)
1034 fDescriptor.fHeaderExtension->AddExtendedColumn(columnDesc);
1042 const auto id = clusterGroup.GetId();
1043 if (fDescriptor.fClusterGroupDescriptors.count(
id) > 0)
1044 return R__FAIL(
"cluster group id clash");
1045 fDescriptor.fNEntries = std::max(fDescriptor.fNEntries, clusterGroup.GetMinEntry() + clusterGroup.GetEntrySpan());
1046 fDescriptor.fNClusters += clusterGroup.GetNClusters();
1047 fDescriptor.fClusterGroupDescriptors.emplace(
id, std::move(clusterGroup));
1053 fDescriptor.fName =
"";
1054 fDescriptor.fDescription =
"";
1055 fDescriptor.fFieldDescriptors.clear();
1056 fDescriptor.fColumnDescriptors.clear();
1057 fDescriptor.fClusterDescriptors.clear();
1058 fDescriptor.fClusterGroupDescriptors.clear();
1059 fDescriptor.fHeaderExtension.reset();
1064 if (!fDescriptor.fHeaderExtension)
1065 fDescriptor.fHeaderExtension = std::make_unique<RNTupleDescriptor::RHeaderExtension>();
1070 if (fDescriptor.GetNLogicalColumns() == 0)
1072 R__ASSERT(fDescriptor.GetNPhysicalColumns() > 0);
1074 for (
DescriptorId_t id = fDescriptor.GetNLogicalColumns() - 1;
id >= fDescriptor.GetNPhysicalColumns(); --
id) {
1075 auto c = fDescriptor.fColumnDescriptors[
id].Clone();
1078 fDescriptor.fColumnDescriptors.erase(
id);
1079 for (
auto &link : fDescriptor.fFieldDescriptors[
c.fFieldId].fLogicalColumnIds) {
1080 if (link ==
c.fLogicalColumnId) {
1086 R__ASSERT(fDescriptor.fColumnDescriptors.count(
c.fLogicalColumnId) == 0);
1087 fDescriptor.fColumnDescriptors.emplace(
c.fLogicalColumnId, std::move(
c));
1094 auto clusterId = clusterDesc.GetId();
1095 if (fDescriptor.fClusterDescriptors.count(clusterId) > 0)
1096 return R__FAIL(
"cluster id clash");
1097 fDescriptor.fClusterDescriptors.emplace(clusterId, std::move(clusterDesc));
1105 if (std::find(fDescriptor.fExtraTypeInfoDescriptors.begin(), fDescriptor.fExtraTypeInfoDescriptors.end(),
1106 extraTypeInfoDesc) != fDescriptor.fExtraTypeInfoDescriptors.end()) {
1107 return R__FAIL(
"extra type info duplicates");
1109 fDescriptor.fExtraTypeInfoDescriptors.emplace_back(std::move(extraTypeInfoDesc));
1117 const auto &desc = GetDescriptor();
1120 fnWalkFieldTree = [&desc, &streamerInfoMap, &fnWalkFieldTree](
const RFieldDescriptor &fieldDesc) {
1121 if (fieldDesc.IsCustomClass()) {
1125 throw RException(
R__FAIL(std::string(
"cannot get TClass for ") + fieldDesc.GetTypeName()));
1127 auto streamerInfo = cl->GetStreamerInfo(fieldDesc.GetTypeVersion());
1128 if (!streamerInfo) {
1129 throw RException(
R__FAIL(std::string(
"cannot get streamerInfo for ") + fieldDesc.GetTypeName()));
1131 streamerInfoMap[streamerInfo->GetNumber()] = streamerInfo;
1135 for (
const auto &subFieldDesc : desc.GetFieldIterable(fieldDesc)) {
1136 fnWalkFieldTree(subFieldDesc);
1140 fnWalkFieldTree(desc.GetFieldZero());
1144 for (
const auto &extraTypeInfo : desc.GetExtraTypeInfoIterable()) {
1153 return streamerInfoMap;
1177 return GetFieldIterable(GetFieldDescriptor(fieldId));
1183 return GetFieldIterable(GetFieldDescriptor(fieldId), comparator);
1189 return GetFieldIterable(GetFieldZeroId());
1196 return GetFieldIterable(GetFieldZeroId(), comparator);
#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...
#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 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 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 id
A helper class for piece-wise construction of an RClusterDescriptor.
RResult< RClusterDescriptor > MoveDescriptor()
Move out the full cluster descriptor including page locations.
RResult< void > MarkSuppressedColumnRange(DescriptorId_t physicalId)
Books the given column ID as being suppressed in this cluster.
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)
RResult< void > CommitSuppressedColumnRanges(const RNTupleDescriptor &desc)
Sets the first element index and number of elements for all the suppressed column ranges.
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
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 & TypeChecksum(const std::optional< std::uint32_t > typeChecksum)
RFieldDescriptorBuilder & TypeAlias(const std::string &typeAlias)
RFieldDescriptorBuilder & FieldDescription(const std::string &fieldDescription)
RNTupleSerializer::StreamerInfoMap_t BuildStreamerInfos() const
Get the streamer info records for custom classes. Currently requires the corresponding dictionaries t...
RResult< void > AddFieldProjection(DescriptorId_t sourceId, DescriptorId_t targetId)
void BeginHeaderExtension()
Mark the beginning of the header extension; any fields and columns added after a call to this functio...
void ShiftAliasColumns(std::uint32_t offset)
If the descriptor is constructed in pieces consisting of physical and alias columns (regular and proj...
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(RColumnDescriptor &&columnDesc)
RNTupleDescriptor MoveDescriptor()
void Reset()
Clears so-far stored clusters, fields, and columns and return to a pristine ntuple descriptor.
RResult< void > AddExtraTypeInfo(RExtraTypeInfoDescriptor &&extraTypeInfoDesc)
static RResult< StreamerInfoMap_t > DeserializeStreamerInfos(const std::string &extraTypeInfoContent)
std::map< Int_t, TVirtualStreamerInfo * > StreamerInfoMap_t
Meta-data for a set of ntuple clusters.
std::unordered_map< DescriptorId_t, RPageRange > fPageRanges
RColumnRangeIterable GetColumnRangeIterable() const
Returns an iterator over pairs { columnId, columnRange }. The iteration order is unspecified.
NTupleSize_t fFirstEntryIndex
Clusters can be swapped by adjusting the entry offsets.
DescriptorId_t fClusterId
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 fPageListLength
Uncompressed size of the page list.
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
RNTupleLocator fPageListLocator
The page list that corresponds to the cluster group.
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.
std::optional< RValueRange > fValueRange
Optional value range (used e.g. by quantized real fields)
std::uint16_t fBitsOnStorage
The size in bits of elements of this column.
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.
std::int64_t fFirstElementIndex
The absolute value specifies the index for the first stored element for this column.
std::uint16_t fRepresentationIndex
A field may use multiple column representations, which are numbered from zero to $m$.
EColumnType fType
The on-disk column type.
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
Base class for all ROOT issued exceptions.
A field translates read and write calls from/to underlying columns to/from tree values.
const std::string & GetTypeAlias() const
const std::string & GetDescription() const
Get the field's description.
const std::string & GetFieldName() const
ENTupleStructure GetStructure() const
const std::string & GetTypeName() const
static RResult< std::unique_ptr< RFieldBase > > Create(const std::string &fieldName, const std::string &canonicalType, const std::string &typeAlias, bool continueOnError=false)
Factory method to resurrect a field from the stored on-disk type information.
static constexpr int kTraitTypeChecksum
The TClass checksum is set and valid.
virtual std::uint32_t GetTypeVersion() const
Indicates an evolution of the C++ type itself.
virtual std::uint32_t GetTypeChecksum() const
Return the current TClass reported checksum of this class. Only valid if kTraitTypeChecksum is set.
virtual std::uint32_t GetFieldVersion() const
Indicates an evolution of the mapping scheme from C++ type to columns.
std::size_t GetNRepetitions() const
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::unique_ptr< RFieldBase > CreateField(const RNTupleDescriptor &ntplDesc, bool continueOnError=false) const
In general, we create a field simply from the C++ type name.
DescriptorId_t GetParentId() const
const std::string & GetFieldName() const
std::uint32_t fTypeVersion
The version of the C++ type itself.
std::uint32_t fColumnCardinality
The number of columns in the column representations of the field.
std::optional< std::uint32_t > fTypeChecksum
For custom classes, we store the ROOT TClass reported checksum to facilitate the use of I/O rules tha...
bool IsCustomClass() const
Tells if the field describes a user-defined class rather than a fundamental type, a collection,...
const std::vector< DescriptorId_t > & GetLogicalColumnIds() 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: first by representation index then by column inde...
DescriptorId_t GetId() const
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
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.
DescriptorId_t fProjectionSourceId
For projected fields, the source field ID.
Used in RFieldBase::Check() to record field creation failures.
Used to loop over all the clusters of an ntuple (in unspecified order)
Used to loop over all the cluster groups of an ntuple (in unspecified order)
Used to loop over a field's associated columns.
std::vector< DescriptorId_t > fColumns
The descriptor ids of the columns ordered by field, representation, and column index.
RColumnDescriptorIterable(const RNTupleDescriptor &ntuple, const RFieldDescriptor &fieldDesc)
Used to loop over a field's child fields.
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.
std::set< unsigned int > fFeatureFlags
std::vector< RExtraTypeInfoDescriptor > fExtraTypeInfoDescriptors
NTupleSize_t GetNElements(DescriptorId_t physicalColumnId) const
std::unordered_map< DescriptorId_t, RClusterGroupDescriptor > fClusterGroupDescriptors
std::unique_ptr< RNTupleModel > CreateModel(const RCreateModelOptions &options=RCreateModelOptions()) const
Re-create the C++ model from the stored meta-data.
DescriptorId_t FindLogicalColumnId(DescriptorId_t fieldId, std::uint32_t columnIndex, std::uint16_t representationIndex) const
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
RColumnDescriptorIterable GetColumnIterable() 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)
std::unordered_map< DescriptorId_t, RFieldDescriptor > fFieldDescriptors
DescriptorId_t GetFieldZeroId() const
Returns the logical parent of all top-level NTuple data fields.
DescriptorId_t FindPhysicalColumnId(DescriptorId_t fieldId, std::uint32_t columnIndex, std::uint16_t representationIndex) const
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 RColumnDescriptor & GetColumnDescriptor(DescriptorId_t columnId) const
RExtraTypeInfoDescriptorIterable GetExtraTypeInfoIterable() const
const RFieldDescriptor & GetFieldDescriptor(DescriptorId_t fieldId) const
RResult< void > DropClusterGroupDetails(DescriptorId_t clusterGroupId)
std::unique_ptr< RHeaderExtension > fHeaderExtension
RClusterGroupDescriptorIterable GetClusterGroupIterable() const
RClusterDescriptorIterable GetClusterIterable() const
std::string fDescription
Free text from the user.
RFieldDescriptorIterable GetTopLevelFields() const
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.
RFieldDescriptorIterable GetFieldIterable(const RFieldDescriptor &fieldDesc) const
std::vector< std::uint64_t > GetFeatureFlags() const
static std::unique_ptr< RNTupleModel > Create()
static std::unique_ptr< RNTupleModel > CreateBare()
A bare model has no default entry.
The class is used as a return type for operations that can fail; wraps a value of type T or an RError...
static std::unique_ptr< RVectorField > CreateUntyped(std::string_view fieldName, std::unique_ptr< RFieldBase > itemField)
static TClass * GetClass(const char *name, Bool_t load=kTRUE, Bool_t silent=kFALSE)
Static method returning pointer to TClass of the specified class name.
RResult< void > EnsureValidNameForRNTuple(std::string_view name, std::string_view where)
Check whether a given string is a valid name according to the RNTuple specification.
std::uint64_t NTupleSize_t
Integer type long enough to hold the maximum number of entries in a column.
constexpr int kUnknownCompressionSettings
std::uint64_t DescriptorId_t
Distriniguishes elements of the same type within a descriptor, e.g. different fields.
constexpr NTupleSize_t kInvalidNTupleIndex
constexpr DescriptorId_t kInvalidDescriptorId
The window of element indexes of a particular column in a particular cluster.
bool fIsSuppressed
Suppressed columns have an empty page range and unknown compression settings.
int fCompressionSettings
The usual format for ROOT compression settings (see Compression.h).
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.
Modifiers passed to CreateModel
bool fCreateBare
If true, the model will be created without a default entry (bare model).
bool fReconstructProjections
If set to true, projected fields will be reconstructed as such.
bool fForwardCompatible
Normally creating a model will fail if any of the reconstructed fields contains an unknown column typ...