Skip to content

Commit 3f2f922

Browse files
committed
[main] RootObjTree: add PrintObjTree utility
1 parent 9e9f870 commit 3f2f922

File tree

2 files changed

+47
-0
lines changed

2 files changed

+47
-0
lines changed

main/src/RootObjTree.cxx

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <algorithm>
1515
#include <deque>
1616
#include <iostream>
17+
#include <set>
1718

1819
static bool MatchesGlob(std::string_view haystack, std::string_view pattern)
1920
{
@@ -156,6 +157,49 @@ ROOT::CmdLine::ParseRootSources(const std::vector<std::string> &sourcesRaw, std:
156157
return sources;
157158
}
158159

160+
void ROOT::CmdLine::PrintObjTree(const RootObjTree &tree, std::ostream &out)
161+
{
162+
if (tree.fNodes.empty())
163+
return;
164+
165+
struct RevNode {
166+
std::set<NodeIdx_t> fChildren;
167+
};
168+
std::vector<RevNode> revNodes;
169+
revNodes.resize(tree.fNodes.size());
170+
171+
// Un-linearize the tree
172+
for (int i = (int)tree.fNodes.size() - 1; i >= 0; --i) {
173+
const auto *node = &tree.fNodes[i];
174+
NodeIdx_t childIdx = i;
175+
NodeIdx_t parentIdx = node->fParent;
176+
while (childIdx != parentIdx) {
177+
auto &revNodeParent = revNodes[parentIdx];
178+
revNodeParent.fChildren.insert(childIdx);
179+
node = &tree.fNodes[parentIdx];
180+
childIdx = parentIdx;
181+
parentIdx = node->fParent;
182+
}
183+
}
184+
185+
// Print out the tree.
186+
// Vector of {nesting, nodeIdx}
187+
std::vector<std::pair<std::uint32_t, NodeIdx_t>> nodesToVisit = {{0, 0}};
188+
while (!nodesToVisit.empty()) {
189+
const auto [nesting, nodeIdx] = nodesToVisit.back();
190+
nodesToVisit.pop_back();
191+
const auto &cur = revNodes[nodeIdx];
192+
const auto &node = tree.fNodes[nodeIdx];
193+
for (auto i = 0u; i < 2 * nesting; ++i)
194+
out << ' ';
195+
out << node.fName << " : " << node.fClassName << "\n";
196+
// Add the children in reverse order to preserve alphabetical order during depth-first visit.
197+
for (auto it = cur.fChildren.rbegin(); it != cur.fChildren.rend(); ++it) {
198+
nodesToVisit.push_back({nesting + 1, *it});
199+
}
200+
}
201+
}
202+
159203
std::string ROOT::CmdLine::NodeFullPath(const ROOT::CmdLine::RootObjTree &tree, ROOT::CmdLine::NodeIdx_t nodeIdx,
160204
ROOT::CmdLine::ENodeFullPathOpt opt)
161205
{

main/src/RootObjTree.hxx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,9 @@ struct RootObjTree {
5656
std::unique_ptr<TFile> fFile;
5757
};
5858

59+
/// Prints out the structure of the object tree. Helpful for debugging.
60+
void PrintObjTree(const RootObjTree &tree, std::ostream &out = std::cout);
61+
5962
enum class ENodeFullPathOpt {
6063
kExcludeFilename,
6164
kIncludeFilename,

0 commit comments

Comments
 (0)