Skip to content

Commit

Permalink
Filesystem: Add a cache for finding file info by disc offset
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
JosJuice committed Aug 9, 2015
1 parent 2866031 commit b8fb589
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 17 deletions.
38 changes: 22 additions & 16 deletions Source/Core/DiscIO/FileSystemGCWii.cpp
Expand Up @@ -6,6 +6,7 @@
#include <cinttypes>
#include <cstddef>
#include <cstring>
#include <map>
#include <memory>
#include <string>
#include <vector>
Expand Down Expand Up @@ -271,27 +272,32 @@ std::unique_ptr<IFileInfo> CFileSystemGCWii::FindFileInfo(u64 disc_offset) const
if (!IsValid())
return nullptr;

return FindFileInfo(disc_offset, m_root);
if (m_offset_file_info_cache.empty())
BuildOffsetFileInfoCache(m_root);

// Get the first file that ends after disc_offset
auto it = m_offset_file_info_cache.upper_bound(disc_offset);
if (it == m_offset_file_info_cache.end())
return nullptr;
std::unique_ptr<IFileInfo> result(new CFileInfoGCWii(m_root, it->second));

// If the file's start isn't after disc_offset, success
if (result->GetOffset() <= disc_offset)
return result;

return nullptr;
}

std::unique_ptr<IFileInfo> CFileSystemGCWii::FindFileInfo(u64 disc_offset, const IFileInfo& file_info) const
void CFileSystemGCWii::BuildOffsetFileInfoCache(const IFileInfo& directory) const
{
for (const IFileInfo& child : file_info)
for (const IFileInfo& file_info : directory)
{
if (child.IsDirectory())
{
std::unique_ptr<IFileInfo> result = FindFileInfo(disc_offset, child);
if (result)
return result;
}
else if ((file_info.GetOffset() <= disc_offset) &&
((file_info.GetOffset() + file_info.GetSize()) > disc_offset))
{
return std::unique_ptr<IFileInfo>(new CFileInfoGCWii((const CFileInfoGCWii&)file_info));
}
if (file_info.IsDirectory())
BuildOffsetFileInfoCache(file_info);
else
m_offset_file_info_cache.emplace(file_info.GetOffset() + file_info.GetSize(),
reinterpret_cast<const CFileInfoGCWii&>(file_info).m_index);
}

return nullptr;
}

u64 CFileSystemGCWii::ReadFile(const IFileInfo* file_info, u8* _pBuffer, u64 _MaxBufferSize, u64 _OffsetInFile) const
Expand Down
7 changes: 6 additions & 1 deletion Source/Core/DiscIO/FileSystemGCWii.h
Expand Up @@ -5,6 +5,7 @@
#pragma once

#include <cstddef>
#include <map>
#include <string>
#include <vector>

Expand All @@ -18,6 +19,8 @@ class IVolume;

class CFileInfoGCWii : public IFileInfo
{
friend class CFileSystemGCWii;

public:
// None of the constructors take ownership of FST pointers

Expand Down Expand Up @@ -86,9 +89,11 @@ class CFileSystemGCWii : public IFileSystem
bool m_Wii;
std::vector<u8> m_file_system_table;
CFileInfoGCWii m_root;
// Maps the end offset of files to FST indexes
mutable std::map<u64, u32> m_offset_file_info_cache;

std::unique_ptr<IFileInfo> FindFileInfo(const std::string& path, const IFileInfo& file_info) const;
std::unique_ptr<IFileInfo> FindFileInfo(u64 disc_offset, const IFileInfo& file_info) const;
void BuildOffsetFileInfoCache(const IFileInfo& directory) const;
u32 GetOffsetShift() const;
};

Expand Down

0 comments on commit b8fb589

Please sign in to comment.