summaryrefslogtreecommitdiff
path: root/Source/Core/DiscIO/FileSystemGCWii.cpp
diff options
context:
space:
mode:
authorJosJuice <josjuice@gmail.com>2015-08-09 13:41:41 +0200
committerJosJuice <josjuice@gmail.com>2017-06-14 15:25:02 +0200
commitee27be06d79a88f4e4344966002211a47a9eafeb (patch)
tree6e94c9012485b03a9a32b8abd9543144b86d4ace /Source/Core/DiscIO/FileSystemGCWii.cpp
parent87916fe09979eea276438deef83ba85fcace91e0 (diff)
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.
Diffstat (limited to 'Source/Core/DiscIO/FileSystemGCWii.cpp')
-rw-r--r--Source/Core/DiscIO/FileSystemGCWii.cpp34
1 files changed, 18 insertions, 16 deletions
diff --git a/Source/Core/DiscIO/FileSystemGCWii.cpp b/Source/Core/DiscIO/FileSystemGCWii.cpp
index 54b7f6a0e2..8546e4d4d1 100644
--- a/Source/Core/DiscIO/FileSystemGCWii.cpp
+++ b/Source/Core/DiscIO/FileSystemGCWii.cpp
@@ -6,6 +6,7 @@
#include <cinttypes>
#include <cstddef>
#include <cstring>
+#include <map>
#include <memory>
#include <optional>
#include <string>
@@ -277,27 +278,28 @@ std::unique_ptr<FileInfo> FileSystemGCWii::FindFileInfo(u64 disc_offset) const
if (!IsValid())
return nullptr;
- return FindFileInfo(disc_offset, m_root);
-}
-
-std::unique_ptr<FileInfo> FileSystemGCWii::FindFileInfo(u64 disc_offset,
- const FileInfo& file_info) const
-{
- for (const FileInfo& child : file_info)
+ // Build a cache (unless there already is one)
+ if (m_offset_file_info_cache.empty())
{
- if (child.IsDirectory())
- {
- std::unique_ptr<FileInfo> result = FindFileInfo(disc_offset, child);
- if (result)
- return result;
- }
- else if ((file_info.GetOffset() <= disc_offset) &&
- ((file_info.GetOffset() + file_info.GetSize()) > disc_offset))
+ u32 fst_entries = m_root.GetSize();
+ for (u32 i = 0; i < fst_entries; i++)
{
- return file_info.clone();
+ FileInfoGCWii file_info(m_root, i);
+ if (!file_info.IsDirectory())
+ m_offset_file_info_cache.emplace(file_info.GetOffset() + file_info.GetSize(), i);
}
}
+ // Get the first file that ends after disc_offset
+ const auto it = m_offset_file_info_cache.upper_bound(disc_offset);
+ if (it == m_offset_file_info_cache.end())
+ return nullptr;
+ std::unique_ptr<FileInfo> result(std::make_unique<FileInfoGCWii>(m_root, it->second));
+
+ // If the file's start isn't after disc_offset, success
+ if (result->GetOffset() <= disc_offset)
+ return result;
+
return nullptr;
}