diff --git a/root/io/hadd/CMakeLists.txt b/root/io/hadd/CMakeLists.txt index 0dfc9cbce7..d188050f5a 100644 --- a/root/io/hadd/CMakeLists.txt +++ b/root/io/hadd/CMakeLists.txt @@ -1,11 +1,17 @@ if(ROOT_pyroot_FOUND) ROOTTEST_ADD_TEST(compression_settings MACRO test_compression_settings.py) - ROOTTEST_ADD_TEST(input_validation MACRO input_validation.py) endif() +ROOTTEST_ADD_TEST(test_MergeChangeComp + COPY_TO_BUILDDIR merge_gen_input_tuples.C merge_changeComp_check_output.C + PRECMD ${ROOT_root_CMD} -q -b -l "merge_gen_input_tuples.C(\"test_comp_in1.root\", \"test_comp_in2.root\")" + COMMAND ${ROOT_hadd_CMD} -f404 test_comp_out.root test_comp_in1.root test_comp_in2.root + POSTCMD ${ROOT_root_CMD} -q -b -l "merge_changeComp_check_output.C(404, \"test_comp_out.root\", \"test_comp_in1.root\", \"test_comp_in2.root\")" +) + ROOTTEST_ADD_TEST(test_TreeChangeComp COPY_TO_BUILDDIR hadd_gen_input_tree.C hadd_check_comp_tree.C PRECMD ${ROOT_root_CMD} -q -b -l "hadd_gen_input_tree.C(\"test_comp_tree_in.root\")" diff --git a/root/io/hadd/Testing/Temporary/CTestCostData.txt b/root/io/hadd/Testing/Temporary/CTestCostData.txt new file mode 100644 index 0000000000..ed97d539c0 --- /dev/null +++ b/root/io/hadd/Testing/Temporary/CTestCostData.txt @@ -0,0 +1 @@ +--- diff --git a/root/io/hadd/foo.root b/root/io/hadd/foo.root new file mode 100644 index 0000000000..39f141c14b Binary files /dev/null and b/root/io/hadd/foo.root differ diff --git a/root/io/hadd/merge_changeComp_check_output.C b/root/io/hadd/merge_changeComp_check_output.C new file mode 100644 index 0000000000..a8e3ee6062 --- /dev/null +++ b/root/io/hadd/merge_changeComp_check_output.C @@ -0,0 +1,63 @@ +#include +#include +#include +#include +#include +#include +#include + +#include + +int merge_changeComp_check_output(int expectedCompression, const char *fnameOut, const char *fnameIn1, + const char *fnameIn2) +{ + using namespace ROOT::Experimental; + + auto noPrereleaseWarning = RLogScopedVerbosity(NTupleLog(), ROOT::Experimental::ELogLevel::kError); + + Internal::RPageSourceFile source("ntpl", fnameOut, RNTupleReadOptions()); + source.Attach(); + + Internal::RClusterPool pool{source}; + + const auto expCompAlgo = ROOT::RCompressionSetting::AlgorithmFromCompressionSettings(expectedCompression); + const auto &desc = source.GetSharedDescriptorGuard(); + auto clusterIter = desc->GetClusterIterable(); + for (const auto &clusterDesc : clusterIter) { + // check advertised compression + int advertisedCompression = clusterDesc.GetColumnRange(0).fCompressionSettings; + if (advertisedCompression != expectedCompression) { + std::cerr << "Expected advertised compression to be " << expectedCompression << " but it is " + << advertisedCompression << "\n"; + return 1; + } + + // check actual compression + for (const auto &column : desc->GetColumnIterable()) { + const auto &pages = clusterDesc.GetPageRange(column.GetLogicalId()); + std::uint64_t pageIdx = 0; + for (const auto &pageInfo : pages.fPageInfos) { + std::vector keys{clusterDesc.GetId(), {column.GetPhysicalId()}}; + auto cluster = pool.GetCluster(clusterDesc.GetId(), {column.GetPhysicalId()}); + Internal::ROnDiskPage::Key key{column.GetPhysicalId(), pageIdx}; + auto onDiskPage = cluster->GetOnDiskPage(key); + R__ASSERT(onDiskPage); + const auto actualCompAlgo = + R__getCompressionAlgorithm((const unsigned char *)onDiskPage->GetAddress(), onDiskPage->GetSize()); + if (actualCompAlgo != expCompAlgo) { + std::cerr << "Expected actual compression to be " + << ROOT::RCompressionSetting::AlgorithmToString(expCompAlgo) << " but it is " + << ROOT::RCompressionSetting::AlgorithmToString(actualCompAlgo) << "\n"; + return 1; + } + ++pageIdx; + } + } + } + + gSystem->Unlink(fnameOut); + gSystem->Unlink(fnameIn1); + gSystem->Unlink(fnameIn2); + + return 0; +} diff --git a/root/io/hadd/merge_gen_input_tuples.C b/root/io/hadd/merge_gen_input_tuples.C new file mode 100644 index 0000000000..f320422e40 --- /dev/null +++ b/root/io/hadd/merge_gen_input_tuples.C @@ -0,0 +1,45 @@ +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +void merge_gen_input_tuples(const char *fname1 = "test_rntuple_input1.root", const char *fname2 = "test_rntuple_input2.root") +{ + using namespace ROOT::Experimental; + + auto noPrereleaseWarning = RLogScopedVerbosity(NTupleLog(), ROOT::Experimental::ELogLevel::kError); + + { + auto model = RNTupleModel::Create(); + auto fi = model->MakeField("I", 1337); + auto fl = model->MakeField("L", 666); + auto opts = RNTupleWriteOptions{}; + opts.SetCompression(ROOT::CompressionSettings(ROOT::RCompressionSetting::EAlgorithm::kZSTD, 5)); + auto writer = RNTupleWriter::Recreate(std::move(model), "ntpl", fname1, opts); + for (int i = 0; i < 1000; ++i) { + *fi = i; + *fl = i; + writer->Fill(); + } + } + { + auto model = RNTupleModel::Create(); + auto fi = model->MakeField("I", 123); + auto fl = model->MakeField("L", 420); + auto opts = RNTupleWriteOptions{}; + opts.SetCompression(ROOT::CompressionSettings(ROOT::RCompressionSetting::EAlgorithm::kZLIB, 1)); + auto writer = RNTupleWriter::Recreate(std::move(model), "ntpl", fname2, opts); + for (int i = 0; i < 100; ++i) { + *fi = i; + *fl = i; + writer->Fill(); + } + } +}