39 : fName(
name),
fType(
type), fStructure(structure), fIsSimple(isSimple), fParent(nullptr), fPrincipalColumn(nullptr)
50 std::string normalizedType(typeName);
51 normalizedType.erase(remove_if(normalizedType.begin(), normalizedType.end(), isspace), normalizedType.end());
53 if (normalizedType ==
"Float_t") normalizedType =
"float";
54 if (normalizedType ==
"Double_t") normalizedType =
"double";
55 if (normalizedType ==
"Int_t") normalizedType =
"std::int32_t";
56 if (normalizedType ==
"int") normalizedType =
"std::int32_t";
57 if (normalizedType ==
"unsigned") normalizedType =
"std::uint32_t";
58 if (normalizedType ==
"unsigned int") normalizedType =
"std::uint32_t";
59 if (normalizedType ==
"UInt_t") normalizedType =
"std::uint32_t";
60 if (normalizedType ==
"ULong64_t") normalizedType =
"std::uint64_t";
61 if (normalizedType ==
"string") normalizedType =
"std::string";
62 if (normalizedType.substr(0, 7) ==
"vector<") normalizedType =
"std::" + normalizedType;
64 if (normalizedType ==
"ROOT::Experimental::ClusterSize_t")
return new RField<ClusterSize_t>(fieldName);
68 if (normalizedType ==
"float")
return new RField<float>(fieldName);
69 if (normalizedType ==
"double")
return new RField<double>(fieldName);
71 if (normalizedType.substr(0, 12) ==
"std::vector<") {
72 std::string itemTypeName = normalizedType.substr(12, normalizedType.length() - 13);
73 auto itemField = Create(GetCollectionName(fieldName), itemTypeName);
74 return new RFieldVector(fieldName, std::unique_ptr<Detail::RFieldBase>(itemField));
77 if (normalizedType.substr(0, 19) ==
"ROOT::VecOps::RVec<") {
78 std::string itemTypeName = normalizedType.substr(19, normalizedType.length() - 20);
79 auto itemField = Create(GetCollectionName(fieldName), itemTypeName);
80 return new RFieldVector(fieldName, std::unique_ptr<Detail::RFieldBase>(itemField));
113 void *where =
malloc(GetValueSize());
115 return GenerateValue(where);
125 std::unique_ptr<ROOT::Experimental::Detail::RFieldBase> child)
127 child->fParent =
this;
128 fSubFields.emplace_back(std::move(child));
133 auto idx = fullName.find_last_of(kCollectionSeparator);
134 return (idx == std::string::npos) ? fullName : fullName.substr(idx + 1);
139 std::string result(parentName);
140 result.push_back(kCollectionSeparator);
141 result.append(GetLeafName(parentName));
147 for (
auto& column : fColumns) {
154 if (fColumns.empty()) DoGenerateColumns();
155 for (
auto& column : fColumns) {
156 if ((fParent !=
nullptr) && (column->GetOffsetColumn() ==
nullptr))
157 column->SetOffsetColumn(fParent->fPrincipalColumn);
158 column->Connect(pageStorage);
164 if (fSubFields.empty())
return RIterator(
this, -1);
165 return RIterator(this->fSubFields[0].get(), 0);
179 auto itr = fStack.rbegin();
180 if (!itr->fFieldPtr->fSubFields.empty()) {
181 fStack.emplace_back(
Position(itr->fFieldPtr->fSubFields[0].get(), 0));
185 unsigned int nextIdxInParent = ++(itr->fIdxInParent);
186 while (nextIdxInParent >= itr->fFieldPtr->fParent->fSubFields.size()) {
187 if (fStack.size() == 1) {
188 itr->fFieldPtr = itr->fFieldPtr->fParent;
189 itr->fIdxInParent = -1;
193 itr = fStack.rbegin();
194 nextIdxInParent = ++(itr->fIdxInParent);
196 itr->fFieldPtr = itr->fFieldPtr->fParent->fSubFields[nextIdxInParent].get();
206 for (
auto&
f : fSubFields) {
207 auto clone =
f->Clone(
f->GetName());
208 result->
Attach(std::unique_ptr<RFieldBase>(clone));
216 auto entry =
new REntry();
217 for (
auto&
f : fSubFields) {
218 entry->AddValue(
f->GenerateValue());
230 fColumns.emplace_back(std::make_unique<Detail::RColumn>(model));
231 fPrincipalColumn = fColumns[0].get();
241 fColumns.emplace_back(std::make_unique<Detail::RColumn>(model));
242 fPrincipalColumn = fColumns[0].get();
250 fColumns.emplace_back(std::make_unique<Detail::RColumn>(model));
251 fPrincipalColumn = fColumns[0].get();
260 fColumns.emplace_back(std::make_unique<Detail::RColumn>(model));
261 fPrincipalColumn = fColumns[0].get();
269 fColumns.emplace_back(std::make_unique<Detail::RColumn>(model));
270 fPrincipalColumn = fColumns[0].get();
278 fColumns.emplace_back(std::make_unique<Detail::RColumn>(model));
279 fPrincipalColumn = fColumns[0].get();
288 fColumns.emplace_back(std::make_unique<Detail::RColumn>(modelIndex));
291 fColumns.emplace_back(std::make_unique<Detail::RColumn>(modelChars));
292 fPrincipalColumn = fColumns[0].get();
293 fColumns[1]->SetOffsetColumn(fPrincipalColumn);
298 auto typedValue = value.
Get<std::string>();
299 auto length = typedValue->length();
300 Detail::RColumnElement<char, EColumnType::kByte> elemChars(
const_cast<char*
>(typedValue->data()));
301 fColumns[1]->AppendV(elemChars, length);
303 fColumns[0]->Append(fElemIndex);
309 auto typedValue = value->
Get<std::string>();
312 fPrincipalColumn->GetCollectionInfo(index, &idxStart, &nChars);
313 typedValue->resize(nChars);
314 Detail::RColumnElement<char, EColumnType::kByte> elemChars(
const_cast<char*
>(typedValue->data()));
315 fColumns[1]->ReadV(idxStart, nChars, &elemChars);
332 throw std::runtime_error(
"RField: no I/O support for type " + std::string(className));
335 while (
auto dataMember =
static_cast<TDataMember *
>(next())) {
338 GetName() +
"." + dataMember->GetName(), dataMember->GetFullTypeName());
339 Attach(std::unique_ptr<Detail::RFieldBase>(subField));
349 TIter next(fClass->GetListOfDataMembers());
351 while (
auto dataMember =
static_cast<TDataMember *
>(next())) {
352 auto memberValue = fSubFields[i]->CaptureValue(value.
Get<
unsigned char>() + dataMember->GetOffset());
353 fSubFields[i]->Append(memberValue);
359 TIter next(fClass->GetListOfDataMembers());
361 while (
auto dataMember =
static_cast<TDataMember *
>(next())) {
362 auto memberValue = fSubFields[i]->GenerateValue(value->
Get<
unsigned char>() + dataMember->GetOffset());
363 fSubFields[i]->Read(index, &memberValue);
384 fClass->Destructor(value.
GetRawPtr(),
true );
396 return fClass->GetClassSize();
407 , fItemSize(itemField->GetValueSize()), fNWritten(0)
409 Attach(std::move(itemField));
414 auto newItemField = fSubFields[0]->Clone(GetCollectionName(std::string(newName)));
415 return new RFieldVector(newName, std::unique_ptr<Detail::RFieldBase>(newItemField));
419 auto typedValue = value.
Get<std::vector<char>>();
420 R__ASSERT((typedValue->size() % fItemSize) == 0);
421 auto count = typedValue->size() / fItemSize;
422 for (
unsigned i = 0; i < count; ++i) {
423 auto itemValue = fSubFields[0]->CaptureValue(typedValue->data() + (i * fItemSize));
424 fSubFields[0]->Append(itemValue);
428 fColumns[0]->Append(elemIndex);
432 auto typedValue = value->
Get<std::vector<char>>();
436 fPrincipalColumn->GetCollectionInfo(index, &idxStart, &nItems);
438 typedValue->resize(nItems * fItemSize);
439 for (
unsigned i = 0; i < nItems; ++i) {
440 auto itemValue = fSubFields[0]->GenerateValue(typedValue->data() + (i * fItemSize));
441 fSubFields[0]->Read(idxStart + i, &itemValue);
448 fColumns.emplace_back(std::make_unique<Detail::RColumn>(modelIndex));
449 fPrincipalColumn = fColumns[0].get();
465 auto vec =
static_cast<std::vector<char>*
>(value.
GetRawPtr());
466 R__ASSERT((vec->size() % fItemSize) == 0);
467 auto nItems = vec->size() / fItemSize;
468 for (
unsigned i = 0; i < nItems; ++i) {
469 auto itemValue = fSubFields[0]->CaptureValue(vec->data() + (i * fItemSize));
470 fSubFields[0]->DestroyValue(itemValue,
true );
484 return sizeof(std::vector<char>);
498 std::shared_ptr<RCollectionNTuple> collectionNTuple,
499 std::unique_ptr<RNTupleModel> collectionModel)
501 , fCollectionNTuple(collectionNTuple)
503 std::string namePrefix(
name);
505 for (
unsigned i = 0; i < collectionModel->GetRootField()->
fSubFields.size(); ++i) {
506 auto& subField = collectionModel->GetRootField()->fSubFields[i];
507 subField->fName = namePrefix + subField->fName;
508 for (
auto& grandChild : subField->fSubFields) {
509 grandChild->fName = namePrefix + grandChild->fName;
511 Attach(std::move(subField));
519 fColumns.emplace_back(std::make_unique<Detail::RColumn>(modelIndex));
520 fPrincipalColumn = fColumns[0].get();
539 *fCollectionNTuple->GetOffsetPtr() = 0;
Iterates over the sub fields in depth-first search order.
void Advance()
Given that the iterator points to a valid field which is not the end iterator, go to the next field i...
static std::string GetCollectionName(const std::string &parentName)
Get the name for an item sub field that is part of a collection, e.g. the float field of std::vector<...
virtual void DoReadV(NTupleSize_t index, NTupleSize_t count, void *dst)
std::vector< std::unique_ptr< RFieldBase > > fSubFields
Collections and classes own sub fields.
RFieldBase(std::string_view name, std::string_view type, ENTupleStructure structure, bool isSimple)
The constructor creates the underlying column objects and connects them to either a sink or a source.
std::string GetName() const
virtual void DoAppend(const RFieldValue &value)
Operations on values of complex types, e.g.
static constexpr char kCollectionSeparator
Field names convey the level of subfields; sub fields (nested collections) are separated by a dot.
virtual void DestroyValue(const RFieldValue &value, bool dtorOnly=false)
Releases the resources acquired during GenerateValue (memory and constructor) This implementation wor...
static std::string GetLeafName(const std::string &fullName)
Get the tail of the field name up to the last dot.
void Flush() const
Ensure that all received items are written from page buffers to the storage.
virtual void CommitCluster()
Perform housekeeping tasks for global to cluster-local index translation.
void ConnectColumns(Detail::RPageStorage *pageStorage)
Registeres (or re-registers) the backing columns with the physical storage.
virtual void DoRead(NTupleSize_t index, RFieldValue *value)
static RFieldBase * Create(const std::string &fieldName, const std::string &typeName)
Factory method to resurrect a field from the stored on-disk type information.
void Attach(std::unique_ptr< Detail::RFieldBase > child)
RFieldValue GenerateValue()
Generates a tree value of the field type and allocates new initialized memory according to the type.
Manages tree meta-data, which is common for sinks and sources.
Holds the static meta-data of a column in a tree.
The REntry is a collection of values in an ntuple corresponding to a complete row in the data set.
A field translates read and write calls from/to underlying columns to/from tree values.
The field for a class with dictionary.
void DoGenerateColumns() final
Creates the backing columns corresponsing to the field type and name.
Detail::RFieldValue CaptureValue(void *where) final
Creates a value from a memory location with an already constructed object.
void DoRead(NTupleSize_t index, Detail::RFieldValue *value) final
void DoAppend(const Detail::RFieldValue &value) final
Operations on values of complex types, e.g.
RFieldClass(std::string_view fieldName, std::string_view className)
size_t GetValueSize() const override
The number of bytes taken by a value of the appropriate type.
void DestroyValue(const Detail::RFieldValue &value, bool dtorOnly=false) final
Releases the resources acquired during GenerateValue (memory and constructor) This implementation wor...
RFieldBase * Clone(std::string_view newName) final
unsigned int GetNColumns() const final
Returns the number of columns generated to store data for the field; defaults to 1.
RFieldCollection(std::string_view name, std::shared_ptr< RCollectionNTuple > collectionNTuple, std::unique_ptr< RNTupleModel > collectionModel)
void DoGenerateColumns() final
Creates the backing columns corresponsing to the field type and name.
void CommitCluster() final
Perform housekeeping tasks for global to cluster-local index translation.
RFieldBase * Clone(std::string_view newName) final
The container field for a tree model, which itself has no physical representation.
RFieldBase * Clone(std::string_view newName)
REntry * GenerateEntry()
Generates managed values for the top-level sub fields.
The generic field for a (nested) std::vector<Type>
size_t GetValueSize() const override
The number of bytes taken by a value of the appropriate type.
void DoAppend(const Detail::RFieldValue &value) final
Operations on values of complex types, e.g.
void CommitCluster() final
Perform housekeeping tasks for global to cluster-local index translation.
void DoGenerateColumns() final
Creates the backing columns corresponsing to the field type and name.
RFieldBase * Clone(std::string_view newName) final
RFieldVector(std::string_view fieldName, std::unique_ptr< Detail::RFieldBase > itemField)
void DestroyValue(const Detail::RFieldValue &value, bool dtorOnly=false) final
Releases the resources acquired during GenerateValue (memory and constructor) This implementation wor...
Detail::RFieldValue CaptureValue(void *where) override
Creates a value from a memory location with an already constructed object.
void DoRead(NTupleSize_t index, Detail::RFieldValue *value) final
unsigned int GetNColumns() const final
Returns the number of columns generated to store data for the field; defaults to 1.
Template specializations for concrete C++ types.
Classes with dictionaries that can be inspected by TClass.
TClass instances represent classes, structs and namespaces in the ROOT type system.
TList * GetListOfDataMembers(Bool_t load=kTRUE)
Return list containing the TDataMembers of a class.
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.
All ROOT classes may have RTTI (run time type identification) support added.
basic_string_view< char > string_view
std::string GetName(const std::string &scope_name)
std::uint64_t NTupleSize_t
Integer type long enough to hold the maximum number of entries in a column.
RClusterSize ClusterSize_t
ENTupleStructure
The fields in the ntuple model tree can carry different structural information about the type system.
Namespace for new ROOT classes and functions.
Type GetType(const std::string &Name)
Wrap the 32bit integer in a struct in order to avoid template specialization clash with std::uint32_t...