add cluster highlighting

This commit is contained in:
silverweed 2024-07-19 16:31:48 +02:00
parent c3ded7b808
commit 83ad84491f
5 changed files with 65 additions and 23 deletions

View file

@ -37,6 +37,7 @@ u32 mem_edit_bg_color_fn(const u8 *, u64 off, void *user_data)
const RNTuple_Data &rdata = app->rndata; const RNTuple_Data &rdata = app->rndata;
const TFile_Data &tdata = app->tfile_data; const TFile_Data &tdata = app->tfile_data;
u64 rblob_sz = rdata.rblob_header_size; // @Incomplete u64 rblob_sz = rdata.rblob_header_size; // @Incomplete
i64 hilite_cluster = app->viewer.highlight_cluster ? app->viewer.highlighted_cluster : -1;
off += app->viewer.base_display_addr; off += app->viewer.base_display_addr;
@ -50,6 +51,8 @@ u32 mem_edit_bg_color_fn(const u8 *, u64 off, void *user_data)
// Handle pages // Handle pages
// fast case: `off` is in the same page info as previous `off`. // fast case: `off` is in the same page info as previous `off`.
if (app->last_pinfo->range.start < off && off < app->last_pinfo->range.end()) { if (app->last_pinfo->range.start < off && off < app->last_pinfo->range.end()) {
if (hilite_cluster >= 0 && app->last_pinfo->cluster_id == (u64)hilite_cluster)
return COL(app->viewer.col_highlight);
if (off >= app->last_pinfo->range.end() - app->last_pinfo->checksum_size()) if (off >= app->last_pinfo->range.end() - app->last_pinfo->checksum_size())
return COL(app->viewer.col_checksum); return COL(app->viewer.col_checksum);
return COL(app->viewer.col_page); return COL(app->viewer.col_page);
@ -60,6 +63,8 @@ u32 mem_edit_bg_color_fn(const u8 *, u64 off, void *user_data)
app->last_pinfo = app->last_pinfo->next; app->last_pinfo = app->last_pinfo->next;
if (app->last_pinfo && app->last_pinfo->range.start <= off && off < app->last_pinfo->range.end()) { if (app->last_pinfo && app->last_pinfo->range.start <= off && off < app->last_pinfo->range.end()) {
if (hilite_cluster >= 0 && app->last_pinfo->cluster_id == (u64)hilite_cluster)
return COL(app->viewer.col_highlight);
if (off == app->last_pinfo->range.start) if (off == app->last_pinfo->range.start)
return COL(app->viewer.col_page_start); return COL(app->viewer.col_page_start);
if (off >= app->last_pinfo->range.end() - app->last_pinfo->checksum_size()) if (off >= app->last_pinfo->range.end() - app->last_pinfo->checksum_size())
@ -99,6 +104,7 @@ u32 mem_edit_bg_color_fn(const u8 *, u64 off, void *user_data)
for (Page_Info_Node *pinfo = group.first; pinfo; pinfo = pinfo->next) { for (Page_Info_Node *pinfo = group.first; pinfo; pinfo = pinfo->next) {
if (pinfo->range.start <= off && off < pinfo->range.end()) { if (pinfo->range.start <= off && off < pinfo->range.end()) {
app->last_pinfo = pinfo; app->last_pinfo = pinfo;
if (hilite_cluster >= 0 && pinfo->cluster_id == (u64)hilite_cluster) return COL(app->viewer.col_highlight);
if (pinfo->range.start == off) return COL(app->viewer.col_page_start); if (pinfo->range.start == off) return COL(app->viewer.col_page_start);
if (off >= pinfo->range.end() - pinfo->checksum_size()) return COL(app->viewer.col_checksum); if (off >= pinfo->range.end() - pinfo->checksum_size()) return COL(app->viewer.col_checksum);
return COL(app->viewer.col_page); return COL(app->viewer.col_page);
@ -120,9 +126,11 @@ internal
MemoryEditor make_memory_editor(App_State &app) MemoryEditor make_memory_editor(App_State &app)
{ {
MemoryEditor mem_edit; MemoryEditor mem_edit;
mem_edit.ReadOnly = true;
mem_edit.Cols = 32; mem_edit.Cols = 32;
mem_edit.OptShowDataPreview = true; mem_edit.OptShowDataPreview = true;
// Do nothing on write.
// Note that we don't use ReadOnly = true because that disables selecting bytes
mem_edit.WriteFn = [] (ImU8*, size_t, ImU8) {};
mem_edit.BgColorFn = mem_edit_bg_color_fn; mem_edit.BgColorFn = mem_edit_bg_color_fn;
mem_edit.BgColorFnUserData = &app; mem_edit.BgColorFnUserData = &app;
return mem_edit; return mem_edit;
@ -147,6 +155,7 @@ void make_viewer(App_State &app)
COL(col_page_start, 200, 0, 200); COL(col_page_start, 200, 0, 200);
COL(col_checksum, 134, 65, 25); COL(col_checksum, 134, 65, 25);
COL(col_page_list, 60, 110, 120); COL(col_page_list, 60, 110, 120);
COL(col_highlight, 160, 160, 160);
#undef COL #undef COL
app.viewer = viewer; app.viewer = viewer;
@ -188,6 +197,25 @@ void viewer_jump_to_page_list(App_State &app, u64 page_list_idx)
viewer_jump_to(app.viewer, cg_info.rng_page_list.start); viewer_jump_to(app.viewer, cg_info.rng_page_list.start);
} }
internal
void viewer_jump_to_cluster(App_State &app, u64 cluster_idx)
{
assert(app.rndata.n_clusters > 0);
cluster_idx = (cluster_idx + app.rndata.n_clusters) % app.rndata.n_clusters;
// @Speed
Page_Info_Node *page = app.rndata.pages;
for (u64 i = 0; i < app.rndata.n_pages; ++i) {
if (page->cluster_id == cluster_idx)
break;
page = page->next;
assert(page);
}
app.viewer.highlighted_cluster = cluster_idx;
viewer_jump_to(app.viewer, page->range.start);
}
internal internal
void update_and_render(Arena *arena, App_State &app, f32 delta_time_ms) void update_and_render(Arena *arena, App_State &app, f32 delta_time_ms)
{ {
@ -228,7 +256,7 @@ void update_and_render(Arena *arena, App_State &app, f32 delta_time_ms)
// Draw main content // Draw main content
{ {
const u64 step_u64 = 1; const i64 step_i64 = 1;
ImGui::BeginTable("Hex View", 2, ImGuiTableFlags_Resizable); ImGui::BeginTable("Hex View", 2, ImGuiTableFlags_Resizable);
@ -296,10 +324,10 @@ void update_and_render(Arena *arena, App_State &app, f32 delta_time_ms)
if (ImGui::Button("Page")) viewer_jump_to_page(app, app.viewer.latest_page_gone_to); if (ImGui::Button("Page")) viewer_jump_to_page(app, app.viewer.latest_page_gone_to);
ImGui::SameLine(); ImGui::SameLine();
{ {
const u64 step_fast_u64 = app.rndata.n_pages / 100; const i64 step_fast_i64 = app.rndata.n_pages / 100;
u64 page_to_go_to = app.viewer.latest_page_gone_to; i64 page_to_go_to = app.viewer.latest_page_gone_to;
ImGui::PushItemWidth(100.f); ImGui::PushItemWidth(100.f);
if (ImGui::InputScalar("##page_viewed", ImGuiDataType_U64, &page_to_go_to, &step_u64, &step_fast_u64, "%u")) if (ImGui::InputScalar("##page_viewed", ImGuiDataType_S64, &page_to_go_to, &step_i64, &step_fast_i64, "%u"))
viewer_jump_to_page(app, page_to_go_to); viewer_jump_to_page(app, page_to_go_to);
ImGui::PopItemWidth(); ImGui::PopItemWidth();
} }
@ -315,9 +343,9 @@ void update_and_render(Arena *arena, App_State &app, f32 delta_time_ms)
if (ImGui::Button("Page List")) viewer_jump_to_page_list(app, app.viewer.latest_page_list_gone_to); if (ImGui::Button("Page List")) viewer_jump_to_page_list(app, app.viewer.latest_page_list_gone_to);
ImGui::SameLine(); ImGui::SameLine();
{ {
u64 page_list_to_go_to = app.viewer.latest_page_list_gone_to; i64 page_list_to_go_to = app.viewer.latest_page_list_gone_to;
ImGui::PushItemWidth(80.f); ImGui::PushItemWidth(80.f);
if (ImGui::InputScalar("##page_list_viewed", ImGuiDataType_U64, &page_list_to_go_to, &step_u64, nullptr, "%u")) if (ImGui::InputScalar("##page_list_viewed", ImGuiDataType_S64, &page_list_to_go_to, &step_i64, nullptr, "%u"))
viewer_jump_to_page_list(app, page_list_to_go_to); viewer_jump_to_page_list(app, page_list_to_go_to);
ImGui::PopItemWidth(); ImGui::PopItemWidth();
} }
@ -334,6 +362,18 @@ void update_and_render(Arena *arena, App_State &app, f32 delta_time_ms)
ImGui::Text("Num pages: %lu", app.rndata.n_pages); ImGui::Text("Num pages: %lu", app.rndata.n_pages);
ImGui::Text("Num elements: %lu", app.rndata.n_elems); ImGui::Text("Num elements: %lu", app.rndata.n_elems);
{
const i64 step_fast_i64 = app.rndata.n_clusters / 100;
i64 cluster_to_highlight = app.viewer.highlighted_cluster;
ImGui::PushItemWidth(100.f);
if (ImGui::InputScalar("##highlighted_cluster", ImGuiDataType_S64, &cluster_to_highlight, &step_i64, &step_fast_i64, "%u")) {
viewer_jump_to_cluster(app, cluster_to_highlight);
}
ImGui::PopItemWidth();
ImGui::SameLine();
ImGui::Checkbox("Highlight cluster", &app.viewer.highlight_cluster);
}
ImGui::EndTable(); ImGui::EndTable();
} }

View file

@ -13,9 +13,13 @@ struct Viewer {
f32 col_page_start[3]; f32 col_page_start[3];
f32 col_checksum[3]; f32 col_checksum[3];
f32 col_page_list[3]; f32 col_page_list[3];
f32 col_highlight[3];
u64 base_display_addr; u64 base_display_addr;
b8 highlight_cluster;
u64 highlighted_cluster;
u64 latest_page_gone_to; u64 latest_page_gone_to;
u64 latest_key_gone_to; u64 latest_key_gone_to;
u64 latest_checksum_gone_to; u64 latest_checksum_gone_to;

View file

@ -119,6 +119,7 @@ void gather_ntuple_metadata(Arena *arena, RMicroFileReader &reader, const RNTupl
pinfo->range.start = page_info.fLocator.GetPosition<u64>(); pinfo->range.start = page_info.fLocator.GetPosition<u64>();
pinfo->range.len = page_info.fLocator.fBytesOnStorage + (page_info.fHasChecksum) * checksum_size; pinfo->range.len = page_info.fLocator.fBytesOnStorage + (page_info.fHasChecksum) * checksum_size;
pinfo->n_elems = page_info.fHasChecksum ? -page_info.fNElements : page_info.fNElements; pinfo->n_elems = page_info.fHasChecksum ? -page_info.fNElements : page_info.fNElements;
pinfo->cluster_id = cluster_desc.GetId();
if (!pinfo_head) { if (!pinfo_head) {
// first node inserted // first node inserted

View file

@ -5,23 +5,24 @@ struct Byte_Range {
u64 end() const { return start + len; } u64 end() const { return start + len; }
}; };
// Used to store location information about stuff like checksums, page lists, etc
struct Range_Seq {
Range_Seq *next;
Byte_Range range;
};
struct Page_Info_Node { struct Page_Info_Node {
Page_Info_Node *next; Page_Info_Node *next;
Byte_Range range; // len includes checksum Byte_Range range; // len includes checksum
i32 n_elems; // negative = page has checksum i32 n_elems; // negative = page has checksum
u64 cluster_id;
u64 checksum_size() const { u64 checksum_size() const {
return (n_elems < 0) * 8; return (n_elems < 0) * 8;
} }
}; };
// Used to store location information about stuff like checksums, page lists, etc
struct Range_Seq {
Range_Seq *next;
Byte_Range range;
};
static const Page_Info_Node invalid_pinfo {}; static const Page_Info_Node invalid_pinfo {};
struct Page_Info_Group { struct Page_Info_Group {
@ -71,12 +72,10 @@ struct RNTuple_Data {
u64 n_elems; u64 n_elems;
u64 tot_page_size; u64 tot_page_size;
// TODO
Range_Seq *checksums; Range_Seq *checksums;
u64 n_checksums; u64 n_checksums;
Range_Seq *page_lists;
u64 n_page_lists;
Cluster_Group_Info *cluster_groups; Cluster_Group_Info *cluster_groups;
u64 n_cluster_groups; u64 n_cluster_groups;
u64 tot_page_list_size; u64 tot_page_list_size;

View file

@ -245,7 +245,7 @@ struct MemoryEditor
bool data_next = false; bool data_next = false;
if (/*ReadOnly ||*/ DataEditingAddr >= mem_size) if (ReadOnly || DataEditingAddr >= mem_size)
DataEditingAddr = (size_t)-1; DataEditingAddr = (size_t)-1;
if (DataPreviewAddr >= mem_size) if (DataPreviewAddr >= mem_size)
DataPreviewAddr = (size_t)-1; DataPreviewAddr = (size_t)-1;
@ -320,7 +320,6 @@ struct MemoryEditor
draw_list->AddRectFilled(pos, ImVec2(pos.x + highlight_width, pos.y + s.LineHeight), BgColorFn(mem_data, addr, BgColorFnUserData)); draw_list->AddRectFilled(pos, ImVec2(pos.x + highlight_width, pos.y + s.LineHeight), BgColorFn(mem_data, addr, BgColorFnUserData));
} }
#if 0
if (DataEditingAddr == addr) if (DataEditingAddr == addr)
{ {
// Display text input on current byte // Display text input on current byte
@ -381,7 +380,6 @@ struct MemoryEditor
ImGui::PopID(); ImGui::PopID();
} }
else else
#endif
{ {
// NB: The trailing space is not visible but ensure there's no gap that the mouse cannot click on. // NB: The trailing space is not visible but ensure there's no gap that the mouse cannot click on.
ImU8 b = ReadFn ? ReadFn(mem_data, addr) : mem_data[addr]; ImU8 b = ReadFn ? ReadFn(mem_data, addr) : mem_data[addr];
@ -404,7 +402,7 @@ struct MemoryEditor
else else
ImGui::Text(format_byte_space, b); ImGui::Text(format_byte_space, b);
} }
if (/*!ReadOnly &&*/ ImGui::IsItemHovered() && ImGui::IsMouseClicked(0)) if (!ReadOnly && ImGui::IsItemHovered() && ImGui::IsMouseClicked(0))
{ {
DataEditingTakeFocus = true; DataEditingTakeFocus = true;
data_editing_addr_next = addr; data_editing_addr_next = addr;