Skip to content

Commit 5133622

Browse files
committed
[ntuple] Expand disk visualizer backend
Adds the ntuple header, footer and page list to the method. Updates its unit test accordingly.
1 parent e348748 commit 5133622

5 files changed

Lines changed: 76 additions & 23 deletions

File tree

tree/ntuple/inc/ROOT/RPageStorageFile.hxx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ namespace Internal {
4242
class RRawFile;
4343
class RPageAllocatorHeap;
4444

45+
RNTuple GetAnchorFromFile(const RPageSourceFile &source);
46+
4547
// clang-format off
4648
/**
4749
\class ROOT::Internal::RPageSinkFile
@@ -122,6 +124,7 @@ public:
122124
// clang-format on
123125
class RPageSourceFile : public RPageSource {
124126
friend class ROOT::RNTuple;
127+
friend ROOT::RNTuple ROOT::Internal::GetAnchorFromFile(const RPageSourceFile &);
125128

126129
private:
127130
/// Either provided by CreateFromAnchor, or read from the ROOT file given the ntuple name

tree/ntuple/src/RPageStorageFile.cxx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,13 @@ ROOT::Internal::RPageSinkFile::CloneAsHidden(std::string_view name, const ROOT::
306306

307307
////////////////////////////////////////////////////////////////////////////////
308308

309+
ROOT::RNTuple ROOT::Internal::GetAnchorFromFile(const RPageSourceFile &source)
310+
{
311+
if (!source.fAnchor)
312+
throw RException(R__FAIL("Cannot retrieve RNTuple anchor: no anchor is available"));
313+
return *source.fAnchor;
314+
}
315+
309316
ROOT::Internal::RPageSourceFile::RPageSourceFile(std::string_view ntupleName, const ROOT::RNTupleReadOptions &opts)
310317
: RPageSource(ntupleName, opts)
311318
{

tree/ntupleutil/inc/ROOT/RNTupleInspector.hxx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -505,8 +505,8 @@ public:
505505
void PrintSchemaProfile(ESchemaProfileFormat format, std::ostream &output = std::cout) const;
506506

507507
////////////////////////////////////////////////////////////////////////////
508-
/// \brief Print a string that represents the on-disk storage of the cluster groups, clusters, column ranges and
509-
/// pages on an RNTuple in a format which a performance profile visualizer can render
508+
/// \brief Print a string that represents the on-disk storage of the cluster groups, clusters, column ranges, pages,
509+
/// header, footer and page lists on an RNTuple in a format which a performance profile visualizer can render
510510
///
511511
/// \warning ntuple must have a file-based backend
512512
void PrintDiskProfile(ESchemaProfileFormat format, std::ostream &output = std::cout) const;

tree/ntupleutil/src/RNTupleInspector.cxx

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -698,6 +698,12 @@ void ROOT::Experimental::RNTupleInspector::PrintDiskProfile([[maybe_unused]] ESc
698698
// There is only one format at the moment
699699
assert(format == ESchemaProfileFormat::kSpeedscopeJSON);
700700

701+
// GetAnchorFromFile() only supports file based backend. Will need the anchor later, but better to check early
702+
const auto *pageSourceFile = dynamic_cast<const ROOT::Internal::RPageSourceFile *>(fPageSource.get());
703+
if (!pageSourceFile)
704+
throw RException(R__FAIL("disk profile is only supported for file-based page sources"));
705+
const auto anchor = ROOT::Internal::GetAnchorFromFile(*pageSourceFile);
706+
701707
const auto &descriptor = GetDescriptor();
702708

703709
struct RDiskPageLeaf {
@@ -754,6 +760,13 @@ void ROOT::Experimental::RNTupleInspector::PrintDiskProfile([[maybe_unused]] ESc
754760

755761
std::uint64_t previouspageLeafEnd = 0;
756762

763+
// Construct frame for ntuple header
764+
SpeedscopeFrame headerFrame;
765+
headerFrame.fString = "ntuple header";
766+
headerFrame.fOpeningPosition = anchor.GetSeekHeader();
767+
headerFrame.fClosingPosition = anchor.GetSeekHeader() + anchor.GetNBytesHeader();
768+
frames.push_back(headerFrame);
769+
757770
// Construct frames from the bottom (leafs ordered by disk address) upwards
758771
for (const auto &pageLeaf : pageLeaves) {
759772
std::size_t sharedDepth = 0;
@@ -800,5 +813,23 @@ void ROOT::Experimental::RNTupleInspector::PrintDiskProfile([[maybe_unused]] ESc
800813
openFrames.pop_back();
801814
}
802815

816+
// Construct frames for page lists
817+
for (const auto &clusterGroupDescriptor : descriptor.GetClusterGroupIterable()) {
818+
const auto locator = clusterGroupDescriptor.GetPageListLocator();
819+
820+
SpeedscopeFrame pageListFrame;
821+
pageListFrame.fString = "[page list " + std::to_string(clusterGroupDescriptor.GetId()) + "]";
822+
pageListFrame.fOpeningPosition = locator.GetPosition<std::uint64_t>();
823+
pageListFrame.fClosingPosition = locator.GetPosition<std::uint64_t>() + locator.GetNBytesOnStorage();
824+
frames.push_back(pageListFrame);
825+
}
826+
827+
// Construct frame for ntuple footer
828+
SpeedscopeFrame footerFrame;
829+
footerFrame.fString = "ntuple footer";
830+
footerFrame.fOpeningPosition = anchor.GetSeekFooter();
831+
footerFrame.fClosingPosition = anchor.GetSeekFooter() + anchor.GetNBytesFooter();
832+
frames.push_back(footerFrame);
833+
803834
PrintSpeedscopeFrames(frames, output);
804835
}

tree/ntupleutil/test/ntuple_inspector.cxx

Lines changed: 33 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1135,6 +1135,7 @@ TEST(RNTupleInspector, DiskProfile)
11351135
"$schema":"https://www.speedscope.app/file-format-schema.json",
11361136
"shared":{
11371137
"frames":[
1138+
{ "name":"ntuple header" },
11381139
{ "name":"[cluster group 0]" },
11391140
{ "name":"[cluster 0]" },
11401141
{ "name":"[column range 0]" },
@@ -1157,7 +1158,10 @@ TEST(RNTupleInspector, DiskProfile)
11571158
{ "name":"[cluster group 0]" },
11581159
{ "name":"[cluster 2]" },
11591160
{ "name":"[column range 0]" },
1160-
{ "name":"[page @3208]" }
1161+
{ "name":"[page @3208]" },
1162+
{ "name":"[page list 0]" },
1163+
{ "name":"[page list 1]" },
1164+
{ "name":"ntuple footer" }
11611165
]
11621166
},
11631167
"profiles":[
@@ -1166,54 +1170,62 @@ TEST(RNTupleInspector, DiskProfile)
11661170
"name":"Flattened Timeline",
11671171
"unit":"bytes",
11681172
"startValue":0,
1169-
"endValue":3608,
1173+
"endValue":4454,
11701174
"events":[
1171-
{"type":"O","frame":0,"at":882},
1175+
{"type":"O","frame":0,"at":290},
1176+
{"type":"C","frame":0,"at":840},
11721177
{"type":"O","frame":1,"at":882},
11731178
{"type":"O","frame":2,"at":882},
11741179
{"type":"O","frame":3,"at":882},
1175-
{"type":"C","frame":3,"at":1082},
1176-
{"type":"O","frame":4,"at":1132},
1177-
{"type":"C","frame":4,"at":1232},
1178-
{"type":"C","frame":2,"at":1232},
1179-
{"type":"O","frame":5,"at":1274},
1180+
{"type":"O","frame":4,"at":882},
1181+
{"type":"C","frame":4,"at":1082},
1182+
{"type":"O","frame":5,"at":1132},
1183+
{"type":"C","frame":5,"at":1232},
1184+
{"type":"C","frame":3,"at":1232},
11801185
{"type":"O","frame":6,"at":1274},
1186+
{"type":"O","frame":7,"at":1274},
1187+
{"type":"C","frame":7,"at":1674},
11811188
{"type":"C","frame":6,"at":1674},
1182-
{"type":"C","frame":5,"at":1674},
1183-
{"type":"O","frame":7,"at":1724},
11841189
{"type":"O","frame":8,"at":1724},
1190+
{"type":"O","frame":9,"at":1724},
1191+
{"type":"C","frame":9,"at":1824},
11851192
{"type":"C","frame":8,"at":1824},
1186-
{"type":"C","frame":7,"at":1824},
1187-
{"type":"C","frame":1,"at":1824},
1188-
{"type":"O","frame":9,"at":1866},
1193+
{"type":"C","frame":2,"at":1824},
11891194
{"type":"O","frame":10,"at":1866},
11901195
{"type":"O","frame":11,"at":1866},
1196+
{"type":"O","frame":12,"at":1866},
1197+
{"type":"C","frame":12,"at":2266},
11911198
{"type":"C","frame":11,"at":2266},
11921199
{"type":"C","frame":10,"at":2266},
1193-
{"type":"C","frame":9,"at":2266},
1194-
{"type":"O","frame":12,"at":2316},
11951200
{"type":"O","frame":13,"at":2316},
11961201
{"type":"O","frame":14,"at":2316},
1202+
{"type":"O","frame":15,"at":2316},
1203+
{"type":"C","frame":15,"at":2716},
11971204
{"type":"C","frame":14,"at":2716},
11981205
{"type":"C","frame":13,"at":2716},
1199-
{"type":"C","frame":12,"at":2716},
1200-
{"type":"C","frame":0,"at":2716},
1201-
{"type":"O","frame":15,"at":2758},
1206+
{"type":"C","frame":1,"at":2716},
12021207
{"type":"O","frame":16,"at":2758},
12031208
{"type":"O","frame":17,"at":2758},
12041209
{"type":"O","frame":18,"at":2758},
1210+
{"type":"O","frame":19,"at":2758},
1211+
{"type":"C","frame":19,"at":3158},
12051212
{"type":"C","frame":18,"at":3158},
12061213
{"type":"C","frame":17,"at":3158},
12071214
{"type":"C","frame":16,"at":3158},
1208-
{"type":"C","frame":15,"at":3158},
1209-
{"type":"O","frame":19,"at":3208},
12101215
{"type":"O","frame":20,"at":3208},
12111216
{"type":"O","frame":21,"at":3208},
12121217
{"type":"O","frame":22,"at":3208},
1218+
{"type":"O","frame":23,"at":3208},
1219+
{"type":"C","frame":23,"at":3608},
12131220
{"type":"C","frame":22,"at":3608},
12141221
{"type":"C","frame":21,"at":3608},
12151222
{"type":"C","frame":20,"at":3608},
1216-
{"type":"C","frame":19,"at":3608}
1223+
{"type":"O","frame":24,"at":3650},
1224+
{"type":"C","frame":24,"at":4038},
1225+
{"type":"O","frame":25,"at":4080},
1226+
{"type":"C","frame":25,"at":4204},
1227+
{"type":"O","frame":26,"at":4246},
1228+
{"type":"C","frame":26,"at":4454}
12171229
]
12181230
}
12191231
]

0 commit comments

Comments
 (0)