Skip to content

Commit c98110a

Browse files
committed
[ntuple] clarify/improve record field reconciliation
Record fields are used for 1) untyped records 2) emulated classes and as 3) base class for the pair and tuple fields. These three cases use different constructors and have different reconciliation logic wrt. to the on-disk information. Make this more clear through code comments. Shortcut reconciliation for emulated fields.
1 parent 3ef1e74 commit c98110a

File tree

2 files changed

+12
-0
lines changed

2 files changed

+12
-0
lines changed

tree/ntuple/inc/ROOT/RField/RFieldRecord.hxx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ class RRecordField : public RFieldBase {
6363

6464
/// If `emulatedFromType` is non-empty, this field was created as a replacement for a ClassField that we lack a
6565
/// dictionary for and reconstructed from the on-disk information.
66+
/// Used by the public constructor and by Internal::CreateEmulatedRecordField().
6667
RRecordField(std::string_view fieldName, std::vector<std::unique_ptr<RFieldBase>> itemFields,
6768
std::string_view emulatedFromType);
6869

@@ -82,6 +83,8 @@ protected:
8283
void ReadGlobalImpl(ROOT::NTupleSize_t globalIndex, void *to) final;
8384
void ReadInClusterImpl(RNTupleLocalIndex localIndex, void *to) final;
8485

86+
/// Used by RPairField and RTupleField descendants. These descendants have their own logic to attach the subfields
87+
/// that ensure that the resulting memory layout matches std::pair or std::tuple, resp.
8588
RRecordField(std::string_view fieldName, std::string_view typeName);
8689

8790
void AttachItemFields(std::vector<std::unique_ptr<RFieldBase>> itemFields);
@@ -106,6 +109,8 @@ protected:
106109
public:
107110
/// Construct a RRecordField based on a vector of child fields. The ownership of the child fields is transferred
108111
/// to the RRecordField instance.
112+
/// The resulting field uses a memory layout for its values as if there was a struct consisting of the passed
113+
/// item fields.
109114
RRecordField(std::string_view fieldName, std::vector<std::unique_ptr<RFieldBase>> itemFields);
110115
RRecordField(RRecordField &&other) = default;
111116
RRecordField &operator=(RRecordField &&other) = default;

tree/ntuple/src/RField.cxx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -607,6 +607,13 @@ void ROOT::RRecordField::ReadInClusterImpl(RNTupleLocalIndex localIndex, void *t
607607

608608
void ROOT::RRecordField::ReconcileOnDiskField(const RNTupleDescriptor &desc)
609609
{
610+
if (fTraits & kTraitEmulatedField) {
611+
// The field has been explicitly constructed following the on-disk information. No further reconcilation needed.
612+
return;
613+
}
614+
// Note that the RPairField and RTupleField descendants have their own reconcilation logic
615+
R__ASSERT(GetTypeName().empty());
616+
610617
const auto &fieldDesc = desc.GetFieldDescriptor(GetOnDiskId());
611618
EnsureMatchingOnDiskField(fieldDesc, kDiffTypeName | kDiffTypeVersion);
612619

0 commit comments

Comments
 (0)