diff --git a/src/render.cpp b/src/render.cpp index a896666..fc34845 100644 --- a/src/render.cpp +++ b/src/render.cpp @@ -30,12 +30,14 @@ String8 to_pretty_size(Arena *arena, u64 bytes) return push_str8f(arena, "%zu B", bytes); } +// @Speed: instead of calling this function for every displayed byte, prefill an array +// of byte -> color only once and then just index it at `off`. internal u32 mem_edit_bg_color_fn(const u8 *, u64 off, void *user_data) { App_State *app = reinterpret_cast(user_data); const RNTuple_Data &rdata = app->rndata; - u64 rblob_sz = rdata.rblob_header_size; + u64 rblob_sz = rdata.rblob_header_size; // @Incomplete off += app->vsettings.base_display_addr; @@ -45,26 +47,33 @@ u32 mem_edit_bg_color_fn(const u8 *, u64 off, void *user_data) // Handle pages // 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 (off >= app->last_pinfo->range.end() - app->last_pinfo->checksum_size()) + return COL(app->vsettings.col_checksum); return COL(app->vsettings.col_page); + } // still fast case: `off is in the next page info as the previous. - if (app->last_pinfo->next) + if (app->last_pinfo->next) // don't check if it's checksum, since it's the first byte of the page app->last_pinfo = app->last_pinfo->next; if (app->last_pinfo && app->last_pinfo->range.start <= off && off < app->last_pinfo->range.end()) { if (off == app->last_pinfo->range.start) return COL(app->vsettings.col_page_start); - else - return COL(app->vsettings.col_page); + if (off >= app->last_pinfo->range.end() - app->last_pinfo->checksum_size()) + return COL(app->vsettings.col_checksum); + return COL(app->vsettings.col_page); } if (rdata.rng_anchor_key.start <= off && off < rdata.rng_anchor_key.end()) return COL(app->vsettings.col_key); if (rdata.rng_header.start - rblob_sz <= off && off < rdata.rng_header.start) return COL(app->vsettings.col_key); if (rdata.rng_footer.start - rblob_sz <= off && off < rdata.rng_footer.start) return COL(app->vsettings.col_key); - if (rdata.rng_anchor.start <= off && off < rdata.rng_anchor.end()) return COL(app->vsettings.col_anchor); - if (rdata.rng_header.start <= off && off < rdata.rng_header.end()) return COL(app->vsettings.col_header); - if (rdata.rng_footer.start <= off && off < rdata.rng_footer.end()) return COL(app->vsettings.col_footer); + if (rdata.rng_anchor.start <= off && off < rdata.rng_anchor.end() - 8) return COL(app->vsettings.col_anchor); + if (rdata.rng_anchor.end() - 8 <= off && off < rdata.rng_anchor.end()) return COL(app->vsettings.col_checksum); + if (rdata.rng_header.start <= off && off < rdata.rng_header.end() - 8) return COL(app->vsettings.col_header); + if (rdata.rng_header.end() - 8 <= off && off < rdata.rng_header.end()) return COL(app->vsettings.col_checksum); + if (rdata.rng_footer.start <= off && off < rdata.rng_footer.end() - 8) return COL(app->vsettings.col_footer); + if (rdata.rng_footer.end() - 8 <= off && off < rdata.rng_footer.end()) return COL(app->vsettings.col_checksum); // Slow page group lookup, ideally only done once per render when last_pinfo is invalid. for (Page_Info_Chunk *chunk = rdata.page_chunks; chunk; chunk = chunk->next) { @@ -79,7 +88,8 @@ u32 mem_edit_bg_color_fn(const u8 *, u64 off, void *user_data) if (pinfo->range.start <= off && off < pinfo->range.end()) { app->last_pinfo = pinfo; if (pinfo->range.start == off) return COL(app->vsettings.col_page_start); - else return COL(app->vsettings.col_page); + if (off >= pinfo->range.end() - pinfo->checksum_size()) return COL(app->vsettings.col_checksum); + return COL(app->vsettings.col_page); } } } @@ -118,6 +128,7 @@ Viewer_Settings make_viewer_settings() COL(col_tfile, 90, 90, 90); COL(col_page, 125, 0, 125); COL(col_page_start, 200, 0, 200); + COL(col_checksum, 134, 65, 25); #undef COL return settings; } @@ -237,6 +248,10 @@ void update_and_render(Arena *arena, App_State &app, f32 delta_time_ms) ImGui::PopItemWidth(); } + ImGui::ColorEdit3("_Checksum", app.vsettings.col_checksum, flags); + ImGui::SameLine(); + if (ImGui::Button("Checksum")) {} // TODO jump to next checksum + ImGui::Separator(); ImGui::Text("Num pages: %lu", app.rndata.n_pages); ImGui::Text("Num elements: %lu", app.rndata.n_elems); diff --git a/src/render.h b/src/render.h index 008419a..acac666 100644 --- a/src/render.h +++ b/src/render.h @@ -1,11 +1,12 @@ struct Viewer_Settings { - float col_anchor[3]; - float col_header[3]; - float col_footer[3]; - float col_key[3]; - float col_tfile[3]; - float col_page[3]; - float col_page_start[3]; + f32 col_anchor[3]; + f32 col_header[3]; + f32 col_footer[3]; + f32 col_key[3]; + f32 col_tfile[3]; + f32 col_page[3]; + f32 col_page_start[3]; + f32 col_checksum[3]; u64 base_display_addr; u64 latest_page_gone_to; diff --git a/src/rntuple.cpp b/src/rntuple.cpp index a644254..3498176 100644 --- a/src/rntuple.cpp +++ b/src/rntuple.cpp @@ -91,8 +91,8 @@ void gather_metadata(Arena *arena, RMicroFileReader &reader, const RNTuple_File_ const u64 checksum_size = sizeof(u64); Page_Info_Node *pinfo = arena_push(arena); pinfo->range.start = page_info.fLocator.GetPosition(); - pinfo->range.len = page_info.fLocator.fBytesOnStorage + page_info.fHasChecksum * checksum_size; - pinfo->n_elems = page_info.fNElements; + pinfo->range.len = page_info.fLocator.fBytesOnStorage + (page_info.fHasChecksum) * checksum_size; + pinfo->n_elems = page_info.fHasChecksum ? -page_info.fNElements : page_info.fNElements; if (!pinfo_head) { // first node inserted diff --git a/src/rntuple.h b/src/rntuple.h index c3380fa..c59cefd 100644 --- a/src/rntuple.h +++ b/src/rntuple.h @@ -8,8 +8,12 @@ struct Byte_Range { struct Page_Info_Node { Page_Info_Node *next; - Byte_Range range; // len of range includes the checksum - u32 n_elems; + Byte_Range range; // len includes checksum + i32 n_elems; // negative = page has checksum + + u64 checksum_size() const { + return (n_elems < 0) * 8; + } }; static const Page_Info_Node invalid_pinfo {};