Filesystem: Add a cache for finding file info by disc offset

FileMonitor calls this every time a read happens, and there's no code that
only calls this a small number of times, so having a cache is worthwhile.
This commit is contained in:
JosJuice 2015-08-09 13:41:41 +02:00
parent 87916fe099
commit ee27be06d7
2 changed files with 21 additions and 17 deletions

View File

@ -6,6 +6,7 @@
#include <cinttypes> #include <cinttypes>
#include <cstddef> #include <cstddef>
#include <cstring> #include <cstring>
#include <map>
#include <memory> #include <memory>
#include <optional> #include <optional>
#include <string> #include <string>
@ -277,26 +278,27 @@ std::unique_ptr<FileInfo> FileSystemGCWii::FindFileInfo(u64 disc_offset) const
if (!IsValid()) if (!IsValid())
return nullptr; return nullptr;
return FindFileInfo(disc_offset, m_root); // Build a cache (unless there already is one)
if (m_offset_file_info_cache.empty())
{
u32 fst_entries = m_root.GetSize();
for (u32 i = 0; i < fst_entries; i++)
{
FileInfoGCWii file_info(m_root, i);
if (!file_info.IsDirectory())
m_offset_file_info_cache.emplace(file_info.GetOffset() + file_info.GetSize(), i);
}
} }
std::unique_ptr<FileInfo> FileSystemGCWii::FindFileInfo(u64 disc_offset, // Get the first file that ends after disc_offset
const FileInfo& file_info) const const auto it = m_offset_file_info_cache.upper_bound(disc_offset);
{ if (it == m_offset_file_info_cache.end())
for (const FileInfo& child : file_info) return nullptr;
{ std::unique_ptr<FileInfo> result(std::make_unique<FileInfoGCWii>(m_root, it->second));
if (child.IsDirectory())
{ // If the file's start isn't after disc_offset, success
std::unique_ptr<FileInfo> result = FindFileInfo(disc_offset, child); if (result->GetOffset() <= disc_offset)
if (result)
return result; return result;
}
else if ((file_info.GetOffset() <= disc_offset) &&
((file_info.GetOffset() + file_info.GetSize()) > disc_offset))
{
return file_info.clone();
}
}
return nullptr; return nullptr;
} }

View File

@ -5,6 +5,7 @@
#pragma once #pragma once
#include <cstddef> #include <cstddef>
#include <map>
#include <memory> #include <memory>
#include <optional> #include <optional>
#include <string> #include <string>
@ -101,9 +102,10 @@ private:
u32 m_offset_shift; u32 m_offset_shift;
std::vector<u8> m_file_system_table; std::vector<u8> m_file_system_table;
FileInfoGCWii m_root; FileInfoGCWii m_root;
// Maps the end offset of files to FST indexes
mutable std::map<u64, u32> m_offset_file_info_cache;
std::unique_ptr<FileInfo> FindFileInfo(const std::string& path, const FileInfo& file_info) const; std::unique_ptr<FileInfo> FindFileInfo(const std::string& path, const FileInfo& file_info) const;
std::unique_ptr<FileInfo> FindFileInfo(u64 disc_offset, const FileInfo& file_info) const;
}; };
} // namespace } // namespace