[VFS] Skip reading from STFS hash table if file has contiguous flag.

If this flag is set there shouldn't be any need to read from the hash tables, we can just read from each subsequent block number.
We'll only trust this flag if the package is read-only (LIVE/PIRS) though, in CON packages we'll always read from hash tables.
This commit is contained in:
emoose 2020-01-19 22:59:37 +00:00
parent 17324c3081
commit 9f9a0d2bcc
1 changed files with 12 additions and 3 deletions

View File

@ -543,7 +543,6 @@ StfsContainerDevice::Error StfsContainerDevice::ReadSTFS() {
// Fill in all block records. // Fill in all block records.
// It's easier to do this now and just look them up later, at the cost // It's easier to do this now and just look them up later, at the cost
// of some memory. Nasty chain walk. // of some memory. Nasty chain walk.
// TODO(benvanik): optimize if flag 0x40 (consecutive) is set.
if (entry->attributes() & X_FILE_ATTRIBUTE_NORMAL) { if (entry->attributes() & X_FILE_ATTRIBUTE_NORMAL) {
uint32_t block_index = start_block_index; uint32_t block_index = start_block_index;
size_t remaining_size = file_size; size_t remaining_size = file_size;
@ -555,10 +554,20 @@ StfsContainerDevice::Error StfsContainerDevice::ReadSTFS() {
size_t offset = STFSDataBlockToOffset(block_index); size_t offset = STFSDataBlockToOffset(block_index);
entry->block_list_.push_back({0, offset, block_size}); entry->block_list_.push_back({0, offset, block_size});
remaining_size -= block_size; remaining_size -= block_size;
// If file entry has contiguous flag (0x40) set, skip reading next
// block from hash table and just use block_index + 1 (but we'll only
// do this if it's a read-only package, just in case the flag is in
// error)
if ((filename_length_flags & 0x40) &&
header_.metadata.stfs_volume_descriptor.flags.read_only_format) {
block_index++;
} else {
auto block_hash = STFSGetLevel0HashEntry(data, block_index); auto block_hash = STFSGetLevel0HashEntry(data, block_index);
block_index = block_hash.level0_next_block(); block_index = block_hash.level0_next_block();
} }
} }
}
parent_entry->children_.emplace_back(std::move(entry)); parent_entry->children_.emplace_back(std::move(entry));
} }