From b37aae728f496c6419a1defa0bcbdc74eaea531b Mon Sep 17 00:00:00 2001 From: "Pierre-Loup A. Griffais" Date: Wed, 23 Sep 2026 20:40:55 -0700 Subject: [PATCH] DiskCache: adjust key strategy The base directory is now the machine bucket, which is everything that affects codegen that you can ask FEX about offline: FEX compiler version, host features. The DB files now carry a process bucket, which is everything else that can affect codegen, on the user/process side: 32-bitness and config. Both together are still the bucket hash that gets laced into every lookup key, so we still won't load mismatching code because a file is in the wrong spot. --- FEXCore/Source/Interface/Core/DiskCache.cpp | 22 ++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/FEXCore/Source/Interface/Core/DiskCache.cpp b/FEXCore/Source/Interface/Core/DiskCache.cpp index d035a3554..8f714800e 100644 --- a/FEXCore/Source/Interface/Core/DiskCache.cpp +++ b/FEXCore/Source/Interface/Core/DiskCache.cpp @@ -367,28 +367,32 @@ namespace DiskCache { struct __attribute__((packed)) { uint16_t FormatVersion; - uint8_t Is64BitMode; uint64_t HostFeaturesHash; - } BucketHeader = {FormatVersion, CTX->Config.Is64BitMode, CTX->HostFeatures.HashForCaching()}; + } MachineBucketData = {FormatVersion, CTX->HostFeatures.HashForCaching()}; - fextl::vector BucketBytes; - BucketBytes.resize(sizeof(BucketHeader) + SerializedConfig.size()); - memcpy(BucketBytes.data(), &BucketHeader, sizeof(BucketHeader)); - memcpy(BucketBytes.data() + sizeof(BucketHeader), SerializedConfig.data(), SerializedConfig.size()); - BucketHash = XXH3_128bits(BucketBytes.data(), BucketBytes.size()); + fextl::vector BucketBytes(sizeof(MachineBucketData) + sizeof(uint8_t) + SerializedConfig.size()); + memcpy(BucketBytes.data(), &MachineBucketData, sizeof(MachineBucketData)); + BucketBytes[sizeof(MachineBucketData)] = CTX->Config.Is64BitMode; + memcpy(BucketBytes.data() + sizeof(MachineBucketData) + 1, SerializedConfig.data(), SerializedConfig.size()); + + uint64_t MachineBucketHash = XXH3_64bits(BucketBytes.data(), sizeof(MachineBucketData)); + uint64_t ProcessBucketHash = XXH3_64bits(BucketBytes.data() + sizeof(MachineBucketData), 1 + SerializedConfig.size()); + BucketHash.high64 = MachineBucketHash; + BucketHash.low64 = ProcessBucketHash; fextl::string BasePath = BasePathOverride(); if (BasePath.empty()) { BasePath = FEXCore::Config::GetCacheDirectory() + "DiskCache/"; - BasePath += fextl::fmt::format("{:016x}{:016x}", BucketHash.high64, BucketHash.low64) + "/"; } + BasePath += fextl::fmt::format("{:016x}", MachineBucketHash) + "/"; FHU::Filesystem::CreateDirectories(BasePath); + // todo could kick off clean up of leftover MachineBucketHash sibling directories here if (!MapDiskCacheFiles) { FileMapper = nullptr; } - fextl::string RWDBBasePath = BasePath + "RWCacheDB"; + const auto RWDBBasePath = fextl::fmt::format("{}RWCacheDB_{:016x}", BasePath, ProcessBucketHash); OpenCacheDB(RWDBBasePath, false); if (RWCacheDB && !FoundMetadata) {