fix page grouping

This commit is contained in:
silverweed 2024-07-15 15:54:22 +02:00
parent 647c8c20f6
commit 700e76366b
2 changed files with 56 additions and 19 deletions

View file

@ -40,16 +40,25 @@ u32 mem_edit_bg_color_fn(const u8 *, u64 off, void *user_data)
off += app->vsettings.base_display_addr; off += app->vsettings.base_display_addr;
#define COL(c) (ImColor((c)[0], (c)[1], (c)[2])) #define COL(c) (ImColor((c)[0], (c)[1], (c)[2]))
// Handle pages // TFile start
// fast case: offset from same page info as previous if (off <= rdata.root_file_header_size) return COL(app->vsettings.col_tfile);
if (off < app->last_pinfo->range.end()) return COL(app->vsettings.col_page);
// still fast case: offset from next page info // Handle pages
if (app->last_pinfo->next) app->last_pinfo = app->last_pinfo->next; // fast case: `off` is in the same page info as previous `off`.
if (app->last_pinfo && 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())
return COL(app->vsettings.col_page); return COL(app->vsettings.col_page);
if (off <= rdata.root_file_header_size) return COL(app->vsettings.col_tfile); // still fast case: `off is in the next page info as the previous.
if (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 (off == app->last_pinfo->range.start)
return COL(app->vsettings.col_page_start);
else
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_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_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_footer.start - rblob_sz <= off && off <= rdata.rng_footer.start) return COL(app->vsettings.col_key);
@ -57,11 +66,9 @@ u32 mem_edit_bg_color_fn(const u8 *, u64 off, void *user_data)
if (rdata.rng_header.start <= off && off <= rdata.rng_header.end()) return COL(app->vsettings.col_header); 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_footer.start <= off && off <= rdata.rng_footer.end()) return COL(app->vsettings.col_footer);
// Slow page group lookup, hopefully rare (ideally only done once) // Slow page group lookup, ideally only done once per render when last_pinfo is invalid.
// printf("%lu vs %lu\n", off, rdata.page_groups[rdata.n_page_groups - 1].range.end());
for (Page_Info_Chunk *chunk = rdata.page_chunks; chunk; chunk = chunk->next) { for (Page_Info_Chunk *chunk = rdata.page_chunks; chunk; chunk = chunk->next) {
if (chunk->range.start <= off && off <= chunk->range.end()) { if (chunk->range.start <= off && off <= chunk->range.end()) {
printf("slow path for 0x%lX (last pinfo: 0x%lX - 0x%lX)\n", off, app->last_pinfo->range.start, app->last_pinfo->range.end());
for (u64 group_idx = chunk->first_group; group_idx < rdata.n_page_groups; ++group_idx) { for (u64 group_idx = chunk->first_group; group_idx < rdata.n_page_groups; ++group_idx) {
const Page_Info_Group &group = rdata.page_groups[group_idx]; const Page_Info_Group &group = rdata.page_groups[group_idx];
if (off < group.range.start || off > group.range.end()) if (off < group.range.start || off > group.range.end())
@ -195,7 +202,15 @@ void update_and_render(Arena *arena, App_State &app, f32 delta_time_ms)
ImGui::ColorEdit3("_TKey Header", app.vsettings.col_key, flags); ImGui::ColorEdit3("_TKey Header", app.vsettings.col_key, flags);
ImGui::SameLine(); ImGui::SameLine();
if (ImGui::Button("TKey Header")) {} // TODO app.vsettings.base_display_addr = app.rndatarng_footer.start; if (ImGui::Button("TKey Header")) {} // TODO jump to next key
ImGui::ColorEdit3("_Page Start", app.vsettings.col_page_start, flags);
ImGui::SameLine();
if (ImGui::Button("Page Start")) {} // TODO: jump to next page
ImGui::ColorEdit3("_Page", app.vsettings.col_page, flags);
ImGui::SameLine();
if (ImGui::Button("Page")) {} // TODO: jump to next page
ImGui::Separator(); ImGui::Separator();
ImGui::Text("Num pages: %lu", app.rndata.n_pages); ImGui::Text("Num pages: %lu", app.rndata.n_pages);

View file

@ -72,13 +72,17 @@ void gather_metadata(Arena *arena, RMicroFileReader &reader, const RNTuple_File_
u64 n_pages = 0; u64 n_pages = 0;
u64 n_elems = 0; u64 n_elems = 0;
Page_Info_Node *pinfo_head = nullptr, *pinfo_tail = nullptr; Page_Info_Node *pinfo_head = nullptr, *pinfo_tail = nullptr;
Page_Info_Node *last_inserted_pinfo = nullptr;
fprintf(stderr, "Loading pages...\n"); fprintf(stderr, "Loading pages...\n");
chr::time_point start_t = chr::high_resolution_clock::now();
// for all clusters, gather page metadata // for all clusters, gather page metadata
for (const RClusterDescriptor &cluster_desc : descriptor.GetClusterIterable()) { for (const RClusterDescriptor &cluster_desc : descriptor.GetClusterIterable()) {
for (const RClusterDescriptor::RColumnRange &col_range : cluster_desc.GetColumnRangeIterable()) { for (const RClusterDescriptor::RColumnRange &col_range : cluster_desc.GetColumnRangeIterable()) {
// insert page infos sorted by byte range // insert page infos sorted by byte range
// @Speed: this is slow! speed it up!
const auto &page_range = cluster_desc.GetPageRange(col_range.fPhysicalColumnId); const auto &page_range = cluster_desc.GetPageRange(col_range.fPhysicalColumnId);
for (const auto &page_info : page_range.fPageInfos) { for (const auto &page_info : page_range.fPageInfos) {
Page_Info_Node *pinfo = arena_push<Page_Info_Node>(arena); Page_Info_Node *pinfo = arena_push<Page_Info_Node>(arena);
@ -98,20 +102,30 @@ void gather_metadata(Arena *arena, RMicroFileReader &reader, const RNTuple_File_
// before head // before head
pinfo->next = pinfo_head; pinfo->next = pinfo_head;
pinfo_head = pinfo; pinfo_head = pinfo;
} else if (last_inserted_pinfo && pinfo->range.start == last_inserted_pinfo->range.end()) {
// common case: insert after previous
pinfo->next = last_inserted_pinfo->next;
last_inserted_pinfo->next = pinfo;
} else for (Page_Info_Node *node = pinfo_head->next, *prev = pinfo_head; node; prev = node, node = node->next) { } else for (Page_Info_Node *node = pinfo_head->next, *prev = pinfo_head; node; prev = node, node = node->next) {
if (pinfo->range.end() < node->range.start) { if (pinfo->range.end() <= node->range.start) {
prev->next = pinfo; prev->next = pinfo;
pinfo->next = node; pinfo->next = node;
break;
} }
} }
last_inserted_pinfo = pinfo;
++n_pages; ++n_pages;
n_elems += page_info.fNElements; n_elems += page_info.fNElements;
} }
} }
} }
fprintf(stderr, "Loaded %lu pages.\nGenerating groups...", n_pages); chr::time_point end_t = chr::high_resolution_clock::now();
u64 time_spent_ms = chr::duration_cast<chr::milliseconds>(end_t - start_t).count();
fprintf(stderr, "Loaded %lu pages in %lu ms.\nGenerating groups...\n", n_pages, time_spent_ms);
// Create page groups and chunks. // Create page groups and chunks.
// Each page group is a grouping of GROUP_SIZE page infos whose range is equal to the combined ranges // Each page group is a grouping of GROUP_SIZE page infos whose range is equal to the combined ranges
@ -121,13 +135,16 @@ void gather_metadata(Arena *arena, RMicroFileReader &reader, const RNTuple_File_
// of a page or not. // of a page or not.
const u64 GROUP_SIZE = 100; const u64 GROUP_SIZE = 100;
Page_Info_Group *groups = arena_push_array_nozero<Page_Info_Group>(arena, n_pages / GROUP_SIZE + 1); Page_Info_Group *groups = arena_push_array_nozero<Page_Info_Group>(arena, n_pages / GROUP_SIZE + 1);
Page_Info_Node *last = nullptr; static const Page_Info_Node invalid_last = { nullptr, { 0, 0 }, 0 };
const Page_Info_Node *last = &invalid_last;
Page_Info_Chunk *chunks_head = nullptr, *chunks_tail = nullptr; Page_Info_Chunk *chunks_head = nullptr, *chunks_tail = nullptr;
u64 idx = 0; u64 idx = 0;
u64 n_groups = 0; u64 n_groups = 0;
u64 n_chunks = 0; u64 n_chunks = 0;
for (Page_Info_Node *pinfo = pinfo_head; pinfo; pinfo = pinfo->next) { for (Page_Info_Node *pinfo = pinfo_head; pinfo; pinfo = pinfo->next) {
assert(last->range.end() <= pinfo->range.start);
last = pinfo; last = pinfo;
if (idx++ % GROUP_SIZE != 0) if (idx++ % GROUP_SIZE != 0)
continue; continue;
@ -136,7 +153,7 @@ void gather_metadata(Arena *arena, RMicroFileReader &reader, const RNTuple_File_
Page_Info_Group &cur_group = groups[n_groups]; Page_Info_Group &cur_group = groups[n_groups];
cur_group.first = pinfo; cur_group.first = pinfo;
cur_group.range.start = pinfo->range.start; cur_group.range.start = pinfo->range.start;
if (n_groups > 1) { if (n_groups > 0) {
Page_Info_Group &prev_group = groups[n_groups - 1]; Page_Info_Group &prev_group = groups[n_groups - 1];
prev_group.range.len = cur_group.range.start - prev_group.range.start; prev_group.range.len = cur_group.range.start - prev_group.range.start;
} }
@ -160,17 +177,22 @@ void gather_metadata(Arena *arena, RMicroFileReader &reader, const RNTuple_File_
chunks_tail->next = chunk; chunks_tail->next = chunk;
chunks_tail = chunk; chunks_tail = chunk;
++n_chunks; ++n_chunks;
} else {
chunks_tail->range.len += cur_group.range.len;
} }
++n_groups; ++n_groups;
} }
if (last)
groups[n_groups - 1].range.len = last->range.end() - groups[n_groups - 1].range.start; if (n_groups) {
Page_Info_Group &last_group = groups[n_groups - 1];
last_group.range.len = last->range.end() - last_group.range.start;
chunks_tail->range.len = last->range.end() - chunks_tail->range.start;
}
fprintf(stderr, "Generated %lu groups and %lu chunks.\n", n_groups, n_chunks); fprintf(stderr, "Generated %lu groups and %lu chunks.\n", n_groups, n_chunks);
assert(!chunks_tail->next);
assert(!pinfo_tail->next);
rndata.pages = pinfo_head; rndata.pages = pinfo_head;
rndata.page_groups = groups; rndata.page_groups = groups;
rndata.n_page_groups = n_groups; rndata.n_page_groups = n_groups;