read any other ROOT obj as a blob, rather than just TBaskets
This commit is contained in:
parent
a9109144a6
commit
885ef4ae3c
8 changed files with 59 additions and 51 deletions
|
@ -5,7 +5,7 @@ void print_help(const char *argv0)
|
|||
"rntviewer v" V_MAJOR "." V_MINOR " by silverweed"
|
||||
"\n"
|
||||
"\nUsage: %s [-Behkntv] [-s START] [-l LEN] [-w WIDTH] <ntuple_file.root> [ntuple_name]"
|
||||
"\n\t-B: disable highlighting of TBaskets"
|
||||
"\n\t-R: disable highlighting of non-RNTuple ROOT objects"
|
||||
"\n\t-e: display some extended info(*) (may slow down the startup)"
|
||||
"\n\t-h: display this help and exit"
|
||||
"\n\t-l: display LEN bytes (only in terminal mode)"
|
||||
|
@ -76,7 +76,7 @@ struct Cmdline_Args {
|
|||
b8 extended_info;
|
||||
b8 only_print_rntuple_names;
|
||||
b8 print_keys_info;
|
||||
b8 disable_tbaskets;
|
||||
b8 dont_collect_other_root_objs;
|
||||
|
||||
String8 ntpl_name;
|
||||
String8 file_name;
|
||||
|
@ -169,8 +169,8 @@ Cmdline_Args parse_args(i32 argc, char **argv)
|
|||
args.show_version_and_exit = true;
|
||||
else if (arg[1] == 'k')
|
||||
args.print_keys_info = true;
|
||||
else if (arg[1] == 'B')
|
||||
args.disable_tbaskets = true;
|
||||
else if (arg[1] == 'R')
|
||||
args.dont_collect_other_root_objs = true;
|
||||
else if (arg[1] == 'w') {
|
||||
u64 n_cols = 0;
|
||||
parse_int_arg(i, argc, argv, n_cols);
|
||||
|
|
|
@ -1060,9 +1060,11 @@ struct Sec_Hover_Fn {
|
|||
});
|
||||
}
|
||||
|
||||
void basket()
|
||||
void other_root_obj()
|
||||
{
|
||||
titled_section("TBasket", [this] {
|
||||
Other_Root_Obj_Info *info = (Other_Root_Obj_Info *)section.info;
|
||||
String8 name = info ? info->class_name : str8("(Unknown)");
|
||||
titled_section(name.c(), [this] {
|
||||
tkey();
|
||||
range("Payload", section.range.len - section.post_size);
|
||||
});
|
||||
|
@ -1104,7 +1106,7 @@ Sec_Hover_Info get_section_hover_info(Arena *arena, Section section, u64 off, co
|
|||
case Sec_TFile_Info: hover.tfile_info(); break;
|
||||
case Sec_TFile_FreeList: hover.tfile_freelist(); break;
|
||||
case Sec_TKey_List: hover.tkey_list(); break;
|
||||
case Sec_Basket: hover.basket(); break;
|
||||
case Sec_Other: hover.other_root_obj(); break;
|
||||
default:
|
||||
info.desc = push_str8_node(arena, nullptr, "%s", sec_name.c());
|
||||
}
|
||||
|
|
|
@ -115,8 +115,8 @@ u32 mem_edit_bg_color_fn(const u8 *data, u64 off, void *user_data)
|
|||
return imcol(app->viewer.col_highlight, brighten);
|
||||
if (section.id == Sec_Page && off == section.range.start)
|
||||
return imcol(app->viewer.col_page_start, brighten);
|
||||
if (section.id == Sec_Basket && off == section.range.start)
|
||||
return imcol(app->viewer.col_basket_start, brighten);
|
||||
if (section.id == Sec_Other && off == section.range.start)
|
||||
return imcol(app->viewer.col_other_root_obj_start, brighten);
|
||||
if (off < section.range.start)
|
||||
return imcol(app->viewer.col_key, brighten);
|
||||
if (section.range.end() - section.post_size <= off && off < section.range.end())
|
||||
|
@ -145,7 +145,7 @@ void init_viewer(App_State &app, u16 n_cols)
|
|||
#define COL(c, r, g, b) viewer.c[0] = r/255.0, viewer.c[1] = g/255.0, viewer.c[2] = b/255.0
|
||||
COL(col_key, 0, 100, 50);
|
||||
COL(col_page_start, 200, 0, 200);
|
||||
COL(col_basket_start, 200, 200, 150);
|
||||
COL(col_other_root_obj_start, 200, 200, 150);
|
||||
COL(col_checksum, 134, 65, 25);
|
||||
COL(col_highlight, 190, 190, 190);
|
||||
#define COL_S(c, r, g, b) viewer.col_section[c][0] = r/255.0, viewer.col_section[c][1] = g/255.0, viewer.col_section[c][2] = b/255.0
|
||||
|
@ -159,7 +159,7 @@ void init_viewer(App_State &app, u16 n_cols)
|
|||
COL_S(Sec_Page, 125, 0, 125);
|
||||
COL_S(Sec_Page_List, 60, 110, 120);
|
||||
COL_S(Sec_TKey_List, 100, 140, 100);
|
||||
COL_S(Sec_Basket, 140, 140, 100);
|
||||
COL_S(Sec_Other, 140, 140, 100);
|
||||
#undef COL
|
||||
#undef COL_S
|
||||
}
|
||||
|
@ -204,20 +204,20 @@ void viewer_jump_to_page_list(App_State &app, u64 page_list_idx)
|
|||
}
|
||||
|
||||
internal
|
||||
void viewer_jump_to_basket(App_State &app, u64 basket_idx)
|
||||
void viewer_jump_to_other_root_obj(App_State &app, u64 obj_idx)
|
||||
{
|
||||
u64 n_baskets = app.tfile_data.tkeys_data.n_baskets;
|
||||
if (n_baskets == 0)
|
||||
u64 n_other_root_objs = app.tfile_data.tkeys_data.n_other_root_obj;
|
||||
if (n_other_root_objs == 0)
|
||||
return;
|
||||
|
||||
basket_idx = (basket_idx + n_baskets) % n_baskets;
|
||||
obj_idx = (obj_idx + n_other_root_objs) % n_other_root_objs;
|
||||
|
||||
Basket_Info *binfo = app.tfile_data.tkeys_data.baskets;
|
||||
for (u64 i = 0; i < basket_idx; ++i)
|
||||
binfo = binfo->next;
|
||||
Other_Root_Obj_Info *info = app.tfile_data.tkeys_data.other_root_obj;
|
||||
for (u64 i = 0; i < obj_idx; ++i)
|
||||
info = info->next;
|
||||
|
||||
app.viewer.latest_basket_gone_to = basket_idx;
|
||||
viewer_jump_to(app, binfo->section.range.start);
|
||||
app.viewer.latest_root_obj_gone_to = obj_idx;
|
||||
viewer_jump_to(app, info->section.range.start);
|
||||
}
|
||||
|
||||
internal
|
||||
|
@ -409,20 +409,20 @@ void update_and_render(Arena *arena, App_State &app, f32 delta_time_ms)
|
|||
ImGui::SameLine();
|
||||
ImGui::Text("%s", to_pretty_size(scratch.arena, app.rndata.tot_page_list_size).c());
|
||||
|
||||
if (app.tfile_data.tkeys_data.n_baskets > 0) {
|
||||
ImGui::ColorEdit3("_TTree Basket", app.viewer.col_section[Sec_Basket], edit_flags);
|
||||
if (app.tfile_data.tkeys_data.n_other_root_obj > 0) {
|
||||
ImGui::ColorEdit3("_Other", app.viewer.col_section[Sec_Other], edit_flags);
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("TTree Basket"))
|
||||
viewer_jump_to_basket(app, app.viewer.latest_basket_gone_to);
|
||||
if (ImGui::Button("Other"))
|
||||
viewer_jump_to_other_root_obj(app, app.viewer.latest_root_obj_gone_to);
|
||||
|
||||
ImGui::SameLine();
|
||||
{
|
||||
i64 basket_to_go_to = app.viewer.latest_basket_gone_to;
|
||||
i64 other_root_obj_to_go_to = app.viewer.latest_root_obj_gone_to;
|
||||
ImGui::PushItemWidth(80.f);
|
||||
if (ImGui::InputScalar("##basket_viewed", ImGuiDataType_S64, &basket_to_go_to, &step_i64, nullptr, "%u")
|
||||
if (ImGui::InputScalar("##other_root_objviewed", ImGuiDataType_S64, &other_root_obj_to_go_to, &step_i64, nullptr, "%u")
|
||||
&& ImGui::IsItemDeactivatedAfterEdit())
|
||||
{
|
||||
viewer_jump_to_basket(app, basket_to_go_to);
|
||||
viewer_jump_to_other_root_obj(app, other_root_obj_to_go_to);
|
||||
}
|
||||
ImGui::PopItemWidth();
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ struct Viewer {
|
|||
f32 col_checksum[3];
|
||||
f32 col_highlight[3];
|
||||
f32 col_page_start[3];
|
||||
f32 col_basket_start[3];
|
||||
f32 col_other_root_obj_start[3];
|
||||
|
||||
#ifndef RNT_NO_GFX
|
||||
MemoryEditor mem_edit;
|
||||
|
@ -22,7 +22,7 @@ struct Viewer {
|
|||
u64 latest_key_gone_to;
|
||||
u64 latest_checksum_gone_to;
|
||||
u64 latest_page_list_gone_to;
|
||||
u64 latest_basket_gone_to;
|
||||
u64 latest_root_obj_gone_to;
|
||||
|
||||
Byte_Range hovered_range;
|
||||
|
||||
|
|
|
@ -539,9 +539,9 @@ Section find_section(App_State &app, u64 off, i64 hilite_cluster = -1)
|
|||
}
|
||||
|
||||
// @Speed
|
||||
for (Basket_Info *basket = tdata.baskets; basket; basket = basket->next) {
|
||||
if (basket->section.range.start - basket->section.pre_size <= off && off < basket->section.range.end()) {
|
||||
return basket->section;
|
||||
for (Other_Root_Obj_Info *other = tdata.other_root_obj; other; other = other->next) {
|
||||
if (other->section.range.start - other->section.pre_size <= off && off < other->section.range.end()) {
|
||||
return other->section;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -68,7 +68,8 @@ enum Section_Id {
|
|||
|
||||
Sec_First_Non_Unique,
|
||||
Sec_Page = Sec_First_Non_Unique,
|
||||
Sec_Basket,
|
||||
// any other object stored in a TKey
|
||||
Sec_Other,
|
||||
|
||||
Sec_COUNT
|
||||
};
|
||||
|
@ -97,7 +98,7 @@ internal const String8 section_names[Sec_COUNT] = {
|
|||
str8("RNTuple Footer"),
|
||||
str8("Page List"),
|
||||
str8("Page"),
|
||||
str8("Basket"),
|
||||
str8("Other"),
|
||||
};
|
||||
|
||||
struct Byte_Range_Node {
|
||||
|
@ -111,8 +112,9 @@ struct RNTuple_Anchor_Info {
|
|||
u64 offset_in_file;
|
||||
};
|
||||
|
||||
struct Basket_Info {
|
||||
Basket_Info *next;
|
||||
struct Other_Root_Obj_Info {
|
||||
Other_Root_Obj_Info *next;
|
||||
String8 class_name;
|
||||
Section section;
|
||||
};
|
||||
|
||||
|
@ -122,8 +124,8 @@ struct TKeys_Data {
|
|||
RNTuple_Anchor_Info *rntuples;
|
||||
Byte_Range_Node *rblob_keys;
|
||||
|
||||
Basket_Info *baskets;
|
||||
u64 n_baskets;
|
||||
Other_Root_Obj_Info *other_root_obj;
|
||||
u64 n_other_root_obj;
|
||||
};
|
||||
|
||||
struct TFile_Data {
|
||||
|
|
|
@ -82,7 +82,7 @@ using ROOT::Experimental::Internal::RNTupleSerializer;
|
|||
#endif
|
||||
|
||||
#define V_MAJOR "0"
|
||||
#define V_MINOR "8"
|
||||
#define V_MINOR "9"
|
||||
|
||||
// Internal sources
|
||||
// --------------------------------------------------
|
||||
|
@ -161,8 +161,8 @@ int main(int argc, char **argv)
|
|||
u32 walk_tkeys_flags = WTK_NONE;
|
||||
if (args.print_keys_info)
|
||||
walk_tkeys_flags |= WTK_PRINT_KEYS_INFO;
|
||||
if (!args.disable_tbaskets)
|
||||
walk_tkeys_flags |= WTK_COLLECT_BASKETS;
|
||||
if (!args.dont_collect_other_root_objs)
|
||||
walk_tkeys_flags |= WTK_COLLECT_OTHER_ROOT_OBJS;
|
||||
b8 success = get_tfile_data(arena, app.inspected_file, walk_tkeys_flags, app.ntpl_name, app.tfile_data);
|
||||
if (args.only_print_rntuple_names) {
|
||||
for (RNTuple_Anchor_Info *info = app.tfile_data.tkeys_data.rntuples; info; info = info->next)
|
||||
|
|
|
@ -58,7 +58,7 @@ T read_be(const void *data)
|
|||
enum {
|
||||
WTK_NONE = 0,
|
||||
WTK_PRINT_KEYS_INFO = 1,
|
||||
WTK_COLLECT_BASKETS = 2,
|
||||
WTK_COLLECT_OTHER_ROOT_OBJS = 2,
|
||||
};
|
||||
|
||||
// Examines the innards of a TFile to get byte range info about the TKeys.
|
||||
|
@ -170,7 +170,7 @@ b8 walk_tkeys(Arena *arena, const u8 *data, u64 data_len, u32 flags, TFile_Data
|
|||
cur = pre + tfile_obj_nbytes;
|
||||
|
||||
RNTuple_Anchor_Info *rntuple_info_tail = nullptr;
|
||||
Basket_Info *baskets_tail = nullptr;
|
||||
Other_Root_Obj_Info *other_root_obj_tail = nullptr;
|
||||
|
||||
u32 n_keys = 0;
|
||||
// Walk through all the TKeys in the file and do two things:
|
||||
|
@ -271,19 +271,23 @@ b8 walk_tkeys(Arena *arena, const u8 *data, u64 data_len, u32 flags, TFile_Data
|
|||
rblob_key->next = tkeys_data.rblob_keys;
|
||||
tkeys_data.rblob_keys = rblob_key;
|
||||
|
||||
} else if ((flags & WTK_COLLECT_BASKETS) && key_has_class_name("TBasket")) {
|
||||
Basket_Info *binfo = arena_push<Basket_Info>(arena);
|
||||
binfo->section.id = Sec_Basket;
|
||||
} else if ((flags & WTK_COLLECT_OTHER_ROOT_OBJS)) {
|
||||
Other_Root_Obj_Info *binfo = arena_push<Other_Root_Obj_Info>(arena);
|
||||
if (cname_len) {
|
||||
binfo->class_name = str8_from_buf(arena, data + cname_off + 1, cname_len);
|
||||
}
|
||||
binfo->section.id = Sec_Other;
|
||||
binfo->section.info = binfo;
|
||||
binfo->section.range.start = cur + keylen;
|
||||
binfo->section.range.len = n_bytes - keylen;
|
||||
binfo->section.pre_size = keylen;
|
||||
if (tkeys_data.baskets) {
|
||||
baskets_tail->next = binfo;
|
||||
if (tkeys_data.other_root_obj) {
|
||||
other_root_obj_tail->next = binfo;
|
||||
} else {
|
||||
tkeys_data.baskets = binfo;
|
||||
tkeys_data.other_root_obj = binfo;
|
||||
}
|
||||
baskets_tail = binfo;
|
||||
tkeys_data.n_baskets++;
|
||||
other_root_obj_tail = binfo;
|
||||
tkeys_data.n_other_root_obj++;
|
||||
}
|
||||
}
|
||||
cur += n_bytes;
|
||||
|
|
Loading…
Add table
Reference in a new issue