VpkLib: strong optimizations for directory tree builder

- Only lookup the map key once, and construct its name with already known size.
- Store pointers to entry blocks rather than copying it, since by the time we build the tree, the entry block vector is guaranteed to not change. It is also qualified as const.
This commit is contained in:
Kawe Mazidjatari 2025-02-09 02:33:37 +01:00
parent 85d99364cb
commit def96b25a7
2 changed files with 11 additions and 25 deletions

View File

@ -1095,25 +1095,11 @@ void VPKDir_t::CTreeBuilder::BuildTree(const CUtlVector<VPKEntryBlock_t>& entryB
* - A file path is only written once per extension tree. * - A file path is only written once per extension tree.
* - A file name is only written once per file path tree. * - A file name is only written once per file path tree.
**********************************************************************/ **********************************************************************/
const char* pFileExt = fileExt.Get(); const auto& extIt = m_FileTree.try_emplace({ fileExt.String(), (size_t)fileExt.Length() }, PathContainer_t()).first;
auto extIt = m_FileTree.find(pFileExt);
if (extIt == m_FileTree.end())
{
extIt = m_FileTree.insert({ pFileExt, PathContainer_t() }).first;
}
PathContainer_t& pathTree = extIt->second; PathContainer_t& pathTree = extIt->second;
const char* pFilePath = filePath.Get(); const auto& pathIt = pathTree.try_emplace({ filePath.String(), (size_t)filePath.Length() }, std::list<const VPKEntryBlock_t*>()).first;
auto pathIt = pathTree.find(pFilePath); pathIt->second.emplace_back(&entryBlock);
if (pathIt == pathTree.end())
{
pathIt = pathTree.insert({ pFilePath, std::list<VPKEntryBlock_t>() }).first;
}
pathIt->second.push_back(entryBlock);
} }
} }
@ -1134,17 +1120,17 @@ int VPKDir_t::CTreeBuilder::WriteTree(FileHandle_t hDirectoryFile) const
FileSystem()->Write(jKeyValue.first.c_str(), jKeyValue.first.length() + 1, hDirectoryFile); FileSystem()->Write(jKeyValue.first.c_str(), jKeyValue.first.length() + 1, hDirectoryFile);
for (auto& vEntry : jKeyValue.second) for (auto& vEntry : jKeyValue.second)
{ {
const CUtlString entryPath = vEntry.m_EntryPath.UnqualifiedFilename().StripExtension(); const CUtlString entryPath = vEntry->m_EntryPath.UnqualifiedFilename().StripExtension();
FileSystem()->Write(entryPath.Get(), entryPath.Length() + 1, hDirectoryFile); FileSystem()->Write(entryPath.Get(), entryPath.Length() + 1, hDirectoryFile);
FileSystem()->Write(&vEntry.m_nFileCRC, sizeof(uint32_t), hDirectoryFile); FileSystem()->Write(&vEntry->m_nFileCRC, sizeof(uint32_t), hDirectoryFile);
FileSystem()->Write(&vEntry.m_iPreloadSize, sizeof(uint16_t), hDirectoryFile); FileSystem()->Write(&vEntry->m_iPreloadSize, sizeof(uint16_t), hDirectoryFile);
FileSystem()->Write(&vEntry.m_iPackFileIndex, sizeof(uint16_t), hDirectoryFile); FileSystem()->Write(&vEntry->m_iPackFileIndex, sizeof(uint16_t), hDirectoryFile);
FOR_EACH_VEC(vEntry.m_Fragments, i) FOR_EACH_VEC(vEntry->m_Fragments, i)
{ {
/*Write chunk descriptor*/ /*Write chunk descriptor*/
const VPKChunkDescriptor_t& descriptor = vEntry.m_Fragments[i]; const VPKChunkDescriptor_t& descriptor = vEntry->m_Fragments[i];
FileSystem()->Write(&descriptor.m_nLoadFlags, sizeof(uint32_t), hDirectoryFile); FileSystem()->Write(&descriptor.m_nLoadFlags, sizeof(uint32_t), hDirectoryFile);
FileSystem()->Write(&descriptor.m_nTextureFlags, sizeof(uint16_t), hDirectoryFile); FileSystem()->Write(&descriptor.m_nTextureFlags, sizeof(uint16_t), hDirectoryFile);
@ -1152,7 +1138,7 @@ int VPKDir_t::CTreeBuilder::WriteTree(FileHandle_t hDirectoryFile) const
FileSystem()->Write(&descriptor.m_nCompressedSize, sizeof(uint64_t), hDirectoryFile); FileSystem()->Write(&descriptor.m_nCompressedSize, sizeof(uint64_t), hDirectoryFile);
FileSystem()->Write(&descriptor.m_nUncompressedSize, sizeof(uint64_t), hDirectoryFile); FileSystem()->Write(&descriptor.m_nUncompressedSize, sizeof(uint64_t), hDirectoryFile);
if (i != (vEntry.m_Fragments.Count() - 1)) if (i != (vEntry->m_Fragments.Count() - 1))
{ {
FileSystem()->Write(&PACKFILEINDEX_SEP, sizeof(uint16_t), hDirectoryFile); FileSystem()->Write(&PACKFILEINDEX_SEP, sizeof(uint16_t), hDirectoryFile);
} }

View File

@ -158,7 +158,7 @@ struct VPKDir_t
class CTreeBuilder class CTreeBuilder
{ {
public: public:
typedef std::map<std::string, std::list<VPKEntryBlock_t>> PathContainer_t; typedef std::map<std::string, std::list<const VPKEntryBlock_t*>> PathContainer_t;
typedef std::map<std::string, PathContainer_t> TypeContainer_t; typedef std::map<std::string, PathContainer_t> TypeContainer_t;
void BuildTree(const CUtlVector<VPKEntryBlock_t>& entryBlocks); void BuildTree(const CUtlVector<VPKEntryBlock_t>& entryBlocks);