64 if (!
target->GetColumnRepresentatives()[0].empty()) {
70 <<
"calling SetQuantized() or SetTruncated() on a projected field has no effect, as the on-disk "
71 "representation of the value is decided by the projection source field. Reading back the field will "
72 "yield the correct values, but the value range and bits of precision you set on the projected field "
81 return R__FAIL(
"field mapping structural mismatch: " +
source->GetFieldName() +
" --> " +
target->GetFieldName());
85 return R__FAIL(
"field mapping type mismatch: " +
source->GetFieldName() +
" --> " +
target->GetFieldName());
89 auto parent =
f.GetParent();
91 if (parent->GetNRepetitions() > 0)
93 parent = parent->GetParent();
98 return R__FAIL(
"unsupported field mapping across fixed-size arrays");
112 parent = parent->GetParent();
121 return R__FAIL(
"unsupported field mapping (source structure)");
124 return R__FAIL(
"unsupported field mapping (target structure)");
140 return R__FAIL(
"field mapping structure mismatch: " +
source->GetFieldName() +
" --> " +
target->GetFieldName());
144 return R__FAIL(
"field mapping structure mismatch: " +
source->GetFieldName() +
" --> " +
target->GetFieldName());
153 for (
const auto &
f : *
field) {
160 fFieldZero->Attach(std::move(
field));
166 if (
auto it = fFieldMap.find(
target); it != fFieldMap.end())
171std::unique_ptr<ROOT::Internal::RProjectedFields>
175 std::unique_ptr<ROOT::RFieldZero>(
static_cast<ROOT::RFieldZero *
>(fFieldZero->Clone(
"").release()));
180 for (
const auto &[k,
v] : fFieldMap) {
181 for (
const auto &
f : clone->GetFieldZero()) {
182 if (
f.GetQualifiedFieldName() == k->GetQualifiedFieldName()) {
183 clone->fFieldMap[&
f] = &
newModel.GetConstField(
v->GetQualifiedFieldName());
192 : fWriter(
writer), fOpenChangeset(fWriter.GetUpdatableModel())
198 fOpenChangeset.fModel.Unfreeze();
201 std::swap(fOpenChangeset.fModel.fModelId, fNewModelId);
206 fOpenChangeset.fModel.Freeze();
207 std::swap(fOpenChangeset.fModel.fModelId, fNewModelId);
208 if (fOpenChangeset.IsEmpty())
211 std::swap(fOpenChangeset.fAddedFields,
toCommit.fAddedFields);
212 std::swap(fOpenChangeset.fAddedProjectedFields,
toCommit.fAddedProjectedFields);
213 fWriter.GetSink().UpdateSchema(
toCommit, fWriter.GetNEntries());
219 fModel.AddField(std::move(
field));
220 fAddedFields.emplace_back(
fieldp);
225 fOpenChangeset.AddField(std::move(
field));
234 fAddedProjectedFields.emplace_back(
fieldp);
277 return CreateBare(std::make_unique<ROOT::RFieldZero>());
283 model->fProjectedFields = std::make_unique<Internal::RProjectedFields>(*model);
289 return Create(std::make_unique<ROOT::RFieldZero>());
294 auto model = CreateBare(std::move(
fieldZero));
295 model->fDefaultEntry = std::unique_ptr<ROOT::REntry>(
new ROOT::REntry(model->fModelId, model->fSchemaId));
301 auto cloneModel = std::unique_ptr<RNTupleModel>(
new RNTupleModel(
302 std::unique_ptr<ROOT::RFieldZero>(
static_cast<ROOT::RFieldZero *
>(fFieldZero->Clone(
"").release()))));
307 cloneModel->fSchemaId = fSchemaId;
309 cloneModel->fSchemaId = cloneModel->fModelId;
311 cloneModel->fModelState = (fModelState == EState::kExpired) ? EState::kFrozen : fModelState;
312 cloneModel->fFieldNames = fFieldNames;
313 cloneModel->fDescription = fDescription;
314 cloneModel->fProjectedFields = fProjectedFields->Clone(*cloneModel);
315 cloneModel->fRegisteredSubfields = fRegisteredSubfields;
317 cloneModel->fDefaultEntry =
318 std::unique_ptr<ROOT::REntry>(
new ROOT::REntry(cloneModel->fModelId, cloneModel->fSchemaId));
319 for (
const auto &
f : cloneModel->fFieldZero->GetMutableSubfields()) {
320 cloneModel->fDefaultEntry->AddValue(
f->CreateValue());
322 for (
const auto &
f : cloneModel->fRegisteredSubfields) {
323 cloneModel->AddSubfield(
f, *cloneModel->fDefaultEntry);
338 [&](
const auto *
f) { return f->GetFieldName() == subfieldName; });
355 EnsureValidFieldName(
field->GetFieldName());
358 fDefaultEntry->AddValue(
field->CreateValue());
359 fFieldNames.insert(
field->GetFieldName());
360 fFieldZero->Attach(std::move(
field));
383 if (fRegisteredSubfields.find(std::string(
qualifiedFieldName)) != fRegisteredSubfields.end())
393 auto parent =
field->GetParent();
394 while (parent && !parent->GetFieldName().empty()) {
398 "registering a subfield as part of a collection, fixed-sized array or std::variant is not supported"));
400 parent = parent->GetParent();
440 throw RException(
R__FAIL(
"invalid attempt to get mutable zero field of frozen model"));
447 throw RException(
R__FAIL(
"invalid attempt to get mutable field of frozen model"));
467 return *fDefaultEntry;
473 throw RException(
R__FAIL(
"invalid attempt to get default entry of unfrozen model"));
475 return *fDefaultEntry;
480 switch (fModelState) {
481 case EState::kBuilding:
throw RException(
R__FAIL(
"invalid attempt to create entry of unfrozen model"));
482 case EState::kExpired:
throw RException(
R__FAIL(
"invalid attempt to create entry of expired model"));
483 case EState::kFrozen:
break;
486 auto entry = std::unique_ptr<ROOT::REntry>(
new ROOT::REntry(fModelId, fSchemaId));
487 for (
const auto &
f : fFieldZero->GetMutableSubfields()) {
488 entry->AddValue(
f->CreateValue());
490 for (
const auto &
f : fRegisteredSubfields) {
498 switch (fModelState) {
499 case EState::kBuilding:
throw RException(
R__FAIL(
"invalid attempt to create entry of unfrozen model"));
500 case EState::kExpired:
throw RException(
R__FAIL(
"invalid attempt to create entry of expired model"));
501 case EState::kFrozen:
break;
504 auto entry = std::unique_ptr<ROOT::REntry>(
new ROOT::REntry(fModelId, fSchemaId));
505 for (
const auto &
f : fFieldZero->GetMutableSubfields()) {
506 entry->AddValue(
f->BindValue(
nullptr));
508 for (
const auto &
f : fRegisteredSubfields) {
509 AddSubfield(
f, *
entry,
false );
516 switch (fModelState) {
517 case EState::kBuilding:
throw RException(
R__FAIL(
"invalid attempt to create entry of unfrozen model"));
518 case EState::kExpired:
throw RException(
R__FAIL(
"invalid attempt to create entry of expired model"));
519 case EState::kFrozen:
break;
523 for (
const auto &
f : fFieldZero->GetMutableSubfields()) {
544 switch (fModelState) {
545 case EState::kBuilding:
throw RException(
R__FAIL(
"invalid attempt to create bulk of unfrozen model"));
546 case EState::kExpired:
throw RException(
R__FAIL(
"invalid attempt to create bulk of expired model"));
547 case EState::kFrozen:
break;
553 return f->CreateBulk();
558 switch (fModelState) {
559 case EState::kExpired:
return;
560 case EState::kBuilding:
throw RException(
R__FAIL(
"invalid attempt to expire unfrozen model"));
561 case EState::kFrozen:
break;
566 fModelState = EState::kExpired;
571 switch (fModelState) {
572 case EState::kBuilding:
return;
573 case EState::kExpired:
throw RException(
R__FAIL(
"invalid attempt to unfreeze expired model"));
574 case EState::kFrozen:
break;
578 fSchemaId = fModelId;
580 fDefaultEntry->fModelId = fModelId;
581 fDefaultEntry->fSchemaId = fSchemaId;
583 fModelState = EState::kBuilding;
588 if (fModelState == EState::kExpired)
591 fModelState = EState::kFrozen;
602 std::size_t
bytes = 0;
607 for (
auto &&
field : *fFieldZero) {
608 for (
const auto &
r :
field.GetColumnRepresentatives()) {
#define R__FORWARD_ERROR(res)
Short-hand to return an RResult<T> in an error state (i.e. after checking)
#define R__FORWARD_RESULT(res)
Short-hand to return an RResult<T> value from a subroutine to the calling stack frame.
#define R__FAIL(msg)
Short-hand to return an RResult<T> in an error state; the RError is implicitly converted into RResult...
#define R__LOG_WARNING(...)
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 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 Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t target
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 r
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 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 Atom_t Int_t ULong_t ULong_t bytes
A container of const raw pointers, corresponding to a row in the data set.
Container for the projected fields of an RNTupleModel.
const ROOT::RFieldBase * GetSourceField(const ROOT::RFieldBase *target) const
std::unordered_map< const ROOT::RFieldBase *, const ROOT::RFieldBase * > FieldMap_t
The map keys are the projected target fields, the map values are the backing source fields Note that ...
RResult< void > Add(std::unique_ptr< ROOT::RFieldBase > field, const FieldMap_t &fieldMap)
Adds a new projected field.
std::unique_ptr< RProjectedFields > Clone(const RNTupleModel &newModel) const
Clones this container and all the projected fields it owns.
RResult< void > EnsureValidMapping(const ROOT::RFieldBase *target, const FieldMap_t &fieldMap)
Asserts that the passed field is a valid target of the source field provided in the field map.
An artificial field that transforms an RNTuple column that contains the offset of collections into co...
The REntry is a collection of values in an RNTuple corresponding to a complete row in the data set.
Base class for all ROOT issued exceptions.
Points to an array of objects with RNTuple I/O support, used for bulk reading.
A field translates read and write calls from/to underlying columns to/from tree values.
const RFieldBase * GetParent() const
A field token identifies a (sub)field in an entry.
The container field for an ntuple model, which itself has no physical representation.
void CommitUpdate()
Commit changes since the last call to BeginUpdate().
RResult< void > AddProjectedField(std::unique_ptr< ROOT::RFieldBase > field, FieldMappingFunc_t mapping)
RUpdater(ROOT::RNTupleWriter &writer)
void AddField(std::unique_ptr< ROOT::RFieldBase > field)
void BeginUpdate()
Begin a new set of alterations to the underlying model.
The RNTupleModel encapulates the schema of an RNTuple.
std::unique_ptr< REntry > CreateEntry() const
Creates a new entry with default values for each field.
RNTupleModel(std::unique_ptr< ROOT::RFieldZero > fieldZero)
void AddSubfield(std::string_view fieldName, ROOT::REntry &entry, bool initializeValue=true) const
Add a subfield to the provided entry.
std::unique_ptr< RNTupleModel > Clone() const
std::uint64_t fModelId
Every model has a unique ID to distinguish it from other models.
void EnsureValidFieldName(std::string_view fieldName)
Checks that user-provided field names are valid in the context of this RNTupleModel.
ROOT::RFieldZero & GetMutableFieldZero()
Retrieves the field zero of this model, i.e.
std::size_t EstimateWriteMemoryUsage(const ROOT::RNTupleWriteOptions &options=ROOT::RNTupleWriteOptions()) const
Estimate the memory usage for this model during writing.
void Unfreeze()
Transitions an RNTupleModel from the frozen state back to the building state, invalidating all previo...
REntry & GetDefaultEntry()
Retrieves the default entry of this model.
ROOT::RFieldBase::RBulkValues CreateBulk(std::string_view fieldName) const
Calls the given field's CreateBulk() method. Throws an RException if no field with the given name exi...
void EnsureNotFrozen() const
Throws an RException if fFrozen is true.
void AddField(std::unique_ptr< ROOT::RFieldBase > field)
Adds a field whose type is not known at compile time.
static std::unique_ptr< RNTupleModel > Create()
void SetDescription(std::string_view description)
std::unique_ptr< Internal::RProjectedFields > fProjectedFields
The set of projected top-level fields.
std::unique_ptr< Detail::RRawPtrWriteEntry > CreateRawPtrWriteEntry() const
RResult< void > AddProjectedField(std::unique_ptr< ROOT::RFieldBase > field, FieldMappingFunc_t mapping)
Adds a top-level field based on existing fields.
ROOT::RFieldToken GetToken(std::string_view fieldName) const
Creates a token to be used in REntry methods to address a field present in the entry.
std::unordered_set< std::string > fFieldNames
Keeps track of which field names are taken, including projected field names.
std::unique_ptr< ROOT::RFieldZero > fFieldZero
Hierarchy of fields consisting of simple types and collections (sub trees)
void EnsureNotBare() const
Throws an RException if fDefaultEntry is nullptr.
void RegisterSubfield(std::string_view qualifiedFieldName)
Register a subfield so it can be accessed directly from entries belonging to the model.
ROOT::RFieldBase * FindField(std::string_view fieldName) const
The field name can be a top-level field or a nested field. Returns nullptr if the field is not in the...
void Freeze()
Transitions an RNTupleModel from the building state to the frozen state, disabling adding additional ...
ROOT::RFieldBase & GetMutableField(std::string_view fieldName)
Retrieves the field with fully-qualified name fieldName.
static std::unique_ptr< RNTupleModel > CreateBare()
Creates a "bare model", i.e. an RNTupleModel with no default entry.
std::function< std::string(const std::string &)> FieldMappingFunc_t
User-provided function that describes the mapping of existing source fields to projected fields in te...
void Expire()
Transitions an RNTupleModel from the frozen state to the expired state, invalidating all previously c...
std::uint64_t fSchemaId
Models have a separate schema ID to remember that the clone of a frozen model still has the same sche...
const ROOT::RFieldBase & GetConstField(std::string_view fieldName) const
std::unique_ptr< REntry > CreateBareEntry() const
Creates a "bare entry", i.e.
Common user-tunable settings for storing RNTuples.
bool GetUseBufferedWrite() const
std::size_t GetPageBufferBudget() const
std::size_t GetApproxZippedClusterSize() const
std::size_t GetMaxUnzippedPageSize() const
std::uint32_t GetCompression() const
EImplicitMT GetUseImplicitMT() const
std::size_t GetInitialUnzippedPageSize() const
An RNTuple that gets filled with entries (data) and writes them to storage.
const_iterator begin() const
const_iterator end() const
The class is used as a return type for operations that can fail; wraps a value of type T or an RError...
ROOT::RFieldZero & GetFieldZeroOfModel(RNTupleModel &model)
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.
ROOT::RLogChannel & NTupleLog()
Log channel for RNTuple diagnostics.
RProjectedFields & GetProjectedFieldsOfModel(RNTupleModel &model)
std::vector< std::string > Split(std::string_view str, std::string_view delims, bool skipEmpty=false)
Splits a string at each character in delims.
The incremental changes to a RNTupleModel
void AddField(std::unique_ptr< ROOT::RFieldBase > field)
ROOT::RResult< void > AddProjectedField(std::unique_ptr< ROOT::RFieldBase > field, RNTupleModel::FieldMappingFunc_t mapping)