48   clone.fFieldId = fFieldId;
 
   49   clone.fFieldVersion = fFieldVersion;
 
   50   clone.fTypeVersion = fTypeVersion;
 
   51   clone.fFieldName = fFieldName;
 
   52   clone.fFieldDescription = fFieldDescription;
 
   54   clone.fTypeAlias = fTypeAlias;
 
   55   clone.fNRepetitions = fNRepetitions;
 
   56   clone.fStructure = fStructure;
 
   57   clone.fParentId = fParentId;
 
   58   clone.fLinkIds = fLinkIds;
 
 
   62std::unique_ptr<ROOT::Experimental::RFieldBase>
 
   65   if (GetTypeName().empty()) {
 
   70      for (
auto id : fLinkIds) {
 
   84         throw RException(
R__FAIL(
"unknown field type for field \"" + GetFieldName() + 
"\""));
 
   88   auto field = 
RFieldBase::Create(GetFieldName(), GetTypeAlias().empty() ? GetTypeName() : GetTypeAlias()).Unwrap();
 
   89   field->SetOnDiskId(fFieldId);
 
   91      f.SetOnDiskId(
ntplDesc.FindFieldId(
f.GetFieldName(), 
f.GetParent()->GetOnDiskId()));
 
 
  101   return fLogicalColumnId == 
other.fLogicalColumnId && fPhysicalColumnId == 
other.fPhysicalColumnId &&
 
  102          fModel == 
other.fModel && fFieldId == 
other.fFieldId && fIndex == 
other.fIndex;
 
 
  110   clone.fLogicalColumnId = fLogicalColumnId;
 
  111   clone.fPhysicalColumnId = fPhysicalColumnId;
 
  112   clone.fModel = fModel;
 
  113   clone.fFieldId = fFieldId;
 
  114   clone.fIndex = fIndex;
 
  115   clone.fFirstElementIndex = fFirstElementIndex;
 
 
  129   for (
const auto &pi : fPageInfos) {
 
 
  149   const auto nElements = std::accumulate(fPageInfos.begin(), fPageInfos.end(), 0U,
 
  150                                          [](std::size_t 
n, 
const auto &
PI) { return n + PI.fNElements; });
 
  165      PI.fLocator.fBytesOnStorage = 
element.GetPackedSize(
PI.fNElements);
 
  171                    std::make_move_iterator(fPageInfos.end()));
 
 
  178   return fClusterId == 
other.fClusterId && fFirstEntryIndex == 
other.fFirstEntryIndex &&
 
  179          fNEntries == 
other.fNEntries && fColumnRanges == 
other.fColumnRanges && fPageRanges == 
other.fPageRanges;
 
 
  185   std::unordered_set<DescriptorId_t> 
result;
 
  186   for (
const auto &
x : fColumnRanges)
 
 
  194   for (
const auto &
pr : fPageRanges) {
 
  195      for (
const auto &pi : 
pr.second.fPageInfos) {
 
  196         nbytes += pi.fLocator.fBytesOnStorage;
 
 
  205   clone.fClusterId = fClusterId;
 
  206   clone.fFirstEntryIndex = fFirstEntryIndex;
 
  207   clone.fNEntries = fNEntries;
 
  208   clone.fColumnRanges = fColumnRanges;
 
  209   for (
const auto &
d : fPageRanges)
 
  210      clone.fPageRanges.emplace(
d.first, 
d.second.Clone());
 
 
  220   return fName == 
other.fName &&
 
  221          fDescription == 
other.fDescription &&
 
  222          fNEntries == 
other.fNEntries &&
 
  223          fGeneration == 
other.fGeneration &&
 
  224          fFieldDescriptors == 
other.fFieldDescriptors &&
 
  225          fColumnDescriptors == 
other.fColumnDescriptors &&
 
  226          fClusterGroupDescriptors == 
other.fClusterGroupDescriptors &&
 
  227          fClusterDescriptors == 
other.fClusterDescriptors;
 
 
  235   for (
const auto &cd : fClusterDescriptors) {
 
 
  250   if (
posDot != std::string::npos) {
 
  255   for (
const auto &fd : fFieldDescriptors) {
 
  256      if (fd.second.GetParentId() == 
parentId && fd.second.GetFieldName() == 
leafName)
 
  257         return fd.second.GetId();
 
 
  286   return FindFieldId(
fieldName, GetFieldZeroId());
 
 
  292   for (
const auto &cd : fColumnDescriptors) {
 
  294         return cd.second.GetLogicalId();
 
 
  305   return GetColumnDescriptor(
logicalId).GetPhysicalId();
 
 
  312   for (
const auto &cd : fClusterDescriptors) {
 
  317         return cd.second.GetId();
 
 
  330   for (
const auto &cd : fClusterDescriptors) {
 
  332         return cd.second.GetId();
 
 
  344   for (
const auto &cd : fClusterDescriptors) {
 
  345      if (cd.second.GetFirstEntryIndex() + cd.second.GetNEntries() == 
clusterDesc.GetFirstEntryIndex())
 
  346         return cd.second.GetId();
 
 
  351std::vector<ROOT::Experimental::DescriptorId_t>
 
  356   std::vector<DescriptorId_t> 
fields;
 
 
  365   for (
unsigned int i = 0; 
true; ++i) {
 
 
  401   std::vector<std::uint64_t> 
result;
 
  402   unsigned int base = 0;
 
  403   std::uint64_t flags = 0;
 
  405      if ((
f > 0) && ((
f % 64) == 0))
 
  407      while (
f > base + 64) {
 
  408         result.emplace_back(flags);
 
  415   result.emplace_back(flags);
 
 
  425      return R__FAIL(
"invalid attempt to add details of unknown cluster group");
 
  426   if (iter->second.HasClusterDetails())
 
  427      return R__FAIL(
"invalid attempt to re-populate cluster group details");
 
  429      return R__FAIL(
"mismatch of number of clusters");
 
  436         return R__FAIL(
"invalid attempt to re-populate existing cluster");
 
  441   iter->second = 
cgBuilder.MoveDescriptor().Unwrap();
 
 
  450      return R__FAIL(
"invalid attempt to drop cluster details of unknown cluster group");
 
  451   if (!iter->second.HasClusterDetails())
 
  452      return R__FAIL(
"invalid attempt to drop details of cluster group summary");
 
  454   for (
auto clusterId : iter->second.GetClusterIds())
 
  456   iter->second = iter->second.CloneSummary();
 
 
  462   auto fieldZero = std::make_unique<RFieldZero>();
 
  466      model->AddField(
topDesc.CreateField(*
this));
 
 
  473   auto clone = std::make_unique<RNTupleDescriptor>();
 
  484      clone->fFieldDescriptors.emplace(
d.first, 
d.second.Clone());
 
  486      clone->fColumnDescriptors.emplace(
d.first, 
d.second.Clone());
 
  488      clone->fClusterGroupDescriptors.emplace(
d.first, 
d.second.Clone());
 
  490      clone->fClusterDescriptors.emplace(
d.first, 
d.second.Clone());
 
 
  500   return fColumnGroupId == 
other.fColumnGroupId && fPhysicalColumnIds == 
other.fPhysicalColumnIds;
 
 
  507   return fClusterGroupId == 
other.fClusterGroupId && fClusterIds == 
other.fClusterIds &&
 
 
  514   clone.fClusterGroupId = fClusterGroupId;
 
  515   clone.fPageListLocator = fPageListLocator;
 
  516   clone.fPageListLength = fPageListLength;
 
  517   clone.fMinEntry = fMinEntry;
 
  518   clone.fEntrySpan = fEntrySpan;
 
 
  526   clone.fClusterIds = fClusterIds;
 
 
  537      return R__FAIL(
"column ID mismatch");
 
  538   if (fCluster.fPageRanges.count(
physicalId) > 0)
 
  539      return R__FAIL(
"column ID conflict");
 
  542   for (
const auto &pi : 
pageRange.fPageInfos) {
 
 
  575            for (const auto &c : desc.GetColumnIterable(fieldId)) {
 
  576               const DescriptorId_t physicalId = c.GetPhysicalId();
 
  577               auto &columnRange = fCluster.fColumnRanges[physicalId];
 
  578               auto &pageRange = fCluster.fPageRanges[physicalId];
 
  582               if (columnRange.fPhysicalColumnId == kInvalidDescriptorId) {
 
  583                  columnRange.fPhysicalColumnId = physicalId;
 
  584                  columnRange.fFirstElementIndex = 0;
 
  585                  columnRange.fNElements = 0;
 
  587                  pageRange.fPhysicalColumnId = physicalId;
 
  595               if (c.IsDeferredColumn()) {
 
  596                  columnRange.fFirstElementIndex = fCluster.GetFirstEntryIndex() * nRepetitions;
 
  597                  columnRange.fNElements = fCluster.GetNEntries() * nRepetitions;
 
  598                  const auto element = Internal::RColumnElementBase::Generate<void>(c.GetModel().GetType());
 
  599                  pageRange.ExtendToFitColumnRange(columnRange, *element, Internal::RPage::kPageZeroSize);
 
 
  612      return R__FAIL(
"unset cluster ID");
 
  613   if (fCluster.fNEntries == 0)
 
  614      return R__FAIL(
"empty cluster");
 
  615   for (
const auto &
pr : fCluster.fPageRanges) {
 
  616      if (fCluster.fColumnRanges.count(
pr.first) == 0) {
 
  617         return R__FAIL(
"missing column range");
 
  621   std::swap(
result, fCluster);
 
 
  645      return R__FAIL(
"unset cluster group ID");
 
  647   std::swap(
result, fClusterGroup);
 
 
  657      return R__FAIL(
"unset column group ID");
 
  659   std::swap(
result, fColumnGroup);
 
 
  668   if (fDescriptor.fFieldDescriptors.count(
fieldId) == 0)
 
  669      return R__FAIL(
"field with id '" + std::to_string(
fieldId) + 
"' doesn't exist");
 
 
  681   for (
const auto& 
key_val: fDescriptor.fFieldDescriptors) {
 
  682      const auto& 
id = 
key_val.first;
 
  683      const auto& desc = 
key_val.second;
 
  686         return R__FAIL(
"field with id '" + std::to_string(
id) + 
"' has an invalid parent id");
 
 
  695   std::swap(
result, fDescriptor);
 
 
  702   fDescriptor.fName = std::string(
name);
 
  703   fDescriptor.fDescription = std::string(
description);
 
 
  710   fDescriptor.fFeatureFlags.insert(
flag);
 
 
  717      return R__FAIL(
"invalid logical column id");
 
  719      return R__FAIL(
"invalid physical column id");
 
  721      return R__FAIL(
"invalid column model");
 
  723      return R__FAIL(
"invalid field id, dangling column");
 
  724   return fColumn.Clone();
 
 
  739      .TypeVersion(
field.GetTypeVersion())
 
  740      .FieldName(
field.GetFieldName())
 
  741      .FieldDescription(
field.GetDescription())
 
  742      .TypeName(
field.GetTypeName())
 
  743      .TypeAlias(
field.GetTypeAlias())
 
  744      .Structure(
field.GetStructure())
 
  745      .NRepetitions(
field.GetNRepetitions());
 
 
  753      return R__FAIL(
"invalid field id");
 
  756      return R__FAIL(
"invalid field structure");
 
  765   return fField.Clone();
 
 
  771   if (fDescriptor.fHeaderExtension)
 
  772      fDescriptor.fHeaderExtension->AddFieldId(
fieldDesc.GetId());
 
 
  782      return  R__FAIL(
"child field with id '" + std::to_string(
linkId) + 
"' doesn't exist in NTuple");
 
  784   if (
linkId == fDescriptor.GetFieldZeroId()) {
 
  785      return R__FAIL(
"cannot make FieldZero a child field");
 
  788   auto parentId = fDescriptor.fFieldDescriptors.at(
linkId).GetParentId();
 
  790      return R__FAIL(
"field '" + std::to_string(
linkId) + 
"' already has a parent ('" +
 
  794      return R__FAIL(
"cannot make field '" + std::to_string(
fieldId) + 
"' a child of itself");
 
  796   fDescriptor.fFieldDescriptors.at(
linkId).fParentId = 
fieldId;
 
  797   fDescriptor.fFieldDescriptors.at(
fieldId).fLinkIds.push_back(
linkId);
 
 
  814   if (!
c.IsAliasColumn())
 
  815      fDescriptor.fNPhysicalColumns++;
 
  816   if (fDescriptor.fHeaderExtension)
 
  817      fDescriptor.fHeaderExtension->AddColumn(
c.IsAliasColumn());
 
  818   fDescriptor.fColumnDescriptors.emplace(
logicalId, std::move(
c));
 
 
  831      return R__FAIL(
"column index clash");
 
  835         return R__FAIL(
"out of bounds column index");
 
  838      if (
columnDesc.GetModel() != fDescriptor.GetColumnDescriptor(
columnDesc.GetPhysicalId()).GetModel())
 
  839         return R__FAIL(
"alias column type mismatch");
 
  844      fDescriptor.fNPhysicalColumns++;
 
  846   if (fDescriptor.fHeaderExtension)
 
  847      fDescriptor.fHeaderExtension->AddColumn(
columnDesc.IsAliasColumn());
 
 
  856   if (fDescriptor.fClusterGroupDescriptors.count(
id) > 0)
 
  857      return R__FAIL(
"cluster group id clash");
 
  860   fDescriptor.fClusterGroupDescriptors.emplace(
id, std::move(
clusterGroup));
 
 
  866   fDescriptor.fName = 
"";
 
  867   fDescriptor.fDescription = 
"";
 
  868   fDescriptor.fFieldDescriptors.clear();
 
  869   fDescriptor.fColumnDescriptors.clear();
 
  870   fDescriptor.fClusterDescriptors.clear();
 
  871   fDescriptor.fClusterGroupDescriptors.clear();
 
  872   fDescriptor.fHeaderExtension.reset();
 
 
  877   if (!fDescriptor.fHeaderExtension)
 
  878      fDescriptor.fHeaderExtension = std::make_unique<RNTupleDescriptor::RHeaderExtension>();
 
 
  885   if (fDescriptor.fClusterDescriptors.count(
clusterId) > 0)
 
  886      return R__FAIL(
"cluster id clash");
 
 
#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
 
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
 
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t 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.
 
RClusterDescriptorBuilder & AddDeferredColumnRanges(const RNTupleDescriptor &desc)
Add column and page ranges for deferred columns missing in this cluster.
 
RResult< RClusterDescriptor > MoveDescriptor()
Move out the full cluster descriptor including page locations.
 
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.
 
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...
 
RResult< RColumnGroupDescriptor > MoveDescriptor()
 
A helper class for piece-wise construction of an RFieldDescriptor.
 
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()=default
Make an empty dangling field descriptor.
 
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)
 
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.
 
Meta-data for a set of ntuple clusters.
 
std::unordered_set< DescriptorId_t > GetColumnIds() const
 
RClusterDescriptor Clone() const
 
bool operator==(const RClusterDescriptor &other) const
 
std::uint64_t GetBytesOnStorage() const
 
Clusters are bundled in cluster groups.
 
RClusterGroupDescriptor Clone() const
 
RClusterGroupDescriptor CloneSummary() const
 
bool operator==(const RClusterGroupDescriptor &other) const
 
Meta-data stored for every column of an ntuple.
 
DescriptorId_t fLogicalColumnId
The actual column identifier, which is the link to the corresponding field.
 
RColumnDescriptor Clone() const
Get a copy of the descriptor.
 
bool operator==(const RColumnDescriptor &other) const
 
Meta-data for a sets of columns; non-trivial column groups are used for sharded clusters.
 
bool operator==(const RColumnGroupDescriptor &other) const
 
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.
 
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.
 
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.
 
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 fFieldDescription
Free text set by the user.
 
std::string fFieldName
The leaf name, not including parent fields.
 
std::uint32_t fFieldVersion
The version of the C++-type-to-column translation mechanics.
 
DescriptorId_t fParentId
Establishes sub field relationships, such as classes and collections.
 
RFieldDescriptor Clone() const
Get a copy of the descriptor.
 
bool operator==(const RFieldDescriptor &other) const
 
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::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
 
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
 
DescriptorId_t GetFieldZeroId() const
Returns the logical parent of all top-level NTuple data fields.
 
std::unordered_map< DescriptorId_t, RColumnDescriptor > fColumnDescriptors
 
std::unique_ptr< RNTupleDescriptor > Clone() const
 
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
 
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.
 
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...
 
const_iterator end() const
 
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.
 
Wrap the integer in a struct in order to avoid template specialization clash with std::uint64_t.