properly set first_group in chunks

This commit is contained in:
silverweed 2024-07-15 11:54:45 +02:00
parent 1f64198640
commit 647c8c20f6
5 changed files with 50 additions and 38 deletions

View file

@ -39,4 +39,4 @@ noasan: $(ROOT_IFACE_DBG) build/imgui.o
$(MOLD) $(CXX) -DDEBUG -g -O0 $(CFLAGS) -fsanitize=undefined $(INC) $(ROOTFLAGS) -o rntviewer src/rntviewer.cpp build/imgui.o $(ROOT_IFACE_DBG) $(LIBS) $(ROOTLIBS)
r: $(ROOT_IFACE) build/imgui.o
$(MOLD) $(CXX) -O2 $(CFLAGS) $(INC) $(ROOTFLAGS) -o rntviewer src/rntviewer.cpp build/imgui.o $(ROOT_IFACE) $(LIBS) $(ROOTLIBS)
$(MOLD) $(CXX) -O2 -DNDEBUG $(CFLAGS) $(INC) $(ROOTFLAGS) -o rntviewer src/rntviewer.cpp build/imgui.o $(ROOT_IFACE) $(LIBS) $(ROOTLIBS)

View file

@ -61,6 +61,7 @@ u32 mem_edit_bg_color_fn(const u8 *, u64 off, void *user_data)
// 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) {
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) {
const Page_Info_Group &group = rdata.page_groups[group_idx];
if (off < group.range.start || off > group.range.end())
@ -74,6 +75,10 @@ u32 mem_edit_bg_color_fn(const u8 *, u64 off, void *user_data)
}
}
}
fprintf(stderr, "Offset 0x%lX is in chunk 0x%lX - 0x%lX, but found in no page_info range!\n",
off, chunk->range.start, chunk->range.end());
assert(false);
}
}
#undef COL
@ -166,6 +171,7 @@ void update_and_render(Arena *arena, App_State &app, f32 delta_time_ms)
assert(app.vsettings.base_display_addr < app.inspected_file_size);
void *content = app.inspected_fmem + app.vsettings.base_display_addr;
u64 content_size = app.inspected_file_size - app.vsettings.base_display_addr;
app.last_pinfo = &invalid_pinfo;
mem_edit.DrawContents(content, content_size, app.vsettings.base_display_addr);
ImGui::TableNextColumn();

View file

@ -77,9 +77,9 @@ void gather_metadata(Arena *arena, RMicroFileReader &reader, const RNTuple_File_
// for all clusters, gather page metadata
for (const RClusterDescriptor &cluster_desc : descriptor.GetClusterIterable()) {
for (const auto &[col_id, col_range] : cluster_desc.GetColumnRangeIterable()) {
for (const RClusterDescriptor::RColumnRange &col_range : cluster_desc.GetColumnRangeIterable()) {
// insert page infos sorted by byte range
const auto &page_range = cluster_desc.GetPageRange(col_id);
const auto &page_range = cluster_desc.GetPageRange(col_range.fPhysicalColumnId);
for (const auto &page_info : page_range.fPageInfos) {
Page_Info_Node *pinfo = arena_push<Page_Info_Node>(arena);
pinfo->range.start = page_info.fLocator.GetPosition<u64>();
@ -113,10 +113,12 @@ void gather_metadata(Arena *arena, RMicroFileReader &reader, const RNTuple_File_
fprintf(stderr, "Loaded %lu pages.\nGenerating groups...", n_pages);
// Create page groups.
// Create page groups and chunks.
// Each page group is a grouping of GROUP_SIZE page infos whose range is equal to the combined ranges
// of its components. It is an acceleration structure used to more quickly find the correct page info
// that an offset belongs to.
// A page chunk is a grouping of adjacent page groups, used to quickly determine if an offset is part
// of a page or not.
const u64 GROUP_SIZE = 100;
Page_Info_Group *groups = arena_push_array_nozero<Page_Info_Group>(arena, n_pages / GROUP_SIZE + 1);
Page_Info_Node *last = nullptr;
@ -125,39 +127,44 @@ void gather_metadata(Arena *arena, RMicroFileReader &reader, const RNTuple_File_
u64 n_groups = 0;
u64 n_chunks = 0;
for (Page_Info_Node *pinfo = pinfo_head; pinfo; pinfo = pinfo->next) {
if (idx++ % GROUP_SIZE == 0) {
Page_Info_Group &cur_group = groups[n_groups];
cur_group.first = pinfo;
cur_group.range.start = pinfo->range.start;
if (n_groups > 1) {
Page_Info_Group &prev_group = groups[n_groups - 1];
prev_group.range.len = cur_group.range.start - prev_group.range.start;
}
assert((!chunks_head) ^ (n_groups > 0));
if (!chunks_head) {
assert(!chunks_tail);
chunks_head = chunks_tail = arena_push<Page_Info_Chunk>(arena);
chunks_head->range.start = cur_group.range.start;
++n_chunks;
} else if (groups[n_groups - 1].range.end() != cur_group.range.start) {
// close current chunk
Page_Info_Group &prev_group = groups[n_groups - 1];
chunks_tail->range.len = (prev_group.range.end() - chunks_tail->range.start);
// open new chunk
Page_Info_Chunk *chunk = arena_push<Page_Info_Chunk>(arena);
chunk->range.start = cur_group.range.start;
chunks_tail->next = chunk;
chunks_tail = chunk;
++n_chunks;
} else {
chunks_tail->range.len += cur_group.range.len;
}
++n_groups;
}
last = pinfo;
if (idx++ % GROUP_SIZE != 0)
continue;
// Create a new group every GROUP_SIZE page infos
Page_Info_Group &cur_group = groups[n_groups];
cur_group.first = pinfo;
cur_group.range.start = pinfo->range.start;
if (n_groups > 1) {
Page_Info_Group &prev_group = groups[n_groups - 1];
prev_group.range.len = cur_group.range.start - prev_group.range.start;
}
assert((!chunks_head) == (n_groups == 0));
if (!chunks_head) {
assert(!chunks_tail);
chunks_head = chunks_tail = arena_push<Page_Info_Chunk>(arena);
chunks_head->range.start = cur_group.range.start;
chunks_head->first_group = n_groups;
++n_chunks;
} else if (groups[n_groups - 1].range.end() != cur_group.range.start) {
// close current chunk
Page_Info_Group &prev_group = groups[n_groups - 1];
chunks_tail->range.len = (prev_group.range.end() - chunks_tail->range.start);
// open new chunk
Page_Info_Chunk *chunk = arena_push<Page_Info_Chunk>(arena);
chunk->range.start = cur_group.range.start;
chunk->first_group = n_groups;
chunks_tail->next = chunk;
chunks_tail = chunk;
++n_chunks;
} else {
chunks_tail->range.len += cur_group.range.len;
}
++n_groups;
}
if (last)
groups[n_groups - 1].range.len = last->range.end() - groups[n_groups - 1].range.start;

View file

@ -12,7 +12,7 @@ struct Page_Info_Node {
u64 n_elems;
};
inline const Page_Info_Node invalid_pinfo = { nullptr, 0, 0 };
static const Page_Info_Node invalid_pinfo {};
struct Page_Info_Group {
Byte_Range range;

View file

@ -121,7 +121,6 @@ int main(int argc, char **argv)
app.ntpl_name = ntpl_name;
app.rndata = get_rntuple_data(arena, fname, ntpl_name);
app.vsettings = make_viewer_settings();
app.last_pinfo = &invalid_pinfo;
// Start main loop
run_main_loop(window, arena, app);