avoid reading the free list to add the free slots

This commit is contained in:
silverweed 2025-02-11 13:31:06 +01:00
parent f68aae33cf
commit 7cbc199f34

View file

@ -45,20 +45,6 @@ struct RNTuple_Anchor_On_Disk {
u64 max_key_size_be;
};
struct TFile_Free_Slot {
u16 version;
union Ranges {
struct Short {
u32 start;
u32 end;
} rng_short;
struct Long {
u64 start;
u64 end;
} rng_long;
} rng;
};
#pragma pack(pop)
template <typename T>
@ -77,8 +63,9 @@ enum {
WTK_PRINT_DECIMAL = 4,
};
// Examines the innards of a TFile to get byte range info about the TKeys.
// Additionally, it returns the names of all the RNTuples stored in it.
// Examines the innards of a TFile to get info about the TKeys (byte ranges, class names, etc).
// This data is written inside `tfile_data`. In particular, `tfile_data.sections` will contain the exhaustive
// list of information about every file section, divided per section type.
// `data` should point to the beginning of a ROOT file.
// If `ntpl_name` is non-empty, skip all RNTuples that are not the one specified.
internal
@ -229,6 +216,11 @@ b8 walk_tkeys(Arena *arena, const u8 *data, u64 data_len, u32 flags, TFile_Data
else
printf("Free Slot at 0x%" PRIX64 ", len: %d (%s)\n", cur, n_bytes, to_pretty_size(scratch.arena, n_bytes).c());
}
Section *sec_free_slot = push_section(arena, tfile_data, Sec_Free_Slot);
sec_free_slot->range.start = cur;
sec_free_slot->range.len = n_bytes;
// don't try to read the rest of the data
cur += n_bytes;
continue;
@ -387,36 +379,6 @@ b8 walk_tkeys(Arena *arena, const u8 *data, u64 data_len, u32 flags, TFile_Data
sec_header.range.len += sec_header.post_size;
}
// collect free slots
TFile_Free_Slot fs;
u64 free_slot_size = sizeof(u16) + (is_big_file ? sizeof(fs.rng.rng_long) : sizeof(fs.rng.rng_short));
Section *sec_tfile_freelist = sections[Sec_TFile_FreeList].head;
u64 free_slots_start = sec_tfile_freelist->range.start;
u64 free_slots_end = sec_tfile_freelist->range.end();
u64 n_free_slots = (free_slots_end - free_slots_start) / free_slot_size;
for (u64 i = 0; i < n_free_slots; ++i) {
u64 cur = free_slots_start + i * free_slot_size;
memcpy(&fs, data + cur, free_slot_size);
u64 start, end;
if (is_big_file) {
start = bswap(fs.rng.rng_long.start);
end = min(data_len, bswap(fs.rng.rng_long.end));
} else {
start = bswap(fs.rng.rng_short.start);
end = min(data_len, bswap(fs.rng.rng_short.end));
}
// The free slot might not be a "real" slot (if its end is lower than its start or if it starts past the end of
// the file): in this case, don't add it to the list.
if (end >= start && start < data_len) {
Section *sec_free_slot = push_section(arena, tfile_data, Sec_Free_Slot);
sec_free_slot->range.start = start;
sec_free_slot->range.len = end - start + 1; // +1 because `end` is inclusive
if (flags & WTK_PRINT_KEYS_INFO)
printf("Free slot in FreeList @0x%lX: 0x%lX - 0x%lX\n", cur, start, end);
}
}
return true;
}