From b7c51821b0955a1d926d5cfc292bc77dae3374aa Mon Sep 17 00:00:00 2001 From: emoose Date: Sun, 19 Jan 2020 22:59:37 +0000 Subject: [PATCH] [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. --- src/xenia/vfs/devices/stfs_container_device.cc | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/xenia/vfs/devices/stfs_container_device.cc b/src/xenia/vfs/devices/stfs_container_device.cc index 1e90acc2a..357c110c2 100644 --- a/src/xenia/vfs/devices/stfs_container_device.cc +++ b/src/xenia/vfs/devices/stfs_container_device.cc @@ -543,7 +543,6 @@ StfsContainerDevice::Error StfsContainerDevice::ReadSTFS() { // Fill in all block records. // It's easier to do this now and just look them up later, at the cost // of some memory. Nasty chain walk. - // TODO(benvanik): optimize if flag 0x40 (consecutive) is set. if (entry->attributes() & X_FILE_ATTRIBUTE_NORMAL) { uint32_t block_index = start_block_index; size_t remaining_size = file_size; @@ -555,8 +554,18 @@ StfsContainerDevice::Error StfsContainerDevice::ReadSTFS() { size_t offset = STFSDataBlockToOffset(block_index); entry->block_list_.push_back({0, offset, block_size}); remaining_size -= block_size; - auto block_hash = STFSGetLevel0HashEntry(data, block_index); - block_index = block_hash.level0_next_block(); + + // 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); + block_index = block_hash.level0_next_block(); + } } }