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:
parent
87916fe099
commit
ee27be06d7
|
@ -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,27 +278,28 @@ 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())
|
||||||
|
|
||||||
std::unique_ptr<FileInfo> FileSystemGCWii::FindFileInfo(u64 disc_offset,
|
|
||||||
const FileInfo& file_info) const
|
|
||||||
{
|
|
||||||
for (const FileInfo& child : file_info)
|
|
||||||
{
|
{
|
||||||
if (child.IsDirectory())
|
u32 fst_entries = m_root.GetSize();
|
||||||
|
for (u32 i = 0; i < fst_entries; i++)
|
||||||
{
|
{
|
||||||
std::unique_ptr<FileInfo> result = FindFileInfo(disc_offset, child);
|
FileInfoGCWii file_info(m_root, i);
|
||||||
if (result)
|
if (!file_info.IsDirectory())
|
||||||
return result;
|
m_offset_file_info_cache.emplace(file_info.GetOffset() + file_info.GetSize(), i);
|
||||||
}
|
|
||||||
else if ((file_info.GetOffset() <= disc_offset) &&
|
|
||||||
((file_info.GetOffset() + file_info.GetSize()) > disc_offset))
|
|
||||||
{
|
|
||||||
return file_info.clone();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue