From 54fa7e97b1b6d402295f97fe705a953e5577a8fa Mon Sep 17 00:00:00 2001 From: Jakob Blomer Date: Tue, 8 Oct 2024 10:53:10 +0200 Subject: [PATCH 1/9] [ntuple] bump anchor version to RC3 --- tree/ntuple/v7/doc/BinaryFormatSpecification.md | 2 +- tree/ntuple/v7/inc/ROOT/RNTuple.hxx | 2 +- tree/ntuple/v7/test/ntuple_storage_daos.cxx | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tree/ntuple/v7/doc/BinaryFormatSpecification.md b/tree/ntuple/v7/doc/BinaryFormatSpecification.md index aa3c2317d5bee..a3f4b8169dcc2 100644 --- a/tree/ntuple/v7/doc/BinaryFormatSpecification.md +++ b/tree/ntuple/v7/doc/BinaryFormatSpecification.md @@ -1,4 +1,4 @@ -# RNTuple Binary Format Specification 0.2.12.0 +# RNTuple Binary Format Specification 0.3.0.0 **Note:** This is work in progress. The RNTuple specification is not yet finalized. diff --git a/tree/ntuple/v7/inc/ROOT/RNTuple.hxx b/tree/ntuple/v7/inc/ROOT/RNTuple.hxx index cad462d556f6b..a4ae3f313285e 100644 --- a/tree/ntuple/v7/inc/ROOT/RNTuple.hxx +++ b/tree/ntuple/v7/inc/ROOT/RNTuple.hxx @@ -77,7 +77,7 @@ class RNTuple final { public: static constexpr std::uint16_t kVersionEpoch = 0; - static constexpr std::uint16_t kVersionMajor = 2; + static constexpr std::uint16_t kVersionMajor = 3; static constexpr std::uint16_t kVersionMinor = 0; static constexpr std::uint16_t kVersionPatch = 0; diff --git a/tree/ntuple/v7/test/ntuple_storage_daos.cxx b/tree/ntuple/v7/test/ntuple_storage_daos.cxx index 645e7f5dd6e0c..40201fdd8842c 100644 --- a/tree/ntuple/v7/test/ntuple_storage_daos.cxx +++ b/tree/ntuple/v7/test/ntuple_storage_daos.cxx @@ -26,7 +26,7 @@ class RPageStorageDaos : public ::testing::Test { // Initialized at the start of each test to expect diagnostic messages from TestSupport fRootDiags.optionalDiag(kWarning, "ROOT::Experimental::Internal::RPageSinkDaos::RPageSinkDaos", "The DAOS backend is experimental and still under development.", false); - fRootDiags.optionalDiag(kWarning, "[ROOT.NTuple]", "Pre-release format version: RC 2", false); + fRootDiags.optionalDiag(kWarning, "[ROOT.NTuple]", "Pre-release format version: RC 3", false); fRootDiags.optionalDiag(kWarning, "in int daos_init()", "This RNTuple build uses libdaos_mock. Use only for testing!"); } From 08dd3365914a31fb23befc42ea0ba4ce4cb52fcb Mon Sep 17 00:00:00 2001 From: Jakob Blomer Date: Tue, 8 Oct 2024 11:27:32 +0200 Subject: [PATCH 2/9] [ntuple] Fix RNTupleCardinality on-disk type name Make the on-disk type name of the cardinality field spell `ROOT::RNTupleCardinality` instead of `ROOT::Experimental::RNTupleCardinality`. --- .../v7/doc/BinaryFormatSpecification.md | 5 +-- tree/ntuple/v7/inc/ROOT/RField.hxx | 2 +- tree/ntuple/v7/inc/ROOT/RNTupleUtil.hxx | 43 ++++++++++--------- tree/ntuple/v7/src/RField.cxx | 10 ++--- tree/ntuple/v7/test/ntuple_bulk.cxx | 7 +-- tree/ntuple/v7/test/ntuple_project.cxx | 4 +- tree/ntuple/v7/test/ntuple_storage.cxx | 2 +- tree/ntuple/v7/test/rfield_vector.cxx | 4 +- tree/ntupleutil/v7/src/RNTupleImporter.cxx | 3 +- tree/ntupleutil/v7/test/ntuple_importer.cxx | 4 +- tree/ntupleutil/v7/test/ntuple_inspector.cxx | 2 +- 11 files changed, 41 insertions(+), 45 deletions(-) diff --git a/tree/ntuple/v7/doc/BinaryFormatSpecification.md b/tree/ntuple/v7/doc/BinaryFormatSpecification.md index a3f4b8169dcc2..27fad715270ef 100644 --- a/tree/ntuple/v7/doc/BinaryFormatSpecification.md +++ b/tree/ntuple/v7/doc/BinaryFormatSpecification.md @@ -1004,10 +1004,9 @@ The on-disk representation of associative collections is identical to a `std::ma N.B., proxy-based associative collections are supported in the RNTuple binary format, but currently are not implemented in ROOT's RNTuple reader and writer. This will be added in the future. -### ROOT::Experimental::RNTupleCardinality +### ROOT::RNTupleCardinality -A field whose type is `ROOT::Experimental::RNTupleCardinality` is associated to a single column -of type `(Split)Index[32|64]`. +A field whose type is `ROOT::RNTupleCardinality` is associated to a single column of type `(Split)Index[32|64]`. This field presents the offsets in the index column as lengths that correspond to the cardinality of the pointed-to collection. It is meant to be used as a projected field and only for reading the size of a collection. diff --git a/tree/ntuple/v7/inc/ROOT/RField.hxx b/tree/ntuple/v7/inc/ROOT/RField.hxx index ce3369ea63556..525b512fa5661 100644 --- a/tree/ntuple/v7/inc/ROOT/RField.hxx +++ b/tree/ntuple/v7/inc/ROOT/RField.hxx @@ -353,7 +353,7 @@ protected: void ConstructValue(void *where) const final { new (where) RNTupleCardinality(0); } public: - static std::string TypeName() { return "ROOT::Experimental::RNTupleCardinality<" + RField::TypeName() + ">"; } + static std::string TypeName() { return "ROOT::RNTupleCardinality<" + RField::TypeName() + ">"; } explicit RField(std::string_view name) : RCardinalityField(name, TypeName()) {} RField(RField &&other) = default; RField &operator=(RField &&other) = default; diff --git a/tree/ntuple/v7/inc/ROOT/RNTupleUtil.hxx b/tree/ntuple/v7/inc/ROOT/RNTupleUtil.hxx index 7118e0363b1d0..03601283dc596 100644 --- a/tree/ntuple/v7/inc/ROOT/RNTupleUtil.hxx +++ b/tree/ntuple/v7/inc/ROOT/RNTupleUtil.hxx @@ -25,6 +25,28 @@ #include namespace ROOT { + +/// Helper types to present an offset column as array of collection sizes. +/// See RField> for details. +template +struct RNTupleCardinality { + static_assert(std::is_same_v || std::is_same_v, + "RNTupleCardinality is only supported with std::uint32_t or std::uint64_t template parameters"); + + using ValueType = SizeT; + + RNTupleCardinality() : fValue(0) {} + explicit constexpr RNTupleCardinality(ValueType value) : fValue(value) {} + RNTupleCardinality &operator=(const ValueType value) + { + fValue = value; + return *this; + } + operator ValueType() const { return fValue; } + + ValueType fValue; +}; + namespace Experimental { class RLogChannel; @@ -123,27 +145,6 @@ constexpr ClusterSize_t kInvalidClusterIndex(std::uint64_t(-1)); constexpr int kUnknownCompressionSettings = -1; -/// Helper types to present an offset column as array of collection sizes. -/// See RField> for details. -template -struct RNTupleCardinality { - static_assert(std::is_same_v || std::is_same_v, - "RNTupleCardinality is only supported with std::uint32_t or std::uint64_t template parameters"); - - using ValueType = SizeT; - - RNTupleCardinality() : fValue(0) {} - explicit constexpr RNTupleCardinality(ValueType value) : fValue(value) {} - RNTupleCardinality &operator=(const ValueType value) - { - fValue = value; - return *this; - } - operator ValueType() const { return fValue; } - - ValueType fValue; -}; - /// Holds the index and the tag of a kSwitch column class RColumnSwitch { private: diff --git a/tree/ntuple/v7/src/RField.cxx b/tree/ntuple/v7/src/RField.cxx index 2fdd93f5c4101..e3223c4a7e72f 100644 --- a/tree/ntuple/v7/src/RField.cxx +++ b/tree/ntuple/v7/src/RField.cxx @@ -150,7 +150,7 @@ std::tuple> ParseArrayType(std::string_view typ std::string GetCanonicalTypeName(const std::string &typeName) { // The following types are asummed to be canonical names; thus, do not perform `typedef` resolution on those - if (typeName.substr(0, 5) == "std::" || typeName.substr(0, 39) == "ROOT::Experimental::RNTupleCardinality<") + if (typeName.substr(0, 5) == "std::" || typeName.substr(0, 25) == "ROOT::RNTupleCardinality<") return typeName; return TClassEdit::ResolveTypedef(typeName.c_str()); @@ -841,8 +841,8 @@ ROOT::Experimental::RFieldBase::Create(const std::string &fieldName, const std:: auto normalizedInnerTypeName = itemField->GetTypeName(); result = std::make_unique(fieldName, "std::atomic<" + normalizedInnerTypeName + ">", std::move(itemField)); - } else if (canonicalType.substr(0, 39) == "ROOT::Experimental::RNTupleCardinality<") { - auto innerTypes = TokenizeTypeList(canonicalType.substr(39, canonicalType.length() - 40)); + } else if (canonicalType.substr(0, 25) == "ROOT::RNTupleCardinality<") { + auto innerTypes = TokenizeTypeList(canonicalType.substr(25, canonicalType.length() - 26)); if (innerTypes.size() != 1) return R__FORWARD_RESULT(fnFail("invalid cardinality template: " + canonicalType)); if (innerTypes[0] == "std::uint32_t") { @@ -1347,13 +1347,13 @@ void ROOT::Experimental::RCardinalityField::AcceptVisitor(Detail::RFieldVisitor visitor.VisitCardinalityField(*this); } -const ROOT::Experimental::RField> * +const ROOT::Experimental::RField> * ROOT::Experimental::RCardinalityField::As32Bit() const { return dynamic_cast> *>(this); } -const ROOT::Experimental::RField> * +const ROOT::Experimental::RField> * ROOT::Experimental::RCardinalityField::As64Bit() const { return dynamic_cast> *>(this); diff --git a/tree/ntuple/v7/test/ntuple_bulk.cxx b/tree/ntuple/v7/test/ntuple_bulk.cxx index c80a7d8bf46a2..f966b84722f4b 100644 --- a/tree/ntuple/v7/test/ntuple_bulk.cxx +++ b/tree/ntuple/v7/test/ntuple_bulk.cxx @@ -75,16 +75,13 @@ TEST(RNTupleBulk, Complex) TEST(RNTupleBulk, CardinalityField) { - using RNTupleCardinality32 = ROOT::Experimental::RNTupleCardinality; - using RNTupleCardinality64 = ROOT::Experimental::RNTupleCardinality; - FileRaii fileGuard("test_ntuple_bulk_cardinality.root"); { auto model = RNTupleModel::Create(); auto fldVec = model->MakeField>("vint"); - model->AddProjectedField(std::make_unique>("card32"), + model->AddProjectedField(std::make_unique>>("card32"), [](const std::string &) { return "vint"; }); - model->AddProjectedField(std::make_unique>("card64"), + model->AddProjectedField(std::make_unique>>("card64"), [](const std::string &) { return "vint"; }); auto writer = RNTupleWriter::Recreate(std::move(model), "ntpl", fileGuard.GetPath()); for (int i = 0; i < 10; ++i) { diff --git a/tree/ntuple/v7/test/ntuple_project.cxx b/tree/ntuple/v7/test/ntuple_project.cxx index 683fa80deb580..abd528b7feb0a 100644 --- a/tree/ntuple/v7/test/ntuple_project.cxx +++ b/tree/ntuple/v7/test/ntuple_project.cxx @@ -22,7 +22,7 @@ TEST(RNTupleProjection, Basics) else return "vec._0"; }); - auto f4 = RFieldBase::Create("vecSize", "ROOT::Experimental::RNTupleCardinality").Unwrap(); + auto f4 = RFieldBase::Create("vecSize", "ROOT::RNTupleCardinality").Unwrap(); model->AddProjectedField(std::move(f4), [](const std::string &) { return "vec"; }); { @@ -40,7 +40,7 @@ TEST(RNTupleProjection, Basics) auto viewMissingE = reader->GetView("missingE"); auto viewNumber = reader->GetView("number"); auto viewAliasVec = reader->GetView>("aliasVec"); - auto viewVecSize = reader->GetView>("vecSize"); + auto viewVecSize = reader->GetView>("vecSize"); EXPECT_FLOAT_EQ(42.0, viewMissingE(0)); EXPECT_EQ(7, viewNumber(0)); EXPECT_EQ(2U, viewAliasVec(0).size()); diff --git a/tree/ntuple/v7/test/ntuple_storage.cxx b/tree/ntuple/v7/test/ntuple_storage.cxx index 036495e7d2cb4..3a8938b5ffbdd 100644 --- a/tree/ntuple/v7/test/ntuple_storage.cxx +++ b/tree/ntuple/v7/test/ntuple_storage.cxx @@ -490,7 +490,7 @@ TEST(RNTuple, OpenHTTP) std::unique_ptr file(TFile::Open("http://root.cern/files/tutorials/ntpl004_dimuon_v1rc2.root")); auto Events = std::unique_ptr(file->Get("Events")); auto model = RNTupleModel::Create(); - model->MakeField>("nMuon"); + model->MakeField>("nMuon"); auto reader = RNTupleReader::Open(std::move(model), *Events); reader->LoadEntry(0); } diff --git a/tree/ntuple/v7/test/rfield_vector.cxx b/tree/ntuple/v7/test/rfield_vector.cxx index 2aa460829e25b..bddca9476faef 100644 --- a/tree/ntuple/v7/test/rfield_vector.cxx +++ b/tree/ntuple/v7/test/rfield_vector.cxx @@ -128,10 +128,10 @@ TEST(RNTuple, InsideCollection) field->SetOnDiskId(idKlassVec); ROOT::Experimental::Internal::CallConnectPageSourceOnField(*field, *source); - auto fieldCardinality64 = RFieldBase::Create("", "ROOT::Experimental::RNTupleCardinality").Unwrap(); + auto fieldCardinality64 = RFieldBase::Create("", "ROOT::RNTupleCardinality").Unwrap(); fieldCardinality64->SetOnDiskId(idKlassVec); ROOT::Experimental::Internal::CallConnectPageSourceOnField(*fieldCardinality64, *source); - auto fieldCardinality32 = RFieldBase::Create("", "ROOT::Experimental::RNTupleCardinality").Unwrap(); + auto fieldCardinality32 = RFieldBase::Create("", "ROOT::RNTupleCardinality").Unwrap(); fieldCardinality32->SetOnDiskId(idKlassVec); ROOT::Experimental::Internal::CallConnectPageSourceOnField(*fieldCardinality32, *source); diff --git a/tree/ntupleutil/v7/src/RNTupleImporter.cxx b/tree/ntupleutil/v7/src/RNTupleImporter.cxx index 3c9b98c227bf0..ab797357633fa 100644 --- a/tree/ntupleutil/v7/src/RNTupleImporter.cxx +++ b/tree/ntupleutil/v7/src/RNTupleImporter.cxx @@ -340,8 +340,7 @@ ROOT::Experimental::RResult ROOT::Experimental::RNTupleImporter::PrepareSc } // Add projected fields for count leaf - auto projectedField = - RFieldBase::Create(countLeafName, "ROOT::Experimental::RNTupleCardinality").Unwrap(); + auto projectedField = RFieldBase::Create(countLeafName, "ROOT::RNTupleCardinality").Unwrap(); fModel->AddProjectedField(std::move(projectedField), [&c](const std::string &) { return c.fFieldName; }); iLeafCountCollection++; diff --git a/tree/ntupleutil/v7/test/ntuple_importer.cxx b/tree/ntupleutil/v7/test/ntuple_importer.cxx index e9dc65b6a3c62..d922b6e45498b 100644 --- a/tree/ntupleutil/v7/test/ntuple_importer.cxx +++ b/tree/ntupleutil/v7/test/ntuple_importer.cxx @@ -441,10 +441,10 @@ TEST(RNTupleImporter, LeafCountArray) auto viewJetEta = viewJets.GetView("_0.jet_eta"); auto viewMuons = reader->GetCollectionView("_collection1"); auto viewMuonPt = viewMuons.GetView("_0.muon_pt"); - auto viewProjectedNjets = reader->GetView>("njets"); + auto viewProjectedNjets = reader->GetView>("njets"); auto viewProjectedJetPt = reader->GetView>("jet_pt"); auto viewProjectedJetEta = reader->GetView>("jet_eta"); - auto viewProjectedNmuons = reader->GetView>("nmuons"); + auto viewProjectedNmuons = reader->GetView>("nmuons"); auto viewProjectedMuonPt = reader->GetView>("muon_pt"); // Entry 0: 1 jet, 1 muon diff --git a/tree/ntupleutil/v7/test/ntuple_inspector.cxx b/tree/ntupleutil/v7/test/ntuple_inspector.cxx index 1d68087126856..70c9fedc7bf2a 100644 --- a/tree/ntupleutil/v7/test/ntuple_inspector.cxx +++ b/tree/ntupleutil/v7/test/ntuple_inspector.cxx @@ -238,7 +238,7 @@ TEST(RNTupleInspector, SizeProjectedFields) muonPt->emplace_back(1.0); muonPt->emplace_back(2.0); - auto nMuons = RFieldBase::Create("nMuons", "ROOT::Experimental::RNTupleCardinality").Unwrap(); + auto nMuons = RFieldBase::Create("nMuons", "ROOT::RNTupleCardinality").Unwrap(); model->AddProjectedField(std::move(nMuons), [](const std::string &) { return "muonPt"; }); auto writer = RNTupleWriter::Recreate(std::move(model), "ntuple", fileGuard.GetPath()); From fb32cb19ed66b1126658c41fa9e12ab14930d980 Mon Sep 17 00:00:00 2001 From: Jakob Blomer Date: Tue, 8 Oct 2024 22:48:58 +0200 Subject: [PATCH 3/9] [ntuple] move anchor out of experimental namespace Moves ROOT::Experimental::RNTuple to ROOT::RNTuple. Resets class version to 2 (general first class version recommendation for new classes). Removes previous compatibility code. --- gui/browsable/src/RFieldHolder.hxx | 2 +- gui/browsable/src/RNTupleBrowseProvider.cxx | 4 +- gui/browsable/src/RNTupleDraw6Provider.cxx | 17 ++-- gui/browsable/src/RNTupleDraw7Provider.cxx | 26 +++--- gui/browsable/src/RProvider.cxx | 5 +- gui/browsable/src/TDirectoryElement.cxx | 2 +- io/io/src/TFileMerger.cxx | 2 +- tree/dataframe/inc/ROOT/RNTupleDS.hxx | 10 +-- tree/dataframe/src/RLoopManager.cxx | 4 +- tree/dataframe/src/RNTupleDS.cxx | 2 +- tree/ntuple/inc/LinkDef.h | 2 +- .../v7/doc/BinaryFormatSpecification.md | 2 +- tree/ntuple/v7/inc/ROOT/RNTuple.hxx | 19 +++-- tree/ntuple/v7/inc/ROOT/RNTupleReader.hxx | 4 +- tree/ntuple/v7/inc/ROOT/RPageStorageFile.hxx | 4 +- tree/ntuple/v7/src/RMiniFile.cxx | 36 ++++----- tree/ntuple/v7/src/RNTuple.cxx | 54 +++---------- tree/ntuple/v7/src/RNTupleMerger.cxx | 10 +-- tree/ntuple/v7/src/RNTupleReader.cxx | 4 +- tree/ntuple/v7/src/RPageStorageDaos.cxx | 2 +- tree/ntuple/v7/test/RXTuple.cxx | 2 +- tree/ntuple/v7/test/RXTuple.hxx | 2 - tree/ntuple/v7/test/RXTupleLinkDef.h | 2 +- tree/ntuple/v7/test/ntuple_basics.cxx | 2 +- tree/ntuple/v7/test/ntuple_compat.cxx | 79 +------------------ tree/ntuple/v7/test/ntuple_extended.cxx | 6 +- tree/ntuple/v7/test/ntuple_minifile.cxx | 18 ++--- tree/ntuple/v7/test/ntuple_serialize.cxx | 4 +- tree/ntuple/v7/test/ntuple_storage.cxx | 4 +- tree/ntuple/v7/test/ntuple_test.hxx | 1 - tree/ntuple/v7/test/ntuple_view.cxx | 2 +- .../v7/inc/ROOT/RNTupleInspector.hxx | 4 +- tree/ntupleutil/v7/src/RNTupleInspector.cxx | 2 +- tree/ntupleutil/v7/test/ntuple_inspector.cxx | 2 +- tutorials/v7/ntuple/ntpl008_import.C | 3 +- tutorials/v7/ntuple/ntpl010_skim.C | 1 - 36 files changed, 116 insertions(+), 229 deletions(-) diff --git a/gui/browsable/src/RFieldHolder.hxx b/gui/browsable/src/RFieldHolder.hxx index c3cd107776d04..7442dcd8d4e6a 100644 --- a/gui/browsable/src/RFieldHolder.hxx +++ b/gui/browsable/src/RFieldHolder.hxx @@ -37,7 +37,7 @@ public: { } - const TClass *GetClass() const override { return TClass::GetClass(); } + const TClass *GetClass() const override { return TClass::GetClass(); } /** Returns direct (temporary) object pointer */ const void *GetObject() const override { return nullptr; } diff --git a/gui/browsable/src/RNTupleBrowseProvider.cxx b/gui/browsable/src/RNTupleBrowseProvider.cxx index 9bbb1e8cb8847..7a42e742a60c9 100644 --- a/gui/browsable/src/RNTupleBrowseProvider.cxx +++ b/gui/browsable/src/RNTupleBrowseProvider.cxx @@ -66,7 +66,7 @@ class RFieldElement : public RElement { std::unique_ptr GetChildsIter() override; /** Return class of field - for a moment using RNTuple class as dummy */ - const TClass *GetClass() const { return TClass::GetClass(); } + const TClass *GetClass() const { return TClass::GetClass(); } std::unique_ptr GetObject() override { @@ -124,7 +124,7 @@ class RNTupleElement : public RElement { /** Create iterator for childs elements if any */ std::unique_ptr GetChildsIter() override; - const TClass *GetClass() const { return TClass::GetClass(); } + const TClass *GetClass() const { return TClass::GetClass(); } std::unique_ptr CreateItem() const override { diff --git a/gui/browsable/src/RNTupleDraw6Provider.cxx b/gui/browsable/src/RNTupleDraw6Provider.cxx index 6525b570937df..b353fdb67b9e5 100644 --- a/gui/browsable/src/RNTupleDraw6Provider.cxx +++ b/gui/browsable/src/RNTupleDraw6Provider.cxx @@ -28,17 +28,16 @@ class RNTupleDraw6Provider : public RFieldProvider { RNTupleDraw6Provider() { - RegisterDraw6(TClass::GetClass(), [this](TVirtualPad *pad, std::unique_ptr &obj, const std::string &opt) -> bool { - - auto h1 = DrawField(dynamic_cast (obj.get())); - if (!h1) return false; - - pad->Add(h1, opt.c_str()); - - return true; - }); + RegisterDraw6(TClass::GetClass(), + [this](TVirtualPad *pad, std::unique_ptr &obj, const std::string &opt) -> bool { + auto h1 = DrawField(dynamic_cast(obj.get())); + if (!h1) + return false; + pad->Add(h1, opt.c_str()); + return true; + }); } } newRNTupleDraw6Provider; diff --git a/gui/browsable/src/RNTupleDraw7Provider.cxx b/gui/browsable/src/RNTupleDraw7Provider.cxx index 46febf998b681..9e4428a51020f 100644 --- a/gui/browsable/src/RNTupleDraw7Provider.cxx +++ b/gui/browsable/src/RNTupleDraw7Provider.cxx @@ -31,18 +31,20 @@ class RNTupleDraw7Provider : public RFieldProvider { RNTupleDraw7Provider() { - RegisterDraw7(TClass::GetClass(), [this](std::shared_ptr &subpad, std::unique_ptr &obj, const std::string &opt) -> bool { - - auto h1 = DrawField(dynamic_cast (obj.get())); - if (!h1) return false; - - std::shared_ptr shared; - shared.reset(h1); - - subpad->Draw(shared, opt); - subpad->GetCanvas()->Update(true); - return true; - }); + RegisterDraw7(TClass::GetClass(), + [this](std::shared_ptr &subpad, std::unique_ptr &obj, + const std::string &opt) -> bool { + auto h1 = DrawField(dynamic_cast(obj.get())); + if (!h1) + return false; + + std::shared_ptr shared; + shared.reset(h1); + + subpad->Draw(shared, opt); + subpad->GetCanvas()->Update(true); + return true; + }); } } newRNTupleDraw7Provider; diff --git a/gui/browsable/src/RProvider.cxx b/gui/browsable/src/RProvider.cxx index d9033d574df13..42302bc8780d5 100644 --- a/gui/browsable/src/RProvider.cxx +++ b/gui/browsable/src/RProvider.cxx @@ -301,7 +301,7 @@ std::shared_ptr RProvider::Browse(std::unique_ptr &object) std::shared_ptr RProvider::BrowseNTuple(const std::string &tuplename, const std::string &filename) { if (!gNTupleFunc) { - auto &entry = GetClassEntry("ROOT::Experimental::RNTuple"); + auto &entry = GetClassEntry("ROOT::RNTuple"); if (entry.browselib.empty()) return nullptr; @@ -513,7 +513,8 @@ class RDefaultProvider : public RProvider { RegisterClass("ROOT::Experimental::RH2D", "sap-icon://pixelate", "", "", "libROOTHistDrawProvider"); RegisterClass("ROOT::Experimental::RH3D", "sap-icon://product", "", "", "libROOTHistDrawProvider"); RegisterClass("ROOT::Experimental::RCanvas", "sap-icon://business-objects-experience", "", "", "libROOTHistDrawProvider"); - RegisterClass("ROOT::Experimental::RNTuple", "sap-icon://table-chart", "libROOTNTupleBrowseProvider", "libROOTNTupleDraw6Provider", "libROOTNTupleDraw7Provider"); + RegisterClass("ROOT::RNTuple", "sap-icon://table-chart", "libROOTNTupleBrowseProvider", + "libROOTNTupleDraw6Provider", "libROOTNTupleDraw7Provider"); } } newRDefaultProvider; diff --git a/gui/browsable/src/TDirectoryElement.cxx b/gui/browsable/src/TDirectoryElement.cxx index 1ff0657764097..f855d8d865a5b 100644 --- a/gui/browsable/src/TDirectoryElement.cxx +++ b/gui/browsable/src/TDirectoryElement.cxx @@ -554,7 +554,7 @@ std::shared_ptr TDirectoryLevelIter::GetDirElement(bool read_dir) if (!fKeysIter && fObj) return std::make_shared(fObj); - if ("ROOT::Experimental::RNTuple"s == fKey->GetClassName()) + if ("ROOT::RNTuple"s == fKey->GetClassName()) return RProvider::BrowseNTuple(fKey->GetName(), fDir->GetFile()->GetName()); std::string key_class = fKey->GetClassName(); diff --git a/io/io/src/TFileMerger.cxx b/io/io/src/TFileMerger.cxx index 0916717fe4eb1..6bda10a191d8a 100644 --- a/io/io/src/TFileMerger.cxx +++ b/io/io/src/TFileMerger.cxx @@ -56,7 +56,7 @@ ClassImp(TFileMerger); TClassRef R__TH1_Class("TH1"); TClassRef R__TTree_Class("TTree"); -TClassRef R__RNTuple_Class("ROOT::Experimental::RNTuple"); +TClassRef R__RNTuple_Class("ROOT::RNTuple"); static const Int_t kCpProgress = BIT(14); static const Int_t kCintFileNumber = 100; diff --git a/tree/dataframe/inc/ROOT/RNTupleDS.hxx b/tree/dataframe/inc/ROOT/RNTupleDS.hxx index 83d4530552066..b121454c9450d 100644 --- a/tree/dataframe/inc/ROOT/RNTupleDS.hxx +++ b/tree/dataframe/inc/ROOT/RNTupleDS.hxx @@ -32,10 +32,10 @@ #include namespace ROOT { -namespace Experimental { +class RNTuple; +namespace Experimental { class RFieldBase; -class RNTuple; class RNTupleDescriptor; namespace Internal { @@ -153,7 +153,7 @@ class RNTupleDS final : public ROOT::RDF::RDataSource { public: RNTupleDS(std::string_view ntupleName, std::string_view fileName); - RNTupleDS(ROOT::Experimental::RNTuple *ntuple); + RNTupleDS(ROOT::RNTuple *ntuple); RNTupleDS(std::string_view ntupleName, const std::vector &fileNames); ~RNTupleDS(); @@ -180,13 +180,13 @@ protected: Record_t GetColumnReadersImpl(std::string_view name, const std::type_info &) final; }; -} // ns Experimental +} // namespace Experimental namespace RDF { namespace Experimental { RDataFrame FromRNTuple(std::string_view ntupleName, std::string_view fileName); RDataFrame FromRNTuple(std::string_view ntupleName, const std::vector &fileNames); -RDataFrame FromRNTuple(ROOT::Experimental::RNTuple *ntuple); +RDataFrame FromRNTuple(ROOT::RNTuple *ntuple); } // namespace Experimental } // namespace RDF diff --git a/tree/dataframe/src/RLoopManager.cxx b/tree/dataframe/src/RLoopManager.cxx index 0edeada86ac3b..a0a049ecd08a9 100644 --- a/tree/dataframe/src/RLoopManager.cxx +++ b/tree/dataframe/src/RLoopManager.cxx @@ -1249,7 +1249,7 @@ ROOT::Detail::RDF::CreateLMFromFile(std::string_view datasetName, std::string_vi if (inFile->Get(datasetName.data())) { return CreateLMFromTTree(datasetName, fileNameGlob, defaultColumns, /*checkFile=*/false); - } else if (inFile->Get(datasetName.data())) { + } else if (inFile->Get(datasetName.data())) { return CreateLMFromRNTuple(datasetName, fileNameGlob, defaultColumns); } @@ -1266,7 +1266,7 @@ ROOT::Detail::RDF::CreateLMFromFile(std::string_view datasetName, const std::vec if (inFile->Get(datasetName.data())) { return CreateLMFromTTree(datasetName, fileNameGlobs, defaultColumns, /*checkFile=*/false); - } else if (inFile->Get(datasetName.data())) { + } else if (inFile->Get(datasetName.data())) { return CreateLMFromRNTuple(datasetName, fileNameGlobs, defaultColumns); } diff --git a/tree/dataframe/src/RNTupleDS.cxx b/tree/dataframe/src/RNTupleDS.cxx index 7cc945b5061fc..c18c3709e3dcc 100644 --- a/tree/dataframe/src/RNTupleDS.cxx +++ b/tree/dataframe/src/RNTupleDS.cxx @@ -757,7 +757,7 @@ ROOT::RDF::Experimental::FromRNTuple(std::string_view ntupleName, const std::vec return ROOT::RDataFrame(std::make_unique(ntupleName, fileNames)); } -ROOT::RDataFrame ROOT::RDF::Experimental::FromRNTuple(ROOT::Experimental::RNTuple *ntuple) +ROOT::RDataFrame ROOT::RDF::Experimental::FromRNTuple(ROOT::RNTuple *ntuple) { return ROOT::RDataFrame(std::make_unique(ntuple)); } diff --git a/tree/ntuple/inc/LinkDef.h b/tree/ntuple/inc/LinkDef.h index 66b60c2138eb1..ef84bb506a250 100644 --- a/tree/ntuple/inc/LinkDef.h +++ b/tree/ntuple/inc/LinkDef.h @@ -14,6 +14,6 @@ #pragma link off all classes; #pragma link off all functions; -#pragma link C++ class ROOT::Experimental::RNTuple - ; +#pragma link C++ class ROOT::RNTuple - ; #endif diff --git a/tree/ntuple/v7/doc/BinaryFormatSpecification.md b/tree/ntuple/v7/doc/BinaryFormatSpecification.md index 27fad715270ef..573ef95ee4302 100644 --- a/tree/ntuple/v7/doc/BinaryFormatSpecification.md +++ b/tree/ntuple/v7/doc/BinaryFormatSpecification.md @@ -50,7 +50,7 @@ The RNTuple format does _not_ establish a semantic mapping from objects to keys For example, one key may hold a single page or a number of pages of the same cluster. The only relevant means of finding objects is the locator information, consisting of an offset and a size. -For the ROOT file embedding, the `ROOT::Experimental::RNTuple` object acts as an anchor. +For the ROOT file embedding, the `ROOT::RNTuple` object acts as an anchor. ### Anchor schema diff --git a/tree/ntuple/v7/inc/ROOT/RNTuple.hxx b/tree/ntuple/v7/inc/ROOT/RNTuple.hxx index a4ae3f313285e..bb73537acc509 100644 --- a/tree/ntuple/v7/inc/ROOT/RNTuple.hxx +++ b/tree/ntuple/v7/inc/ROOT/RNTuple.hxx @@ -25,12 +25,11 @@ class TFile; class TFileMergeInfo; namespace ROOT { -namespace Experimental { class RNTuple; +namespace Experimental { namespace Internal { -class RMiniFileReader; class RNTupleFileWriter; class RPageSourceFile; @@ -40,10 +39,11 @@ RNTuple CreateAnchor(std::uint16_t versionEpoch, std::uint16_t versionMajor, std std::uint64_t lenFooter, std::uint64_t maxKeySize); } // namespace Internal +} // namespace Experimental // clang-format off /** -\class ROOT::Experimental::RNTuple +\class ROOT::RNTuple \ingroup NTuple \brief Representation of an RNTuple data set in a ROOT file @@ -52,7 +52,7 @@ Only the RNTuple key will be listed in the list of keys. Like TBaskets, the page Byte offset references in the RNTuple header and footer reference directly the data part of page records, skipping the TFile key part. -In the list of keys, this object appears as "ROOT::Experimental::RNTuple". +In the list of keys, this object appears as "ROOT::RNTuple". It is the user-facing representation of an RNTuple data set in a ROOT file and it provides an API entry point to an RNTuple stored in a ROOT file. Its main purpose is to construct a page source for an RNTuple, which in turn can be used to read an RNTuple with an RDF or @@ -61,16 +61,16 @@ an RNTupleReader. For instance, for an RNTuple called "Events" in a ROOT file, usage can be ~~~ {.cpp} auto f = TFile::Open("data.root"); -auto ntpl = f->Get("Events"); +auto ntpl = f->Get("Events"); auto reader = RNTupleReader::Open(ntpl); ~~~ */ // clang-format on class RNTuple final { - friend class Internal::RNTupleFileWriter; - friend class Internal::RPageSourceFile; + friend class Experimental::Internal::RNTupleFileWriter; + friend class Experimental::Internal::RPageSourceFile; - friend ROOT::Experimental::RNTuple ROOT::Experimental::Internal::CreateAnchor( + friend ROOT::RNTuple ROOT::Experimental::Internal::CreateAnchor( std::uint16_t versionEpoch, std::uint16_t versionMajor, std::uint16_t versionMinor, std::uint16_t versionPatch, std::uint64_t seekHeader, std::uint64_t nbytesHeader, std::uint64_t lenHeader, std::uint64_t seekFooter, std::uint64_t nbytesFooter, std::uint64_t lenFooter, std::uint64_t maxKeySize); @@ -133,10 +133,9 @@ public: Long64_t Merge(TCollection *input, TFileMergeInfo *mergeInfo); /// NOTE: if you change this version you also need to update RTFNTuple::fClassVersion in RMiniFile.cxx - ClassDefNV(RNTuple, 6); + ClassDefNV(RNTuple, 2); }; // class RNTuple -} // namespace Experimental } // namespace ROOT #endif diff --git a/tree/ntuple/v7/inc/ROOT/RNTupleReader.hxx b/tree/ntuple/v7/inc/ROOT/RNTupleReader.hxx index 2c39b03b94867..65e94d3e872fe 100644 --- a/tree/ntuple/v7/inc/ROOT/RNTupleReader.hxx +++ b/tree/ntuple/v7/inc/ROOT/RNTupleReader.hxx @@ -34,10 +34,10 @@ #include namespace ROOT { -namespace Experimental { +class RNTuple; +namespace Experimental { class REntry; -class RNTuple; /// Listing of the different options that can be printed by RNTupleReader::GetInfo() enum class ENTupleInfo { diff --git a/tree/ntuple/v7/inc/ROOT/RPageStorageFile.hxx b/tree/ntuple/v7/inc/ROOT/RPageStorageFile.hxx index 00904a22c032c..e3b9820017824 100644 --- a/tree/ntuple/v7/inc/ROOT/RPageStorageFile.hxx +++ b/tree/ntuple/v7/inc/ROOT/RPageStorageFile.hxx @@ -34,13 +34,13 @@ class TFile; namespace ROOT { +class RNTuple; // for making RPageSourceFile a friend of RNTuple namespace Internal { class RRawFile; } namespace Experimental { -class RNTuple; // for making RPageSourceFile a friend of RNTuple struct RNTupleLocator; namespace Internal { @@ -115,7 +115,7 @@ public: */ // clang-format on class RPageSourceFile : public RPageSource { - friend class ROOT::Experimental::RNTuple; + friend class ROOT::RNTuple; private: /// Holds the uncompressed header and footer diff --git a/tree/ntuple/v7/src/RMiniFile.cxx b/tree/ntuple/v7/src/RMiniFile.cxx index b26bfcb590751..f5de3a53bf854 100644 --- a/tree/ntuple/v7/src/RMiniFile.cxx +++ b/tree/ntuple/v7/src/RMiniFile.cxx @@ -538,7 +538,7 @@ struct RTFUUID { /// that fVersionClass matches the class version of RNTuple. struct RTFNTuple { RUInt32BE fByteCount{0x40000000 | (sizeof(RTFNTuple) - sizeof(fByteCount))}; - RUInt16BE fVersionClass{6}; + RUInt16BE fVersionClass{2}; RUInt16BE fVersionEpoch{0}; RUInt16BE fVersionMajor{0}; RUInt16BE fVersionMinor{0}; @@ -554,7 +554,7 @@ struct RTFNTuple { static constexpr std::uint32_t GetSizePlusChecksum() { return sizeof(RTFNTuple) + sizeof(std::uint64_t); } RTFNTuple() = default; - explicit RTFNTuple(const ROOT::Experimental::RNTuple &inMemoryAnchor) + explicit RTFNTuple(const ROOT::RNTuple &inMemoryAnchor) { fVersionEpoch = inMemoryAnchor.GetVersionEpoch(); fVersionMajor = inMemoryAnchor.GetVersionMajor(); @@ -590,7 +590,7 @@ struct RBareFileHeader { /// The artifical class name shown for opaque RNTuple keys (see TBasket) constexpr char const *kBlobClassName = "RBlob"; /// The class name of the RNTuple anchor -constexpr char const *kNTupleClassName = "ROOT::Experimental::RNTuple"; +constexpr char const *kNTupleClassName = "ROOT::RNTuple"; } // anonymous namespace @@ -664,7 +664,7 @@ static size_t ComputeNumChunks(size_t nbytes, size_t maxChunkSize) ROOT::Experimental::Internal::RMiniFileReader::RMiniFileReader(ROOT::Internal::RRawFile *rawFile) : fRawFile(rawFile) {} -ROOT::Experimental::RResult +ROOT::Experimental::RResult ROOT::Experimental::Internal::RMiniFileReader::GetNTuple(std::string_view ntupleName) { char ident[4]; @@ -675,7 +675,7 @@ ROOT::Experimental::Internal::RMiniFileReader::GetNTuple(std::string_view ntuple return GetNTupleBare(ntupleName); } -ROOT::Experimental::RResult +ROOT::Experimental::RResult ROOT::Experimental::Internal::RMiniFileReader::GetNTupleProper(std::string_view ntupleName) { RTFHeader fileHeader; @@ -727,7 +727,9 @@ ROOT::Experimental::Internal::RMiniFileReader::GetNTupleProper(std::string_view offset = key.GetSeekKey() + key.fKeyLen; - constexpr size_t kMinNTupleSize = 70; // size of a RTFNTuple version 4 (min supported version) + // size of a RTFNTuple version 2 (min supported version); future anchor versions can grow. + constexpr size_t kMinNTupleSize = 78; + static_assert(kMinNTupleSize == RTFNTuple::GetSizePlusChecksum()); if (key.fObjLen < kMinNTupleSize) { return R__FAIL("invalid anchor size: " + std::to_string(key.fObjLen) + " < " + std::to_string(sizeof(RTFNTuple))); } @@ -743,24 +745,14 @@ ROOT::Experimental::Internal::RMiniFileReader::GetNTupleProper(std::string_view decompressor.Unzip(bufAnchor.get(), objNbytes, key.fObjLen); } - if (ntuple->fVersionClass < 4) { - return R__FAIL("invalid anchor, unsupported pre-release of RNTuple"); - } - // We require that future class versions only append members and store the checksum in the last 8 bytes // Checksum calculation: strip byte count, class version, fChecksum member auto lenCkData = key.fObjLen - ntuple->GetOffsetCkData() - sizeof(uint64_t); auto ckCalc = XXH3_64bits(ntuple->GetPtrCkData(), lenCkData); uint64_t ckOnDisk; - // For version 4 there is no maxKeySize (there is the checksum instead) - if (ntuple->fVersionClass == 4) { - ckOnDisk = ntuple->fMaxKeySize; - ntuple->fMaxKeySize = 0; - } else { - RUInt64BE *ckOnDiskPtr = reinterpret_cast(bufAnchor.get() + key.fObjLen - sizeof(uint64_t)); - ckOnDisk = static_cast(*ckOnDiskPtr); - } + RUInt64BE *ckOnDiskPtr = reinterpret_cast(bufAnchor.get() + key.fObjLen - sizeof(uint64_t)); + ckOnDisk = static_cast(*ckOnDiskPtr); if (ckCalc != ckOnDisk) { return R__FAIL("RNTuple anchor checksum mismatch"); } @@ -770,7 +762,7 @@ ROOT::Experimental::Internal::RMiniFileReader::GetNTupleProper(std::string_view ntuple->fNBytesFooter, ntuple->fLenFooter, ntuple->fMaxKeySize); } -ROOT::Experimental::RResult +ROOT::Experimental::RResult ROOT::Experimental::Internal::RMiniFileReader::GetNTupleBare(std::string_view ntupleName) { RBareFileHeader fileHeader; @@ -1361,7 +1353,7 @@ void ROOT::Experimental::Internal::RNTupleFileWriter::WriteTFileStreamerInfo() void ROOT::Experimental::Internal::RNTupleFileWriter::WriteTFileKeysList() { RTFString strEmpty; - RTFString strRNTupleClass{"ROOT::Experimental::RNTuple"}; + RTFString strRNTupleClass{"ROOT::RNTuple"}; RTFString strRNTupleName{fNTupleName}; RTFString strFileName{fFileName}; @@ -1406,7 +1398,7 @@ void ROOT::Experimental::Internal::RNTupleFileWriter::WriteTFileFreeList() void ROOT::Experimental::Internal::RNTupleFileWriter::WriteTFileNTupleKey() { - RTFString strRNTupleClass{"ROOT::Experimental::RNTuple"}; + RTFString strRNTupleClass{"ROOT::RNTuple"}; RTFString strRNTupleName{fNTupleName}; RTFString strEmpty; @@ -1421,7 +1413,7 @@ void ROOT::Experimental::Internal::RNTupleFileWriter::WriteTFileNTupleKey() memcpy(keyBuf + sizeof(RTFNTuple), &checksum, sizeof(checksum)); fFileSimple.WriteKey(keyBuf, sizeof(keyBuf), sizeof(keyBuf), fFileSimple.fControlBlock->fSeekNTuple, 100, - "ROOT::Experimental::RNTuple", fNTupleName, ""); + "ROOT::RNTuple", fNTupleName, ""); } void ROOT::Experimental::Internal::RNTupleFileWriter::WriteTFileSkeleton(int defaultCompression) diff --git a/tree/ntuple/v7/src/RNTuple.cxx b/tree/ntuple/v7/src/RNTuple.cxx index bd4e564fb7a04..a436bfa9a5fc2 100644 --- a/tree/ntuple/v7/src/RNTuple.cxx +++ b/tree/ntuple/v7/src/RNTuple.cxx @@ -24,24 +24,18 @@ #include -void ROOT::Experimental::RNTuple::Streamer(TBuffer &buf) +void ROOT::RNTuple::Streamer(TBuffer &buf) { if (buf.IsReading()) { UInt_t offClassBuf; UInt_t bcnt; auto classVersion = buf.ReadVersion(&offClassBuf, &bcnt); - if (classVersion < 4) - throw RException(R__FAIL("unsupported RNTuple pre-release")); // Strip class version from checksum calculation UInt_t lenStrip = sizeof(Version_t); - // TEMP(version4): In version 4 checksum is embedded in the on disk representation, - // so we need to strip that as well from the byte count. - // Support for version 4 will be dropped before the class moves out of experimental. - lenStrip += (classVersion == 4) * sizeof(std::uint64_t); if (bcnt < lenStrip) - throw RException(R__FAIL("invalid anchor byte count: " + std::to_string(bcnt))); + throw Experimental::RException(R__FAIL("invalid anchor byte count: " + std::to_string(bcnt))); auto lenCkData = bcnt - lenStrip; // Skip byte count and class version @@ -49,36 +43,13 @@ void ROOT::Experimental::RNTuple::Streamer(TBuffer &buf) auto expectedChecksum = XXH3_64bits(buf.Buffer() + offCkData, lenCkData); std::uint64_t onDiskChecksum; - if (classVersion == 4) { - // TEMP(version4): Version 5 of the anchor breaks backward compat, but we still want to support version 4 - // for a while. Support for version 4, as well as this code, will be removed before the RNTuple stabilization. - // For version 4 we need to manually read all the known members as we cannot rely on ReadClassBuffer. - constexpr std::size_t expectedBytes = 66; - if (bcnt != expectedBytes) - throw RException(R__FAIL("byte count mismatch in RNTuple anchor v4: expected=" + - std::to_string(expectedBytes) + ", got=" + std::to_string(bcnt))); - buf >> fVersionEpoch; - buf >> fVersionMajor; - buf >> fVersionMinor; - buf >> fVersionPatch; - buf >> fSeekHeader; - buf >> fNBytesHeader; - buf >> fLenHeader; - buf >> fSeekFooter; - buf >> fNBytesFooter; - buf >> fLenFooter; - buf >> onDiskChecksum; - } else { - // Rewind the version bytes, as ReadClassBuffer needs to read the version again. - buf.SetBufferOffset(offClassBuf); - buf.ReadClassBuffer(RNTuple::Class(), this); - if (static_cast(buf.BufferSize()) < buf.Length() + sizeof(onDiskChecksum)) - throw RException(R__FAIL("the buffer containing RNTuple is too small to contain the checksum!")); - buf >> onDiskChecksum; - } + buf.ReadClassBuffer(RNTuple::Class(), this, classVersion, offClassBuf, bcnt); + if (static_cast(buf.BufferSize()) < buf.Length() + sizeof(onDiskChecksum)) + throw Experimental::RException(R__FAIL("the buffer containing RNTuple is too small to contain the checksum!")); + buf >> onDiskChecksum; if (expectedChecksum != onDiskChecksum) - throw RException(R__FAIL("checksum mismatch in RNTuple anchor")); + throw Experimental::RException(R__FAIL("checksum mismatch in RNTuple anchor")); R__ASSERT(buf.GetParent() && buf.GetParent()->InheritsFrom("TFile")); fFile = static_cast(buf.GetParent()); @@ -90,11 +61,12 @@ void ROOT::Experimental::RNTuple::Streamer(TBuffer &buf) } } - -ROOT::Experimental::RNTuple ROOT::Experimental::Internal::CreateAnchor( - std::uint16_t versionEpoch, std::uint16_t versionMajor, std::uint16_t versionMinor, std::uint16_t versionPatch, - std::uint64_t seekHeader, std::uint64_t nbytesHeader, std::uint64_t lenHeader, std::uint64_t seekFooter, - std::uint64_t nbytesFooter, std::uint64_t lenFooter, std::uint64_t maxKeySize) +ROOT::RNTuple ROOT::Experimental::Internal::CreateAnchor(std::uint16_t versionEpoch, std::uint16_t versionMajor, + std::uint16_t versionMinor, std::uint16_t versionPatch, + std::uint64_t seekHeader, std::uint64_t nbytesHeader, + std::uint64_t lenHeader, std::uint64_t seekFooter, + std::uint64_t nbytesFooter, std::uint64_t lenFooter, + std::uint64_t maxKeySize) { RNTuple ntuple; ntuple.fVersionEpoch = versionEpoch; diff --git a/tree/ntuple/v7/src/RNTupleMerger.cxx b/tree/ntuple/v7/src/RNTupleMerger.cxx index 2c2f703668e03..77f6e52d391a8 100644 --- a/tree/ntuple/v7/src/RNTupleMerger.cxx +++ b/tree/ntuple/v7/src/RNTupleMerger.cxx @@ -42,7 +42,7 @@ using namespace ROOT::Experimental; using namespace ROOT::Experimental::Internal; // Entry point for TFileMerger. Internally calls RNTupleMerger::Merge(). -Long64_t RNTuple::Merge(TCollection *inputs, TFileMergeInfo *mergeInfo) +Long64_t ROOT::RNTuple::Merge(TCollection *inputs, TFileMergeInfo *mergeInfo) // IMPORTANT: this function must not throw, as it is used in exception-unsafe code (TFileMerger). try { // Check the inputs @@ -67,9 +67,9 @@ try { // Check if the output file already has a key with that name TKey *outKey = outFile->FindKey(ntupleName.c_str()); - RNTuple *outNTuple = nullptr; + ROOT::RNTuple *outNTuple = nullptr; if (outKey) { - outNTuple = outKey->ReadObject(); + outNTuple = outKey->ReadObject(); if (!outNTuple) { Error("RNTuple::Merge", "Output file already has key, but not of type RNTuple!"); return -1; @@ -102,7 +102,7 @@ try { while (const auto &pitr = itr()) { TFile *inFile = dynamic_cast(pitr); - RNTuple *anchor = inFile ? inFile->Get(ntupleName.c_str()) : nullptr; + ROOT::RNTuple *anchor = inFile ? inFile->Get(ntupleName.c_str()) : nullptr; if (!anchor) { Error("RNTuple::Merge", "Failed to retrieve RNTuple anchor named '%s' from file '%s'", ntupleName.c_str(), inFile->GetName()); @@ -125,7 +125,7 @@ try { // Provide the caller with a merged anchor object (even though we've already // written it). - *this = *outFile->Get(ntupleName.c_str()); + *this = *outFile->Get(ntupleName.c_str()); return 0; } catch (const RException &ex) { diff --git a/tree/ntuple/v7/src/RNTupleReader.cxx b/tree/ntuple/v7/src/RNTupleReader.cxx index 498fcd2785d07..a3eb47929b054 100644 --- a/tree/ntuple/v7/src/RNTupleReader.cxx +++ b/tree/ntuple/v7/src/RNTupleReader.cxx @@ -99,14 +99,14 @@ ROOT::Experimental::RNTupleReader::Open(std::string_view ntupleName, std::string } std::unique_ptr -ROOT::Experimental::RNTupleReader::Open(const ROOT::Experimental::RNTuple &ntuple, const RNTupleReadOptions &options) +ROOT::Experimental::RNTupleReader::Open(const ROOT::RNTuple &ntuple, const RNTupleReadOptions &options) { return std::unique_ptr( new RNTupleReader(Internal::RPageSourceFile::CreateFromAnchor(ntuple, options), options)); } std::unique_ptr -ROOT::Experimental::RNTupleReader::Open(std::unique_ptr model, const ROOT::Experimental::RNTuple &ntuple, +ROOT::Experimental::RNTupleReader::Open(std::unique_ptr model, const ROOT::RNTuple &ntuple, const RNTupleReadOptions &options) { return std::unique_ptr( diff --git a/tree/ntuple/v7/src/RPageStorageDaos.cxx b/tree/ntuple/v7/src/RPageStorageDaos.cxx index ea137440d6086..9afadc7d1b68d 100644 --- a/tree/ntuple/v7/src/RPageStorageDaos.cxx +++ b/tree/ntuple/v7/src/RPageStorageDaos.cxx @@ -168,7 +168,7 @@ struct RDaosContainerNTupleLocator { } anchor.Deserialize(buffer.get(), anchorSize).Unwrap(); - if (anchor.fVersionEpoch != ROOT::Experimental::RNTuple::kVersionEpoch) { + if (anchor.fVersionEpoch != ROOT::RNTuple::kVersionEpoch) { throw ROOT::Experimental::RException( R__FAIL("unsupported RNTuple epoch version: " + std::to_string(anchor.fVersionEpoch))); } diff --git a/tree/ntuple/v7/test/RXTuple.cxx b/tree/ntuple/v7/test/RXTuple.cxx index 58d3ee214ed59..df368c66362b7 100644 --- a/tree/ntuple/v7/test/RXTuple.cxx +++ b/tree/ntuple/v7/test/RXTuple.cxx @@ -7,7 +7,7 @@ #include -void ROOT::Experimental::RXTuple::Streamer(TBuffer &buf) +void ROOT::RXTuple::Streamer(TBuffer &buf) { if (buf.IsReading()) { assert(!"This class should never be read!"); diff --git a/tree/ntuple/v7/test/RXTuple.hxx b/tree/ntuple/v7/test/RXTuple.hxx index fa1a574058994..71e098ed24278 100644 --- a/tree/ntuple/v7/test/RXTuple.hxx +++ b/tree/ntuple/v7/test/RXTuple.hxx @@ -6,7 +6,6 @@ // NOTE: This namespace must be the same as RNTuple namespace ROOT { -namespace Experimental { // A mock of the RNTuple class, used to write a "future version" of RNTuple to a file. // The idea is: @@ -42,7 +41,6 @@ public: ClassDefNV(RXTuple, 99); }; // class RXTuple -} // namespace Experimental } // namespace ROOT #endif diff --git a/tree/ntuple/v7/test/RXTupleLinkDef.h b/tree/ntuple/v7/test/RXTupleLinkDef.h index 6f9031723394d..d7d5d96362f88 100644 --- a/tree/ntuple/v7/test/RXTupleLinkDef.h +++ b/tree/ntuple/v7/test/RXTupleLinkDef.h @@ -1,5 +1,5 @@ #ifdef __CLING__ -#pragma link C++ class ROOT::Experimental::RXTuple - ; +#pragma link C++ class ROOT::RXTuple - ; #endif diff --git a/tree/ntuple/v7/test/ntuple_basics.cxx b/tree/ntuple/v7/test/ntuple_basics.cxx index 04423ff0aaeb3..48e30dafe619a 100644 --- a/tree/ntuple/v7/test/ntuple_basics.cxx +++ b/tree/ntuple/v7/test/ntuple_basics.cxx @@ -223,7 +223,7 @@ TEST(RNTuple, FileAnchor) auto readerB = RNTupleReader::Open("B", fileGuard.GetPath()); auto f = std::unique_ptr(TFile::Open(fileGuard.GetPath().c_str())); - auto ntuple = std::unique_ptr(f->Get("A")); + auto ntuple = std::unique_ptr(f->Get("A")); auto readerA = RNTupleReader::Open(*ntuple); EXPECT_EQ(1U, readerA->GetNEntries()); diff --git a/tree/ntuple/v7/test/ntuple_compat.cxx b/tree/ntuple/v7/test/ntuple_compat.cxx index 616660748c668..a0cf57537cad1 100644 --- a/tree/ntuple/v7/test/ntuple_compat.cxx +++ b/tree/ntuple/v7/test/ntuple_compat.cxx @@ -14,7 +14,7 @@ TEST(RNTupleCompat, Epoch) { FileRaii fileGuard("test_ntuple_compat_epoch.root"); - RNTuple ntpl; + ROOT::RNTuple ntpl; // The first 16 bit integer in the struct is the epoch std::uint16_t *versionEpoch = reinterpret_cast(&ntpl); *versionEpoch = *versionEpoch + 1; @@ -71,7 +71,7 @@ TEST(RNTupleCompat, FeatureFlag) TEST(RNTupleCompat, FwdCompat_FutureNTupleAnchor) { - using ROOT::Experimental::RXTuple; + using ROOT::RXTuple; constexpr static const char *kNtupleObjName = "ntpl"; @@ -124,7 +124,7 @@ TEST(RNTupleCompat, FwdCompat_FutureNTupleAnchor) { auto tfile = std::unique_ptr(TFile::Open(fileGuard.GetPath().c_str(), "READ")); assert(!tfile->IsZombie()); - auto ntuple = std::unique_ptr(tfile->Get(kNtupleObjName)); + auto ntuple = std::unique_ptr(tfile->Get(kNtupleObjName)); EXPECT_EQ(ntuple->GetVersionEpoch(), RXTuple{}.fVersionEpoch); EXPECT_EQ(ntuple->GetVersionMajor(), RXTuple{}.fVersionMajor); EXPECT_EQ(ntuple->GetVersionMinor(), RXTuple{}.fVersionMinor); @@ -155,79 +155,6 @@ TEST(RNTupleCompat, FwdCompat_FutureNTupleAnchor) } } -TEST(RNTupleCompat, NTupleV4) -{ - // A valid RNTuple with ClassVersion 4 and name "myNTuple" - constexpr const char kNtupleV4Bin[1336] = - "\x72\x6F\x6F\x74\x00\x00\xF6\xE2\x00\x00\x00\x64\x00\x00\x05\x37\x00\x00\x04\xF4\x00\x00\x00\x43\x00\x00\x00\x01" - "\x00\x00\x00\x5C\x04\x00\x00\x01\xF9\x00\x00\x03\x51\x00\x00\x01\xA3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" - "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" - "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x98\x00\x04\x00\x00\x00\x5A\x75\xB6" - "\xF7\xC4\x00\x3E\x00\x01\x00\x00\x00\x64\x00\x00\x00\x00\x05\x54\x46\x69\x6C\x65\x1C\x74\x65\x73\x74\x5F\x6E\x74" - "\x75\x70\x6C\x65\x5F\x72\x65\x63\x6F\x6E\x73\x74\x72\x75\x63\x74\x2E\x72\x6F\x6F\x74\x00\x1C\x74\x65\x73\x74\x5F" - "\x6E\x74\x75\x70\x6C\x65\x5F\x72\x65\x63\x6F\x6E\x73\x74\x72\x75\x63\x74\x2E\x72\x6F\x6F\x74\x00\x00\x05\x75\xB6" - "\xF7\xC4\x75\xB6\xF7\xC4\x00\x00\x00\x7D\x00\x00\x00\x5C\x00\x00\x00\x64\x00\x00\x00\x00\x00\x00\x02\xD4\x00\x01" - "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" - "\x00\x00\x00\x94\x00\x04\x00\x00\x00\xAC\x75\xB6\xF7\xC4\x00\x22\x00\x01\x00\x00\x00\xFC\x00\x00\x00\x64\x05\x52" - "\x42\x6C\x6F\x62\x00\x00\x5A\x53\x01\x69\x00\x00\xAC\x00\x00\x28\xB5\x2F\xFD\x20\xAC\x05\x03\x00\x64\x04\x01\x00" - "\xAC\x00\x08\x00\x00\x00\x6D\x79\x4E\x54\x75\x70\x6C\x65\x0D\x00\x00\x00\x52\x4F\x4F\x54\x20\x76\x36\x2E\x33\x32" - "\x2E\x30\x32\xC5\xFF\x01\x00\x00\x00\x2F\x00\x02\x00\x00\x00\x70\x74\x05\x00\x00\x00\x66\x6C\x6F\x61\x74\xE0\x14" - "\x11\x00\x20\xF4\x8A\x45\x01\xC9\xD7\x47\x57\x03\x0A\x00\x2F\x08\x86\xCA\x17\x94\x01\xF9\xBC\x32\xAC\x4E\xA2\x02" - "\x05\xE3\xC6\xCE\x0C\x28\x07\xB2\x00\x00\x00\x52\x00\x04\x00\x00\x00\x30\x75\xB6\xF7\xC4\x00\x22\x00\x01\x00\x00" - "\x01\x90\x00\x00\x00\x64\x05\x52\x42\x6C\x6F\x62\x00\x00\x03\x00\x30\x00\x00\x00\x00\x00\x8A\x45\x01\xC9\xD7\x47" - "\x57\x03\xF4\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\xF4\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\xFE\x7E" - "\x98\x45\xDD\x66\xDF\xC8\x00\x00\x00\x6C\x00\x04\x00\x00\x00\xAC\x75\xB6\xF7\xC4\x00\x22\x00\x01\x00\x00\x01\xE2" - "\x00\x00\x00\x64\x05\x52\x42\x6C\x6F\x62\x00\x00\x5A\x53\x01\x41\x00\x00\xAC\x00\x00\x28\xB5\x2F\xFD\x20\xAC\xC5" - "\x01\x00\x14\x02\x02\x00\xAC\x00\x8A\x45\x01\xC9\xD7\x47\x57\x03\x38\xF4\xFF\xC4\x01\x00\x00\x00\x30\x00\x30\xB2" - "\x01\x7F\x84\x7E\xE1\xE9\xED\xAD\xBF\x08\x00\x7B\xF0\xB8\x62\x30\x9C\x85\xC0\x95\xBC\x1C\x80\xC3\x78\x66\x76\x38" - "\x40\x04\x00\x00\x00\x86\x00\x04\x00\x00\x00\x46\x75\xB6\xF7\xC4\x00\x40\x00\x01\x00\x00\x02\x4E\x00\x00\x00\x64" - "\x1B\x52\x4F\x4F\x54\x3A\x3A\x45\x78\x70\x65\x72\x69\x6D\x65\x6E\x74\x61\x6C\x3A\x3A\x52\x4E\x54\x75\x70\x6C\x65" - "\x08\x6D\x79\x4E\x54\x75\x70\x6C\x65\x00\x40\x00\x00\x42\x00\x04\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00" - "\x00\x00\x01\x1E\x00\x00\x00\x00\x00\x00\x00\x72\x00\x00\x00\x00\x00\x00\x00\xAC\x00\x00\x00\x00\x00\x00\x02\x04" - "\x00\x00\x00\x00\x00\x00\x00\x4A\x00\x00\x00\x00\x00\x00\x00\xAC\x11\x78\xC1\xFB\x65\x67\x92\xE4\x00\x00\x00\x7D" - "\x00\x04\x00\x00\x00\x44\x75\xB6\xF7\xC4\x00\x39\x00\x01\x00\x00\x02\xD4\x00\x00\x00\x64\x00\x1C\x74\x65\x73\x74" - "\x5F\x6E\x74\x75\x70\x6C\x65\x5F\x72\x65\x63\x6F\x6E\x73\x74\x72\x75\x63\x74\x2E\x72\x6F\x6F\x74\x00\x00\x00\x00" - "\x01\x00\x00\x00\x86\x00\x04\x00\x00\x00\x46\x75\xB6\xF7\xC4\x00\x40\x00\x01\x00\x00\x02\x4E\x00\x00\x00\x64\x1B" - "\x52\x4F\x4F\x54\x3A\x3A\x45\x78\x70\x65\x72\x69\x6D\x65\x6E\x74\x61\x6C\x3A\x3A\x52\x4E\x54\x75\x70\x6C\x65\x08" - "\x6D\x79\x4E\x54\x75\x70\x6C\x65\x00\x00\x00\x01\xA3\x00\x04\x00\x00\x04\xF2\x75\xB6\xF7\xC4\x00\x40\x00\x01\x00" - "\x00\x03\x51\x00\x00\x00\x64\x05\x54\x4C\x69\x73\x74\x0C\x53\x74\x72\x65\x61\x6D\x65\x72\x49\x6E\x66\x6F\x12\x44" - "\x6F\x75\x62\x6C\x79\x20\x6C\x69\x6E\x6B\x65\x64\x20\x6C\x69\x73\x74\x5A\x4C\x08\x5A\x01\x00\xF2\x04\x00\x78\x01" - "\xBD\x92\x4D\x4E\xC2\x40\x1C\xC5\x1F\x05\x13\x91\x8F\xAD\x1A\x36\x6E\xBD\x42\x57\x15\x83\x91\x44\x29\x42\xC5\x68" - "\x82\x66\x80\x29\x94\x8F\x99\x66\xDA\x26\xB2\x63\xE7\x69\xBC\x84\x97\xD0\x53\x78\x05\xFD\x77\x24\x04\x12\x89\x68" - "\x83\x2F\x99\x69\x3B\xED\xBC\x5F\xFB\x5E\x2D\x64\xDE\xB1\x83\x14\x48\x46\x3C\x91\x52\x16\x32\x6F\x1F\x24\xA7\x19" - "\x2A\xCE\x26\x5C\x55\x85\x2B\x41\xAB\x2F\xC8\x5A\xC0\x31\x3D\xAE\x37\xA4\x69\x2E\x35\x6C\xDB\x31\xCD\xCA\xA3\xCF" - "\x95\x37\xE1\x22\x64\x63\xD3\x6C\xD4\x9C\xC8\x1F\x73\xB4\xF3\xCF\x55\x32\xCC\xD0\xD6\x27\x6D\x68\x77\x86\x27\x4A" - "\xB1\x69\x6C\x16\x21\xBD\xCA\xCD\xC5\x70\xF2\x8F\x56\xD8\x65\x16\x78\x5D\x67\xEA\xF3\xF8\xD6\x1D\x0C\x9A\x9D\xD8" - "\x11\xA5\xC5\x6B\x00\x28\xB8\x2D\xAE\x02\x4F\x8A\x8A\x2F\xBB\x03\x5A\x40\x9E\x86\x11\x9F\xAC\x53\x31\x12\x81\xD7" - "\x17\xBC\x77\x14\x0C\xA4\x0A\x2D\xA0\x33\x03\x5E\xE9\xF8\x33\xE5\x92\x0D\xA5\x8A\x8D\xB7\x4B\xF1\xC4\x3F\x50\xEA" - "\x2C\xFC\x73\x62\x0F\xF3\xC4\x6E\x60\x58\xC0\x95\xEE\xE5\x70\xB9\x97\x9C\xDB\xE4\x7C\x74\xCE\x59\x8F\xEB\xBC\x8A" - "\x00\x76\x69\xAC\x55\x61\xD1\xCA\x58\x8A\xBE\x05\xB0\xD9\x57\x29\xB7\x30\xE8\xAA\xF9\x5D\xF5\xB5\xF2\x34\xE4\x41" - "\x12\xC8\xFD\x1C\xD2\xD2\x90\xBA\x86\x1C\x2C\x7F\xC7\x9E\x7B\xC1\x45\x12\xC2\x86\x49\x9D\x49\x19\x6E\x3D\xA9\x24" - "\x90\xCD\x92\x4A\x42\x68\xCF\xBB\xB8\xD6\x5D\xD8\xBA\x8B\xFD\xE5\x2E\xB2\xEE\xE9\x80\x77\x47\x41\x34\x01\xE9\x97" - "\x7F\x14\x3E\x01\x15\x3D\xC1\xCA\x00\x00\x00\x43\x00\x04\x00\x00\x00\x0A\x75\xB6\xF7\xC4\x00\x39\x00\x01\x00\x00" - "\x04\xF4\x00\x00\x00\x64\x00\x1C\x74\x65\x73\x74\x5F\x6E\x74\x75\x70\x6C\x65\x5F\x72\x65\x63\x6F\x6E\x73\x74\x72" - "\x75\x63\x74\x2E\x72\x6F\x6F\x74\x00\x00\x01\x00\x00\x05\x37\x77\x35\x94\x00"; - - FileRaii fileGuard("test_ntuple_compat_ntuplev4.root"); - { - FILE *f = fopen(fileGuard.GetPath().c_str(), "wb+"); - auto written = fwrite(kNtupleV4Bin, 1, sizeof(kNtupleV4Bin) - 1, f); - EXPECT_EQ(written, sizeof(kNtupleV4Bin) - 1); - fclose(f); - } - { - auto reader = RNTupleReader::Open("myNTuple", fileGuard.GetPath()); - EXPECT_EQ(reader->GetDescriptor().GetName(), "myNTuple"); - } - { - auto rawFile = RRawFile::Create(fileGuard.GetPath()); - auto reader = RMiniFileReader{rawFile.get()}; - auto ntuple = reader.GetNTuple("myNTuple").Unwrap(); - EXPECT_EQ(ntuple.GetVersionMajor(), 2); - EXPECT_EQ(ntuple.GetMaxKeySize(), 0); - } -} - template <> class ROOT::Experimental::RField final : public RSimpleField { diff --git a/tree/ntuple/v7/test/ntuple_extended.cxx b/tree/ntuple/v7/test/ntuple_extended.cxx index c0b3925113b3f..e751bbf58353a 100644 --- a/tree/ntuple/v7/test/ntuple_extended.cxx +++ b/tree/ntuple/v7/test/ntuple_extended.cxx @@ -167,7 +167,7 @@ TEST(RNTuple, LargeFile1) { auto f = std::unique_ptr(TFile::Open(fileGuard.GetPath().c_str(), "READ")); EXPECT_TRUE(f); - auto ntuple = std::unique_ptr(f->Get("myNTuple")); + auto ntuple = std::unique_ptr(f->Get("myNTuple")); auto reader = RNTupleReader::Open(*ntuple); auto rdEnergy = reader->GetView("energy"); @@ -258,12 +258,12 @@ TEST(RNTuple, LargeFile2) auto s2 = f->Get("s2"); EXPECT_EQ("two", *s2); - auto small = std::unique_ptr(f->Get("small")); + auto small = std::unique_ptr(f->Get("small")); auto reader = RNTupleReader::Open(*small); reader->LoadEntry(0); EXPECT_EQ(42.0f, *reader->GetModel().GetDefaultEntry().GetPtr("pt")); - auto large = std::unique_ptr(f->Get("large")); + auto large = std::unique_ptr(f->Get("large")); reader = RNTupleReader::Open(*large); auto viewE = reader->GetView("E"); double chksumRead = 0.0; diff --git a/tree/ntuple/v7/test/ntuple_minifile.cxx b/tree/ntuple/v7/test/ntuple_minifile.cxx index 10ababcd099d6..dc55ef3e5b7d2 100644 --- a/tree/ntuple/v7/test/ntuple_minifile.cxx +++ b/tree/ntuple/v7/test/ntuple_minifile.cxx @@ -10,7 +10,7 @@ using ROOT::Experimental::Internal::RNTupleWriteOptionsManip; namespace { -bool IsEqual(const ROOT::Experimental::RNTuple &a, const ROOT::Experimental::RNTuple &b) +bool IsEqual(const ROOT::RNTuple &a, const ROOT::RNTuple &b) { return a.GetVersionEpoch() == b.GetVersionEpoch() && a.GetVersionMajor() == b.GetVersionMajor() && a.GetVersionMinor() == b.GetVersionMinor() && a.GetVersionPatch() == b.GetVersionPatch() && @@ -21,10 +21,10 @@ bool IsEqual(const ROOT::Experimental::RNTuple &a, const ROOT::Experimental::RNT } struct RNTupleTester { - ROOT::Experimental::RNTuple fNtpl; + ROOT::RNTuple fNtpl; - explicit RNTupleTester(const ROOT::Experimental::RNTuple &ntpl) : fNtpl(ntpl) {} - RNTuple GetAnchor() const { return fNtpl; } + explicit RNTupleTester(const ROOT::RNTuple &ntpl) : fNtpl(ntpl) {} + ROOT::RNTuple GetAnchor() const { return fNtpl; } }; } // namespace @@ -87,7 +87,7 @@ TEST(MiniFile, Stream) auto file = std::unique_ptr(TFile::Open(fileGuard.GetPath().c_str(), "READ")); ASSERT_TRUE(file); - auto k = std::unique_ptr(file->Get("MyNTuple")); + auto k = std::unique_ptr(file->Get("MyNTuple")); EXPECT_TRUE(IsEqual(ntuple, RNTupleTester(*k).GetAnchor())); } @@ -214,7 +214,7 @@ TEST(MiniFile, SimpleKeys) EXPECT_EQ(buffer[offBlob6], blob6); ASSERT_TRUE(readNextKey()); - EXPECT_STREQ(key->GetClassName(), "ROOT::Experimental::RNTuple"); + EXPECT_STREQ(key->GetClassName(), "ROOT::RNTuple"); ASSERT_TRUE(readNextKey()); // KeysList @@ -319,7 +319,7 @@ TEST(MiniFile, ProperKeys) EXPECT_EQ(buffer[offBlob6], blob6); ASSERT_TRUE(readNextKey()); - EXPECT_STREQ(key->GetClassName(), "ROOT::Experimental::RNTuple"); + EXPECT_STREQ(key->GetClassName(), "ROOT::RNTuple"); ASSERT_TRUE(readNextKey()); // KeysList @@ -616,7 +616,7 @@ TEST(MiniFile, Failures) auto rawFile = RRawFile::Create(fileGuard.GetPath()); RMiniFileReader reader(rawFile.get()); - ROOT::Experimental::RNTuple anchor; + ROOT::RNTuple anchor; try { anchor = reader.GetNTuple("No such RNTuple").Inspect(); FAIL() << "bad RNTuple names should throw"; @@ -699,7 +699,7 @@ TEST(MiniFile, StreamerInfo) }; std::sort(vecInfos.begin(), vecInfos.end(), fnComp); ASSERT_EQ(3u, vecInfos.size()); - EXPECT_STREQ("ROOT::Experimental::RNTuple", vecInfos[0]->GetName()); + EXPECT_STREQ("ROOT::RNTuple", vecInfos[0]->GetName()); EXPECT_STREQ("TVector2", vecInfos[1]->GetName()); EXPECT_STREQ("TVector3", vecInfos[2]->GetName()); } diff --git a/tree/ntuple/v7/test/ntuple_serialize.cxx b/tree/ntuple/v7/test/ntuple_serialize.cxx index 6ffcdadfff6fa..2de1edb8c9f5d 100644 --- a/tree/ntuple/v7/test/ntuple_serialize.cxx +++ b/tree/ntuple/v7/test/ntuple_serialize.cxx @@ -926,12 +926,12 @@ TEST(RNTuple, SerializeStreamerInfos) auto content = RNTupleSerializer::SerializeStreamerInfos(infos); EXPECT_TRUE(RNTupleSerializer::DeserializeStreamerInfos(content).Unwrap().empty()); - auto streamerInfo = RNTuple::Class()->GetStreamerInfo(); + auto streamerInfo = ROOT::RNTuple::Class()->GetStreamerInfo(); infos[streamerInfo->GetNumber()] = streamerInfo; content = RNTupleSerializer::SerializeStreamerInfos(infos); auto result = RNTupleSerializer::DeserializeStreamerInfos(content).Unwrap(); EXPECT_EQ(1u, result.size()); - EXPECT_STREQ("ROOT::Experimental::RNTuple", std::string(result.begin()->second->GetName()).c_str()); + EXPECT_STREQ("ROOT::RNTuple", std::string(result.begin()->second->GetName()).c_str()); } TEST(RNTuple, SerializeMultiColumnRepresentation) diff --git a/tree/ntuple/v7/test/ntuple_storage.cxx b/tree/ntuple/v7/test/ntuple_storage.cxx index 3a8938b5ffbdd..2cdd8389a43e6 100644 --- a/tree/ntuple/v7/test/ntuple_storage.cxx +++ b/tree/ntuple/v7/test/ntuple_storage.cxx @@ -488,7 +488,7 @@ TEST(RNTuple, WritePageBudget) TEST(RNTuple, OpenHTTP) { std::unique_ptr file(TFile::Open("http://root.cern/files/tutorials/ntpl004_dimuon_v1rc2.root")); - auto Events = std::unique_ptr(file->Get("Events")); + auto Events = std::unique_ptr(file->Get("Events")); auto model = RNTupleModel::Create(); model->MakeField>("nMuon"); auto reader = RNTupleReader::Open(std::move(model), *Events); @@ -508,7 +508,7 @@ TEST(RNTuple, TMemFile) writer->Fill(); } - auto ntpl = std::unique_ptr(file.Get("ntpl")); + auto ntpl = std::unique_ptr(file.Get("ntpl")); auto reader = RNTupleReader::Open(*ntpl); auto pt = reader->GetModel().GetDefaultEntry().GetPtr("pt"); reader->LoadEntry(0); diff --git a/tree/ntuple/v7/test/ntuple_test.hxx b/tree/ntuple/v7/test/ntuple_test.hxx index 0e8161bd04f15..99b200cb203cc 100644 --- a/tree/ntuple/v7/test/ntuple_test.hxx +++ b/tree/ntuple/v7/test/ntuple_test.hxx @@ -77,7 +77,6 @@ using RFieldDescriptor = ROOT::Experimental::RFieldDescriptor; using RNTupleLocator = ROOT::Experimental::RNTupleLocator; using RNTupleLocatorObject64 = ROOT::Experimental::RNTupleLocatorObject64; using RMiniFileReader = ROOT::Experimental::Internal::RMiniFileReader; -using RNTuple = ROOT::Experimental::RNTuple; using RNTupleAtomicCounter = ROOT::Experimental::Detail::RNTupleAtomicCounter; using RNTupleAtomicTimer = ROOT::Experimental::Detail::RNTupleAtomicTimer; using RNTupleCalcPerf = ROOT::Experimental::Detail::RNTupleCalcPerf; diff --git a/tree/ntuple/v7/test/ntuple_view.cxx b/tree/ntuple/v7/test/ntuple_view.cxx index 5a638bcfbc99e..2c5c07e9bb967 100644 --- a/tree/ntuple/v7/test/ntuple_view.cxx +++ b/tree/ntuple/v7/test/ntuple_view.cxx @@ -351,7 +351,7 @@ TEST(RNTuple, ViewFrameworkUse) } } - auto ntpl = std::unique_ptr(file.Get("ntpl")); + auto ntpl = std::unique_ptr(file.Get("ntpl")); auto reader = RNTupleReader::Open(*ntpl); reader->EnableMetrics(); diff --git a/tree/ntupleutil/v7/inc/ROOT/RNTupleInspector.hxx b/tree/ntupleutil/v7/inc/ROOT/RNTupleInspector.hxx index 20ecd06984a8b..4f65d79160c57 100644 --- a/tree/ntupleutil/v7/inc/ROOT/RNTupleInspector.hxx +++ b/tree/ntupleutil/v7/inc/ROOT/RNTupleInspector.hxx @@ -31,10 +31,10 @@ #include namespace ROOT { -namespace Experimental { - class RNTuple; +namespace Experimental { + namespace Internal { class RPageSource; } // namespace Internal diff --git a/tree/ntupleutil/v7/src/RNTupleInspector.cxx b/tree/ntupleutil/v7/src/RNTupleInspector.cxx index b524a2a0a8d48..f22fb95e12285 100644 --- a/tree/ntupleutil/v7/src/RNTupleInspector.cxx +++ b/tree/ntupleutil/v7/src/RNTupleInspector.cxx @@ -151,7 +151,7 @@ ROOT::Experimental::RNTupleInspector::GetColumnsByFieldId(DescriptorId_t fieldId } std::unique_ptr -ROOT::Experimental::RNTupleInspector::Create(const ROOT::Experimental::RNTuple &sourceNTuple) +ROOT::Experimental::RNTupleInspector::Create(const ROOT::RNTuple &sourceNTuple) { auto pageSource = Internal::RPageSourceFile::CreateFromAnchor(sourceNTuple); return std::unique_ptr(new RNTupleInspector(std::move(pageSource))); diff --git a/tree/ntupleutil/v7/test/ntuple_inspector.cxx b/tree/ntupleutil/v7/test/ntuple_inspector.cxx index 70c9fedc7bf2a..08660e1fa8e8e 100644 --- a/tree/ntupleutil/v7/test/ntuple_inspector.cxx +++ b/tree/ntupleutil/v7/test/ntuple_inspector.cxx @@ -9,10 +9,10 @@ #include "CustomStructUtil.hxx" #include "ntupleutil_test.hxx" +using ROOT::RNTuple; using ROOT::Experimental::EColumnType; using ROOT::Experimental::RField; using ROOT::Experimental::RFieldBase; -using ROOT::Experimental::RNTuple; using ROOT::Experimental::RNTupleInspector; using ROOT::Experimental::RNTupleModel; using ROOT::Experimental::RNTupleWriteOptions; diff --git a/tutorials/v7/ntuple/ntpl008_import.C b/tutorials/v7/ntuple/ntpl008_import.C index 6b32198fd947f..c5638457788ae 100644 --- a/tutorials/v7/ntuple/ntpl008_import.C +++ b/tutorials/v7/ntuple/ntpl008_import.C @@ -23,7 +23,6 @@ #include // Import classes from experimental namespace for the time being. -using RNTuple = ROOT::Experimental::RNTuple; using RNTupleImporter = ROOT::Experimental::RNTupleImporter; using RNTupleReader = ROOT::Experimental::RNTupleReader; @@ -53,7 +52,7 @@ void ntpl008_import() std::cerr << "cannot open " << kNTupleFileName << std::endl; return; } - auto ntpl = std::unique_ptr(file->Get("Events")); + auto ntpl = std::unique_ptr(file->Get("Events")); auto reader = RNTupleReader::Open(*ntpl); reader->PrintInfo(); diff --git a/tutorials/v7/ntuple/ntpl010_skim.C b/tutorials/v7/ntuple/ntpl010_skim.C index 7d3dffadbd413..7ac16c614b5fa 100644 --- a/tutorials/v7/ntuple/ntpl010_skim.C +++ b/tutorials/v7/ntuple/ntpl010_skim.C @@ -24,7 +24,6 @@ #include // Import classes from experimental namespace for the time being. -using ROOT::Experimental::RNTuple; using ROOT::Experimental::RNTupleModel; using ROOT::Experimental::RNTupleReader; using ROOT::Experimental::RNTupleWriter; From c5887c1de60460dbcabb3a4d978812e368af6593 Mon Sep 17 00:00:00 2001 From: Jakob Blomer Date: Wed, 9 Oct 2024 00:07:14 +0200 Subject: [PATCH 4/9] [ntuple] remove column groups --- .../v7/doc/BinaryFormatSpecification.md | 25 ------------------- tree/ntuple/v7/src/RNTupleSerialize.cxx | 14 ----------- 2 files changed, 39 deletions(-) diff --git a/tree/ntuple/v7/doc/BinaryFormatSpecification.md b/tree/ntuple/v7/doc/BinaryFormatSpecification.md index 573ef95ee4302..02d61f7a655c2 100644 --- a/tree/ntuple/v7/doc/BinaryFormatSpecification.md +++ b/tree/ntuple/v7/doc/BinaryFormatSpecification.md @@ -627,7 +627,6 @@ The footer envelope has the following structure: - Feature flags - Header checksum (XxHash-3 64bit) - Schema extension record frame -- List frame of column group record frames - List frame of cluster group record frames The header checksum can be used to cross-check that header and footer belong together. @@ -658,30 +657,6 @@ should continue from the largest IDs found in the header. Note that is it possible to extend existing fields by additional column representations. This means that columns of the extension header may point to fields of the regular header. -#### Column Group Record Frame -The column group record frame is used to set IDs for certain subsets of column IDs. -Column groups are only used when there are sharded clusters. -Otherwise, the enclosing list frame in the footer envelope is empty and all clusters span all columns. -The purpose of column groups is to prevent repetition of column ID ranges in cluster summaries. - -The column group record frame consists of a list frame of 32bit integer items. -Every item denotes a column ID that is part of this particular column group. -The ID of the column group is given implicitly by the order of column groups. - -The frame hierarchy is as follows - - - Column group outer list frame - | - |---- Column group 1 record frame - | |---- List frame of column IDs - | | |---- Column ID 1 [32bit integer] - | | |---- Column ID 2 [32bit integer] - | | | ... - | - |---- Column group 2 record frame - | ... - - #### Cluster Group Record Frame The cluster group record frame references the page list envelopes for groups of clusters. diff --git a/tree/ntuple/v7/src/RNTupleSerialize.cxx b/tree/ntuple/v7/src/RNTupleSerialize.cxx index 61d0972d13dee..6e8bb1e695bbf 100644 --- a/tree/ntuple/v7/src/RNTupleSerialize.cxx +++ b/tree/ntuple/v7/src/RNTupleSerialize.cxx @@ -1624,11 +1624,6 @@ ROOT::Experimental::Internal::RNTupleSerializer::SerializeFooter(void *buffer, pos += SerializeSchemaDescription(*where, desc, context, /*forHeaderExtension=*/true); pos += SerializeFramePostscript(buffer ? frame : nullptr, pos - frame); - // So far no support for shared clusters (no column groups) - frame = pos; - pos += SerializeListFramePreamble(0, *where); - pos += SerializeFramePostscript(buffer ? frame : nullptr, pos - frame); - // Cluster groups frame = pos; const auto nClusterGroups = desc.GetNClusterGroups(); @@ -1754,15 +1749,6 @@ ROOT::Experimental::Internal::RNTupleSerializer::DeserializeFooter(const void *b } bytes = frame + frameSize; - std::uint32_t nColumnGroups; - frame = bytes; - result = DeserializeFrameHeader(bytes, fnBufSizeLeft(), frameSize, nColumnGroups); - if (!result) - return R__FORWARD_ERROR(result); - if (nColumnGroups > 0) - return R__FAIL("sharded clusters are still unsupported"); - bytes = frame + frameSize; - std::uint32_t nClusterGroups; frame = bytes; result = DeserializeFrameHeader(bytes, fnBufSizeLeft(), frameSize, nClusterGroups); From 8528ac320c8cece2941e57635430de7439fcba05 Mon Sep 17 00:00:00 2001 From: Jakob Blomer Date: Wed, 9 Oct 2024 09:14:46 +0200 Subject: [PATCH 5/9] [ntuple] reset on-disk column flags For historical reasons, the current column flags are 0x08 and 0x10. Reset to 0x01 and 0x02 for format RC3. --- tree/ntuple/v7/doc/BinaryFormatSpecification.md | 14 +++++++------- tree/ntuple/v7/inc/ROOT/RNTupleSerialize.hxx | 4 ++-- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/tree/ntuple/v7/doc/BinaryFormatSpecification.md b/tree/ntuple/v7/doc/BinaryFormatSpecification.md index 02d61f7a655c2..54fe7cb0bcc3c 100644 --- a/tree/ntuple/v7/doc/BinaryFormatSpecification.md +++ b/tree/ntuple/v7/doc/BinaryFormatSpecification.md @@ -449,15 +449,15 @@ Top-level fields have their own field ID set as parent ID. | Flags | Representation Index | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | | -+ First element index (if flag 0x08 is set) + ++ First element index (if flag 0x01 is set) + | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | | -+ Min value (if flag 0x10 is set) + ++ Min value (if flag 0x02 is set) + | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | | -+ Max value (if flag 0x10 is set) + ++ Max value (if flag 0x02 is set) + | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ``` @@ -544,10 +544,10 @@ The "flags" field can have one of the following bits set | Bit | Meaning | |----------|-------------------------------------------------------------------| -| 0x08 | Deferred column: index of first element in the column is not zero | -| 0x10 | Column with a range of possible values | +| 0x01 | Deferred column: index of first element in the column is not zero | +| 0x02 | Column with a range of possible values | -If flag 0x08 (deferred column) is set, the index of the first element in this column is not zero, +If flag 0x01 (deferred column) is set, the index of the first element in this column is not zero, which happens if the column is added at a later point during write. In this case, an additional 64bit integer containing the first element index follows the representation index field. Compliant implementations should yield synthetic data pages made up of 0x00 bytes @@ -557,7 +557,7 @@ including `std::variant` and collections such as `std::vector`. The leading zero pages of deferred columns are _not_ part of the page list, i.e. they have no page locator. In practice, deferred columns only appear in the schema extension record frame (see Section Footer Envelope). -If flag 0x10 (column with range) is set, the column metadata contains the inclusive range of valid values +If flag 0x02 (column with range) is set, the column metadata contains the inclusive range of valid values for this column (used e.g. for quantized real values). The range is represented as a min and a max value, specified as IEEE 754 little-endian double precision floats. diff --git a/tree/ntuple/v7/inc/ROOT/RNTupleSerialize.hxx b/tree/ntuple/v7/inc/ROOT/RNTupleSerialize.hxx index 72a5f0a31cbfe..931a004326455 100644 --- a/tree/ntuple/v7/inc/ROOT/RNTupleSerialize.hxx +++ b/tree/ntuple/v7/inc/ROOT/RNTupleSerialize.hxx @@ -69,8 +69,8 @@ public: static constexpr std::uint16_t kFlagProjectedField = 0x02; static constexpr std::uint16_t kFlagHasTypeChecksum = 0x04; - static constexpr std::uint16_t kFlagDeferredColumn = 0x08; - static constexpr std::uint16_t kFlagHasValueRange = 0x10; + static constexpr std::uint16_t kFlagDeferredColumn = 0x01; + static constexpr std::uint16_t kFlagHasValueRange = 0x02; static constexpr DescriptorId_t kZeroFieldId = std::uint64_t(-2); From c211a5e0a261a8779a84b85fad69b9203c756453 Mon Sep 17 00:00:00 2001 From: Jakob Blomer Date: Wed, 9 Oct 2024 10:04:26 +0200 Subject: [PATCH 6/9] [ntuple] field s11n: optional bits last Make sure that we can easily extend the field meta-data by putting all the mandatory components first and the optional components last. --- .../v7/doc/BinaryFormatSpecification.md | 14 ++--- tree/ntuple/v7/src/RNTupleSerialize.cxx | 54 +++++++++---------- 2 files changed, 34 insertions(+), 34 deletions(-) diff --git a/tree/ntuple/v7/doc/BinaryFormatSpecification.md b/tree/ntuple/v7/doc/BinaryFormatSpecification.md index 54fe7cb0bcc3c..2ea04627ad2c4 100644 --- a/tree/ntuple/v7/doc/BinaryFormatSpecification.md +++ b/tree/ntuple/v7/doc/BinaryFormatSpecification.md @@ -365,6 +365,13 @@ Every field record frame of the list of fields has the following contents +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ``` +The block of integers is followed by a list of strings: + +- String: field name +- String: type name +- String: type alias +- String: field description + The field version and type version are used for schema evolution. The structural role of the field can have one of the following values: @@ -423,13 +430,6 @@ Depending on the flags, the following optional values follow: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ``` -The block of integers is followed by a list of strings: - -- String: field name -- String: type name -- String: type alias -- String: field description - The order of fields matters: every field gets an implicit field ID which is equal the zero-based index of the field in the serialized list; subfields are ordered from smaller IDs to larger IDs. diff --git a/tree/ntuple/v7/src/RNTupleSerialize.cxx b/tree/ntuple/v7/src/RNTupleSerialize.cxx index 6e8bb1e695bbf..033ab4df4da7c 100644 --- a/tree/ntuple/v7/src/RNTupleSerialize.cxx +++ b/tree/ntuple/v7/src/RNTupleSerialize.cxx @@ -70,6 +70,11 @@ std::uint32_t SerializeField(const ROOT::Experimental::RFieldDescriptor &fieldDe flags |= RNTupleSerializer::kFlagHasTypeChecksum; pos += RNTupleSerializer::SerializeUInt16(flags, *where); + pos += RNTupleSerializer::SerializeString(fieldDesc.GetFieldName(), *where); + pos += RNTupleSerializer::SerializeString(fieldDesc.GetTypeName(), *where); + pos += RNTupleSerializer::SerializeString(fieldDesc.GetTypeAlias(), *where); + pos += RNTupleSerializer::SerializeString(fieldDesc.GetFieldDescription(), *where); + if (flags & RNTupleSerializer::kFlagRepetitiveField) { pos += RNTupleSerializer::SerializeUInt64(fieldDesc.GetNRepetitions(), *where); } @@ -80,11 +85,6 @@ std::uint32_t SerializeField(const ROOT::Experimental::RFieldDescriptor &fieldDe pos += RNTupleSerializer::SerializeUInt32(fieldDesc.GetTypeChecksum().value(), *where); } - pos += RNTupleSerializer::SerializeString(fieldDesc.GetFieldName(), *where); - pos += RNTupleSerializer::SerializeString(fieldDesc.GetTypeName(), *where); - pos += RNTupleSerializer::SerializeString(fieldDesc.GetTypeAlias(), *where); - pos += RNTupleSerializer::SerializeString(fieldDesc.GetFieldDescription(), *where); - auto size = pos - base; RNTupleSerializer::SerializeFramePostscript(base, size); @@ -158,6 +158,28 @@ RResult DeserializeField(const void *buffer, std::uint64_t bufSiz bytes += RNTupleSerializer::DeserializeUInt16(bytes, flags); fieldDesc.FieldVersion(fieldVersion).TypeVersion(typeVersion).ParentId(parentId).Structure(structure); + std::string fieldName; + std::string typeName; + std::string aliasName; + std::string description; + result = RNTupleSerializer::DeserializeString(bytes, fnFrameSizeLeft(), fieldName).Unwrap(); + if (!result) + return R__FORWARD_ERROR(result); + bytes += result.Unwrap(); + result = RNTupleSerializer::DeserializeString(bytes, fnFrameSizeLeft(), typeName).Unwrap(); + if (!result) + return R__FORWARD_ERROR(result); + bytes += result.Unwrap(); + result = RNTupleSerializer::DeserializeString(bytes, fnFrameSizeLeft(), aliasName).Unwrap(); + if (!result) + return R__FORWARD_ERROR(result); + bytes += result.Unwrap(); + result = RNTupleSerializer::DeserializeString(bytes, fnFrameSizeLeft(), description).Unwrap(); + if (!result) + return R__FORWARD_ERROR(result); + bytes += result.Unwrap(); + fieldDesc.FieldName(fieldName).TypeName(typeName).TypeAlias(aliasName).FieldDescription(description); + if (flags & RNTupleSerializer::kFlagRepetitiveField) { if (fnFrameSizeLeft() < sizeof(std::uint64_t)) return R__FAIL("field record frame too short"); @@ -182,28 +204,6 @@ RResult DeserializeField(const void *buffer, std::uint64_t bufSiz fieldDesc.TypeChecksum(typeChecksum); } - std::string fieldName; - std::string typeName; - std::string aliasName; - std::string description; - result = RNTupleSerializer::DeserializeString(bytes, fnFrameSizeLeft(), fieldName).Unwrap(); - if (!result) - return R__FORWARD_ERROR(result); - bytes += result.Unwrap(); - result = RNTupleSerializer::DeserializeString(bytes, fnFrameSizeLeft(), typeName).Unwrap(); - if (!result) - return R__FORWARD_ERROR(result); - bytes += result.Unwrap(); - result = RNTupleSerializer::DeserializeString(bytes, fnFrameSizeLeft(), aliasName).Unwrap(); - if (!result) - return R__FORWARD_ERROR(result); - bytes += result.Unwrap(); - result = RNTupleSerializer::DeserializeString(bytes, fnFrameSizeLeft(), description).Unwrap(); - if (!result) - return R__FORWARD_ERROR(result); - bytes += result.Unwrap(); - fieldDesc.FieldName(fieldName).TypeName(typeName).TypeAlias(aliasName).FieldDescription(description); - return frameSize; } From 4fed80203e1c1fda3e074ae7dec76347b54ed467 Mon Sep 17 00:00:00 2001 From: Jakob Blomer Date: Wed, 9 Oct 2024 10:31:03 +0200 Subject: [PATCH 7/9] [ntuple] reorder column constants --- .../v7/doc/BinaryFormatSpecification.md | 56 ++++----- tree/ntuple/v7/src/RNTupleSerialize.cxx | 109 +++++++++--------- 2 files changed, 82 insertions(+), 83 deletions(-) diff --git a/tree/ntuple/v7/doc/BinaryFormatSpecification.md b/tree/ntuple/v7/doc/BinaryFormatSpecification.md index 2ea04627ad2c4..82603b069ed9b 100644 --- a/tree/ntuple/v7/doc/BinaryFormatSpecification.md +++ b/tree/ntuple/v7/doc/BinaryFormatSpecification.md @@ -480,36 +480,36 @@ The column type and bits on storage integers can have one of the following value | Type | Bits | Name | Contents | |------|------|--------------|-----------------------------------------------------------------------------------------------| -| 0x01 | 64 | Index64 | Parent columns of (nested) collections, counting is relative to the cluster | -| 0x02 | 32 | Index32 | Parent columns of (nested) collections, counting is relative to the cluster | -| 0x03 | 96 | Switch | Tuple of a kIndex64 value followed by a 32 bits dispatch tag to a column ID | -| 0x04 | 8 | Byte | An uninterpreted byte, e.g. part of a blob | -| 0x05 | 8 | Char | ASCII character | -| 0x06 | 1 | Bit | Boolean value | -| 0x07 | 64 | Real64 | IEEE-754 double precision float | -| 0x08 | 32 | Real32 | IEEE-754 single precision float | -| 0x09 | 16 | Real16 | IEEE-754 half precision float | -| 0x16 | 64 | Int64 | Two's complement, little-endian 8-byte signed integer | +| 0x00 | 1 | Bit | Boolean value | +| 0x01 | 8 | Byte | An uninterpreted byte, e.g. part of a blob | +| 0x02 | 8 | Char | ASCII character | +| 0x03 | 8 | Int8 | Two's complement, 1-byte signed integer | +| 0x04 | 8 | UInt8 | 1 byte unsigned integer | +| 0x05 | 16 | Int16 | Two's complement, little-endian 2-byte signed integer | +| 0x06 | 16 | UInt16 | Little-endian 2-byte unsigned integer | +| 0x07 | 32 | Int32 | Two's complement, little-endian 4-byte signed integer | +| 0x08 | 32 | UInt32 | Little-endian 4-byte unsigned integer | +| 0x09 | 64 | Int64 | Two's complement, little-endian 8-byte signed integer | | 0x0A | 64 | UInt64 | Little-endian 8-byte unsigned integer | -| 0x17 | 32 | Int32 | Two's complement, little-endian 4-byte signed integer | -| 0x0B | 32 | UInt32 | Little-endian 4-byte unsigned integer | -| 0x18 | 16 | Int16 | Two's complement, little-endian 2-byte signed integer | -| 0x0C | 16 | UInt16 | Little-endian 2-byte unsigned integer | -| 0x19 | 8 | Int8 | Two's complement, 1-byte signed integer | -| 0x0D | 8 | UInt8 | 1 byte unsigned integer | -| 0x0E | 64 | SplitIndex64 | Like Index64 but pages are stored in split + delta encoding | -| 0x0F | 32 | SplitIndex32 | Like Index32 but pages are stored in split + delta encoding | -| 0x10 | 64 | SplitReal64 | Like Real64 but in split encoding | -| 0x11 | 32 | SplitReal32 | Like Real32 but in split encoding | -| 0x12 | 16 | SplitReal16 | Like Real16 but in split encoding | -| 0x1A | 64 | SplitInt64 | Like Int64 but in split + zigzag encoding | -| 0x13 | 64 | SplitUInt64 | Like UInt64 but in split encoding | -| 0x1B | 64 | SplitInt32 | Like Int32 but in split + zigzag encoding | +| 0x0B | 16 | Real16 | IEEE-754 half precision float | +| 0x0C | 32 | Real32 | IEEE-754 single precision float | +| 0x0D | 64 | Real64 | IEEE-754 double precision float | +| 0x0E | 32 | Index32 | Parent columns of (nested) collections, counting is relative to the cluster | +| 0x0F | 64 | Index64 | Parent columns of (nested) collections, counting is relative to the cluster | +| 0x10 | 96 | Switch | Tuple of a kIndex64 value followed by a 32 bits dispatch tag to a column ID | +| 0x11 | 16 | SplitInt16 | Like Int16 but in split + zigzag encoding | +| 0x12 | 16 | SplitUInt16 | Like UInt16 but in split encoding | +| 0x13 | 64 | SplitInt32 | Like Int32 but in split + zigzag encoding | | 0x14 | 32 | SplitUInt32 | Like UInt32 but in split encoding | -| 0x1C | 16 | SplitInt16 | Like Int16 but in split + zigzag encoding | -| 0x15 | 16 | SplitUInt16 | Like UInt16 but in split encoding | -| 0x1D |10-31 | Real32Trunc | IEEE-754 single precision float with truncated mantissa | -| 0x1E | 1-32 | Real32Quant | Real value contained in a specified range with an underlying quantized integer representation | +| 0x15 | 64 | SplitInt64 | Like Int64 but in split + zigzag encoding | +| 0x16 | 64 | SplitUInt64 | Like UInt64 but in split encoding | +| 0x17 | 16 | SplitReal16 | Like Real16 but in split encoding | +| 0x18 | 32 | SplitReal32 | Like Real32 but in split encoding | +| 0x19 | 64 | SplitReal64 | Like Real64 but in split encoding | +| 0x1A | 32 | SplitIndex32 | Like Index32 but pages are stored in split + delta encoding | +| 0x1B | 64 | SplitIndex64 | Like Index64 but pages are stored in split + delta encoding | +| 0x1C |10-31 | Real32Trunc | IEEE-754 single precision float with truncated mantissa | +| 0x1D | 1-32 | Real32Quant | Real value contained in a specified range with an underlying quantized integer representation | The "split encoding" columns apply a byte transformation encoding to all pages of that column and in addition, depending on the column type, delta or zigzag encoding: diff --git a/tree/ntuple/v7/src/RNTupleSerialize.cxx b/tree/ntuple/v7/src/RNTupleSerialize.cxx index 033ab4df4da7c..46eb6a465823a 100644 --- a/tree/ntuple/v7/src/RNTupleSerialize.cxx +++ b/tree/ntuple/v7/src/RNTupleSerialize.cxx @@ -682,35 +682,35 @@ ROOT::Experimental::Internal::RNTupleSerializer::SerializeColumnType(ROOT::Exper using EColumnType = ROOT::Experimental::EColumnType; switch (type) { - case EColumnType::kIndex64: return SerializeUInt16(0x01, buffer); - case EColumnType::kIndex32: return SerializeUInt16(0x02, buffer); - case EColumnType::kSwitch: return SerializeUInt16(0x03, buffer); - case EColumnType::kByte: return SerializeUInt16(0x04, buffer); - case EColumnType::kChar: return SerializeUInt16(0x05, buffer); - case EColumnType::kBit: return SerializeUInt16(0x06, buffer); - case EColumnType::kReal64: return SerializeUInt16(0x07, buffer); - case EColumnType::kReal32: return SerializeUInt16(0x08, buffer); - case EColumnType::kReal16: return SerializeUInt16(0x09, buffer); - case EColumnType::kInt64: return SerializeUInt16(0x16, buffer); + case EColumnType::kBit: return SerializeUInt16(0x00, buffer); + case EColumnType::kByte: return SerializeUInt16(0x01, buffer); + case EColumnType::kChar: return SerializeUInt16(0x02, buffer); + case EColumnType::kInt8: return SerializeUInt16(0x03, buffer); + case EColumnType::kUInt8: return SerializeUInt16(0x04, buffer); + case EColumnType::kInt16: return SerializeUInt16(0x05, buffer); + case EColumnType::kUInt16: return SerializeUInt16(0x06, buffer); + case EColumnType::kInt32: return SerializeUInt16(0x07, buffer); + case EColumnType::kUInt32: return SerializeUInt16(0x08, buffer); + case EColumnType::kInt64: return SerializeUInt16(0x09, buffer); case EColumnType::kUInt64: return SerializeUInt16(0x0A, buffer); - case EColumnType::kInt32: return SerializeUInt16(0x17, buffer); - case EColumnType::kUInt32: return SerializeUInt16(0x0B, buffer); - case EColumnType::kInt16: return SerializeUInt16(0x18, buffer); - case EColumnType::kUInt16: return SerializeUInt16(0x0C, buffer); - case EColumnType::kInt8: return SerializeUInt16(0x19, buffer); - case EColumnType::kUInt8: return SerializeUInt16(0x0D, buffer); - case EColumnType::kSplitIndex64: return SerializeUInt16(0x0E, buffer); - case EColumnType::kSplitIndex32: return SerializeUInt16(0x0F, buffer); - case EColumnType::kSplitReal64: return SerializeUInt16(0x10, buffer); - case EColumnType::kSplitReal32: return SerializeUInt16(0x11, buffer); - case EColumnType::kSplitInt64: return SerializeUInt16(0x1A, buffer); - case EColumnType::kSplitUInt64: return SerializeUInt16(0x13, buffer); - case EColumnType::kSplitInt32: return SerializeUInt16(0x1B, buffer); + case EColumnType::kReal16: return SerializeUInt16(0x0B, buffer); + case EColumnType::kReal32: return SerializeUInt16(0x0C, buffer); + case EColumnType::kReal64: return SerializeUInt16(0x0D, buffer); + case EColumnType::kIndex32: return SerializeUInt16(0x0E, buffer); + case EColumnType::kIndex64: return SerializeUInt16(0x0F, buffer); + case EColumnType::kSwitch: return SerializeUInt16(0x10, buffer); + case EColumnType::kSplitInt16: return SerializeUInt16(0x11, buffer); + case EColumnType::kSplitUInt16: return SerializeUInt16(0x12, buffer); + case EColumnType::kSplitInt32: return SerializeUInt16(0x13, buffer); case EColumnType::kSplitUInt32: return SerializeUInt16(0x14, buffer); - case EColumnType::kSplitInt16: return SerializeUInt16(0x1C, buffer); - case EColumnType::kSplitUInt16: return SerializeUInt16(0x15, buffer); - case EColumnType::kReal32Trunc: return SerializeUInt16(0x1D, buffer); - case EColumnType::kReal32Quant: return SerializeUInt16(0x1E, buffer); + case EColumnType::kSplitInt64: return SerializeUInt16(0x15, buffer); + case EColumnType::kSplitUInt64: return SerializeUInt16(0x16, buffer); + case EColumnType::kSplitReal32: return SerializeUInt16(0x18, buffer); + case EColumnType::kSplitReal64: return SerializeUInt16(0x19, buffer); + case EColumnType::kSplitIndex32: return SerializeUInt16(0x1A, buffer); + case EColumnType::kSplitIndex64: return SerializeUInt16(0x1B, buffer); + case EColumnType::kReal32Trunc: return SerializeUInt16(0x1C, buffer); + case EColumnType::kReal32Quant: return SerializeUInt16(0x1D, buffer); default: if (type == kTestFutureType) return SerializeUInt16(0x99, buffer); @@ -727,36 +727,35 @@ ROOT::Experimental::Internal::RNTupleSerializer::DeserializeColumnType(const voi auto result = DeserializeUInt16(buffer, onDiskType); switch (onDiskType) { - case 0x00: return R__FAIL("unexpected on-disk column type"); - case 0x01: type = EColumnType::kIndex64; break; - case 0x02: type = EColumnType::kIndex32; break; - case 0x03: type = EColumnType::kSwitch; break; - case 0x04: type = EColumnType::kByte; break; - case 0x05: type = EColumnType::kChar; break; - case 0x06: type = EColumnType::kBit; break; - case 0x07: type = EColumnType::kReal64; break; - case 0x08: type = EColumnType::kReal32; break; - case 0x09: type = EColumnType::kReal16; break; - case 0x16: type = EColumnType::kInt64; break; + case 0x00: type = EColumnType::kBit; break; + case 0x01: type = EColumnType::kByte; break; + case 0x02: type = EColumnType::kChar; break; + case 0x03: type = EColumnType::kInt8; break; + case 0x04: type = EColumnType::kUInt8; break; + case 0x05: type = EColumnType::kInt16; break; + case 0x06: type = EColumnType::kUInt16; break; + case 0x07: type = EColumnType::kInt32; break; + case 0x08: type = EColumnType::kUInt32; break; + case 0x09: type = EColumnType::kInt64; break; case 0x0A: type = EColumnType::kUInt64; break; - case 0x17: type = EColumnType::kInt32; break; - case 0x0B: type = EColumnType::kUInt32; break; - case 0x18: type = EColumnType::kInt16; break; - case 0x0C: type = EColumnType::kUInt16; break; - case 0x19: type = EColumnType::kInt8; break; - case 0x0D: type = EColumnType::kUInt8; break; - case 0x0E: type = EColumnType::kSplitIndex64; break; - case 0x0F: type = EColumnType::kSplitIndex32; break; - case 0x10: type = EColumnType::kSplitReal64; break; - case 0x11: type = EColumnType::kSplitReal32; break; - case 0x1A: type = EColumnType::kSplitInt64; break; - case 0x13: type = EColumnType::kSplitUInt64; break; - case 0x1B: type = EColumnType::kSplitInt32; break; + case 0x0B: type = EColumnType::kReal16; break; + case 0x0C: type = EColumnType::kReal32; break; + case 0x0D: type = EColumnType::kReal64; break; + case 0x0E: type = EColumnType::kIndex32; break; + case 0x0F: type = EColumnType::kIndex64; break; + case 0x10: type = EColumnType::kSwitch; break; + case 0x11: type = EColumnType::kSplitInt16; break; + case 0x12: type = EColumnType::kSplitUInt16; break; + case 0x13: type = EColumnType::kSplitInt32; break; case 0x14: type = EColumnType::kSplitUInt32; break; - case 0x1C: type = EColumnType::kSplitInt16; break; - case 0x15: type = EColumnType::kSplitUInt16; break; - case 0x1D: type = EColumnType::kReal32Trunc; break; - case 0x1E: type = EColumnType::kReal32Quant; break; + case 0x15: type = EColumnType::kSplitInt64; break; + case 0x16: type = EColumnType::kSplitUInt64; break; + case 0x18: type = EColumnType::kSplitReal32; break; + case 0x19: type = EColumnType::kSplitReal64; break; + case 0x1A: type = EColumnType::kSplitIndex32; break; + case 0x1B: type = EColumnType::kSplitIndex64; break; + case 0x1C: type = EColumnType::kReal32Trunc; break; + case 0x1D: type = EColumnType::kReal32Quant; break; // case 0x99 => kTestFutureType missing on purpose default: // may be a column type introduced by a future version From dd667bac306c4d23ee615212a3edad35b19df0f0 Mon Sep 17 00:00:00 2001 From: Jakob Blomer Date: Wed, 9 Oct 2024 11:08:05 +0200 Subject: [PATCH 8/9] [ntuple] merge version to/from in extra type info There is no (foreseen) use of a version range for the extra type info. Its only current purpose, storing streamer info records, does not need the version at all. A possible future use is storing enum constant names, but that would also be bound to a specific type version and not to a version range. If needed in a future version, a type version range can be added then. --- tree/ntuple/v7/doc/BinaryFormatSpecification.md | 8 +++----- tree/ntuple/v7/inc/ROOT/RNTupleDescriptor.hxx | 17 +++++------------ tree/ntuple/v7/src/RField.cxx | 3 +-- tree/ntuple/v7/src/RNTupleDescriptor.cxx | 6 ++---- tree/ntuple/v7/src/RNTupleSerialize.cxx | 17 +++++------------ tree/ntuple/v7/test/ntuple_serialize.cxx | 6 ++---- 6 files changed, 18 insertions(+), 39 deletions(-) diff --git a/tree/ntuple/v7/doc/BinaryFormatSpecification.md b/tree/ntuple/v7/doc/BinaryFormatSpecification.md index 82603b069ed9b..1dcc12a981728 100644 --- a/tree/ntuple/v7/doc/BinaryFormatSpecification.md +++ b/tree/ntuple/v7/doc/BinaryFormatSpecification.md @@ -599,13 +599,11 @@ The type information record frame has the following contents followed by a strin +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + Content Identifier + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| Type Version From | -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| Type Version To | +| Type Version | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ``` -The combination of type version from/to, type name, and content identifier should be unique in the list. +The combination of type version, type name, and content identifier should be unique in the list. However, not every type needs to provide additional type information. The following kinds of content are supported: @@ -616,7 +614,7 @@ The following kinds of content are supported: The serialized ROOT streamer info is not bound to a specific type. It is the combined streamer information from all fields serialized by the ROOT streamer. -Writers set version from/to to zero and use an empty type name. +Writers set the version to zero and use an empty type name. Readers should ignore the type-specific information. The format of the content is a ROOT streamed `TList` of `TStreamerInfo` objects. diff --git a/tree/ntuple/v7/inc/ROOT/RNTupleDescriptor.hxx b/tree/ntuple/v7/inc/ROOT/RNTupleDescriptor.hxx index 12fcb5fb7d506..a013b3c139ba4 100644 --- a/tree/ntuple/v7/inc/ROOT/RNTupleDescriptor.hxx +++ b/tree/ntuple/v7/inc/ROOT/RNTupleDescriptor.hxx @@ -481,9 +481,8 @@ class RExtraTypeInfoDescriptor { private: /// Specifies the meaning of the extra information EExtraTypeInfoIds fContentId = EExtraTypeInfoIds::kInvalid; - /// Extra type information restricted to a certain version range of the type - std::uint32_t fTypeVersionFrom = 0; - std::uint32_t fTypeVersionTo = 0; + /// Type version the extra type information is bound to + std::uint32_t fTypeVersion = 0; /// The type name the extra information refers to; empty for RNTuple-wide extra information std::string fTypeName; /// The content format depends on the content ID and may be binary @@ -501,8 +500,7 @@ public: RExtraTypeInfoDescriptor Clone() const; EExtraTypeInfoIds GetContentId() const { return fContentId; } - std::uint32_t GetTypeVersionFrom() const { return fTypeVersionFrom; } - std::uint32_t GetTypeVersionTo() const { return fTypeVersionTo; } + std::uint32_t GetTypeVersion() const { return fTypeVersion; } const std::string &GetTypeName() const { return fTypeName; } const std::string &GetContent() const { return fContent; } }; @@ -1332,14 +1330,9 @@ public: fExtraTypeInfo.fContentId = contentId; return *this; } - RExtraTypeInfoDescriptorBuilder &TypeVersionFrom(std::uint32_t typeVersionFrom) - { - fExtraTypeInfo.fTypeVersionFrom = typeVersionFrom; - return *this; - } - RExtraTypeInfoDescriptorBuilder &TypeVersionTo(std::uint32_t typeVersionTo) + RExtraTypeInfoDescriptorBuilder &TypeVersion(std::uint32_t typeVersion) { - fExtraTypeInfo.fTypeVersionTo = typeVersionTo; + fExtraTypeInfo.fTypeVersion = typeVersion; return *this; } RExtraTypeInfoDescriptorBuilder &TypeName(const std::string &typeName) diff --git a/tree/ntuple/v7/src/RField.cxx b/tree/ntuple/v7/src/RField.cxx index e3223c4a7e72f..526534c794b79 100644 --- a/tree/ntuple/v7/src/RField.cxx +++ b/tree/ntuple/v7/src/RField.cxx @@ -2210,8 +2210,7 @@ ROOT::Experimental::RExtraTypeInfoDescriptor ROOT::Experimental::RStreamerField: { Internal::RExtraTypeInfoDescriptorBuilder extraTypeInfoBuilder; extraTypeInfoBuilder.ContentId(EExtraTypeInfoIds::kStreamerInfo) - .TypeVersionFrom(GetTypeVersion()) - .TypeVersionTo(GetTypeVersion()) + .TypeVersion(GetTypeVersion()) .TypeName(GetTypeName()) .Content(Internal::RNTupleSerializer::SerializeStreamerInfos(fStreamerInfos)); return extraTypeInfoBuilder.MoveDescriptor().Unwrap(); diff --git a/tree/ntuple/v7/src/RNTupleDescriptor.cxx b/tree/ntuple/v7/src/RNTupleDescriptor.cxx index 990eed965f27e..6c6722cbb1100 100644 --- a/tree/ntuple/v7/src/RNTupleDescriptor.cxx +++ b/tree/ntuple/v7/src/RNTupleDescriptor.cxx @@ -264,16 +264,14 @@ ROOT::Experimental::RClusterDescriptor ROOT::Experimental::RClusterDescriptor::C bool ROOT::Experimental::RExtraTypeInfoDescriptor::operator==(const RExtraTypeInfoDescriptor &other) const { - return fContentId == other.fContentId && fTypeName == other.fTypeName && - fTypeVersionFrom == other.fTypeVersionFrom && fTypeVersionTo == other.fTypeVersionTo; + return fContentId == other.fContentId && fTypeName == other.fTypeName && fTypeVersion == other.fTypeVersion; } ROOT::Experimental::RExtraTypeInfoDescriptor ROOT::Experimental::RExtraTypeInfoDescriptor::Clone() const { RExtraTypeInfoDescriptor clone; clone.fContentId = fContentId; - clone.fTypeVersionFrom = fTypeVersionFrom; - clone.fTypeVersionTo = fTypeVersionTo; + clone.fTypeVersion = fTypeVersion; clone.fTypeName = fTypeName; clone.fContent = fContent; return clone; diff --git a/tree/ntuple/v7/src/RNTupleSerialize.cxx b/tree/ntuple/v7/src/RNTupleSerialize.cxx index 46eb6a465823a..299379f3b0d7d 100644 --- a/tree/ntuple/v7/src/RNTupleSerialize.cxx +++ b/tree/ntuple/v7/src/RNTupleSerialize.cxx @@ -337,8 +337,7 @@ std::uint32_t SerializeExtraTypeInfo(const ROOT::Experimental::RExtraTypeInfoDes pos += RNTupleSerializer::SerializeRecordFramePreamble(*where); pos += RNTupleSerializer::SerializeExtraTypeInfoId(desc.GetContentId(), *where); - pos += RNTupleSerializer::SerializeUInt32(desc.GetTypeVersionFrom(), *where); - pos += RNTupleSerializer::SerializeUInt32(desc.GetTypeVersionTo(), *where); + pos += RNTupleSerializer::SerializeUInt32(desc.GetTypeVersion(), *where); pos += RNTupleSerializer::SerializeString(desc.GetTypeName(), *where); pos += RNTupleSerializer::SerializeString(desc.GetContent(), *where); @@ -376,17 +375,15 @@ RResult DeserializeExtraTypeInfo(const void *buffer, std::uint64_ bytes += result.Unwrap(); EExtraTypeInfoIds contentId{EExtraTypeInfoIds::kInvalid}; - std::uint32_t typeVersionFrom; - std::uint32_t typeVersionTo; - if (fnFrameSizeLeft() < 3 * sizeof(std::uint32_t)) { + std::uint32_t typeVersion; + if (fnFrameSizeLeft() < 2 * sizeof(std::uint32_t)) { return R__FAIL("extra type info record frame too short"); } result = RNTupleSerializer::DeserializeExtraTypeInfoId(bytes, contentId); if (!result) return R__FORWARD_ERROR(result); bytes += result.Unwrap(); - bytes += RNTupleSerializer::DeserializeUInt32(bytes, typeVersionFrom); - bytes += RNTupleSerializer::DeserializeUInt32(bytes, typeVersionTo); + bytes += RNTupleSerializer::DeserializeUInt32(bytes, typeVersion); std::string typeName; std::string content; @@ -399,11 +396,7 @@ RResult DeserializeExtraTypeInfo(const void *buffer, std::uint64_ return R__FORWARD_ERROR(result); bytes += result.Unwrap(); - desc.ContentId(contentId) - .TypeVersionFrom(typeVersionFrom) - .TypeVersionTo(typeVersionTo) - .TypeName(typeName) - .Content(content); + desc.ContentId(contentId).TypeVersion(typeVersion).TypeName(typeName).Content(content); return frameSize; } diff --git a/tree/ntuple/v7/test/ntuple_serialize.cxx b/tree/ntuple/v7/test/ntuple_serialize.cxx index 2de1edb8c9f5d..10d66c943cd8a 100644 --- a/tree/ntuple/v7/test/ntuple_serialize.cxx +++ b/tree/ntuple/v7/test/ntuple_serialize.cxx @@ -641,8 +641,7 @@ TEST(RNTuple, SerializeHeader) EXPECT_EQ(1u, desc.GetNExtraTypeInfos()); const auto &extraTypeInfoDesc = *desc.GetExtraTypeInfoIterable().begin(); EXPECT_EQ(EExtraTypeInfoIds::kStreamerInfo, extraTypeInfoDesc.GetContentId()); - EXPECT_EQ(0u, extraTypeInfoDesc.GetTypeVersionFrom()); - EXPECT_EQ(0u, extraTypeInfoDesc.GetTypeVersionTo()); + EXPECT_EQ(0u, extraTypeInfoDesc.GetTypeVersion()); EXPECT_TRUE(extraTypeInfoDesc.GetTypeName().empty()); EXPECT_STREQ("xyz", extraTypeInfoDesc.GetContent().c_str()); } @@ -914,8 +913,7 @@ TEST(RNTuple, SerializeFooterXHeader) EXPECT_EQ(1u, desc.GetNExtraTypeInfos()); const auto &extraTypeInfoDesc = *desc.GetExtraTypeInfoIterable().begin(); EXPECT_EQ(EExtraTypeInfoIds::kStreamerInfo, extraTypeInfoDesc.GetContentId()); - EXPECT_EQ(0u, extraTypeInfoDesc.GetTypeVersionFrom()); - EXPECT_EQ(0u, extraTypeInfoDesc.GetTypeVersionTo()); + EXPECT_EQ(0u, extraTypeInfoDesc.GetTypeVersion()); EXPECT_TRUE(extraTypeInfoDesc.GetTypeName().empty()); EXPECT_STREQ("xyz", extraTypeInfoDesc.GetContent().c_str()); } From 2a90c5f721592b8db8ad16196c0234b750c47723 Mon Sep 17 00:00:00 2001 From: Jakob Blomer Date: Wed, 9 Oct 2024 21:57:23 +0200 Subject: [PATCH 9/9] [ntuple] update links to input files to RC3 --- tree/ntuple/v7/test/ntuple_storage.cxx | 2 +- tutorials/v7/ntuple/ntpl004_dimuon.C | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tree/ntuple/v7/test/ntuple_storage.cxx b/tree/ntuple/v7/test/ntuple_storage.cxx index 2cdd8389a43e6..b93a23263cd40 100644 --- a/tree/ntuple/v7/test/ntuple_storage.cxx +++ b/tree/ntuple/v7/test/ntuple_storage.cxx @@ -487,7 +487,7 @@ TEST(RNTuple, WritePageBudget) #ifdef R__HAS_DAVIX TEST(RNTuple, OpenHTTP) { - std::unique_ptr file(TFile::Open("http://root.cern/files/tutorials/ntpl004_dimuon_v1rc2.root")); + std::unique_ptr file(TFile::Open("http://root.cern/files/tutorials/ntpl004_dimuon_v1rc3.root")); auto Events = std::unique_ptr(file->Get("Events")); auto model = RNTupleModel::Create(); model->MakeField>("nMuon"); diff --git a/tutorials/v7/ntuple/ntpl004_dimuon.C b/tutorials/v7/ntuple/ntpl004_dimuon.C index c6e24abc7ba11..df526b8fddd89 100644 --- a/tutorials/v7/ntuple/ntpl004_dimuon.C +++ b/tutorials/v7/ntuple/ntpl004_dimuon.C @@ -37,7 +37,7 @@ // Import classes from experimental namespace for the time being using RNTupleDS = ROOT::Experimental::RNTupleDS; -constexpr char const* kNTupleFileName = "http://root.cern/files/tutorials/ntpl004_dimuon_v1rc2.root"; +constexpr char const *kNTupleFileName = "http://root.cern/files/tutorials/ntpl004_dimuon_v1rc3.root"; using namespace ROOT::VecOps;