72 if (buffer !=
nullptr) {
73 auto pos =
reinterpret_cast<unsigned char *
>(buffer);
83 auto bytes =
reinterpret_cast<const unsigned char *
>(buffer);
90std::uint32_t SerializeFrame(std::uint16_t protocolVersionCurrent, std::uint16_t protocolVersionMin,
void *buffer,
93 if (buffer !=
nullptr) {
94 auto pos =
reinterpret_cast<unsigned char *
>(buffer);
103std::uint32_t DeserializeFrame(std::uint16_t protocolVersion,
const void *buffer, std::uint32_t *
size)
105 auto bytes =
reinterpret_cast<const unsigned char *
>(buffer);
106 std::uint16_t protocolVersionAtWrite;
107 std::uint16_t protocolVersionMinRequired;
110 if (protocolVersion < protocolVersionMinRequired) {
112 + std::to_string(protocolVersionMinRequired)
113 +
"), version <= " + std::to_string(protocolVersion) +
" required"));
121 auto base =
reinterpret_cast<unsigned char *
>((buffer !=
nullptr) ? buffer : 0);
123 void** where = (buffer ==
nullptr) ? &buffer : reinterpret_cast<
void**>(&pos);
125 void *ptrSize =
nullptr;
126 pos += SerializeFrame(0, 0, *where, &ptrSize);
132 auto size = pos - base;
139 auto bytes =
reinterpret_cast<const unsigned char *
>(buffer);
140 std::uint32_t frameSize;
141 bytes += DeserializeFrame(0, bytes, &frameSize);
143 std::uint32_t versionUse;
144 std::uint32_t versionMin;
156 auto base =
reinterpret_cast<unsigned char *
>((buffer !=
nullptr) ? buffer : 0);
158 void** where = (buffer ==
nullptr) ? &buffer : reinterpret_cast<
void**>(&pos);
160 void *ptrSize =
nullptr;
161 pos += SerializeFrame(0, 0, *where, &ptrSize);
165 auto size = pos - base;
172 auto bytes =
reinterpret_cast<const unsigned char *
>(buffer);
173 std::uint32_t frameSize;
174 bytes += DeserializeFrame(0, bytes, &frameSize);
183 auto base =
reinterpret_cast<unsigned char *
>((buffer !=
nullptr) ? buffer : 0);
185 void** where = (buffer ==
nullptr) ? &buffer : reinterpret_cast<
void**>(&pos);
187 void *ptrSize =
nullptr;
188 pos += SerializeFrame(0, 0, *where, &ptrSize);
193 auto size = pos - base;
200 auto bytes =
reinterpret_cast<const unsigned char *
>(buffer);
201 std::uint32_t frameSize;
202 bytes += DeserializeFrame(0, bytes, &frameSize);
205 std::int32_t isSorted;
213std::uint32_t SerializeTimeStamp(
const std::chrono::system_clock::time_point &val,
void *buffer)
215 return SerializeInt64(std::chrono::system_clock::to_time_t(val), buffer);
218std::uint32_t DeserializeTimeStamp(
const void *buffer, std::chrono::system_clock::time_point *timeStamp)
220 std::int64_t secSinceUnixEpoch;
222 *timeStamp = std::chrono::system_clock::from_time_t(secSinceUnixEpoch);
229 if (buffer !=
nullptr) {
230 auto pos =
reinterpret_cast<unsigned char *
>(buffer);
233 pos += SerializeClusterSize(val.
fNElements, pos);
239std::uint32_t DeserializeColumnRange(
const void *buffer,
242 auto bytes =
reinterpret_cast<const unsigned char *
>(buffer);
245 bytes += DeserializeClusterSize(bytes, &columnRange->
fNElements);
253 if (buffer !=
nullptr) {
254 auto pos =
reinterpret_cast<unsigned char *
>(buffer);
256 pos += SerializeClusterSize(val.
fNElements, pos);
257 pos += SerializeLocator(val.
fLocator, pos);
259 return 4 + SerializeLocator(val.
fLocator,
nullptr);
262std::uint32_t DeserializePageInfo(
const void *buffer,
265 auto base =
reinterpret_cast<const unsigned char *
>(buffer);
268 bytes += DeserializeClusterSize(bytes, &pageInfo->
fNElements);
269 bytes += DeserializeLocator(bytes, &pageInfo->
fLocator);
273std::uint32_t SerializeCrc32(
const unsigned char *data, std::uint32_t length,
void *buffer)
275 auto checksum = R__crc32(0,
nullptr, 0);
276 if (buffer !=
nullptr) {
277 checksum = R__crc32(checksum, data, length);
283void VerifyCrc32(
const unsigned char *data, std::uint32_t length)
285 auto checksumReal = R__crc32(0,
nullptr, 0);
286 checksumReal = R__crc32(checksumReal, data, length);
287 std::uint32_t checksumFound;
289 if (checksumFound != checksumReal)
295 auto base =
reinterpret_cast<unsigned char *
>((buffer !=
nullptr) ? buffer : 0);
297 void** where = (buffer ==
nullptr) ? &buffer : reinterpret_cast<
void**>(&pos);
299 void *ptrSize =
nullptr;
313 for (
const auto&
l : val.GetLinkIds())
316 auto size = pos - base;
323 auto base =
reinterpret_cast<unsigned char *
>((buffer !=
nullptr) ? buffer : 0);
325 void** where = (buffer ==
nullptr) ? &buffer : reinterpret_cast<
void**>(&pos);
327 void *ptrSize =
nullptr;
332 pos += SerializeVersion(val.
GetVersion(), *where);
333 pos += SerializeColumnModel(val.
GetModel(), *where);
337 auto size = pos - base;
344 auto base =
reinterpret_cast<unsigned char *
>((buffer !=
nullptr) ? buffer : 0);
346 void** where = (buffer ==
nullptr) ? &buffer : reinterpret_cast<
void**>(&pos);
348 void *ptrSize =
nullptr;
353 pos += SerializeVersion(val.
GetVersion(), *where);
356 pos += SerializeLocator({0, 1,
""}, *where);
358 auto size = pos - base;
397std::unique_ptr<ROOT::Experimental::Detail::RFieldBase>
403 std::vector<std::unique_ptr<Detail::RFieldBase>> memberFields;
404 for (
auto id : fLinkIds) {
406 memberFields.emplace_back(memberDesc.CreateField(ntplDesc));
408 auto recordField = std::make_unique<RRecordField>(
"_0", memberFields);
409 auto collectionField = std::make_unique<RVectorField>(GetFieldName(), std::move(recordField));
410 collectionField->SetOnDiskId(fFieldId);
411 return collectionField;
415 field->SetOnDiskId(fFieldId);
416 for (
auto &
f : *field)
417 f.SetOnDiskId(ntplDesc.
FindFieldId(
f.GetName(),
f.GetParent()->GetOnDiskId()));
456 decltype(idxInCluster) firstInPage = 0;
458 for (
const auto &pi : fPageInfos) {
459 if (firstInPage + pi.fNElements > idxInCluster) {
485 std::unordered_set<DescriptorId_t> result;
486 for (
const auto &
x : fColumnRanges)
487 result.emplace(
x.first);
494 return fColumnRanges.find(columnId) != fColumnRanges.end();
500 std::uint64_t nbytes = 0;
501 for (
const auto &pr : fPageRanges) {
502 for (
const auto &pi : pr.second.fPageInfos) {
503 nbytes += pi.fLocator.fBytesOnStorage;
515 return fName == other.
fName &&
532 auto base =
reinterpret_cast<unsigned char *
>((buffer !=
nullptr) ? buffer : 0);
534 void** where = (buffer ==
nullptr) ? &buffer :
reinterpret_cast<void**
>(&pos);
536 void *ptrSize =
nullptr;
537 pos += SerializeFrame(
545 pos += SerializeTimeStamp(fTimeStampData, *where);
546 pos += SerializeTimeStamp(fTimeStampWritten, *where);
547 pos += SerializeVersion(fVersion, *where);
548 pos += SerializeUuid(fOwnUuid, *where);
549 pos += SerializeUuid(fGroupUuid, *where);
551 for (
const auto&
f : fFieldDescriptors) {
552 pos += SerializeField(
f.second, *where);
555 for (
const auto&
c : fColumnDescriptors) {
556 pos += SerializeColumn(
c.second, *where);
559 std::uint32_t
size = pos - base;
561 size += SerializeCrc32(base,
size, *where);
568 auto base =
reinterpret_cast<unsigned char *
>((buffer !=
nullptr) ? buffer : 0);
570 void** where = (buffer ==
nullptr) ? &buffer :
reinterpret_cast<void**
>(&pos);
572 void *ptrSize =
nullptr;
573 pos += SerializeFrame(
578 for (
const auto& cluster : fClusterDescriptors) {
579 pos += SerializeUuid(fOwnUuid, *where);
580 pos += SerializeClusterSummary(cluster.second, *where);
583 for (
const auto& column : fColumnDescriptors) {
584 auto columnId = column.first;
587 const auto &columnRange = cluster.second.GetColumnRange(columnId);
588 R__ASSERT(columnRange.fColumnId == columnId);
589 pos += SerializeColumnRange(columnRange, *where);
591 const auto &pageRange = cluster.second.GetPageRange(columnId);
592 R__ASSERT(pageRange.fColumnId == columnId);
593 auto nPages = pageRange.fPageInfos.size();
595 for (
unsigned int i = 0; i < nPages; ++i) {
596 pos += SerializePageInfo(pageRange.fPageInfos[i], *where);
606 std::uint32_t
size = pos - base + 4;
608 size += SerializeCrc32(base,
size, *where);
615 const void *postscript, std::uint32_t &szHeader, std::uint32_t &szFooter)
617 auto pos =
reinterpret_cast<const unsigned char *
>(postscript);
629 for (
const auto &cd : fClusterDescriptors) {
630 result = std::max(result, cd.second.GetFirstEntryIndex() + cd.second.GetNEntries());
638 for (
const auto &cd : fClusterDescriptors) {
639 if (!cd.second.ContainsColumn(columnId))
641 auto columnRange = cd.second.GetColumnRange(columnId);
642 result = std::max(result, columnRange.fFirstElementIndex + columnRange.fNElements);
651 std::string leafName(fieldName);
652 auto posDot = leafName.find_last_of(
'.');
653 if (posDot != std::string::npos) {
654 auto parentName = leafName.substr(0, posDot);
655 leafName = leafName.substr(posDot + 1);
656 parentId = FindFieldId(parentName, parentId);
658 for (
const auto &fd : fFieldDescriptors) {
659 if (fd.second.GetParentId() == parentId && fd.second.GetFieldName() == leafName)
660 return fd.second.GetId();
671 const auto &fieldDescriptor = fFieldDescriptors.at(fieldId);
672 auto prefix = GetQualifiedFieldName(fieldDescriptor.GetParentId());
674 return fieldDescriptor.GetFieldName();
675 return prefix +
"." + fieldDescriptor.GetFieldName();
689 return FindFieldId(fieldName, GetFieldZeroId());
696 for (
const auto &cd : fColumnDescriptors) {
697 if (cd.second.GetFieldId() == fieldId && cd.second.GetIndex() == columnIndex)
698 return cd.second.GetId();
708 for (
const auto &cd : fClusterDescriptors) {
709 if (!cd.second.ContainsColumn(columnId))
711 auto columnRange = cd.second.GetColumnRange(columnId);
712 if (columnRange.Contains(index))
713 return cd.second.GetId();
723 const auto &clusterDesc = GetClusterDescriptor(clusterId);
724 auto firstEntryInNextCluster = clusterDesc.GetFirstEntryIndex() + clusterDesc.GetNEntries();
726 for (
const auto &cd : fClusterDescriptors) {
727 if (cd.second.GetFirstEntryIndex() == firstEntryInNextCluster)
728 return cd.second.GetId();
738 const auto &clusterDesc = GetClusterDescriptor(clusterId);
740 for (
const auto &cd : fClusterDescriptors) {
741 if (cd.second.GetFirstEntryIndex() + cd.second.GetNEntries() == clusterDesc.GetFirstEntryIndex())
742 return cd.second.GetId();
750 auto model = std::make_unique<RNTupleModel>();
751 model->GetFieldZero()->SetOnDiskId(GetFieldZeroId());
752 for (
const auto &topDesc : GetTopLevelFields())
753 model->AddField(topDesc.CreateField(*
this));
763 DescriptorId_t columnId, std::uint64_t firstElementIndex, std::uint32_t compressionSettings,
767 return R__FAIL(
"column ID mismatch");
768 if (fCluster.fPageRanges.count(columnId) > 0)
769 return R__FAIL(
"column ID conflict");
771 columnRange.fCompressionSettings = compressionSettings;
773 columnRange.fNElements += pi.fNElements;
775 fCluster.fPageRanges[columnId] = pageRange.
Clone();
776 fCluster.fColumnRanges[columnId] = columnRange;
785 return R__FAIL(
"unset cluster ID");
786 if (fCluster.fNEntries == 0)
787 return R__FAIL(
"empty cluster");
788 for (
const auto &pr : fCluster.fPageRanges) {
789 if (fCluster.fColumnRanges.count(pr.first) == 0) {
790 return R__FAIL(
"missing column range");
794 std::swap(result, fCluster);
804 if (fDescriptor.fFieldDescriptors.count(fieldId) == 0)
805 return R__FAIL(
"field with id '" + std::to_string(fieldId) +
"' doesn't exist");
817 for (
const auto& key_val: fDescriptor.fFieldDescriptors) {
818 const auto&
id = key_val.first;
819 const auto& desc = key_val.second;
822 return R__FAIL(
"field with id '" + std::to_string(
id) +
"' has an invalid parent id");
831 std::swap(result, fDescriptor);
837 auto pos =
reinterpret_cast<unsigned char *
>(headerBuffer);
840 std::uint32_t frameSize;
842 VerifyCrc32(base, frameSize);
843 std::uint64_t reserved;
850 pos += DeserializeTimeStamp(pos, &fDescriptor.fTimeStampData);
851 pos += DeserializeTimeStamp(pos, &fDescriptor.fTimeStampWritten);
852 pos += DeserializeVersion(pos, &fDescriptor.fVersion);
853 pos += DeserializeUuid(pos, &fDescriptor.fOwnUuid);
854 pos += DeserializeUuid(pos, &fDescriptor.fGroupUuid);
856 std::uint32_t nFields;
858 for (std::uint32_t i = 0; i < nFields; ++i) {
859 auto fieldBase = pos;
864 pos += DeserializeVersion(pos, &
f.fFieldVersion);
865 pos += DeserializeVersion(pos, &
f.fTypeVersion);
870 std::int32_t structure;
875 std::uint32_t nLinks;
877 f.fLinkIds.resize(nLinks);
878 for (std::uint32_t j = 0; j < nLinks; ++j) {
882 pos = fieldBase + frameSize;
883 fDescriptor.fFieldDescriptors.emplace(
f.fFieldId, std::move(
f));
886 std::uint32_t nColumns;
888 for (std::uint32_t i = 0; i < nColumns; ++i) {
889 auto columnBase = pos;
894 pos += DeserializeVersion(pos, &
c.fVersion);
895 pos += DeserializeColumnModel(pos, &
c.fModel);
899 pos = columnBase + frameSize;
900 fDescriptor.fColumnDescriptors.emplace(
c.fColumnId, std::move(
c));
905 auto pos =
reinterpret_cast<unsigned char *
>(footerBuffer);
908 std::uint32_t frameSize;
910 VerifyCrc32(base, frameSize);
911 std::uint64_t reserved;
914 std::uint64_t nClusters;
916 for (std::uint64_t i = 0; i < nClusters; ++i) {
918 pos += DeserializeUuid(pos, &uuid);
920 auto clusterBase = pos;
923 std::uint64_t clusterId;
925 std::uint64_t firstEntry;
926 std::uint64_t nEntries;
928 pos += DeserializeVersion(pos, &version);
933 pos += DeserializeLocator(pos, &locator);
935 pos = clusterBase + frameSize;
937 std::uint32_t nColumns;
939 for (std::uint32_t j = 0; j < nColumns; ++j) {
945 pos += DeserializeColumnRange(pos, &columnRange);
946 AddClusterColumnRange(clusterId, columnRange);
950 std::uint32_t nPages;
952 for (
unsigned int k = 0; k < nPages; ++k) {
954 pos += DeserializePageInfo(pos, &pageInfo);
957 AddClusterPageRange(clusterId, std::move(pageRange));
963 const std::string_view
name,
const std::string_view description,
const std::string_view author,
966 fDescriptor.fName = std::string(
name);
967 fDescriptor.fDescription = std::string(description);
968 fDescriptor.fAuthor = std::string(author);
969 fDescriptor.fVersion = version;
970 fDescriptor.fOwnUuid = uuid;
971 fDescriptor.fGroupUuid = uuid;
978 return R__FAIL(
"invalid column id");
980 return R__FAIL(
"invalid column model");
982 return R__FAIL(
"invalid field id, dangling column");
983 return fColumn.Clone();
1009 return R__FAIL(
"invalid field id");
1012 return R__FAIL(
"invalid field structure");
1021 return fField.Clone();
1025 fDescriptor.fFieldDescriptors.emplace(fieldDesc.
GetId(), fieldDesc.
Clone());
1032 if (!(fieldExists = EnsureFieldExists(fieldId)))
1034 if (!(fieldExists = EnsureFieldExists(linkId)))
1035 return R__FAIL(
"child field with id '" + std::to_string(linkId) +
"' doesn't exist in NTuple");
1037 if (linkId == fDescriptor.GetFieldZeroId()) {
1038 return R__FAIL(
"cannot make FieldZero a child field");
1041 auto parentId = fDescriptor.fFieldDescriptors.at(linkId).GetParentId();
1043 return R__FAIL(
"field '" + std::to_string(linkId) +
"' already has a parent ('" +
1044 std::to_string(parentId) +
")");
1046 if (fieldId == linkId) {
1047 return R__FAIL(
"cannot make field '" + std::to_string(fieldId) +
"' a child of itself");
1049 fDescriptor.fFieldDescriptors.at(linkId).fParentId = fieldId;
1050 fDescriptor.fFieldDescriptors.at(fieldId).fLinkIds.push_back(linkId);
1056 std::uint32_t index)
1060 c.fFieldId = fieldId;
1061 c.fVersion = version;
1064 fDescriptor.fColumnDescriptors.emplace(columnId, std::move(
c));
1071 const auto fieldId = columnDesc.GetFieldId();
1072 const auto index = columnDesc.GetIndex();
1074 auto fieldExists = EnsureFieldExists(fieldId);
1078 return R__FAIL(
"column index clash");
1082 return R__FAIL(
"out of bounds column index");
1085 fDescriptor.fColumnDescriptors.emplace(columnDesc.GetId(), std::move(columnDesc));
1096 c.fVersion = version;
1097 c.fFirstEntryIndex = firstEntryIndex;
1098 c.fNEntries = nEntries;
1099 fDescriptor.fClusterDescriptors.emplace(clusterId, std::move(
c));
1105 fDescriptor.fClusterDescriptors[clusterId].fColumnRanges[columnRange.
fColumnId] = columnRange;
1111 fDescriptor.fClusterDescriptors[clusterId].fPageRanges.emplace(pageRange.fColumnId, std::move(pageRange));
1117 fClusterSummaries.push_back(clusterSummary);
1123 fClusterGroups.push_back(clusterGroup);
1130 if (clusterId >= fClusterSummaries.size())
1131 return R__FAIL(
"unknown cluster id");
1132 if (fDescriptor.fClusterDescriptors.count(clusterId) != 0)
1133 return R__FAIL(
"cluster clash");
1134 const auto &summary = fClusterSummaries.at(clusterId);
1135 partialCluster.ClusterId(clusterId)
1136 .FirstEntryIndex(summary.fFirstEntry)
1137 .NEntries(summary.fNEntries);
1138 auto cluster = partialCluster.MoveDescriptor();
1141 fDescriptor.fClusterDescriptors.emplace(clusterId, cluster.Unwrap());
1147 fDescriptor.fName =
"";
1149 fDescriptor.fFieldDescriptors.clear();
1150 fDescriptor.fColumnDescriptors.clear();
1151 fDescriptor.fClusterDescriptors.clear();
typedef void(GLAPIENTRYP _GLUfuncptr)(void)
#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...
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
std::string GetDescription() const
Get the field's description.
std::string GetName() const
std::size_t GetNRepetitions() const
virtual RNTupleVersion GetTypeVersion() const
Indicates an evolution of the C++ type itself.
std::string GetType() const
static RResult< void > EnsureValidFieldName(std::string_view fieldName)
Check whether a given string is a valid field name.
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.
virtual RNTupleVersion GetFieldVersion() const
Indicates an evolution of the mapping scheme from C++ type to columns.
ENTupleStructure GetStructure() const
The available trivial, native content types of a column.
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()
Attempt to make a cluster descriptor.
Meta-data for a set of ntuple clusters.
std::unordered_map< DescriptorId_t, RPageRange > fPageRanges
RNTupleVersion fVersion
Future versions of the cluster descriptor might add more meta-data, e.g. a semantic checksum.
bool ContainsColumn(DescriptorId_t columnId) const
static constexpr std::uint16_t kFrameVersionMin
RNTupleVersion GetVersion() const
NTupleSize_t fFirstEntryIndex
Clusters can be swapped by adjusting the entry offsets.
DescriptorId_t fClusterId
NTupleSize_t GetFirstEntryIndex() const
std::unordered_set< DescriptorId_t > GetColumnIds() const
std::unordered_map< DescriptorId_t, RColumnRange > fColumnRanges
bool operator==(const RClusterDescriptor &other) const
ClusterSize_t GetNEntries() const
std::uint64_t GetBytesOnStorage() const
static constexpr std::uint16_t kFrameVersionCurrent
In order to handle changes to the serialization routine in future ntuple versions.
DescriptorId_t GetId() const
RResult< RColumnDescriptor > MakeDescriptor() const
Attempt to make a column descriptor.
Meta-data stored for every column of an ntuple.
RNTupleVersion GetVersion() const
RColumnModel GetModel() const
static constexpr std::uint16_t kFrameVersionCurrent
In order to handle changes to the serialization routine in future ntuple versions.
RColumnDescriptor Clone() const
Get a copy of the descriptor.
DescriptorId_t GetId() const
DescriptorId_t fFieldId
Every column belongs to one and only one field.
DescriptorId_t GetFieldId() const
RColumnModel fModel
Contains the column type and whether it is sorted.
static constexpr std::uint16_t kFrameVersionMin
RNTupleVersion fVersion
Versions can change, e.g., when new column types are added.
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
Holds the static meta-data of a column in a tree.
EColumnType GetType() const
Base class for all ROOT issued exceptions.
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 & FieldVersion(const RNTupleVersion &fieldVersion)
RFieldDescriptorBuilder & Structure(const ENTupleStructure &structure)
RResult< RFieldDescriptor > MakeDescriptor() const
Attempt to make a field descriptor.
RFieldDescriptorBuilder & TypeName(const std::string &typeName)
RFieldDescriptorBuilder & FieldDescription(const std::string &fieldDescription)
RFieldDescriptorBuilder & TypeVersion(const RNTupleVersion &typeVersion)
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.
DescriptorId_t GetParentId() const
RNTupleVersion GetTypeVersion() const
RNTupleVersion fFieldVersion
The version of the C++-type-to-column translation mechanics.
RNTupleVersion GetFieldVersion() const
std::string GetFieldName() const
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.
static constexpr std::uint16_t kFrameVersionMin
std::string fFieldName
The leaf name, not including parent fields.
DescriptorId_t GetId() const
const std::vector< DescriptorId_t > & GetLinkIds() const
std::string GetFieldDescription() const
std::string GetTypeName() const
DescriptorId_t fParentId
Establishes sub field relationships, such as classes and collections.
RNTupleVersion fTypeVersion
The version of the C++ type itself.
std::uint64_t GetNRepetitions() const
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.
ENTupleStructure GetStructure() const
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.
static constexpr std::uint16_t kFrameVersionCurrent
In order to handle changes to the serialization routine in future ntuple versions.
RNTupleDescriptor MoveDescriptor()
RResult< void > EnsureValidDescriptor() const
Checks whether invariants hold:
void AddClusterSummary(Internal::RNTupleSerializer::RClusterSummary &clusterSummary)
void SetFromHeader(void *headerBuffer)
RResult< void > EnsureFieldExists(DescriptorId_t fieldId) const
void AddCluster(DescriptorId_t clusterId, RNTupleVersion version, NTupleSize_t firstEntryIndex, ClusterSize_t nEntries)
RResult< void > AddFieldLink(DescriptorId_t fieldId, DescriptorId_t linkId)
void AddColumn(DescriptorId_t columnId, DescriptorId_t fieldId, const RNTupleVersion &version, const RColumnModel &model, std::uint32_t index)
void Reset()
Clears so-far stored clusters, fields, and columns and return to a pristine ntuple descriptor.
void AddClusterColumnRange(DescriptorId_t clusterId, const RClusterDescriptor::RColumnRange &columnRange)
void AddClusterGroup(Internal::RNTupleSerializer::RClusterGroup &clusterGroup)
void AddClustersFromFooter(void *footerBuffer)
void SetNTuple(const std::string_view name, const std::string_view description, const std::string_view author, const RNTupleVersion &version, const RNTupleUuid &uuid)
void AddClusterPageRange(DescriptorId_t clusterId, RClusterDescriptor::RPageRange &&pageRange)
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.
RNTupleUuid fGroupUuid
Column sets that are created as derived sets from existing NTuples share the same group id.
std::unique_ptr< RNTupleModel > GenerateModel() const
Re-create the C++ model from the stored meta-data.
std::chrono::system_clock::time_point fTimeStampWritten
The time stamp of writing the data to storage, which gets updated when re-written.
DescriptorId_t FindNextClusterId(DescriptorId_t clusterId) const
std::uint32_t SerializeHeader(void *buffer) const
We deliberately do not use ROOT's built-in serialization in order to allow for use of RNTuple's witho...
DescriptorId_t FindPrevClusterId(DescriptorId_t clusterId) const
DescriptorId_t GetFieldZeroId() const
Returns the logical parent of all top-level NTuple data fields.
std::unordered_map< DescriptorId_t, RColumnDescriptor > fColumnDescriptors
NTupleSize_t GetNEntries() const
std::string fName
The ntuple name needs to be unique in a given storage location (file)
std::uint32_t SerializeFooter(void *buffer) const
Serializes cluster meta data. Returns the number of bytes and fills buffer if it is not nullptr.
std::string fAuthor
The origin of the data.
std::unordered_map< DescriptorId_t, RFieldDescriptor > fFieldDescriptors
static constexpr std::uint16_t kFrameVersionMin
RNTupleVersion fVersion
The version evolves with the ntuple summary meta-data.
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
const RFieldDescriptor & GetFieldDescriptor(DescriptorId_t fieldId) const
std::string fCustodian
The current responsible for storing the data.
DescriptorId_t FindColumnId(DescriptorId_t fieldId, std::uint32_t columnIndex) const
NTupleSize_t GetNElements(DescriptorId_t columnId) const
static void LocateMetadata(const void *postscript, std::uint32_t &szHeader, std::uint32_t &szFooter)
Given kNBytesPostscript bytes, extract the header and footer lengths in bytes.
std::string fDescription
Free text from the user.
static constexpr std::uint16_t kFrameVersionCurrent
In order to handle changes to the serialization routine in future ntuple versions.
RNTupleUuid fOwnUuid
Every NTuple gets a unique identifier.
std::chrono::system_clock::time_point fTimeStampData
The time stamp of the ntuple data (immutable)
DescriptorId_t FindClusterId(DescriptorId_t columnId, NTupleSize_t index) const
For forward and backward compatibility, attach version information to the consitituents of the file f...
std::uint32_t GetVersionUse() const
NTupleFlags_t GetFlags() const
std::uint32_t GetVersionMin() const
The class is used as a return type for operations that can fail; wraps a value of type T or an RError...
Machine-independent serialization functions for fundamental types.
std::uint32_t DeserializeInt64(const void *buffer, std::int64_t *val)
std::uint32_t DeserializeUInt16(const void *buffer, std::uint16_t *val)
std::uint32_t SerializeInt64(std::int64_t val, void *buffer)
std::uint32_t SerializeUInt32(std::uint32_t val, void *buffer)
std::uint32_t SerializeInt32(std::int32_t val, void *buffer)
std::uint32_t SerializeUInt16(std::uint16_t val, void *buffer)
std::uint32_t DeserializeUInt64(const void *buffer, std::uint64_t *val)
std::uint32_t SerializeUInt64(std::uint64_t val, void *buffer)
std::uint32_t DeserializeString(const void *buffer, std::string *val)
std::uint32_t DeserializeInt32(const void *buffer, std::int32_t *val)
std::uint32_t DeserializeUInt32(const void *buffer, std::uint32_t *val)
std::uint32_t SerializeString(const std::string &val, void *buffer)
std::uint64_t NTupleSize_t
Integer type long enough to hold the maximum number of entries in a column.
ENTupleStructure
The fields in the ntuple model tree can carry different structural information about the type system.
std::uint64_t DescriptorId_t
Distriniguishes elements of the same type within a descriptor, e.g. different fields.
std::string RNTupleUuid
Every NTuple is identified by a UUID. TODO(jblomer): should this be a TUUID?
constexpr DescriptorId_t kInvalidDescriptorId
The window of element indexes of a particular column in a particular cluster.
std::int64_t fCompressionSettings
The usual format for ROOT compression settings (see Compression.h).
NTupleSize_t fFirstElementIndex
A 64bit element index.
ClusterSize_t fNElements
A 32bit value for the number of column elements in the cluster.
Wrap the 32bit integer in a struct in order to avoid template specialization clash with std::uint32_t...
Generic information about the physical location of data.
std::uint32_t fBytesOnStorage