parse root version
This commit is contained in:
parent
d177ea66a8
commit
5923ac4360
10 changed files with 90 additions and 24 deletions
|
@ -10,7 +10,7 @@ struct Inspected_File {
|
|||
u8 *mem;
|
||||
u64 size;
|
||||
|
||||
const char *name;
|
||||
String8 name;
|
||||
|
||||
// @Platform: inotify file descriptor
|
||||
int inot;
|
||||
|
@ -20,10 +20,11 @@ struct App_State {
|
|||
Window_Data win_data;
|
||||
User_Input user_input;
|
||||
RNTuple_Data rndata;
|
||||
TFile_Data tfile_data;
|
||||
Viewer viewer;
|
||||
Inspected_File inspected_file;
|
||||
|
||||
const char *ntpl_name;
|
||||
String8 ntpl_name;
|
||||
|
||||
Delta_Time_Accum delta_time_accum;
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ bool os_open_and_map_file(const char *fname, App_State &app)
|
|||
if (!fmem)
|
||||
fprintf(stderr, "Failed to open file %s\n", fname);
|
||||
|
||||
app.inspected_file.name = fname;
|
||||
app.inspected_file.name = str8(fname);
|
||||
app.inspected_file.stream = file;
|
||||
app.inspected_file.size = fsize;
|
||||
app.inspected_file.mem = reinterpret_cast<u8*>(fmem);
|
||||
|
|
|
@ -35,13 +35,15 @@ u32 mem_edit_bg_color_fn(const u8 *, u64 off, void *user_data)
|
|||
{
|
||||
App_State *app = reinterpret_cast<App_State *>(user_data);
|
||||
const RNTuple_Data &rdata = app->rndata;
|
||||
const TFile_Data &tdata = app->tfile_data;
|
||||
u64 rblob_sz = rdata.rblob_header_size; // @Incomplete
|
||||
|
||||
off += app->viewer.base_display_addr;
|
||||
|
||||
#define COL(c) (ImColor((c)[0], (c)[1], (c)[2]))
|
||||
// TFile start
|
||||
if (off <= rdata.root_file_header_size) return COL(app->viewer.col_tfile);
|
||||
if (off <= tdata.root_file_header_size) return COL(app->viewer.col_tfile_header);
|
||||
if (tdata.rng_root_file_obj.start <= off && off < tdata.rng_root_file_obj.end()) return COL(app->viewer.col_tfile_obj);
|
||||
|
||||
// Handle pages
|
||||
// fast case: `off` is in the same page info as previous `off`.
|
||||
|
@ -135,7 +137,8 @@ void make_viewer(App_State &app)
|
|||
COL(col_header, 150, 0, 50);
|
||||
COL(col_footer, 50, 0, 150);
|
||||
COL(col_key, 0, 100, 50);
|
||||
COL(col_tfile, 90, 90, 90);
|
||||
COL(col_tfile_header, 90, 90, 90);
|
||||
COL(col_tfile_obj, 120, 120, 120);
|
||||
COL(col_page, 125, 0, 125);
|
||||
COL(col_page_start, 200, 0, 200);
|
||||
COL(col_checksum, 134, 65, 25);
|
||||
|
@ -184,7 +187,7 @@ void update_and_render(Arena *arena, App_State &app, f32 delta_time_ms)
|
|||
if (ImGui::Begin("main", nullptr, main_win_flags)) {
|
||||
|
||||
String8 ntpl_desc = rntuple_description(scratch.arena, app.rndata);
|
||||
ImGui::Text("RNTuple '%s' (%s) from file \"%s\"", app.ntpl_name, ntpl_desc.c(), app.inspected_file.name);
|
||||
ImGui::Text("RNTuple '%s' (%s) from file \"%s\"", app.ntpl_name.c(), ntpl_desc.c(), app.inspected_file.name.c());
|
||||
|
||||
// Draw stats
|
||||
{
|
||||
|
@ -222,9 +225,13 @@ void update_and_render(Arena *arena, App_State &app, f32 delta_time_ms)
|
|||
ImGui::TableNextColumn();
|
||||
ImGuiColorEditFlags flags = ImGuiColorEditFlags_NoInputs|ImGuiColorEditFlags_NoLabel;
|
||||
|
||||
ImGui::ColorEdit3("_TFile", app.viewer.col_tfile, flags);
|
||||
ImGui::ColorEdit3("_TFile Header", app.viewer.col_tfile_header, flags);
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("TFile")) viewer_jump_to(app.viewer, 0);
|
||||
if (ImGui::Button("TFile Header")) viewer_jump_to(app.viewer, 0);
|
||||
|
||||
ImGui::ColorEdit3("_TFile Object", app.viewer.col_tfile_obj, flags);
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("TFile Object")) viewer_jump_to(app.viewer, app.tfile_data.rng_root_file_obj.start);
|
||||
|
||||
ImGui::ColorEdit3("_RNTuple Anchor", app.viewer.col_anchor, flags);
|
||||
ImGui::SameLine();
|
||||
|
@ -278,6 +285,11 @@ void update_and_render(Arena *arena, App_State &app, f32 delta_time_ms)
|
|||
ImGui::Text("%s", to_pretty_size(scratch.arena, app.rndata.tot_page_list_size).c());
|
||||
|
||||
ImGui::Separator();
|
||||
String8 root_version_str = push_str8f(scratch.arena, "%u.%u.%u",
|
||||
app.tfile_data.root_version_major,
|
||||
app.tfile_data.root_version_minor,
|
||||
app.tfile_data.root_version_patch);
|
||||
ImGui::Text("ROOT version: %s", root_version_str.c());
|
||||
ImGui::Text("Num pages: %lu", app.rndata.n_pages);
|
||||
ImGui::Text("Num elements: %lu", app.rndata.n_elems);
|
||||
|
||||
|
|
|
@ -5,7 +5,8 @@ struct Viewer {
|
|||
f32 col_header[3];
|
||||
f32 col_footer[3];
|
||||
f32 col_key[3];
|
||||
f32 col_tfile[3];
|
||||
f32 col_tfile_header[3];
|
||||
f32 col_tfile_obj[3];
|
||||
f32 col_page[3];
|
||||
f32 col_page_start[3];
|
||||
f32 col_checksum[3];
|
||||
|
|
|
@ -63,7 +63,7 @@ ROOT::Experimental::RNTupleDescriptor create_descriptor(Arena *arena, RMicroFile
|
|||
}
|
||||
|
||||
internal
|
||||
void gather_metadata(Arena *arena, RMicroFileReader &reader, const RNTuple_File_Info &info, RNTuple_Data &rndata)
|
||||
void gather_ntuple_metadata(Arena *arena, RMicroFileReader &reader, const RNTuple_File_Info &info, RNTuple_Data &rndata)
|
||||
{
|
||||
using namespace ROOT::Experimental;
|
||||
using namespace ROOT::Experimental::Internal;
|
||||
|
@ -230,13 +230,39 @@ void gather_metadata(Arena *arena, RMicroFileReader &reader, const RNTuple_File_
|
|||
}
|
||||
|
||||
internal
|
||||
RNTuple_Data get_rntuple_data(Arena *arena, const char *fname, const char *ntpl_name)
|
||||
TFile_Data get_tfile_data(const Inspected_File &file)
|
||||
{
|
||||
TFile_Data tfile_data{};
|
||||
|
||||
Root_File_Info root_file_info = get_root_file_info(file.name.c());
|
||||
tfile_data.root_file_header_size = root_file_info.tfile_header_nbytes;
|
||||
tfile_data.rng_root_file_obj.start = root_file_info.tfile_obj_seek;
|
||||
tfile_data.rng_root_file_obj.len = root_file_info.tfile_obj_nbytes;
|
||||
|
||||
// parse root version
|
||||
const u64 len_root_magic = 4;
|
||||
assert(file.size > len_root_magic + sizeof(u32));
|
||||
u32 version_be;
|
||||
memcpy(&version_be, file.mem + len_root_magic, sizeof(version_be));
|
||||
u32 version = bswap_32(version_be);
|
||||
u32 version_major = version / 10000;
|
||||
u32 version_minor = (version - version_major * 10000) / 100;
|
||||
u32 version_patch = (version - version_major * 10000 - version_minor * 100);
|
||||
tfile_data.root_version_major = (u16)version_major;
|
||||
tfile_data.root_version_minor = (u16)version_minor;
|
||||
tfile_data.root_version_patch = (u16)version_patch;
|
||||
|
||||
return tfile_data;
|
||||
}
|
||||
|
||||
internal
|
||||
RNTuple_Data get_rntuple_data(Arena *arena, const Inspected_File &file, String8 ntpl_name)
|
||||
{
|
||||
RNTuple_Data rndata = {};
|
||||
RNTuple_Data rndata {};
|
||||
|
||||
// TODO: proper error handling
|
||||
RMicroFileReader file_reader { fname };
|
||||
RNTuple_File_Info file_info = file_reader.GetNTupleProper(ntpl_name);
|
||||
RMicroFileReader file_reader { file.name.c() };
|
||||
RNTuple_File_Info file_info = file_reader.GetNTupleProper(ntpl_name.c());
|
||||
if (!file_info.failed) {
|
||||
rndata.version.epoch = file_info.anchor.fVersionEpoch;
|
||||
rndata.version.major = file_info.anchor.fVersionMajor;
|
||||
|
@ -251,9 +277,8 @@ RNTuple_Data get_rntuple_data(Arena *arena, const char *fname, const char *ntpl_
|
|||
rndata.rng_anchor_key.start = file_info.anchor_key_seek;
|
||||
rndata.rng_anchor_key.len = file_info.anchor_key_nbytes;
|
||||
rndata.rblob_header_size = file_info.rblob_key_header_nbytes;
|
||||
rndata.root_file_header_size = file_info.tfile_header_nbytes;
|
||||
|
||||
gather_metadata(arena, file_reader, file_info, rndata);
|
||||
gather_ntuple_metadata(arena, file_reader, file_info, rndata);
|
||||
}
|
||||
|
||||
return rndata;
|
||||
|
|
|
@ -37,12 +37,19 @@ struct Cluster_Group_Info {
|
|||
Byte_Range rng_page_list;
|
||||
};
|
||||
|
||||
struct TFile_Data {
|
||||
u64 root_file_header_size;
|
||||
Byte_Range rng_root_file_obj;
|
||||
u16 root_version_major;
|
||||
u16 root_version_minor;
|
||||
u16 root_version_patch;
|
||||
};
|
||||
|
||||
struct RNTuple_Data {
|
||||
struct {
|
||||
u16 epoch, major, minor, patch;
|
||||
} version;
|
||||
|
||||
u64 root_file_header_size;
|
||||
u64 rblob_header_size;
|
||||
Byte_Range rng_anchor;
|
||||
Byte_Range rng_anchor_key;
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
|
||||
#include <cstdio>
|
||||
#include <cstdint>
|
||||
#include <byteswap.h>
|
||||
#include <utility> // for std::forward
|
||||
#include <chrono>
|
||||
|
||||
|
@ -124,8 +125,9 @@ int main(int argc, char **argv)
|
|||
os_start_file_watch(fname, app);
|
||||
}
|
||||
|
||||
app.ntpl_name = ntpl_name;
|
||||
app.rndata = get_rntuple_data(arena, fname, ntpl_name);
|
||||
app.ntpl_name = str8(ntpl_name);
|
||||
app.tfile_data = get_tfile_data(app.inspected_file);
|
||||
app.rndata = get_rntuple_data(arena, app.inspected_file, app.ntpl_name);
|
||||
make_viewer(app);
|
||||
|
||||
// Start main loop
|
||||
|
|
|
@ -1068,17 +1068,29 @@ static size_t ComputeNumChunks(size_t nbytes, size_t maxChunkSize)
|
|||
// PUBLIC INTERFACE
|
||||
// =========================================================================================
|
||||
|
||||
Root_File_Info get_root_file_info(const char *fname)
|
||||
{
|
||||
RTFString fileName { fname };
|
||||
Root_File_Info fileInfo {};
|
||||
fileInfo.tfile_header_nbytes = RTFHeader{}.GetSize();
|
||||
fileInfo.tfile_obj_seek = 100; // kBEGIN
|
||||
fileInfo.tfile_obj_nbytes = sizeof(RTFFile) + fileName.GetSize() + RTFString{}.GetSize() + RTFUUID{}.GetSize();
|
||||
return fileInfo;
|
||||
}
|
||||
|
||||
struct RMicroFileReader::Impl {
|
||||
std::unique_ptr<ROOT::Internal::RRawFile> fRawFile;
|
||||
std::uint64_t fMaxBlobSize = 0;
|
||||
};
|
||||
|
||||
RMicroFileReader::RMicroFileReader(const char *fname) {
|
||||
RMicroFileReader::RMicroFileReader(const char *fname)
|
||||
{
|
||||
impl = new Impl;
|
||||
impl->fRawFile = ROOT::Internal::RRawFile::Create(fname);
|
||||
}
|
||||
|
||||
RMicroFileReader::~RMicroFileReader() {
|
||||
RMicroFileReader::~RMicroFileReader()
|
||||
{
|
||||
delete impl;
|
||||
}
|
||||
|
||||
|
@ -1183,7 +1195,6 @@ RMicroFileReader::GetNTupleProper(const char *ntupleName)
|
|||
dummy.MakeBigKey();
|
||||
fileInfo.rblob_key_header_nbytes = dummy.GetHeaderSize();
|
||||
}
|
||||
fileInfo.tfile_header_nbytes = RTFHeader{}.GetSize();
|
||||
// @----
|
||||
ReadBuffer(ntuple, objNbytes, offset);
|
||||
if (objNbytes != key.fObjLen) {
|
||||
|
|
|
@ -38,9 +38,16 @@ struct RNTuple_File_Info {
|
|||
std::uint64_t anchor_key_seek;
|
||||
std::uint64_t anchor_key_nbytes;
|
||||
std::uint64_t rblob_key_header_nbytes;
|
||||
std::uint64_t tfile_header_nbytes;
|
||||
};
|
||||
|
||||
struct Root_File_Info {
|
||||
std::uint64_t tfile_header_nbytes;
|
||||
std::uint64_t tfile_obj_seek;
|
||||
std::uint64_t tfile_obj_nbytes;
|
||||
};
|
||||
|
||||
Root_File_Info get_root_file_info(const char *fname);
|
||||
|
||||
class RMicroFileReader final {
|
||||
public:
|
||||
explicit RMicroFileReader(const char *fname);
|
||||
|
|
|
@ -5,6 +5,6 @@ struct String8 {
|
|||
const char *c() const { return reinterpret_cast<const char *>(str); }
|
||||
};
|
||||
|
||||
#define str8(s) String8((u8*)(s), sizeof(s) - 1)
|
||||
#define str8(s) String8 { (u8*)(s), sizeof(s) - 1 }
|
||||
|
||||
String8 push_str8f(Arena *arena, char *fmt, ...);
|
||||
|
|
Loading…
Reference in a new issue