From 295a68f43dd235ceab889e51e0168d095b8eb641 Mon Sep 17 00:00:00 2001 From: Sour Date: Sun, 20 Jan 2019 16:33:23 -0500 Subject: [PATCH] Core: Optimize rom search logic and set a maximum limit (100) to the number of files that are hashed before giving up --- Core/Console.cpp | 11 +++++++---- Core/FdsLoader.cpp | 2 -- Core/RomLoader.cpp | 21 +++++++++++++++++---- Core/RomLoader.h | 4 +++- Utilities/FolderUtilities.cpp | 19 +++++++++++++------ 5 files changed, 40 insertions(+), 17 deletions(-) diff --git a/Core/Console.cpp b/Core/Console.cpp index b73b8421..0956b59b 100644 --- a/Core/Console.cpp +++ b/Core/Console.cpp @@ -223,13 +223,16 @@ string Console::FindMatchingRom(string romName, HashInfo hashInfo) romFiles.insert(romFiles.end(), files.begin(), files.end()); } - string match = RomLoader::FindMatchingRom(romFiles, romName, hashInfo, true); - if(!match.empty()) { - return match; + if(!romName.empty()) { + //Perform quick search based on file name + string match = RomLoader::FindMatchingRom(romFiles, romName, hashInfo, true); + if(!match.empty()) { + return match; + } } //Perform slow CRC32 search for ROM - match = RomLoader::FindMatchingRom(romFiles, romName, hashInfo, false); + string match = RomLoader::FindMatchingRom(romFiles, romName, hashInfo, false); if(!match.empty()) { return match; } diff --git a/Core/FdsLoader.cpp b/Core/FdsLoader.cpp index ae2e8b38..a7525c0d 100644 --- a/Core/FdsLoader.cpp +++ b/Core/FdsLoader.cpp @@ -136,8 +136,6 @@ RomData FdsLoader::LoadRom(vector& romFile, string filename) { RomData romData; - romData.Info.Hash.Sha1 = SHA1::GetHash(romFile); - romData.Info.Hash.Crc32 = CRC32::GetCRC(romFile.data(), romFile.size()); romData.Info.Hash.PrgCrc32 = CRC32::GetCRC(romFile.data(), romFile.size()); romData.Info.Format = RomFormat::Fds; diff --git a/Core/RomLoader.cpp b/Core/RomLoader.cpp index 103dea45..83300d22 100644 --- a/Core/RomLoader.cpp +++ b/Core/RomLoader.cpp @@ -96,7 +96,7 @@ RomData RomLoader::GetRomData() return _romData; } -string RomLoader::FindMatchingRomInFile(string filePath, HashInfo hashInfo) +string RomLoader::FindMatchingRomInFile(string filePath, HashInfo hashInfo, int &iterationCount) { shared_ptr reader = ArchiveReader::GetReader(filePath); if(reader) { @@ -107,6 +107,11 @@ string RomLoader::FindMatchingRomInFile(string filePath, HashInfo hashInfo) if(hashInfo.Crc32 == loader._romData.Info.Hash.Crc32 || hashInfo.Sha1.compare(loader._romData.Info.Hash.Sha1) == 0) { return VirtualFile(filePath, file); } + + iterationCount++; + if(iterationCount > RomLoader::MaxFilesToCheck) { + break; + } } } } else { @@ -117,12 +122,14 @@ string RomLoader::FindMatchingRomInFile(string filePath, HashInfo hashInfo) return filePath; } } + iterationCount++; } return ""; } string RomLoader::FindMatchingRom(vector romFiles, string romFilename, HashInfo hashInfo, bool useFastSearch) { + int iterationCount = 0; if(useFastSearch) { string lcRomFile = romFilename; std::transform(lcRomFile.begin(), lcRomFile.end(), lcRomFile.begin(), ::tolower); @@ -131,8 +138,8 @@ string RomLoader::FindMatchingRom(vector romFiles, string romFilename, H //Quick search by filename string lcCurrentFile = currentFile; std::transform(lcCurrentFile.begin(), lcCurrentFile.end(), lcCurrentFile.begin(), ::tolower); - if(FolderUtilities::GetFilename(lcRomFile, false).compare(FolderUtilities::GetFilename(lcCurrentFile, false)) == 0) { - string match = RomLoader::FindMatchingRomInFile(currentFile, hashInfo); + if(lcCurrentFile.find(lcRomFile) != string::npos && FolderUtilities::GetFilename(lcRomFile, true) == FolderUtilities::GetFilename(lcCurrentFile, true)) { + string match = RomLoader::FindMatchingRomInFile(currentFile, hashInfo, iterationCount); if(!match.empty()) { return match; } @@ -141,10 +148,16 @@ string RomLoader::FindMatchingRom(vector romFiles, string romFilename, H } else { for(string romFile : romFiles) { //Slower search by CRC value - string match = RomLoader::FindMatchingRomInFile(romFile, hashInfo); + string match = RomLoader::FindMatchingRomInFile(romFile, hashInfo, iterationCount); if(!match.empty()) { return match; } + iterationCount++; + + if(iterationCount > RomLoader::MaxFilesToCheck) { + MessageManager::Log("[RomLoader] Could not find a file matching the specified name/hash after 100 tries, giving up..."); + break; + } } } diff --git a/Core/RomLoader.h b/Core/RomLoader.h index fb96c657..f3ca7f5e 100644 --- a/Core/RomLoader.h +++ b/Core/RomLoader.h @@ -8,10 +8,12 @@ class ArchiveReader; class RomLoader : public BaseLoader { private: + static constexpr int MaxFilesToCheck = 100; + RomData _romData; string _filename; - static string FindMatchingRomInFile(string filePath, HashInfo hashInfo); + static string FindMatchingRomInFile(string filePath, HashInfo hashInfo, int &iterationCount); public: using BaseLoader::BaseLoader; diff --git a/Utilities/FolderUtilities.cpp b/Utilities/FolderUtilities.cpp index d02f8ecf..45bc8d2d 100644 --- a/Utilities/FolderUtilities.cpp +++ b/Utilities/FolderUtilities.cpp @@ -160,13 +160,20 @@ vector FolderUtilities::GetFilesInFolder(string rootFolder, std::unorder } if(recursive) { - for(string subFolder : GetFolders(rootFolder)) { - folders.push_back(subFolder); + for(fs::recursive_directory_iterator i(fs::u8path(rootFolder)), end; i != end; i++) { + if(i.depth() > 1) { + //Prevent excessive recursion + i.disable_recursion_pending(); + } else { + string extension = i->path().extension().u8string(); + std::transform(extension.begin(), extension.end(), extension.begin(), ::tolower); + if(extensions.find(extension) != extensions.end()) { + files.push_back(i->path().u8string()); + } + } } - } - - for(string folder : folders) { - for(fs::directory_iterator i(fs::u8path(folder.c_str())), end; i != end; i++) { + } else { + for(fs::directory_iterator i(fs::u8path(rootFolder)), end; i != end; i++) { string extension = i->path().extension().u8string(); std::transform(extension.begin(), extension.end(), extension.begin(), ::tolower); if(extensions.find(extension) != extensions.end()) {