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 fModel.AddField(std::move(
field));
202 fAddedFields.emplace_back(
fieldp);
207 fOpenChangeset.AddField(std::move(
field));
217 fAddedProjectedFields.emplace_back(
fieldp);
260 return CreateBare(std::make_unique<RFieldZero>());
263std::unique_ptr<ROOT::Experimental::RNTupleModel>
267 model->fProjectedFields = std::make_unique<Internal::RProjectedFields>(*model);
273 return Create(std::make_unique<RFieldZero>());
276std::unique_ptr<ROOT::Experimental::RNTupleModel>
279 auto model = CreateBare(std::move(
fieldZero));
280 model->fDefaultEntry = std::unique_ptr<REntry>(
new REntry(model->fModelId, model->fSchemaId));
286 auto cloneModel = std::unique_ptr<RNTupleModel>(
287 new RNTupleModel(std::unique_ptr<RFieldZero>(
static_cast<RFieldZero *
>(fFieldZero->Clone(
"").release()))));
292 cloneModel->fSchemaId = fSchemaId;
294 cloneModel->fSchemaId = cloneModel->fModelId;
296 cloneModel->fModelState = (fModelState == EState::kExpired) ? EState::kFrozen : fModelState;
297 cloneModel->fFieldNames = fFieldNames;
298 cloneModel->fDescription = fDescription;
299 cloneModel->fProjectedFields = fProjectedFields->Clone(*cloneModel);
300 cloneModel->fRegisteredSubfields = fRegisteredSubfields;
302 cloneModel->fDefaultEntry = std::unique_ptr<REntry>(
new REntry(cloneModel->fModelId, cloneModel->fSchemaId));
303 for (
const auto &
f : cloneModel->fFieldZero->GetSubFields()) {
304 cloneModel->fDefaultEntry->AddValue(
f->CreateValue());
306 for (
const auto &
f : cloneModel->fRegisteredSubfields) {
307 cloneModel->AddSubfield(
f, *cloneModel->fDefaultEntry);
322 [&](
const auto *
f) { return f->GetFieldName() == subfieldName; });
339 EnsureValidFieldName(
field->GetFieldName());
342 fDefaultEntry->AddValue(
field->CreateValue());
343 fFieldNames.insert(
field->GetFieldName());
344 fFieldZero->Attach(std::move(
field));
367 if (fRegisteredSubfields.find(std::string(
qualifiedFieldName)) != fRegisteredSubfields.end())
377 auto parent =
field->GetParent();
378 while (parent && !parent->GetFieldName().empty()) {
382 "registering a subfield as part of a collection, fixed-sized array or std::variant is not supported"));
384 parent = parent->GetParent();
424 throw RException(
R__FAIL(
"invalid attempt to get mutable zero field of frozen model"));
431 throw RException(
R__FAIL(
"invalid attempt to get mutable field of frozen model"));
451 return *fDefaultEntry;
457 throw RException(
R__FAIL(
"invalid attempt to get default entry of unfrozen model"));
459 return *fDefaultEntry;
464 switch (fModelState) {
465 case EState::kBuilding:
throw RException(
R__FAIL(
"invalid attempt to create entry of unfrozen model"));
466 case EState::kExpired:
throw RException(
R__FAIL(
"invalid attempt to create entry of expired model"));
467 case EState::kFrozen:
break;
470 auto entry = std::unique_ptr<REntry>(
new REntry(fModelId, fSchemaId));
471 for (
const auto &
f : fFieldZero->GetSubFields()) {
472 entry->AddValue(
f->CreateValue());
474 for (
const auto &
f : fRegisteredSubfields) {
482 switch (fModelState) {
483 case EState::kBuilding:
throw RException(
R__FAIL(
"invalid attempt to create entry of unfrozen model"));
484 case EState::kExpired:
throw RException(
R__FAIL(
"invalid attempt to create entry of expired model"));
485 case EState::kFrozen:
break;
488 auto entry = std::unique_ptr<REntry>(
new REntry(fModelId, fSchemaId));
489 for (
const auto &
f : fFieldZero->GetSubFields()) {
490 entry->AddValue(
f->BindValue(
nullptr));
492 for (
const auto &
f : fRegisteredSubfields) {
493 AddSubfield(
f, *
entry,
false );
512 switch (fModelState) {
513 case EState::kBuilding:
throw RException(
R__FAIL(
"invalid attempt to create bulk of unfrozen model"));
514 case EState::kExpired:
throw RException(
R__FAIL(
"invalid attempt to create bulk of expired model"));
515 case EState::kFrozen:
break;
521 return f->CreateBulk();
526 switch (fModelState) {
527 case EState::kExpired:
return;
528 case EState::kBuilding:
throw RException(
R__FAIL(
"invalid attempt to expire unfrozen model"));
529 case EState::kFrozen:
break;
534 fModelState = EState::kExpired;
539 switch (fModelState) {
540 case EState::kBuilding:
return;
541 case EState::kExpired:
throw RException(
R__FAIL(
"invalid attempt to unfreeze expired model"));
542 case EState::kFrozen:
break;
546 fSchemaId = fModelId;
548 fDefaultEntry->fModelId = fModelId;
549 fDefaultEntry->fSchemaId = fSchemaId;
551 fModelState = EState::kBuilding;
556 if (fModelState == EState::kExpired)
559 fModelState = EState::kFrozen;
570 std::size_t
bytes = 0;
575 for (
auto &&
field : *fFieldZero) {
576 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 ROOT::RNTupleWriteOptions &options=ROOT::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)
An RNTuple that gets filled with entries (data) and writes them to storage.
Base class for all ROOT issued exceptions.
Common user-tunable settings for storing ntuples.
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
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
void AddField(std::unique_ptr< RFieldBase > field)
ROOT::RResult< void > AddProjectedField(std::unique_ptr< RFieldBase > field, RNTupleModel::FieldMappingFunc_t mapping)