Skip to content

Commit 2393c19

Browse files
committed
[df] Move RNoCleanupNotifier usage to RTTreeDS
To keep the implementation aligned with the previously existing one from RLoopManager. As a result of this, the header `InternalTreeUtils.hxx` can be removed from the includes of `RLoopManager.hxx`, removing a further header dependency on TTree. This change trickled some missing header errors in other places that have been addressed.
1 parent 2a65c39 commit 2393c19

File tree

7 files changed

+39
-19
lines changed

7 files changed

+39
-19
lines changed

tree/dataframe/inc/ROOT/RDF/RInterface.hxx

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1411,18 +1411,15 @@ public:
14111411
const RSnapshotOptions &options = RSnapshotOptions())
14121412
{
14131413
const auto definedColumns = fColRegister.GenerateColumnNames();
1414-
auto *tree = fLoopManager->GetTree();
14151414

1416-
const auto treeBranchNames = tree != nullptr ? ROOT::Internal::TreeUtils::GetTopLevelBranchNames(*tree) : ColumnNames_t{};
14171415
const auto dsColumns = GetDataSource() ? ROOT::Internal::RDF::GetTopLevelFieldNames(*GetDataSource()) : ColumnNames_t{};
14181416
// Ignore R_rdf_sizeof_* columns coming from datasources: we don't want to Snapshot those
14191417
ColumnNames_t dsColumnsWithoutSizeColumns;
14201418
std::copy_if(dsColumns.begin(), dsColumns.end(), std::back_inserter(dsColumnsWithoutSizeColumns),
14211419
[](const std::string &name) { return name.size() < 13 || name.substr(0, 13) != "R_rdf_sizeof_"; });
14221420
ColumnNames_t columnNames;
1423-
columnNames.reserve(definedColumns.size() + treeBranchNames.size() + dsColumnsWithoutSizeColumns.size());
1421+
columnNames.reserve(definedColumns.size() + dsColumnsWithoutSizeColumns.size());
14241422
columnNames.insert(columnNames.end(), definedColumns.begin(), definedColumns.end());
1425-
columnNames.insert(columnNames.end(), treeBranchNames.begin(), treeBranchNames.end());
14261423
columnNames.insert(columnNames.end(), dsColumnsWithoutSizeColumns.begin(), dsColumnsWithoutSizeColumns.end());
14271424

14281425
// The only way we can get duplicate entries is if a column coming from a tree or data-source is Redefine'd.
@@ -1560,18 +1557,14 @@ public:
15601557
RInterface<RLoopManager> Cache(std::string_view columnNameRegexp = "")
15611558
{
15621559
const auto definedColumns = fColRegister.GenerateColumnNames();
1563-
auto *tree = fLoopManager->GetTree();
1564-
const auto treeBranchNames =
1565-
tree != nullptr ? ROOT::Internal::TreeUtils::GetTopLevelBranchNames(*tree) : ColumnNames_t{};
15661560
const auto dsColumns = GetDataSource() ? GetDataSource()->GetColumnNames() : ColumnNames_t{};
15671561
// Ignore R_rdf_sizeof_* columns coming from datasources: we don't want to Snapshot those
15681562
ColumnNames_t dsColumnsWithoutSizeColumns;
15691563
std::copy_if(dsColumns.begin(), dsColumns.end(), std::back_inserter(dsColumnsWithoutSizeColumns),
15701564
[](const std::string &name) { return name.size() < 13 || name.substr(0, 13) != "R_rdf_sizeof_"; });
15711565
ColumnNames_t columnNames;
1572-
columnNames.reserve(definedColumns.size() + treeBranchNames.size() + dsColumns.size());
1566+
columnNames.reserve(definedColumns.size() + dsColumns.size());
15731567
columnNames.insert(columnNames.end(), definedColumns.begin(), definedColumns.end());
1574-
columnNames.insert(columnNames.end(), treeBranchNames.begin(), treeBranchNames.end());
15751568
columnNames.insert(columnNames.end(), dsColumns.begin(), dsColumns.end());
15761569
const auto selectedColumns = RDFInternal::ConvertRegexToColumns(columnNames, columnNameRegexp, "Cache");
15771570
return Cache(selectedColumns);

tree/dataframe/inc/ROOT/RDF/RLoopManager.hxx

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
#ifndef ROOT_RLOOPMANAGER
1212
#define ROOT_RLOOPMANAGER
1313

14-
#include "ROOT/InternalTreeUtils.hxx" // RNoCleanupNotifier
1514
#include "ROOT/RDataSource.hxx"
1615
#include "ROOT/RDF/RColumnReaderBase.hxx"
1716
#include "ROOT/RDF/RDatasetSpec.hxx"
@@ -129,6 +128,13 @@ class RLoopManager : public RNodeBase {
129128
friend struct RCallCleanUpTask;
130129
friend struct ROOT::Internal::RDF::RDSRangeRAII;
131130

131+
/*
132+
A wrapped reference to a TTree dataset that can be shared by many computation graphs. Ensures lifetime management.
133+
It needs to be destroyed *after* the fDataSource data member, in case it is holding the only Python reference to the
134+
input dataset and the data source needs to access it before it is destroyed.
135+
*/
136+
std::any fTTreeLifeline{};
137+
132138
std::vector<RDFInternal::RActionBase *> fBookedActions; ///< Non-owning pointers to actions to be run
133139
std::vector<RDFInternal::RActionBase *> fRunActions; ///< Non-owning pointers to actions already run
134140
std::vector<RFilterBase *> fBookedFilters;
@@ -172,7 +178,6 @@ class RLoopManager : public RNodeBase {
172178
/// Cache of the tree/chain branch names. Never access directy, always use GetBranchNames().
173179
ColumnNames_t fValidBranchNames;
174180

175-
ROOT::Internal::TreeUtils::RNoCleanupNotifier fNoCleanupNotifier;
176181
/// Pointer to a shared slot stack in case this instance runs concurrently with others:
177182
std::weak_ptr<ROOT::Internal::RSlotStack> fSlotStack;
178183

@@ -201,10 +206,6 @@ class RLoopManager : public RNodeBase {
201206
std::set<std::pair<std::string_view, std::unique_ptr<ROOT::Internal::RDF::RVariationsWithReaders>>>
202207
fUniqueVariationsWithReaders;
203208

204-
/// A wrapped reference to a TTree dataset that can be shared by many computation graphs. Ensures lifetime
205-
/// management.
206-
std::any fTTreeLifeline{};
207-
208209
public:
209210
RLoopManager(const ColumnNames_t &defaultColumns = {});
210211
RLoopManager(TTree *tree, const ColumnNames_t &defaultBranches);

tree/dataframe/inc/ROOT/RTTreeDS.hxx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,10 @@ namespace ROOT::TreeUtils {
4646
struct RFriendInfo;
4747
}
4848

49+
namespace ROOT::Internal::TreeUtils {
50+
class RNoCleanupNotifier;
51+
}
52+
4953
class TChain;
5054
class TDirectory;
5155
class TTree;
@@ -66,6 +70,10 @@ class RTTreeDS final : public ROOT::RDF::RDataSource {
6670

6771
std::vector<std::unique_ptr<TChain>> fFriends;
6872

73+
// Should be needed mostly for MT runs, but we keep it here to document and align the existing functionality
74+
// from RLoopManager. See https://github.com/root-project/root/pull/10729
75+
std::unique_ptr<ROOT::Internal::TreeUtils::RNoCleanupNotifier> fNoCleanupNotifier;
76+
6977
ROOT::RDF::RSampleInfo
7078
CreateSampleInfo(const std::unordered_map<std::string, ROOT::RDF::Experimental::RSample *> &sampleMap) const final;
7179

tree/dataframe/src/RLoopManager.cxx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include "TROOT.h" // IsImplicitMTEnabled, gCoreMutex, R__*_LOCKGUARD
3333
#include "TTreeReader.h"
3434
#include "TTree.h" // For MaxTreeSizeRAII. Revert when #6640 will be solved.
35+
#include "ROOT/InternalTreeUtils.hxx" // GetTopLevelBranchNames
3536

3637
#include "ROOT/RTTreeDS.hxx"
3738

@@ -534,6 +535,7 @@ void RLoopManager::RunEmptySource()
534535
}
535536
}
536537

538+
#ifdef R__USE_IMT
537539
namespace {
538540
/// Return true on succesful entry read.
539541
///
@@ -558,6 +560,7 @@ bool validTTreeReaderRead(TTreeReader &treeReader)
558560
}
559561
}
560562
} // namespace
563+
#endif
561564

562565
namespace {
563566
struct DSRunRAII {

tree/dataframe/src/RTTreeDS.cxx

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,18 @@
11
#include <sstream>
22

3-
#include <ROOT/InternalTreeUtils.hxx> // GetTopLevelBranchNames
4-
#include <ROOT/RDataFrame.hxx>
5-
#include <ROOT/RFriendInfo.hxx>
63
#include <ROOT/RTTreeDS.hxx>
4+
#include <ROOT/RDataFrame.hxx>
75
#include <ROOT/RDF/RLoopManager.hxx> // GetBranchNames
86
#include <ROOT/RDF/RTreeColumnReader.hxx>
97
#include <ROOT/RDF/Utils.hxx> // GetBranchOrLeafTypeName
108

119
#include <TClassEdit.h>
1210
#include <TFile.h>
1311
#include <TTree.h>
12+
#include <TChain.h>
1413
#include <TTreeReader.h>
14+
#include <ROOT/RFriendInfo.hxx>
15+
#include <ROOT/InternalTreeUtils.hxx> // GetTopLevelBranchNames
1516

1617
#ifdef R__USE_IMT
1718
#include <TROOT.h>
@@ -62,12 +63,24 @@ GetCollectionInfo(const std::string &typeName)
6263
} // namespace
6364

6465
// Destructor is defined here, where the data member types are actually available
65-
ROOT::Internal::RDF::RTTreeDS::~RTTreeDS() = default;
66+
ROOT::Internal::RDF::RTTreeDS::~RTTreeDS()
67+
{
68+
if (fNoCleanupNotifier && fTree)
69+
// fNoCleanupNotifier was created only if the input TTree is a TChain
70+
fNoCleanupNotifier->RemoveLink(*static_cast<TChain *>(fTree.get()));
71+
};
6672

6773
void ROOT::Internal::RDF::RTTreeDS::Setup(std::shared_ptr<TTree> &&tree, const ROOT::TreeUtils::RFriendInfo *friendInfo)
6874
{
6975
fTree = tree;
7076

77+
// We keep the existing functionality from RLoopManager, until proven not necessary.
78+
// See https://github.com/root-project/root/pull/10729
79+
if (auto ch = dynamic_cast<TChain *>(fTree.get()); ch && !fNoCleanupNotifier) {
80+
fNoCleanupNotifier = std::make_unique<ROOT::Internal::TreeUtils::RNoCleanupNotifier>();
81+
fNoCleanupNotifier->RegisterChain(*ch);
82+
}
83+
7184
if (friendInfo) {
7285
fFriends = ROOT::Internal::TreeUtils::MakeFriends(*friendInfo);
7386
for (std::size_t i = 0ul; i < fFriends.size(); i++) {

tree/dataframe/test/dataframe_interface.cxx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "TMemFile.h"
1010
#include "TSystem.h"
1111
#include "TTree.h"
12+
#include "TChain.h"
1213

1314
#include "gtest/gtest.h"
1415

tree/dataframe/test/dataframe_snapshot_emptyoutput.cxx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
// We only use this header to generate the dictionary for RVec<ROOT::Math::PtEtaPhiMVector>
55
#include "DummyHeader.hxx"
66

7+
#include <ROOT/InternalTreeUtils.hxx>
78
#include <ROOT/RDataFrame.hxx>
89

910
#include <thread>

0 commit comments

Comments
 (0)