Skip to content
Snippets Groups Projects
Commit bf6364ee authored by Danilo Piparo's avatar Danilo Piparo
Browse files

[TTreeProcessorMT][NFC] Respect data member naming convention

parent 9d0c5ec5
No related branches found
No related tags found
No related merge requests found
......@@ -170,7 +170,7 @@ namespace ROOT {
const TEntryList fEntryList; // const to be sure to avoid race conditions among TTreeViews
const Internal::FriendInfo fFriendInfo;
ROOT::TThreadedObject<ROOT::Internal::TTreeView> treeView; ///<! Thread-local TreeViews
ROOT::TThreadedObject<ROOT::Internal::TTreeView> fTreeView; ///<! Thread-local TreeViews
Internal::FriendInfo GetFriendInfo(TTree &tree);
std::string FindTreeName();
......
......@@ -35,6 +35,119 @@ namespace ROOT {
unsigned int TTreeProcessorMT::fgMaxTasksPerFilePerWorker = 24U;
namespace Internal {
/// A cluster of entries
struct EntryCluster {
Long64_t start;
Long64_t end;
};
/// Names, aliases, and file names of a TTree's or TChain's friends
using NameAlias = std::pair<std::string, std::string>;
struct FriendInfo {
/// Pairs of names and aliases of friend trees/chains
std::vector<Internal::NameAlias> fFriendNames;
/// Names of the files where each friend is stored. fFriendFileNames[i] is the list of files for friend with
/// name fFriendNames[i]
std::vector<std::vector<std::string>> fFriendFileNames;
};
class TTreeView {
private:
using TreeReaderEntryListPair = std::pair<std::unique_ptr<TTreeReader>, std::unique_ptr<TEntryList>>;
// NOTE: fFriends must come before fChain to be deleted after it, see ROOT-9281 for more details
std::vector<std::unique_ptr<TChain>> fFriends; ///< Friends of the tree/chain
std::unique_ptr<TChain> fChain; ///< Chain on which to operate
////////////////////////////////////////////////////////////////////////////////
/// Construct fChain, also adding friends if needed and injecting knowledge of offsets if available.
void MakeChain(const std::string &treeName, const std::vector<std::string> &fileNames, const FriendInfo &friendInfo,
const std::vector<Long64_t> &nEntries, const std::vector<std::vector<Long64_t>> &friendEntries)
{
const std::vector<NameAlias> &friendNames = friendInfo.fFriendNames;
const std::vector<std::vector<std::string>> &friendFileNames = friendInfo.fFriendFileNames;
fChain.reset(new TChain(treeName.c_str()));
const auto nFiles = fileNames.size();
for (auto i = 0u; i < nFiles; ++i) {
fChain->Add(fileNames[i].c_str(), nEntries[i]);
}
fChain->ResetBit(TObject::kMustCleanup);
fFriends.clear();
const auto nFriends = friendNames.size();
for (auto i = 0u; i < nFriends; ++i) {
const auto &friendName = friendNames[i];
const auto &name = friendName.first;
const auto &alias = friendName.second;
// Build a friend chain
auto frChain = std::make_unique<TChain>(name.c_str());
const auto nFileNames = friendFileNames[i].size();
for (auto j = 0u; j < nFileNames; ++j)
frChain->Add(friendFileNames[i][j].c_str(), friendEntries[i][j]);
// Make it friends with the main chain
fChain->AddFriend(frChain.get(), alias.c_str());
fFriends.emplace_back(std::move(frChain));
}
}
TreeReaderEntryListPair MakeReaderWithEntryList(TEntryList &globalList, Long64_t start, Long64_t end)
{
// TEntryList and SetEntriesRange do not work together (the former has precedence).
// We need to construct a TEntryList that contains only those entry numbers in our desired range.
auto localList = std::make_unique<TEntryList>();
Long64_t entry = globalList.GetEntry(0);
do {
if (entry >= end)
break;
else if (entry >= start)
localList->Enter(entry);
} while ((entry = globalList.Next()) >= 0);
auto reader = std::make_unique<TTreeReader>(fChain.get(), localList.get());
return std::make_pair(std::move(reader), std::move(localList));
}
std::unique_ptr<TTreeReader> MakeReader(Long64_t start, Long64_t end)
{
auto reader = std::make_unique<TTreeReader>(fChain.get());
reader->SetEntriesRange(start, end);
return reader;
}
public:
TTreeView() {}
// no-op, we don't want to copy the local TChains
TTreeView(const TTreeView &) {}
//////////////////////////////////////////////////////////////////////////
/// Get a TTreeReader for the current tree of this view.
TreeReaderEntryListPair GetTreeReader(Long64_t start, Long64_t end, const std::string &treeName,
const std::vector<std::string> &fileNames, const FriendInfo &friendInfo,
TEntryList entryList, const std::vector<Long64_t> &nEntries,
const std::vector<std::vector<Long64_t>> &friendEntries)
{
const bool usingLocalEntries = friendInfo.fFriendNames.empty() && entryList.GetN() == 0;
if (fChain == nullptr || (usingLocalEntries && fileNames[0] != fChain->GetListOfFiles()->At(0)->GetTitle()))
MakeChain(treeName, fileNames, friendInfo, nEntries, friendEntries);
std::unique_ptr<TTreeReader> reader;
std::unique_ptr<TEntryList> localList;
if (entryList.GetN() > 0) {
std::tie(reader, localList) = MakeReaderWithEntryList(entryList, start, end);
} else {
reader = MakeReader(start, end);
}
// we need to return the entry list too, as it needs to be in scope as long as the reader is
return std::make_pair(std::move(reader), std::move(localList));
}
};
////////////////////////////////////////////////////////////////////////
/// Return a vector of cluster boundaries for the given tree and files.
// EntryClusters and number of entries per file
......@@ -388,8 +501,8 @@ void TTreeProcessorMT::Process(std::function<void(TTreeReader &)> func)
auto processCluster = [&](const Internal::EntryCluster &c) {
std::unique_ptr<TTreeReader> reader;
std::unique_ptr<TEntryList> elist;
std::tie(reader, elist) = treeView->GetTreeReader(c.start, c.end, fTreeName, theseFiles, fFriendInfo,
fEntryList, theseEntries, friendEntries);
std::tie(reader, elist) = fTreeView->GetTreeReader(c.start, c.end, fTreeName, theseFiles, fFriendInfo,
fEntryList, theseEntries, friendEntries);
func(*reader);
};
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment