diff --git a/src/render.cpp b/src/render.cpp index dbf10e6..50aae8f 100644 --- a/src/render.cpp +++ b/src/render.cpp @@ -514,7 +514,11 @@ void update_and_render(Arena *arena, App_State &app, f32 delta_time_ms) ImGui::TextColored(ImColor(0.f, 0.65f, 0.f), "Offset: 0x%" PRIX64, hovered_off - 1); Section hovered_section = find_section(app, hovered_off - 1); b8 hover_display_grouped = !(app.user_input.key_state[KEY_ALT] & KEY_STATE_IS_DOWN); - b8 old_version = hovered_section.from_old_version_rntuple; + Section_Id sec_id = hovered_section.id; + // NOTE: anchor/header/footer sections all have their *info point to their parent rntuple anchor info. + b8 old_version = + (sec_id == Sec_RNTuple_Anchor || sec_id == Sec_RNTuple_Header || sec_id == Sec_RNTuple_Footer) && + rntuple_is_old_version(((const RNTuple_Anchor_Info *)hovered_section.info)->anchor); Sec_Hover_Info hover_info = get_section_hover_info(scratch.arena, hovered_section, hovered_off - 1, app.inspected_file.mem, hover_display_grouped, old_version); ImGui::TextColored(ImColor(0.5f, 0.5f, 0.5f), "(Hint: hold Alt for single-field hover information)"); diff --git a/src/rntuple.h b/src/rntuple.h index 402a80a..fb804a5 100644 --- a/src/rntuple.h +++ b/src/rntuple.h @@ -84,13 +84,13 @@ struct Section { u32 pre_size; // usually the TKey header, excluded from `range` u32 post_size; // usually the checksum, included in `range` b8 highlighted; - b8 from_old_version_rntuple; // Optional pointer to the specific information for the section. // Here are the actual types: // - Sec_RNTuple_Anchor => RNTuple_Anchor_Info // - Sec_Page => Page_Info_Node (aliased from RNTuple_Data::pages) // - Sec_Other => String8 (the class name of the object) + // - Sec_RNTuple_Header / Sec_RNTuple_Footer => parent RNTuple_Anchor_Info const void *info; }; static const Section invalid_section {}; @@ -130,10 +130,6 @@ struct Sections { u64 tot_size; }; -struct TKeys_Data { - Byte_Range_Node *rblob_keys; -}; - struct TFile_Data { u16 root_version_major; u16 root_version_minor; @@ -141,7 +137,7 @@ struct TFile_Data { u32 compression; Sections sections[Sec_COUNT]; - TKeys_Data tkeys_data; + Byte_Range_Node *rblob_keys; }; // @Volatile: when changed, remember to update merge_rntuple_data() diff --git a/src/rntviewer.cpp b/src/rntviewer.cpp index fcd9d5f..b2646e2 100644 --- a/src/rntviewer.cpp +++ b/src/rntviewer.cpp @@ -173,9 +173,7 @@ int main(int argc, char **argv) return 0; } - // if (!app.ntpl_name.str) - // fprintf(stderr, "Warning: found no RNTuples in %s\n", args.file_name.c()); - // else if (success) + if (success) app.rndata = get_rntuple_data(arena, app.inspected_file, app.tfile_data, args.extended_info); compute_tot_sections_size(app.tfile_data.sections); diff --git a/src/tfile.cpp b/src/tfile.cpp index 70ddef9..9a14a4e 100644 --- a/src/tfile.cpp +++ b/src/tfile.cpp @@ -88,8 +88,6 @@ b8 walk_tkeys(Arena *arena, const u8 *data, u64 data_len, u32 flags, TFile_Data return false; } - TKeys_Data &tkeys_data = tfile_data.tkeys_data; - Temp scratch = scratch_begin(&arena, 1); defer { scratch_end(scratch); }; @@ -170,7 +168,7 @@ b8 walk_tkeys(Arena *arena, const u8 *data, u64 data_len, u32 flags, TFile_Data // skip title cur += 1 + data[cur]; - // read TFile object relevant tkeys_data + // read TFile object relevant data u16 tfile_class_version = read_be<u16>(data + cur); u64 seek_keys; @@ -295,7 +293,6 @@ b8 walk_tkeys(Arena *arena, const u8 *data, u64 data_len, u32 flags, TFile_Data sec_anchor->range.len = n_bytes - keylen; sec_anchor->pre_size = keylen; sec_anchor->post_size = 8; - sec_anchor->from_old_version_rntuple = rntuple_is_old_version(rntuple_info->anchor); } else if (key_has_class_name("RBlob")) { if (!sections[Sec_Page].head) { @@ -309,8 +306,8 @@ b8 walk_tkeys(Arena *arena, const u8 *data, u64 data_len, u32 flags, TFile_Data rblob_key->rng.start = cur; rblob_key->rng.len = keylen; // Push byte range to the front of the list, so rblob_keys is sorted by decreasing address - rblob_key->next = tkeys_data.rblob_keys; - tkeys_data.rblob_keys = rblob_key; + rblob_key->next = tfile_data.rblob_keys; + tfile_data.rblob_keys = rblob_key; } else if (flags & WTK_COLLECT_OTHER_ROOT_OBJS) { Section *sec_other = push_section(arena, tfile_data, Sec_Other); @@ -374,7 +371,6 @@ void map_rntuple_rblobs(Arena *arena, TFile_Data &tfile_data) Temp scratch = scratch_begin(&arena, 1); defer { scratch_end(scratch); }; - TKeys_Data &tkeys_data = tfile_data.tkeys_data; u64 n_anchors = tfile_data.sections[Sec_RNTuple_Anchor].count; // 0: header, 1: footer @@ -383,24 +379,25 @@ void map_rntuple_rblobs(Arena *arena, TFile_Data &tfile_data) arena_push_array<b8>(scratch.arena, n_anchors) }; - for (Byte_Range_Node *tkey = tkeys_data.rblob_keys; tkey; tkey = tkey->next) { + for (Byte_Range_Node *tkey = tfile_data.rblob_keys; tkey; tkey = tkey->next) { // NOTE: since we know the rblob_keys list is sorted by decreasing address, as soon as we find an address that's // lower than the section we're looking for, we know it must be the closest one (therefore the correct one). for (Section_Id sec_id : { Sec_RNTuple_Header, Sec_RNTuple_Footer }) { i64 best_anchor_idx = -1; - const ROOT::RNTuple *best_anchor = nullptr; + const RNTuple_Anchor_Info *best_anchor = nullptr; u64 i = 0; u64 best_anchor_diff = (u64)-1; b8 *found_sec = found[sec_id == Sec_RNTuple_Footer]; for (Section *sec_anchor = tfile_data.sections[Sec_RNTuple_Anchor].head; sec_anchor; sec_anchor = sec_anchor->next, ++i) { - const ROOT::RNTuple &anchor = ((const RNTuple_Anchor_Info *)sec_anchor->info)->anchor; + const RNTuple_Anchor_Info *anchor_info = (const RNTuple_Anchor_Info *)sec_anchor->info; + const ROOT::RNTuple &anchor = anchor_info->anchor; if (!found_sec[i]) { u64 seek = sec_id == Sec_RNTuple_Header ? anchor.GetSeekHeader() : anchor.GetSeekFooter(); i64 diff = seek - tkey->rng.start; if (diff > 0 && (u64)diff < best_anchor_diff) { best_anchor_idx = i; - best_anchor = &anchor; + best_anchor = anchor_info; best_anchor_diff = diff; } } @@ -409,10 +406,10 @@ void map_rntuple_rblobs(Arena *arena, TFile_Data &tfile_data) found_sec[best_anchor_idx] = true; Section *section = push_section(arena, tfile_data, sec_id); section->range.start = tkey->rng.start + tkey->rng.len; - section->range.len = sec_id == Sec_RNTuple_Header ? best_anchor->GetNBytesHeader() : best_anchor->GetNBytesFooter(); + section->range.len = sec_id == Sec_RNTuple_Header ? best_anchor->anchor.GetNBytesHeader() : best_anchor->anchor.GetNBytesFooter(); section->pre_size = tkey->rng.len; section->post_size = 8; - section->from_old_version_rntuple = rntuple_is_old_version(*best_anchor); + section->info = best_anchor; } } }