22class CreateContextGuard;
24 friend class CreateContextGuard;
26 std::vector<std::string> fClassesOnStack;
29 bool fContinueOnError =
false;
32 CreateContext() =
default;
37class CreateContextGuard {
38 CreateContext &fCreateContext;
39 std::size_t fNOriginalClassesOnStack;
40 bool fOriginalContinueOnError;
43 CreateContextGuard(CreateContext &ctx)
44 : fCreateContext(ctx),
45 fNOriginalClassesOnStack(ctx.fClassesOnStack.
size()),
46 fOriginalContinueOnError(ctx.fContinueOnError)
51 fCreateContext.fClassesOnStack.resize(fNOriginalClassesOnStack);
52 fCreateContext.fContinueOnError = fOriginalContinueOnError;
57 if (std::find(fCreateContext.fClassesOnStack.begin(), fCreateContext.fClassesOnStack.end(), cl) !=
58 fCreateContext.fClassesOnStack.end()) {
61 fCreateContext.fClassesOnStack.emplace_back(cl);
75 field.CommitCluster();
124 : fField(
other.fField),
126 fCapacity(
other.fCapacity),
128 fIsAdopted(
other.fIsAdopted),
129 fNValidValues(
other.fNValidValues),
130 fFirstIndex(
other.fFirstIndex)
139 std::swap(fField,
other.fField);
140 std::swap(fDeleter,
other.fDeleter);
141 std::swap(fValues,
other.fValues);
143 std::swap(fCapacity,
other.fCapacity);
145 std::swap(fIsAdopted,
other.fIsAdopted);
146 std::swap(fMaskAvail,
other.fMaskAvail);
147 std::swap(fNValidValues,
other.fNValidValues);
148 std::swap(fFirstIndex,
other.fFirstIndex);
164 for (std::size_t i = 0; i < fCapacity; ++i) {
165 fDeleter->operator()(GetValuePtrAt(i),
true );
169 operator delete(fValues);
174 if (fCapacity <
size) {
176 throw RException(
R__FAIL(
"invalid attempt to bulk read beyond the adopted buffer"));
182 for (std::size_t i = 0; i <
size; ++i) {
183 fField->ConstructValue(GetValuePtrAt(i));
187 fMaskAvail = std::make_unique<bool[]>(
size);
191 std::fill(fMaskAvail.get(), fMaskAvail.get() +
size,
false);
201 for (std::size_t i = 0; i <
fSize; ++i)
202 fNValidValues +=
static_cast<std::size_t
>(fMaskAvail[i]);
209 fCapacity = capacity;
212 fMaskAvail = std::make_unique<bool[]>(capacity);
227std::unique_ptr<void, typename ROOT::RFieldBase::RCreateObjectDeleter<void>::deleter>
228ROOT::RFieldBase::CreateObject<void>()
const
252 std::string
result = GetFieldName();
253 auto parent = GetParent();
254 while (parent && !parent->GetFieldName().empty()) {
256 parent = parent->GetParent();
268std::vector<ROOT::RFieldBase::RCheckResult>
273 cfOpts.SetReturnInvalidOnError(
true);
274 cfOpts.SetEmulateUnknownTypes(
false);
277 std::vector<RCheckResult>
result;
320 std::unique_ptr<ROOT::RFieldBase>
result;
336 for (
int i =
arraySizes.size() - 1; i >= 0; --i) {
380 }
else if (
resolvedType.substr(0, 12) ==
"std::vector<") {
384 }
else if (
resolvedType.substr(0, 19) ==
"ROOT::VecOps::RVec<") {
388 }
else if (
resolvedType.substr(0, 11) ==
"std::array<") {
396 }
else if (
resolvedType.substr(0, 13) ==
"std::variant<") {
398 std::vector<std::unique_ptr<RFieldBase>>
items;
400 for (
unsigned int i = 0; i <
innerTypes.size(); ++i) {
405 }
else if (
resolvedType.substr(0, 10) ==
"std::pair<") {
410 std::array<std::unique_ptr<RFieldBase>, 2>
items{
414 }
else if (
resolvedType.substr(0, 11) ==
"std::tuple<") {
416 std::vector<std::unique_ptr<RFieldBase>>
items;
418 for (
unsigned int i = 0; i <
innerTypes.size(); ++i) {
423 }
else if (
resolvedType.substr(0, 12) ==
"std::bitset<") {
426 }
else if (
resolvedType.substr(0, 16) ==
"std::unique_ptr<") {
432 }
else if (
resolvedType.substr(0, 14) ==
"std::optional<") {
444 }
else if (
resolvedType.substr(0, 19) ==
"std::unordered_set<") {
450 }
else if (
resolvedType.substr(0, 14) ==
"std::multiset<") {
456 }
else if (
resolvedType.substr(0, 24) ==
"std::unordered_multiset<") {
479 }
else if (
resolvedType.substr(0, 19) ==
"std::unordered_map<") {
493 result = std::make_unique<RMapField>(
495 }
else if (
resolvedType.substr(0, 14) ==
"std::multimap<") {
511 }
else if (
resolvedType.substr(0, 24) ==
"std::unordered_multimap<") {
515 fnFail(
"the type list for std::unordered_multimap must have exactly two elements"));
526 result = std::make_unique<RMapField>(
528 }
else if (
resolvedType.substr(0, 12) ==
"std::atomic<") {
534 }
else if (
resolvedType.substr(0, 25) ==
"ROOT::RNTupleCardinality<") {
540 result = std::make_unique<RField<RNTupleCardinality<std::uint32_t>>>(
fieldName);
542 result = std::make_unique<RField<RNTupleCardinality<std::uint64_t>>>(
fieldName);
563 if (cl->GetCollectionProxy()) {
564 result = std::make_unique<RProxiedCollectionField>(
fieldName, typeName);
591 }
catch (RException &
e) {
592 auto error =
e.GetError();
594 return std::unique_ptr<RFieldBase>(std::make_unique<RInvalidField>(
fieldName, typeName, error.GetReport(),
599 }
catch (std::logic_error &
e) {
602 return std::unique_ptr<RFieldBase>(
627 auto clone = CloneImpl(
newName);
628 clone->fTypeAlias = fTypeAlias;
629 clone->fOnDiskId = fOnDiskId;
630 clone->fDescription = fDescription;
632 clone->fColumnRepresentatives = fColumnRepresentatives;
638 R__ASSERT(
false &&
"A non-simple RField must implement its own AppendImpl");
649 ReadGlobalImpl(fPrincipalColumn->GetGlobalIndex(
localIndex), to);
655 std::size_t
nRead = 0;
656 for (std::size_t i = 0; i <
bulkSpec.fCount; ++i) {
674 void *
where =
operator new(GetValueSize());
676 ConstructValue(
where);
682 void *obj = CreateObjectRawPtr();
688 return std::vector<RValue>();
695 if (fState != EState::kUnconnected)
696 throw RException(
R__FAIL(
"invalid attempt to attach subfield to already connected field"));
697 child->fParent =
this;
698 fSubfields.emplace_back(std::move(
child));
704 for (
auto f =
this;
f !=
nullptr;
f =
f->GetParent()) {
705 auto parent =
f->GetParent();
710 result *= std::max(
f->GetNRepetitions(), std::size_t{1U});
717 std::vector<RFieldBase *>
result;
718 result.reserve(fSubfields.size());
719 for (
const auto &
f : fSubfields) {
727 std::vector<const RFieldBase *>
result;
728 result.reserve(fSubfields.size());
729 for (
const auto &
f : fSubfields) {
737 if (!fAvailableColumns.empty()) {
739 for (
auto &column : fAvailableColumns) {
749 if (!fAvailableColumns.empty()) {
751 for (
auto &column : fAvailableColumns) {
755 column->CommitSuppressed();
764 if (fState != EState::kUnconnected)
765 throw RException(
R__FAIL(
"cannot set field description once field is connected"));
771 if (fState != EState::kUnconnected)
780 if (~fTraits & kTraitMappable)
781 return AppendImpl(from);
783 fPrincipalColumn->Append(from);
784 return fPrincipalColumn->GetElement()->GetPackedSize();
803 return RBulkSpec::kAllSet;
841 if (fColumnRepresentatives.empty()) {
842 return {GetColumnRepresentations().GetSerializationDefault()};
846 result.reserve(fColumnRepresentatives.size());
847 for (
const auto &
r : fColumnRepresentatives) {
855 if (fState != EState::kUnconnected)
856 throw RException(
R__FAIL(
"cannot set column representative once field is connected"));
857 const auto &
validTypes = GetColumnRepresentations().GetSerializationTypes();
858 fColumnRepresentatives.clear();
866 if (std::find_if(fColumnRepresentatives.begin(), fColumnRepresentatives.end(),
867 [&
r](
const auto &
rep) { return r == rep.get(); }) == fColumnRepresentatives.end())
879 throw RException(
R__FAIL(
"No on-disk field information for `" + GetQualifiedFieldName() +
"`"));
888 throw RException(
R__FAIL(
"No on-disk column information for field `" + GetQualifiedFieldName() +
"`"));
893 for (
const auto &t : GetColumnRepresentations().GetDeserializationTypes()) {
905 "` cannot be matched to its in-memory type `" + GetTypeName() +
"` " +
911 fReadCallbacks.push_back(func);
913 return fReadCallbacks.size() - 1;
918 fReadCallbacks.erase(fReadCallbacks.begin() + idx);
919 fIsSimple = (fTraits & kTraitMappable) && !fIsArtificial && fReadCallbacks.empty();
924 if ((options.
GetCompression() == 0) && HasDefaultColumnRepresentative()) {
941 SetColumnRepresentatives({
rep});
944 if (fTypeAlias ==
"Double32_t")
952 if (fState != EState::kUnconnected)
953 throw RException(
R__FAIL(
"invalid attempt to connect an already connected field to a page sink"));
955 AutoAdjustColumnTypes(
pageSink.GetWriteOptions());
958 for (
auto &column : fAvailableColumns) {
966 if (HasExtraTypeInfo()) {
967 pageSink.RegisterOnCommitDatasetCallback(
971 fState = EState::kConnectedToSink;
977 throw RException(
R__FAIL(
"invalid attempt to connect zero field to page source"));
978 if (fState != EState::kUnconnected)
979 throw RException(
R__FAIL(
"invalid attempt to connect an already connected field to a page source"));
981 if (!fColumnRepresentatives.empty())
982 throw RException(
R__FAIL(
"fixed column representative only valid when connecting to a page sink"));
983 if (!fDescription.empty())
984 throw RException(
R__FAIL(
"setting description only valid when connecting to a page sink"));
988 for (
auto &
f : fSubfields) {
990 f->SetOnDiskId(
pageSource.GetSharedDescriptorGuard()->FindFieldId(
f->GetFieldName(), GetOnDiskId()));
996 if (!fIsArtificial) {
999 GenerateColumns(desc);
1000 if (fColumnRepresentatives.empty()) {
1002 for (
const auto &t : GetColumnRepresentations().GetDeserializationTypes()) {
1004 fColumnRepresentatives = {t};
1009 R__ASSERT(!fColumnRepresentatives.empty());
1012 fOnDiskTypeVersion =
fieldDesc.GetTypeVersion();
1013 if (
fieldDesc.GetTypeChecksum().has_value())
1014 fOnDiskTypeChecksum = *
fieldDesc.GetTypeChecksum();
1017 for (
auto &column : fAvailableColumns)
1018 column->ConnectPageSource(fOnDiskId,
pageSource);
1020 AfterConnectPageSource();
1022 fState = EState::kConnectedToSource;
#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(...)
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
#define R__ASSERT(e)
Checks condition e and reports a fatal error if it's false.
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 id
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 child
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
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 Atom_t Time_t type
Abstract base class for classes implementing the visitor design pattern.
static const char * GetColumnTypeName(ROOT::ENTupleColumnType type)
Abstract interface to write data into an ntuple.
Abstract interface to read data from an ntuple.
Base class for all ROOT issued exceptions.
Points to an array of objects with RNTuple I/O support, used for bulk reading.
std::unique_ptr< bool[]> fMaskAvail
Masks invalid values in the array.
std::unique_ptr< RFieldBase::RDeleter > fDeleter
void Reset(RNTupleLocalIndex firstIndex, std::size_t size)
Sets a new range for the bulk.
void * fValues
Cached deleter of fField.
RBulkValues & operator=(const RBulkValues &)=delete
RBulkValues(RFieldBase *field)
void AdoptBuffer(void *buf, std::size_t capacity)
The list of column representations a field can have.
Selection_t fSerializationTypes
std::vector< ColumnRepresentation_t > Selection_t
A list of column representations.
Selection_t fDeserializationTypes
The union of the serialization types and the deserialization extra types passed during construction.
Points to an object with RNTuple I/O support and keeps a pointer to the corresponding field.
void BindRawPtr(void *rawPtr)
A field translates read and write calls from/to underlying columns to/from tree values.
void SetColumnRepresentatives(const RColumnRepresentations::Selection_t &representatives)
Fixes a column representative.
ROOT::Internal::RColumn * fPrincipalColumn
All fields that have columns have a distinct main column.
ROOT::NTupleSize_t EntryToColumnElementIndex(ROOT::NTupleSize_t globalIndex) const
Translate an entry index to a column element index of the principal column and vice versa.
void Attach(std::unique_ptr< RFieldBase > child)
Add a new subfield to the list of nested fields.
virtual void AcceptVisitor(ROOT::Detail::RFieldVisitor &visitor) const
void FlushColumns()
Flushes data from active columns.
virtual void ReadGlobalImpl(ROOT::NTupleSize_t globalIndex, void *to)
virtual const RColumnRepresentations & GetColumnRepresentations() const
Implementations in derived classes should return a static RColumnRepresentations object.
bool fIsSimple
A field qualifies as simple if it is mappable (which implies it has a single principal column),...
RConstSchemaIterator cbegin() const
void AutoAdjustColumnTypes(const ROOT::RNTupleWriteOptions &options)
When connecting a field to a page sink, the field's default column representation is subject to adjus...
std::vector< const RFieldBase * > GetConstSubfields() const
void SetOnDiskId(ROOT::DescriptorId_t id)
void RemoveReadCallback(size_t idx)
std::vector< RFieldBase * > GetMutableSubfields()
static std::vector< RCheckResult > Check(const std::string &fieldName, const std::string &typeName)
Checks if the given type is supported by RNTuple.
size_t AddReadCallback(ReadCallback_t func)
Set a user-defined function to be called after reading a value, giving a chance to inspect and/or mod...
RConstSchemaIterator cend() const
std::size_t fNRepetitions
For fixed sized arrays, the array length.
std::function< void(void *)> ReadCallback_t
std::size_t Append(const void *from)
Write the given value into columns.
RValue CreateValue()
Generates an object of the field's type, wraps it in a shared pointer and returns it as an RValue con...
const ColumnRepresentation_t & EnsureCompatibleColumnTypes(const ROOT::RNTupleDescriptor &desc, std::uint16_t representationIndex) const
Returns the on-disk column types found in the provided descriptor for fOnDiskId and the given represe...
virtual std::vector< RValue > SplitValue(const RValue &value) const
Creates the list of direct child values given an existing value for this field.
std::string GetQualifiedFieldName() const
Returns the field name and parent field names separated by dots (grandparent.parent....
RBulkValues CreateBulk()
Creates a new, initially empty bulk.
void ConnectPageSink(ROOT::Internal::RPageSink &pageSink, ROOT::NTupleSize_t firstEntry=0)
Fields and their columns live in the void until connected to a physical page storage.
std::size_t ReadBulk(const RBulkSpec &bulkSpec)
Returns the number of newly available values, that is the number of bools in bulkSpec....
std::vector< ROOT::ENTupleColumnType > ColumnRepresentation_t
virtual void ReadInClusterImpl(RNTupleLocalIndex localIndex, void *to)
std::uint32_t fTraits
Properties of the type that allow for optimizations of collections of that type.
virtual std::size_t AppendImpl(const void *from)
Operations on values of complex types, e.g.
RFieldBase * fParent
Subfields point to their mother field.
RFieldBase(std::string_view name, std::string_view type, ROOT::ENTupleStructure structure, bool isSimple, std::size_t nRepetitions=0)
The constructor creates the underlying column objects and connects them to either a sink or a source.
@ kTraitTriviallyDestructible
The type is cleaned up just by freeing its memory. I.e. the destructor performs a no-op.
@ kTraitTriviallyConstructible
No constructor needs to be called, i.e.
@ kTraitMappable
A field of a fundamental type that can be directly mapped via RField<T>::Map(), i....
@ kTraitInvalidField
This field is an instance of RInvalidField and can be safely static_cast to it.
static RResult< std::unique_ptr< RFieldBase > > Create(const std::string &fieldName, const std::string &typeName, const ROOT::RCreateFieldOptions &options, const ROOT::RNTupleDescriptor *desc, ROOT::DescriptorId_t fieldId)
Factory method to resurrect a field from the stored on-disk type information.
std::string fType
The C++ type captured by this field.
RColumnRepresentations::Selection_t GetColumnRepresentatives() const
Returns the fColumnRepresentative pointee or, if unset (always the case for artificial fields),...
ROOT::ENTupleStructure fStructure
The role of this field in the data model structure.
RValue BindValue(std::shared_ptr< void > objPtr)
Creates a value from a memory location with an already constructed object.
void SetDescription(std::string_view description)
std::unique_ptr< RFieldBase > Clone(std::string_view newName) const
Copies the field and its subfields using a possibly new name and a new, unconnected set of columns.
std::string fName
The field name relative to its parent field.
void CommitCluster()
Flushes data from active columns to disk and calls CommitClusterImpl()
void ConnectPageSource(ROOT::Internal::RPageSource &pageSource)
Connects the field and its subfield tree to the given page source.
void * CreateObjectRawPtr() const
Factory method for the field's type. The caller owns the returned pointer.
virtual std::size_t ReadBulkImpl(const RBulkSpec &bulkSpec)
General implementation of bulk read.
The container field for an ntuple model, which itself has no physical representation.
Used in RFieldBase::Check() to record field creation failures.
@ kGeneric
Generic unrecoverable error.
@ kUnknownType
The type given to RFieldBase::Create was unknown.
@ kTypeError
The type given to RFieldBase::Create was invalid.
The on-storage metadata of an RNTuple.
const RFieldDescriptor & GetFieldDescriptor(ROOT::DescriptorId_t fieldId) const
RColumnDescriptorIterable GetColumnIterable() const
Addresses a column element or field item relative to a particular cluster, instead of a global NTuple...
Common user-tunable settings for storing RNTuples.
std::uint32_t GetCompression() 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...
static TClass * GetClass(const char *name, Bool_t load=kTRUE, Bool_t silent=kFALSE)
Static method returning pointer to TClass of the specified class name.
static TEnum * GetEnum(const std::type_info &ti, ESearchAction sa=kALoadAndInterpLookup)
std::tuple< std::string, std::vector< std::size_t > > ParseArrayType(const std::string &typeName)
Parse a type name of the form T[n][m]... and return the base type T and a vector that contains,...
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.
void CallCommitClusterOnField(RFieldBase &)
void CallConnectPageSourceOnField(RFieldBase &, ROOT::Internal::RPageSource &)
unsigned long long ParseUIntTypeToken(const std::string &uintToken)
ROOT::RResult< std::unique_ptr< ROOT::RFieldBase > > CallFieldBaseCreate(const std::string &fieldName, const std::string &typeName, const ROOT::RCreateFieldOptions &options, const ROOT::RNTupleDescriptor *desc, ROOT::DescriptorId_t fieldId)
ERNTupleSerializationMode GetRNTupleSerializationMode(TClass *cl)
auto MakeAliasedSharedPtr(T *rawPtr)
std::string GetCanonicalTypePrefix(const std::string &typeName)
Applies RNTuple specific type name normalization rules (see specs) that help the string parsing in RF...
void CallFlushColumnsOnField(RFieldBase &)
std::unique_ptr< RFieldBase > CreateEmulatedField(std::string_view fieldName, std::vector< std::unique_ptr< RFieldBase > > itemFields, std::string_view emulatedFromType)
std::string GetNormalizedUnresolvedTypeName(const std::string &origName)
Applies all RNTuple type normalization rules except typedef resolution.
std::vector< std::string > TokenizeTypeList(std::string_view templateType)
Used in RFieldBase::Create() in order to get the comma-separated list of template types E....
void CallConnectPageSinkOnField(RFieldBase &, ROOT::Internal::RPageSink &, ROOT::NTupleSize_t firstEntry=0)
std::uint64_t DescriptorId_t
Distriniguishes elements of the same type within a descriptor, e.g. different fields.
std::uint64_t NTupleSize_t
Integer type long enough to hold the maximum number of entries in a column.
constexpr DescriptorId_t kInvalidDescriptorId
ENTupleStructure
The fields in the ntuple model tree can carry different structural information about the type system.
std::string ResolveTypedef(const char *tname, bool resolveAll=false)
bool GetReturnInvalidOnError() const
bool GetEmulateUnknownTypes() const
Input parameter to RFieldBase::ReadBulk() and RFieldBase::ReadBulkImpl().
Used in the return value of the Check() method.
std::default_delete< T > deleter