25std::string GetCanonicalTypeName(
const std::string &typeName)
28 if (typeName.substr(0, 5) ==
"std::" || typeName.substr(0, 25) ==
"ROOT::RNTupleCardinality<")
35class CreateContextGuard;
37 friend class CreateContextGuard;
39 std::vector<std::string> fClassesOnStack;
42 bool fContinueOnError =
false;
45 CreateContext() =
default;
46 bool GetContinueOnError()
const {
return fContinueOnError; }
50class CreateContextGuard {
51 CreateContext &fCreateContext;
52 std::size_t fNOriginalClassesOnStack;
53 bool fOriginalContinueOnError;
56 CreateContextGuard(CreateContext &ctx)
57 : fCreateContext(ctx),
58 fNOriginalClassesOnStack(ctx.fClassesOnStack.
size()),
59 fOriginalContinueOnError(ctx.fContinueOnError)
64 fCreateContext.fClassesOnStack.resize(fNOriginalClassesOnStack);
65 fCreateContext.fContinueOnError = fOriginalContinueOnError;
68 void AddClassToStack(
const std::string &cl)
70 if (std::find(fCreateContext.fClassesOnStack.begin(), fCreateContext.fClassesOnStack.end(), cl) !=
71 fCreateContext.fClassesOnStack.end()) {
74 fCreateContext.fClassesOnStack.emplace_back(cl);
77 void SetContinueOnError(
bool value) { fCreateContext.fContinueOnError =
value; }
111 : fSerializationTypes(serializationTypes), fDeserializationTypes(serializationTypes)
114 deserializationExtraTypes.end());
129 : fField(other.fField),
131 fCapacity(other.fCapacity),
133 fIsAdopted(other.fIsAdopted),
134 fNValidValues(other.fNValidValues),
135 fFirstIndex(other.fFirstIndex)
137 std::swap(
fDeleter, other.fDeleter);
138 std::swap(
fValues, other.fValues);
144 std::swap(fField, other.fField);
145 std::swap(fDeleter, other.fDeleter);
146 std::swap(fValues, other.fValues);
148 std::swap(fCapacity, other.fCapacity);
149 std::swap(
fSize, other.fSize);
150 std::swap(fIsAdopted, other.fIsAdopted);
151 std::swap(fMaskAvail, other.fMaskAvail);
152 std::swap(fNValidValues, other.fNValidValues);
153 std::swap(fFirstIndex, other.fFirstIndex);
169 for (std::size_t i = 0; i < fCapacity; ++i) {
170 fDeleter->operator()(GetValuePtrAt(i),
true );
174 operator delete(fValues);
179 if (fCapacity <
size) {
181 throw RException(
R__FAIL(
"invalid attempt to bulk read beyond the adopted buffer"));
187 for (std::size_t i = 0; i <
size; ++i) {
188 fField->ConstructValue(GetValuePtrAt(i));
192 fMaskAvail = std::make_unique<bool[]>(
size);
196 std::fill(fMaskAvail.get(), fMaskAvail.get() +
size,
false);
199 fFirstIndex = firstIndex;
206 for (std::size_t i = 0; i <
fSize; ++i)
207 fNValidValues +=
static_cast<std::size_t
>(fMaskAvail[i]);
214 fCapacity = capacity;
217 fMaskAvail = std::make_unique<bool[]>(capacity);
232std::unique_ptr<void, typename ROOT::Experimental::RFieldBase::RCreateObjectDeleter<void>::deleter>
233ROOT::Experimental::RFieldBase::CreateObject<void>()
const
236 return std::unique_ptr<void, RCreateObjectDeleter<void>::deleter>(
CreateObjectRawPtr(), gDeleter);
242 bool isSimple, std::size_t nRepetitions)
257 std::string
result = GetFieldName();
258 auto parent = GetParent();
259 while (parent && !parent->GetFieldName().empty()) {
261 parent = parent->GetParent();
274std::vector<ROOT::Experimental::RFieldBase::RCheckResult>
283 std::vector<RCheckResult>
result;
284 for (
const auto &
f : fieldZero) {
290 RCheckResult{invalidField->GetQualifiedFieldName(), invalidField->GetTypeName(), invalidField->GetError()});
297 const std::string &typeAlias,
bool continueOnError)
299 thread_local CreateContext createContext;
300 CreateContextGuard createContextGuard(createContext);
302 createContextGuard.SetContinueOnError(
true);
304 auto fnFail = [&fieldName, &canonicalType](
const std::string &errMsg) ->
RResult<std::unique_ptr<RFieldBase>> {
305 if (createContext.GetContinueOnError()) {
306 return std::unique_ptr<RFieldBase>(std::make_unique<RInvalidField>(fieldName, canonicalType, errMsg));
312 if (canonicalType.empty())
313 return R__FORWARD_RESULT(fnFail(
"no type name specified for field '" + fieldName +
"'"));
315 std::unique_ptr<ROOT::Experimental::RFieldBase>
result;
321 std::unique_ptr<RFieldBase> arrayField = Create(
"_0", arrayBaseType).Unwrap();
322 for (
int i = arraySizes.size() - 1; i >= 0; --i) {
324 std::make_unique<RArrayField>((i == 0) ? fieldName :
"_0", std::move(arrayField), arraySizes[i]);
329 if (canonicalType ==
"bool") {
330 result = std::make_unique<RField<bool>>(fieldName);
331 }
else if (canonicalType ==
"char") {
332 result = std::make_unique<RField<char>>(fieldName);
333 }
else if (canonicalType ==
"signed char") {
334 result = std::make_unique<RField<signed char>>(fieldName);
335 }
else if (canonicalType ==
"unsigned char") {
336 result = std::make_unique<RField<unsigned char>>(fieldName);
337 }
else if (canonicalType ==
"short") {
338 result = std::make_unique<RField<short>>(fieldName);
339 }
else if (canonicalType ==
"unsigned short") {
340 result = std::make_unique<RField<unsigned short>>(fieldName);
341 }
else if (canonicalType ==
"int") {
342 result = std::make_unique<RField<int>>(fieldName);
343 }
else if (canonicalType ==
"unsigned int") {
344 result = std::make_unique<RField<unsigned int>>(fieldName);
345 }
else if (canonicalType ==
"long") {
346 result = std::make_unique<RField<long>>(fieldName);
347 }
else if (canonicalType ==
"unsigned long") {
348 result = std::make_unique<RField<unsigned long>>(fieldName);
349 }
else if (canonicalType ==
"long long") {
350 result = std::make_unique<RField<long long>>(fieldName);
351 }
else if (canonicalType ==
"unsigned long long") {
352 result = std::make_unique<RField<unsigned long long>>(fieldName);
353 }
else if (canonicalType ==
"std::byte") {
354 result = std::make_unique<RField<std::byte>>(fieldName);
355 }
else if (canonicalType ==
"std::int8_t") {
356 result = std::make_unique<RField<std::int8_t>>(fieldName);
357 }
else if (canonicalType ==
"std::uint8_t") {
358 result = std::make_unique<RField<std::uint8_t>>(fieldName);
359 }
else if (canonicalType ==
"std::int16_t") {
360 result = std::make_unique<RField<std::int16_t>>(fieldName);
361 }
else if (canonicalType ==
"std::uint16_t") {
362 result = std::make_unique<RField<std::uint16_t>>(fieldName);
363 }
else if (canonicalType ==
"std::int32_t") {
364 result = std::make_unique<RField<std::int32_t>>(fieldName);
365 }
else if (canonicalType ==
"std::uint32_t") {
366 result = std::make_unique<RField<std::uint32_t>>(fieldName);
367 }
else if (canonicalType ==
"std::int64_t") {
368 result = std::make_unique<RField<std::int64_t>>(fieldName);
369 }
else if (canonicalType ==
"std::uint64_t") {
370 result = std::make_unique<RField<std::uint64_t>>(fieldName);
371 }
else if (canonicalType ==
"float") {
372 result = std::make_unique<RField<float>>(fieldName);
373 }
else if (canonicalType ==
"double") {
374 result = std::make_unique<RField<double>>(fieldName);
375 }
else if (canonicalType ==
"Double32_t") {
376 result = std::make_unique<RField<double>>(fieldName);
380 }
else if (canonicalType ==
"std::string") {
381 result = std::make_unique<RField<std::string>>(fieldName);
382 }
else if (canonicalType ==
"TObject") {
383 result = std::make_unique<RField<TObject>>(fieldName);
384 }
else if (canonicalType ==
"std::vector<bool>") {
385 result = std::make_unique<RField<std::vector<bool>>>(fieldName);
386 }
else if (canonicalType.substr(0, 12) ==
"std::vector<") {
387 std::string itemTypeName = canonicalType.substr(12, canonicalType.length() - 13);
388 auto itemField = Create(
"_0", itemTypeName);
389 result = std::make_unique<RVectorField>(fieldName, itemField.Unwrap());
390 }
else if (canonicalType.substr(0, 19) ==
"ROOT::VecOps::RVec<") {
391 std::string itemTypeName = canonicalType.substr(19, canonicalType.length() - 20);
392 auto itemField = Create(
"_0", itemTypeName);
393 result = std::make_unique<RRVecField>(fieldName, itemField.Unwrap());
394 }
else if (canonicalType.substr(0, 11) ==
"std::array<") {
396 if (arrayDef.size() != 2) {
397 return R__FORWARD_RESULT(fnFail(
"the template list for std::array must have exactly two elements"));
399 auto arrayLength = std::stoi(arrayDef[1]);
400 auto itemField = Create(
"_0", arrayDef[0]);
401 result = std::make_unique<RArrayField>(fieldName, itemField.Unwrap(), arrayLength);
402 }
else if (canonicalType.substr(0, 13) ==
"std::variant<") {
404 std::vector<std::unique_ptr<RFieldBase>> items;
405 items.reserve(innerTypes.size());
406 for (
unsigned int i = 0; i < innerTypes.size(); ++i) {
407 items.emplace_back(Create(
"_" + std::to_string(i), innerTypes[i]).Unwrap());
409 result = std::make_unique<RVariantField>(fieldName, std::move(items));
410 }
else if (canonicalType.substr(0, 10) ==
"std::pair<") {
412 if (innerTypes.size() != 2) {
413 return R__FORWARD_RESULT(fnFail(
"the type list for std::pair must have exactly two elements"));
415 std::array<std::unique_ptr<RFieldBase>, 2> items{Create(
"_0", innerTypes[0]).Unwrap(),
416 Create(
"_1", innerTypes[1]).Unwrap()};
417 result = std::make_unique<RPairField>(fieldName, std::move(items));
418 }
else if (canonicalType.substr(0, 11) ==
"std::tuple<") {
420 std::vector<std::unique_ptr<RFieldBase>> items;
421 items.reserve(innerTypes.size());
422 for (
unsigned int i = 0; i < innerTypes.size(); ++i) {
423 items.emplace_back(Create(
"_" + std::to_string(i), innerTypes[i]).Unwrap());
425 result = std::make_unique<RTupleField>(fieldName, std::move(items));
426 }
else if (canonicalType.substr(0, 12) ==
"std::bitset<") {
427 auto size = std::stoull(canonicalType.substr(12, canonicalType.length() - 13));
428 result = std::make_unique<RBitsetField>(fieldName,
size);
429 }
else if (canonicalType.substr(0, 16) ==
"std::unique_ptr<") {
430 std::string itemTypeName = canonicalType.substr(16, canonicalType.length() - 17);
431 auto itemField = Create(
"_0", itemTypeName).Unwrap();
432 auto normalizedInnerTypeName = itemField->GetTypeName();
433 result = std::make_unique<RUniquePtrField>(fieldName,
"std::unique_ptr<" + normalizedInnerTypeName +
">",
434 std::move(itemField));
435 }
else if (canonicalType.substr(0, 14) ==
"std::optional<") {
436 std::string itemTypeName = canonicalType.substr(14, canonicalType.length() - 15);
437 auto itemField = Create(
"_0", itemTypeName).Unwrap();
438 auto normalizedInnerTypeName = itemField->GetTypeName();
439 result = std::make_unique<ROptionalField>(fieldName,
"std::optional<" + normalizedInnerTypeName +
">",
440 std::move(itemField));
441 }
else if (canonicalType.substr(0, 9) ==
"std::set<") {
442 std::string itemTypeName = canonicalType.substr(9, canonicalType.length() - 10);
443 auto itemField = Create(
"_0", itemTypeName).Unwrap();
444 auto normalizedInnerTypeName = itemField->GetTypeName();
446 std::make_unique<RSetField>(fieldName,
"std::set<" + normalizedInnerTypeName +
">", std::move(itemField));
447 }
else if (canonicalType.substr(0, 19) ==
"std::unordered_set<") {
448 std::string itemTypeName = canonicalType.substr(19, canonicalType.length() - 20);
449 auto itemField = Create(
"_0", itemTypeName).Unwrap();
450 auto normalizedInnerTypeName = itemField->GetTypeName();
451 result = std::make_unique<RSetField>(fieldName,
"std::unordered_set<" + normalizedInnerTypeName +
">",
452 std::move(itemField));
453 }
else if (canonicalType.substr(0, 14) ==
"std::multiset<") {
454 std::string itemTypeName = canonicalType.substr(14, canonicalType.length() - 15);
455 auto itemField = Create(
"_0", itemTypeName).Unwrap();
456 auto normalizedInnerTypeName = itemField->GetTypeName();
457 result = std::make_unique<RSetField>(fieldName,
"std::multiset<" + normalizedInnerTypeName +
">",
458 std::move(itemField));
459 }
else if (canonicalType.substr(0, 24) ==
"std::unordered_multiset<") {
460 std::string itemTypeName = canonicalType.substr(24, canonicalType.length() - 25);
461 auto itemField = Create(
"_0", itemTypeName).Unwrap();
462 auto normalizedInnerTypeName = itemField->GetTypeName();
463 result = std::make_unique<RSetField>(fieldName,
"std::unordered_multiset<" + normalizedInnerTypeName +
">",
464 std::move(itemField));
465 }
else if (canonicalType.substr(0, 9) ==
"std::map<") {
467 if (innerTypes.size() != 2) {
468 return R__FORWARD_RESULT(fnFail(
"the type list for std::map must have exactly two elements"));
471 auto itemField = Create(
"_0",
"std::pair<" + innerTypes[0] +
"," + innerTypes[1] +
">").Unwrap();
475 auto keyTypeName = itemField->GetSubFields()[0]->GetTypeName();
476 auto valueTypeName = itemField->GetSubFields()[1]->GetTypeName();
478 result = std::make_unique<RMapField>(fieldName,
"std::map<" + keyTypeName +
"," + valueTypeName +
">",
479 std::move(itemField));
480 }
else if (canonicalType.substr(0, 19) ==
"std::unordered_map<") {
482 if (innerTypes.size() != 2)
483 return R__FORWARD_RESULT(fnFail(
"the type list for std::unordered_map must have exactly two elements"));
485 auto itemField = Create(
"_0",
"std::pair<" + innerTypes[0] +
"," + innerTypes[1] +
">").Unwrap();
489 auto keyTypeName = itemField->GetSubFields()[0]->GetTypeName();
490 auto valueTypeName = itemField->GetSubFields()[1]->GetTypeName();
492 result = std::make_unique<RMapField>(
493 fieldName,
"std::unordered_map<" + keyTypeName +
"," + valueTypeName +
">", std::move(itemField));
494 }
else if (canonicalType.substr(0, 14) ==
"std::multimap<") {
496 if (innerTypes.size() != 2)
497 return R__FORWARD_RESULT(fnFail(
"the type list for std::multimap must have exactly two elements"));
499 auto itemField = Create(
"_0",
"std::pair<" + innerTypes[0] +
"," + innerTypes[1] +
">").Unwrap();
503 auto keyTypeName = itemField->GetSubFields()[0]->GetTypeName();
504 auto valueTypeName = itemField->GetSubFields()[1]->GetTypeName();
506 result = std::make_unique<RMapField>(fieldName,
"std::multimap<" + keyTypeName +
"," + valueTypeName +
">",
507 std::move(itemField));
508 }
else if (canonicalType.substr(0, 24) ==
"std::unordered_multimap<") {
510 if (innerTypes.size() != 2)
512 fnFail(
"the type list for std::unordered_multimap must have exactly two elements"));
514 auto itemField = Create(
"_0",
"std::pair<" + innerTypes[0] +
"," + innerTypes[1] +
">").Unwrap();
518 auto keyTypeName = itemField->GetSubFields()[0]->GetTypeName();
519 auto valueTypeName = itemField->GetSubFields()[1]->GetTypeName();
521 result = std::make_unique<RMapField>(
522 fieldName,
"std::unordered_multimap<" + keyTypeName +
"," + valueTypeName +
">", std::move(itemField));
523 }
else if (canonicalType.substr(0, 12) ==
"std::atomic<") {
524 std::string itemTypeName = canonicalType.substr(12, canonicalType.length() - 13);
525 auto itemField = Create(
"_0", itemTypeName).Unwrap();
526 auto normalizedInnerTypeName = itemField->GetTypeName();
527 result = std::make_unique<RAtomicField>(fieldName,
"std::atomic<" + normalizedInnerTypeName +
">",
528 std::move(itemField));
529 }
else if (canonicalType.substr(0, 25) ==
"ROOT::RNTupleCardinality<") {
531 if (innerTypes.size() != 1)
532 return R__FORWARD_RESULT(fnFail(
"invalid cardinality template: " + canonicalType));
533 if (innerTypes[0] ==
"std::uint32_t") {
534 result = std::make_unique<RField<RNTupleCardinality<std::uint32_t>>>(fieldName);
535 }
else if (innerTypes[0] ==
"std::uint64_t") {
536 result = std::make_unique<RField<RNTupleCardinality<std::uint64_t>>>(fieldName);
538 return R__FORWARD_RESULT(fnFail(
"invalid cardinality template: " + canonicalType));
545 result = std::make_unique<REnumField>(fieldName, canonicalType);
552 createContextGuard.AddClassToStack(canonicalType);
553 if (cl->GetCollectionProxy()) {
554 result = std::make_unique<RProxiedCollectionField>(fieldName, canonicalType);
558 result = std::make_unique<RStreamerField>(fieldName, canonicalType);
560 result = std::make_unique<RClassField>(fieldName, canonicalType);
565 }
catch (RException &
e) {
566 auto error =
e.GetError();
567 if (createContext.GetContinueOnError()) {
568 return std::unique_ptr<RFieldBase>(
569 std::make_unique<RInvalidField>(fieldName, canonicalType, error.GetReport()));
576 if (typeAlias != canonicalType)
577 result->fTypeAlias = typeAlias;
587 return representations;
592 auto clone = CloneImpl(newName);
593 clone->fTypeAlias = fTypeAlias;
594 clone->fOnDiskId = fOnDiskId;
595 clone->fDescription = fDescription;
597 clone->fColumnRepresentatives = fColumnRepresentatives;
603 R__ASSERT(
false &&
"A non-simple RField must implement its own AppendImpl");
614 ReadGlobalImpl(fPrincipalColumn->GetGlobalIndex(clusterIndex), to);
619 const auto valueSize = GetValueSize();
620 std::size_t nRead = 0;
621 for (std::size_t i = 0; i < bulkSpec.
fCount; ++i) {
630 Read(bulkSpec.
fFirstIndex + i,
reinterpret_cast<unsigned char *
>(bulkSpec.
fValues) + i * valueSize);
639 void *where =
operator new(GetValueSize());
641 ConstructValue(where);
647 void *obj = CreateObjectRawPtr();
651std::vector<ROOT::Experimental::RFieldBase::RValue>
654 return std::vector<RValue>();
661 if (fState != EState::kUnconnected)
662 throw RException(
R__FAIL(
"invalid attempt to attach subfield to already connected field"));
663 child->fParent =
this;
664 fSubFields.emplace_back(std::move(
child));
670 std::size_t
result = globalIndex;
671 for (
auto f =
this;
f !=
nullptr;
f =
f->GetParent()) {
672 auto parent =
f->GetParent();
673 if (parent && (parent->GetStructure() ==
kCollection || parent->GetStructure() ==
kVariant))
675 result *= std::max(
f->GetNRepetitions(), std::size_t{1U});
682 std::vector<RFieldBase *>
result;
683 result.reserve(fSubFields.size());
684 for (
const auto &
f : fSubFields) {
692 std::vector<const RFieldBase *>
result;
693 result.reserve(fSubFields.size());
694 for (
const auto &
f : fSubFields) {
702 if (!fAvailableColumns.empty()) {
703 const auto activeRepresentationIndex = fPrincipalColumn->GetRepresentationIndex();
704 for (
auto &column : fAvailableColumns) {
705 if (column->GetRepresentationIndex() == activeRepresentationIndex) {
714 if (!fAvailableColumns.empty()) {
715 const auto activeRepresentationIndex = fPrincipalColumn->GetRepresentationIndex();
716 for (
auto &column : fAvailableColumns) {
717 if (column->GetRepresentationIndex() == activeRepresentationIndex) {
720 column->CommitSuppressed();
729 if (fState != EState::kUnconnected)
730 throw RException(
R__FAIL(
"cannot set field description once field is connected"));
731 fDescription = std::string(description);
736 if (fState != EState::kUnconnected)
745 if (~fTraits & kTraitMappable)
746 return AppendImpl(from);
748 fPrincipalColumn->Append(from);
749 return fPrincipalColumn->GetElement()->GetPackedSize();
759 return RValue(
this, objPtr);
768 return RBulkSpec::kAllSet;
771 return ReadBulkImpl(bulkSpec);
807 if (fColumnRepresentatives.empty()) {
808 return {GetColumnRepresentations().GetSerializationDefault()};
812 result.reserve(fColumnRepresentatives.size());
813 for (
const auto &
r : fColumnRepresentatives) {
822 if (fState != EState::kUnconnected)
823 throw RException(
R__FAIL(
"cannot set column representative once field is connected"));
824 const auto &validTypes = GetColumnRepresentations().GetSerializationTypes();
825 fColumnRepresentatives.clear();
826 fColumnRepresentatives.reserve(representatives.size());
827 for (
const auto &
r : representatives) {
828 auto itRepresentative = std::find(validTypes.begin(), validTypes.end(),
r);
829 if (itRepresentative == std::end(validTypes))
831 fColumnRepresentatives.emplace_back(*itRepresentative);
837 std::uint16_t representationIndex)
const
842 throw RException(
R__FAIL(
"No on-disk field information for `" + GetQualifiedFieldName() +
"`"));
846 if (
c.GetRepresentationIndex() == representationIndex)
847 onDiskTypes.emplace_back(
c.GetType());
849 if (onDiskTypes.empty()) {
850 if (representationIndex == 0) {
851 throw RException(
R__FAIL(
"No on-disk column information for field `" + GetQualifiedFieldName() +
"`"));
856 for (
const auto &t : GetColumnRepresentations().GetDeserializationTypes()) {
857 if (t == onDiskTypes)
861 std::string columnTypeNames;
862 for (
const auto &t : onDiskTypes) {
863 if (!columnTypeNames.empty())
864 columnTypeNames +=
", ";
867 throw RException(
R__FAIL(
"On-disk column types {" + columnTypeNames +
"} for field `" + GetQualifiedFieldName() +
868 "` cannot be matched to its in-memory type `" + GetTypeName() +
"` " +
869 "(representation index: " + std::to_string(representationIndex) +
")"));
874 fReadCallbacks.push_back(func);
876 return fReadCallbacks.size() - 1;
881 fReadCallbacks.erase(fReadCallbacks.begin() + idx);
882 fIsSimple = (fTraits & kTraitMappable) && !fIsArtificial && fReadCallbacks.empty();
887 if ((options.
GetCompression() == 0) && HasDefaultColumnRepresentative()) {
889 for (
auto &colType : rep) {
904 SetColumnRepresentatives({rep});
907 if (fTypeAlias ==
"Double32_t")
915 if (fState != EState::kUnconnected)
916 throw RException(
R__FAIL(
"invalid attempt to connect an already connected field to a page sink"));
921 for (
auto &column : fAvailableColumns) {
925 auto firstElementIndex = (column->GetIndex() == 0) ? EntryToColumnElementIndex(firstEntry) : 0;
926 column->ConnectPageSink(fOnDiskId, pageSink, firstElementIndex);
929 if (HasExtraTypeInfo()) {
934 fState = EState::kConnectedToSink;
940 throw RException(
R__FAIL(
"invalid attempt to connect zero field to page source"));
941 if (fState != EState::kUnconnected)
942 throw RException(
R__FAIL(
"invalid attempt to connect an already connected field to a page source"));
944 if (!fColumnRepresentatives.empty())
945 throw RException(
R__FAIL(
"fixed column representative only valid when connecting to a page sink"));
946 if (!fDescription.empty())
947 throw RException(
R__FAIL(
"setting description only valid when connecting to a page sink"));
949 BeforeConnectPageSource(pageSource);
951 for (
auto &
f : fSubFields) {
955 f->ConnectPageSource(pageSource);
959 if (!fIsArtificial) {
962 GenerateColumns(desc);
963 if (fColumnRepresentatives.empty()) {
965 for (
const auto &t : GetColumnRepresentations().GetDeserializationTypes()) {
967 fColumnRepresentatives = {t};
972 R__ASSERT(!fColumnRepresentatives.empty());
976 if (fieldDesc.GetTypeChecksum().has_value())
977 fOnDiskTypeChecksum = *fieldDesc.GetTypeChecksum();
980 for (
auto &column : fAvailableColumns)
981 column->ConnectPageSource(fOnDiskId, pageSource);
982 OnConnectPageSource();
984 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
#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.
virtual void VisitField(const RFieldBase &field)=0
static const char * GetColumnTypeName(EColumnType type)
Abstract interface to write data into an ntuple.
virtual void UpdateExtraTypeInfo(const RExtraTypeInfoDescriptor &extraTypeInfo)=0
Adds an extra type information record to schema.
const RNTupleWriteOptions & GetWriteOptions() const
Returns the sink's write options.
void RegisterOnCommitDatasetCallback(Callback_t callback)
The registered callback is executed at the beginning of CommitDataset();.
Abstract interface to read data from an ntuple.
const RSharedDescriptorGuard GetSharedDescriptorGuard() const
Takes the read lock for the descriptor.
Addresses a column element or field item relative to a particular cluster, instead of a global NTuple...
Similar to RValue but manages an array of consecutive values.
std::unique_ptr< bool[]> fMaskAvail
Masks invalid values in the array.
void AdoptBuffer(void *buf, std::size_t capacity)
RBulk & operator=(const RBulk &)=delete
void Reset(RClusterIndex firstIndex, std::size_t size)
Sets a new range for the bulk.
void * fValues
Cached deleter of fField.
std::unique_ptr< RFieldBase::RDeleter > fDeleter
Some fields have multiple possible column representations, e.g.
std::vector< ColumnRepresentation_t > Selection_t
A list of column representations.
Selection_t fSerializationTypes
Selection_t fDeserializationTypes
The union of the serialization types and the deserialization extra types.
Iterates over the sub tree of fields in depth-first search order.
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.
RBulk CreateBulk()
The returned bulk is initially empty; RBulk::ReadBulk will construct the array of values.
static constexpr int kTraitTriviallyDestructible
The type is cleaned up just by freeing its memory. I.e. the destructor performs a no-op.
void Attach(std::unique_ptr< RFieldBase > child)
Add a new subfield to the list of nested fields.
void AutoAdjustColumnTypes(const RNTupleWriteOptions &options)
When connecting a field to a page sink, the field's default column representation is subject to adjus...
void SetColumnRepresentatives(const RColumnRepresentations::Selection_t &representatives)
Fixes a column representative.
ENTupleStructure fStructure
The role of this field in the data model structure.
std::vector< RFieldBase * > GetSubFields()
static std::vector< RCheckResult > Check(const std::string &fieldName, const std::string &typeName)
Checks if the given type is supported by RNTuple.
static constexpr int kTraitMappable
A field of a fundamental type that can be directly mapped via RField<T>::Map(), i....
std::function< void(void *)> ReadCallback_t
static constexpr int kTraitTriviallyConstructible
No constructor needs to be called, i.e.
virtual void AcceptVisitor(Detail::RFieldVisitor &visitor) const
std::size_t fNRepetitions
For fixed sized arrays, the array length.
RFieldBase * fParent
Sub fields point to their mother field.
void FlushColumns()
Flushes data from active columns.
int fTraits
Properties of the type that allow for optimizations of collections of that type.
void ConnectPageSink(Internal::RPageSink &pageSink, NTupleSize_t firstEntry=0)
Fields and their columns live in the void until connected to a physical page storage.
virtual std::size_t AppendImpl(const void *from)
Operations on values of complex types, e.g.
bool fIsSimple
A field qualifies as simple if it is mappable (which implies it has a single principal column),...
RConstSchemaIterator cend() const
std::string GetQualifiedFieldName() const
Returns the field name and parent field names separated by dots ("grandparent.parent....
std::vector< EColumnType > ColumnRepresentation_t
virtual std::size_t ReadBulkImpl(const RBulkSpec &bulkSpec)
General implementation of bulk read.
std::size_t Append(const void *from)
Write the given value into columns.
virtual void ReadInClusterImpl(RClusterIndex clusterIndex, void *to)
void RemoveReadCallback(size_t idx)
void * CreateObjectRawPtr() const
Factory method for the field's type. The caller owns the returned pointer.
void CommitCluster()
Flushes data from active columns to disk and calls CommitClusterImpl.
const ColumnRepresentation_t & EnsureCompatibleColumnTypes(const RNTupleDescriptor &desc, std::uint16_t representationIndex) const
Returns the on-disk column types found in the provided descriptor for fOnDiskId and the given represe...
void ConnectPageSource(Internal::RPageSource &pageSource)
Connects the field and its sub field tree to the given page source.
RValue CreateValue()
Generates an object of the field type and wraps the created object in a shared pointer and returns it...
std::unique_ptr< RFieldBase > Clone(std::string_view newName) const
Copies the field and its sub fields using a possibly new name and a new, unconnected set of columns.
std::size_t ReadBulk(const RBulkSpec &bulkSpec)
Returns the number of newly available values, that is the number of bools in bulkSpec....
RConstSchemaIterator cbegin() const
static RResult< std::unique_ptr< RFieldBase > > Create(const std::string &fieldName, const std::string &canonicalType, const std::string &typeAlias, bool continueOnError=false)
Factory method to resurrect a field from the stored on-disk type information.
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...
virtual std::vector< RValue > SplitValue(const RValue &value) const
Creates the list of direct child values given a value for this field.
void SetOnDiskId(DescriptorId_t id)
RColumnRepresentations::Selection_t GetColumnRepresentatives() const
Returns the fColumnRepresentative pointee or, if unset (always the case for artificial fields),...
std::string fName
The field name relative to its parent field.
std::string fType
The C++ type captured by this field.
Internal::RColumn * fPrincipalColumn
All fields that have columns have a distinct main column.
void SetDescription(std::string_view description)
NTupleSize_t EntryToColumnElementIndex(NTupleSize_t globalIndex) const
Translate an entry index to a column element index of the principal column and viceversa.
RValue BindValue(std::shared_ptr< void > objPtr)
Creates a value from a memory location with an already constructed object.
virtual void ReadGlobalImpl(NTupleSize_t globalIndex, void *to)
RFieldBase(std::string_view name, std::string_view type, 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.
virtual const RColumnRepresentations & GetColumnRepresentations() const
Implementations in derived classes should return a static RColumnRepresentations object.
std::uint32_t GetTypeVersion() const
The container field for an ntuple model, which itself has no physical representation.
void Attach(std::unique_ptr< RFieldBase > child)
Add a new subfield to the list of nested fields.
Classes with dictionaries that can be inspected by TClass.
Used in RFieldBase::Check() to record field creation failures.
The on-storage meta-data of an ntuple.
RColumnDescriptorIterable GetColumnIterable() const
DescriptorId_t FindFieldId(std::string_view fieldName, DescriptorId_t parentId) const
const RFieldDescriptor & GetFieldDescriptor(DescriptorId_t fieldId) const
Common user-tunable settings for storing ntuples.
int GetCompression() const
Base class for all ROOT issued exceptions.
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)
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.
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....
std::string GetNormalizedTypeName(const std::string &typeName)
Applies type name normalization rules that lead to the final name used to create a RField,...
auto MakeAliasedSharedPtr(T *rawPtr)
void CallConnectPageSinkOnField(RFieldBase &, RPageSink &, NTupleSize_t firstEntry=0)
void CallFlushColumnsOnField(RFieldBase &)
void CallConnectPageSourceOnField(RFieldBase &, RPageSource &)
ERNTupleSerializationMode GetRNTupleSerializationMode(TClass *cl)
void CallCommitClusterOnField(RFieldBase &)
std::tuple< std::string, std::vector< size_t > > ParseArrayType(std::string_view typeName)
Parse a type name of the form T[n][m]... and return the base type T and a vector that contains,...
RLogChannel & NTupleLog()
Log channel for RNTuple diagnostics.
std::uint64_t NTupleSize_t
Integer type long enough to hold the maximum number of entries in a column.
std::uint64_t DescriptorId_t
Distriniguishes elements of the same type within a descriptor, e.g. different fields.
ENTupleStructure
The fields in the ntuple model tree can carry different structural information about the type system.
constexpr DescriptorId_t kInvalidDescriptorId
std::string ResolveTypedef(const char *tname, bool resolveAll=false)
void * fValues
The destination area, which has to be a big enough array of valid objects of the correct type.
const bool * fMaskReq
A bool array of size fCount, indicating the required values in the requested range.
bool * fMaskAvail
A bool array of size fCount, indicating the valid values in fValues.
std::size_t fCount
Size of the bulk range.
RClusterIndex fFirstIndex
Start of the bulk range.
Used in the return value of the Check() method.
std::default_delete< T > deleter