From 23647eea37639099a0bba65af5d01f195847d2f7 Mon Sep 17 00:00:00 2001 From: Philippe Canal Date: Thu, 8 Oct 2026 15:20:51 -0500 Subject: [PATCH] [ntuple] Update test for v1 streamer field to realistic handle alignment. Move the (so far ununused) VersionedStreamerField in the right header and dictionary. Attach that type as the data type of the test RVersionStreamerField which has been updated to record the class and use its alignment and sizeof. --- tree/ntuple/test/CustomStruct.hxx | 4 --- tree/ntuple/test/CustomStructLinkDef.h | 1 - tree/ntuple/test/StreamerField.hxx | 4 +++ tree/ntuple/test/StreamerFieldLinkDef.h | 1 + tree/ntuple/test/rfield_streamer.cxx | 36 +++++++++++++++++++------ 5 files changed, 33 insertions(+), 13 deletions(-) diff --git a/tree/ntuple/test/CustomStruct.hxx b/tree/ntuple/test/CustomStruct.hxx index 0cde0ccb3e091..350305a28fc6c 100644 --- a/tree/ntuple/test/CustomStruct.hxx +++ b/tree/ntuple/test/CustomStruct.hxx @@ -497,8 +497,4 @@ struct AlignmentEnvelope { std::array fArr; }; -struct VersionedStreamerField { - ClassDefNV(VersionedStreamerField, 2); -}; - #endif diff --git a/tree/ntuple/test/CustomStructLinkDef.h b/tree/ntuple/test/CustomStructLinkDef.h index c8e6ec796cad9..4786ce21e2860 100644 --- a/tree/ntuple/test/CustomStructLinkDef.h +++ b/tree/ntuple/test/CustomStructLinkDef.h @@ -185,6 +185,5 @@ #pragma link C++ class AlignedAs+; #pragma link C++ class OverAligned+; #pragma link C++ class AlignmentEnvelope+; -#pragma link C++ class VersionedStreamerField+; #endif diff --git a/tree/ntuple/test/StreamerField.hxx b/tree/ntuple/test/StreamerField.hxx index cf5d29d4d26bc..dbf957d96cce4 100644 --- a/tree/ntuple/test/StreamerField.hxx +++ b/tree/ntuple/test/StreamerField.hxx @@ -101,4 +101,8 @@ struct TemperatureKelvin { float fValue; }; +struct VersionedStreamerField { + ClassDefNV(VersionedStreamerField, 2); +}; + #endif // ROOT_RNTuple_Test_StreamerField diff --git a/tree/ntuple/test/StreamerFieldLinkDef.h b/tree/ntuple/test/StreamerFieldLinkDef.h index 59010c53264e4..4d5b33de2e90e 100644 --- a/tree/ntuple/test/StreamerFieldLinkDef.h +++ b/tree/ntuple/test/StreamerFieldLinkDef.h @@ -26,5 +26,6 @@ #pragma link C++ options = rntupleStreamerMode(true) class TemperatureCelsius + ; #pragma link C++ options = rntupleStreamerMode(true) class TemperatureKelvin + ; +#pragma link C++ options = rntupleStreamerMode(true) class VersionedStreamerField + ; #endif diff --git a/tree/ntuple/test/rfield_streamer.cxx b/tree/ntuple/test/rfield_streamer.cxx index 1a331b5b195fb..41137cedad18e 100644 --- a/tree/ntuple/test/rfield_streamer.cxx +++ b/tree/ntuple/test/rfield_streamer.cxx @@ -412,10 +412,26 @@ namespace { /// Used to create on-disk streamer fields with different field versions class RVersionedStreamerField : public RFieldBase { +private: + class RVersionedStreamerFieldDeleter : public RDeleter { + private: + TClass *fClass = nullptr; + + public: + explicit RVersionedStreamerFieldDeleter(TClass *cl) : RDeleter(cl->GetClassAlignment()), fClass(cl) {} + void operator()(void *objPtr, bool dtorOnly) final + { + fClass->Destructor(objPtr, true /* dtorOnly */); + RDeleter::operator()(objPtr, dtorOnly); + } + }; + + TClass *fClass = nullptr; + protected: std::unique_ptr CloneImpl(std::string_view newName) const final { - return std::make_unique(newName, fCustomVersion); + return std::make_unique(newName, fClass->GetName(), fCustomVersion); } const RColumnRepresentations &GetColumnRepresentations() const final @@ -428,23 +444,27 @@ class RVersionedStreamerField : public RFieldBase { void GenerateColumns() final { GenerateColumnsImpl(); } void GenerateColumns(const ROOT::RNTupleDescriptor &) final {} - void ConstructValue(void *) const final {} + void ConstructValue(void *where) const final { fClass->New(where); } + std::unique_ptr GetDeleter() const final + { + return std::make_unique(fClass); + } std::size_t AppendImpl(const void *) final { return 0; } public: std::uint32_t fCustomVersion = 0; - RVersionedStreamerField(std::string_view name, std::uint32_t version) - : RFieldBase(name, "VersionedStreamerField", ROOT::ENTupleStructure::kStreamer, /*isSimple=*/false), - fCustomVersion(version) + RVersionedStreamerField(std::string_view name, std::string_view classname, std::uint32_t version) + : RFieldBase(name, classname, ROOT::ENTupleStructure::kStreamer, /*isSimple=*/false), + fClass(TClass::GetClass(std::string(classname).c_str())), fCustomVersion(version) { } std::uint32_t GetFieldVersion() const final { return fCustomVersion; } std::uint32_t GetTypeVersion() const final { return 137; } - std::size_t GetValueSize() const final { return 0; } - std::size_t GetAlignment() const final { return 0; } + std::size_t GetValueSize() const final { return fClass->GetClassSize(); } + std::size_t GetAlignment() const final { return fClass->GetClassAlignment(); } }; } // anonymous namespace @@ -455,7 +475,7 @@ TEST(RField, StreamerFieldVersion) FileRaii fileGuard("test_ntuple_rfield_streamer_version.root"); { auto model = RNTupleModel::Create(); - model->AddField(std::make_unique("f", version)); + model->AddField(std::make_unique("f", "VersionedStreamerField", version)); auto writer = RNTupleWriter::Recreate(std::move(model), "ntpl", fileGuard.GetPath()); } auto reader = RNTupleReader::Open("ntpl", fileGuard.GetPath());