63 return R__FAIL(
"field mapping structural mismatch: " +
source->GetFieldName() +
" --> " +
target->GetFieldName());
67 return R__FAIL(
"field mapping type mismatch: " +
source->GetFieldName() +
" --> " +
target->GetFieldName());
71 auto parent =
f.GetParent();
73 if (parent->GetNRepetitions() > 0)
75 parent = parent->GetParent();
80 return R__FAIL(
"unsupported field mapping across fixed-size arrays");
94 parent = parent->GetParent();
103 return R__FAIL(
"unsupported field mapping (source structure)");
106 return R__FAIL(
"unsupported field mapping (target structure)");
122 return R__FAIL(
"field mapping structure mismatch: " +
source->GetFieldName() +
" --> " +
target->GetFieldName());
126 return R__FAIL(
"field mapping structure mismatch: " +
source->GetFieldName() +
" --> " +
target->GetFieldName());
135 for (
const auto &
f : *
field) {
142 fFieldZero->Attach(std::move(
field));
149 if (
auto it = fFieldMap.find(
target); it != fFieldMap.end())
154std::unique_ptr<ROOT::Experimental::Internal::RProjectedFields>
162 for (
const auto &[k,
v] : fFieldMap) {
163 for (
const auto &
f : clone->GetFieldZero()) {
164 if (
f.GetQualifiedFieldName() == k->GetQualifiedFieldName()) {
165 clone->fFieldMap[&
f] = &
newModel.GetConstField(
v->GetQualifiedFieldName());
174 : fWriter(
writer), fOpenChangeset(fWriter.GetUpdatableModel())
180 fOpenChangeset.fModel.Unfreeze();
183 std::swap(fOpenChangeset.fModel.fModelId, fNewModelId);
188 fOpenChangeset.fModel.Freeze();
189 std::swap(fOpenChangeset.fModel.fModelId, fNewModelId);
190 if (fOpenChangeset.IsEmpty())
193 std::swap(fOpenChangeset.fAddedFields,
toCommit.fAddedFields);
194 std::swap(fOpenChangeset.fAddedProjectedFields,
toCommit.fAddedProjectedFields);
195 fWriter.GetSink().UpdateSchema(
toCommit, fWriter.GetNEntries());
201 fOpenChangeset.fModel.AddField(std::move(
field));
202 fOpenChangeset.fAddedFields.emplace_back(
fieldp);
211 fOpenChangeset.fAddedProjectedFields.emplace_back(
fieldp);
247 return CreateBare(std::make_unique<RFieldZero>());
250std::unique_ptr<ROOT::Experimental::RNTupleModel>
254 model->fProjectedFields = std::make_unique<Internal::RProjectedFields>(*model);
260 return Create(std::make_unique<RFieldZero>());
263std::unique_ptr<ROOT::Experimental::RNTupleModel>
266 auto model = CreateBare(std::move(
fieldZero));
267 model->fDefaultEntry = std::unique_ptr<REntry>(
new REntry(model->fModelId, model->fSchemaId));
273 auto cloneModel = std::unique_ptr<RNTupleModel>(
274 new RNTupleModel(std::unique_ptr<RFieldZero>(
static_cast<RFieldZero *
>(fFieldZero->Clone(
"").release()))));
279 cloneModel->fSchemaId = fSchemaId;
281 cloneModel->fSchemaId = cloneModel->fModelId;
283 cloneModel->fModelState = (fModelState == EState::kExpired) ? EState::kFrozen : fModelState;
284 cloneModel->fFieldNames = fFieldNames;
285 cloneModel->fDescription = fDescription;
286 cloneModel->fProjectedFields = fProjectedFields->Clone(*cloneModel);
287 cloneModel->fRegisteredSubfields = fRegisteredSubfields;
289 cloneModel->fDefaultEntry = std::unique_ptr<REntry>(
new REntry(cloneModel->fModelId, cloneModel->fSchemaId));
290 for (
const auto &
f : cloneModel->fFieldZero->GetSubFields()) {
291 cloneModel->fDefaultEntry->AddValue(
f->CreateValue());
293 for (
const auto &
f : cloneModel->fRegisteredSubfields) {
294 cloneModel->AddSubfield(
f, *cloneModel->fDefaultEntry);
309 [&](
const auto *
f) { return f->GetFieldName() == subfieldName; });
326 EnsureValidFieldName(
field->GetFieldName());
329 fDefaultEntry->AddValue(
field->CreateValue());
330 fFieldNames.insert(
field->GetFieldName());
331 fFieldZero->Attach(std::move(
field));
354 if (fRegisteredSubfields.find(std::string(
qualifiedFieldName)) != fRegisteredSubfields.end())
364 auto parent =
field->GetParent();
365 while (parent && !parent->GetFieldName().empty()) {
369 "registering a subfield as part of a collection, fixed-sized array or std::variant is not supported"));
371 parent = parent->GetParent();
411 throw RException(
R__FAIL(
"invalid attempt to get mutable zero field of frozen model"));
418 throw RException(
R__FAIL(
"invalid attempt to get mutable field of frozen model"));
438 return *fDefaultEntry;
444 throw RException(
R__FAIL(
"invalid attempt to get default entry of unfrozen model"));
446 return *fDefaultEntry;
451 switch (fModelState) {
452 case EState::kBuilding:
throw RException(
R__FAIL(
"invalid attempt to create entry of unfrozen model"));
453 case EState::kExpired:
throw RException(
R__FAIL(
"invalid attempt to create entry of expired model"));
454 case EState::kFrozen:
break;
457 auto entry = std::unique_ptr<REntry>(
new REntry(fModelId, fSchemaId));
458 for (
const auto &
f : fFieldZero->GetSubFields()) {
459 entry->AddValue(
f->CreateValue());
461 for (
const auto &
f : fRegisteredSubfields) {
469 switch (fModelState) {
470 case EState::kBuilding:
throw RException(
R__FAIL(
"invalid attempt to create entry of unfrozen model"));
471 case EState::kExpired:
throw RException(
R__FAIL(
"invalid attempt to create entry of expired model"));
472 case EState::kFrozen:
break;
475 auto entry = std::unique_ptr<REntry>(
new REntry(fModelId, fSchemaId));
476 for (
const auto &
f : fFieldZero->GetSubFields()) {
477 entry->AddValue(
f->BindValue(
nullptr));
479 for (
const auto &
f : fRegisteredSubfields) {
480 AddSubfield(
f, *
entry,
false );
499 switch (fModelState) {
500 case EState::kBuilding:
throw RException(
R__FAIL(
"invalid attempt to create bulk of unfrozen model"));
501 case EState::kExpired:
throw RException(
R__FAIL(
"invalid attempt to create bulk of expired model"));
502 case EState::kFrozen:
break;
508 return f->CreateBulk();
513 switch (fModelState) {
514 case EState::kExpired:
return;
515 case EState::kBuilding:
throw RException(
R__FAIL(
"invalid attempt to expire unfrozen model"));
516 case EState::kFrozen:
break;
521 fModelState = EState::kExpired;
526 switch (fModelState) {
527 case EState::kBuilding:
return;
528 case EState::kExpired:
throw RException(
R__FAIL(
"invalid attempt to unfreeze expired model"));
529 case EState::kFrozen:
break;
533 fSchemaId = fModelId;
535 fDefaultEntry->fModelId = fModelId;
536 fDefaultEntry->fSchemaId = fSchemaId;
538 fModelState = EState::kBuilding;
543 if (fModelState == EState::kExpired)
546 fModelState = EState::kFrozen;
557 std::size_t
bytes = 0;
562 for (
auto &&
field : *fFieldZero) {
563 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...
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
The projected fields of a RNTupleModel
RResult< void > EnsureValidMapping(const RFieldBase *target, const FieldMap_t &fieldMap)
Asserts that the passed field is a valid target of the source field provided in the field map.
std::unique_ptr< RProjectedFields > Clone(const RNTupleModel &newModel) const
The new model needs to be a clone of fModel.
std::unordered_map< const RFieldBase *, const 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< RFieldBase > field, const FieldMap_t &fieldMap)
Adds a new projected field.
const RFieldBase * GetSourceField(const RFieldBase *target) const
An artificial field that transforms an RNTuple column that contains the offset of collections into co...
The field token identifies a (sub)field in this entry.
The REntry is a collection of values in an ntuple corresponding to a complete row in the data set.
Similar to RValue but manages an array of consecutive values.
A field translates read and write calls from/to underlying columns to/from tree values.
const RFieldBase * GetParent() const
The container field for an ntuple model, which itself has no physical representation.
RResult< void > AddProjectedField(std::unique_ptr< RFieldBase > field, FieldMappingFunc_t mapping)
RUpdater(RNTupleWriter &writer)
void CommitUpdate()
Commit changes since the last call to BeginUpdate().
void BeginUpdate()
Begin a new set of alterations to the underlying model.
void AddField(std::unique_ptr< RFieldBase > field)
The RNTupleModel encapulates the schema of an ntuple.
std::unordered_set< std::string > fFieldNames
Keeps track of which field names are taken, including projected field names.
void EnsureValidFieldName(std::string_view fieldName)
Checks that user-provided field names are valid in the context of this RNTuple model.
std::uint64_t fModelId
Every model has a unique ID to distinguish it from other models.
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...
std::unique_ptr< Internal::RProjectedFields > fProjectedFields
The set of projected top-level fields.
const RFieldBase & GetConstField(std::string_view fieldName) const
std::uint64_t fSchemaId
Models have a separate schema ID to remember that the clone of a frozen model still has the same sche...
REntry::RFieldToken GetToken(std::string_view fieldName) const
Creates a token to be used in REntry methods to address a field present in the entry.
void EnsureNotBare() const
Throws an RException if fDefaultEntry is nullptr.
std::unique_ptr< RNTupleModel > Clone() const
void EnsureNotFrozen() const
Throws an RException if fFrozen is true.
RFieldZero & GetMutableFieldZero()
Mutable access to the root field is used to make adjustments to the fields.
REntry & GetDefaultEntry()
std::size_t EstimateWriteMemoryUsage(const RNTupleWriteOptions &options=RNTupleWriteOptions()) const
Estimate the memory usage for this model during writing.
std::unique_ptr< REntry > CreateBareEntry() const
In a bare entry, all values point to nullptr.
std::unique_ptr< REntry > CreateEntry() const
RFieldBase::RBulk CreateBulk(std::string_view fieldName) const
Calls the given field's CreateBulk() method. Throws an exception if no field with the given name exis...
static std::unique_ptr< RNTupleModel > Create()
void AddSubfield(std::string_view fieldName, REntry &entry, bool initializeValue=true) const
Add a subfield to the provided entry.
void SetDescription(std::string_view description)
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...
RResult< void > AddProjectedField(std::unique_ptr< RFieldBase > field, FieldMappingFunc_t mapping)
Adds a top-level field based on existing fields.
RNTupleModel(std::unique_ptr< RFieldZero > fieldZero)
RFieldBase & GetMutableField(std::string_view fieldName)
static std::unique_ptr< RNTupleModel > CreateBare()
A bare model has no default entry.
void AddField(std::unique_ptr< RFieldBase > field)
Adds a field whose type is not known at compile time.
void RegisterSubfield(std::string_view qualifiedFieldName)
Register a subfield so it can be accessed directly from entries belonging to the model.
std::unique_ptr< RFieldZero > fFieldZero
Hierarchy of fields consisting of simple types and collections (sub trees)
Common user-tunable settings for storing ntuples.
std::size_t GetPageBufferBudget() const
std::size_t GetApproxZippedClusterSize() const
bool GetUseBufferedWrite() 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.
Base class for all ROOT issued exceptions.
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...
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.
RProjectedFields & GetProjectedFieldsOfModel(RNTupleModel &model)
RFieldZero & GetFieldZeroOfModel(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