mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Merge pull request #1145 from unknownbrackets/perf
Speed up ISO reading for the gameinfocache
This commit is contained in:
commit
53cdfbef86
3 changed files with 62 additions and 12 deletions
|
@ -131,8 +131,23 @@ struct VolDescriptor
|
|||
|
||||
#pragma pack(pop)
|
||||
|
||||
ISOFileSystem::ISOFileSystem(IHandleAllocator *_hAlloc, BlockDevice *_blockDevice)
|
||||
std::list<ISOFileSystem::TreeEntry *> ISOFileSystem::entryFreeList;
|
||||
|
||||
ISOFileSystem::ISOFileSystem(IHandleAllocator *_hAlloc, BlockDevice *_blockDevice, std::string _restrictPath)
|
||||
{
|
||||
if (!_restrictPath.empty())
|
||||
{
|
||||
size_t pos = _restrictPath.find_first_not_of('/');
|
||||
while (!_restrictPath.empty())
|
||||
{
|
||||
size_t endPos = _restrictPath.find_first_of('/', pos);
|
||||
if (pos != endPos)
|
||||
restrictTree.push_back(_restrictPath.substr(pos, endPos));
|
||||
pos = _restrictPath.find_first_not_of('/', endPos);
|
||||
_restrictPath.erase(0, pos);
|
||||
}
|
||||
}
|
||||
|
||||
blockDevice = _blockDevice;
|
||||
hAlloc = _hAlloc;
|
||||
|
||||
|
@ -156,7 +171,7 @@ ISOFileSystem::ISOFileSystem(IHandleAllocator *_hAlloc, BlockDevice *_blockDevic
|
|||
ERROR_LOG(FILESYS, "ISO looks bogus? trying anyway...");
|
||||
}
|
||||
|
||||
treeroot = new TreeEntry;
|
||||
treeroot = GetTreeEntry();
|
||||
treeroot->isDirectory = true;
|
||||
treeroot->startingPosition = 0;
|
||||
treeroot->size = 0;
|
||||
|
@ -167,16 +182,16 @@ ISOFileSystem::ISOFileSystem(IHandleAllocator *_hAlloc, BlockDevice *_blockDevic
|
|||
u32 rootSector = desc.root.firstDataSectorLE;
|
||||
u32 rootSize = desc.root.dataLengthLE;
|
||||
|
||||
ReadDirectory(rootSector, rootSize, treeroot);
|
||||
ReadDirectory(rootSector, rootSize, treeroot, 0);
|
||||
}
|
||||
|
||||
ISOFileSystem::~ISOFileSystem()
|
||||
{
|
||||
delete blockDevice;
|
||||
delete treeroot;
|
||||
ReleaseTreeEntry(treeroot);
|
||||
}
|
||||
|
||||
void ISOFileSystem::ReadDirectory(u32 startsector, u32 dirsize, TreeEntry *root)
|
||||
void ISOFileSystem::ReadDirectory(u32 startsector, u32 dirsize, TreeEntry *root, size_t level)
|
||||
{
|
||||
for (u32 secnum = startsector, endsector = dirsize/2048 + startsector; secnum < endsector; ++secnum)
|
||||
{
|
||||
|
@ -196,7 +211,7 @@ void ISOFileSystem::ReadDirectory(u32 startsector, u32 dirsize, TreeEntry *root)
|
|||
if (offset + IDENTIFIER_OFFSET + dir.identifierLength > 2048)
|
||||
{
|
||||
ERROR_LOG(FILESYS, "Directory entry crosses sectors, corrupt iso?");
|
||||
break;
|
||||
return;
|
||||
}
|
||||
|
||||
offset += dir.size;
|
||||
|
@ -204,7 +219,7 @@ void ISOFileSystem::ReadDirectory(u32 startsector, u32 dirsize, TreeEntry *root)
|
|||
bool isFile = (dir.flags & 2) ? false : true;
|
||||
bool relative;
|
||||
|
||||
TreeEntry *e = new TreeEntry();
|
||||
TreeEntry *e = GetTreeEntry();
|
||||
if (dir.identifierLength == 1 && (dir.firstIdChar == '\x00' || dir.firstIdChar == '.'))
|
||||
{
|
||||
e->name = ".";
|
||||
|
@ -239,7 +254,14 @@ void ISOFileSystem::ReadDirectory(u32 startsector, u32 dirsize, TreeEntry *root)
|
|||
}
|
||||
else
|
||||
{
|
||||
ReadDirectory(dir.firstDataSectorLE, dir.dataLengthLE, e);
|
||||
bool doRecurse = true;
|
||||
if (!restrictTree.empty())
|
||||
doRecurse = level < restrictTree.size() && restrictTree[level] == e->name;
|
||||
|
||||
if (doRecurse)
|
||||
ReadDirectory(dir.firstDataSectorLE, dir.dataLengthLE, e, level + 1);
|
||||
else
|
||||
continue;
|
||||
}
|
||||
}
|
||||
root->children.push_back(e);
|
||||
|
@ -591,6 +613,25 @@ std::string ISOFileSystem::EntryFullPath(TreeEntry *e)
|
|||
return path;
|
||||
}
|
||||
|
||||
ISOFileSystem::TreeEntry *ISOFileSystem::GetTreeEntry()
|
||||
{
|
||||
if (entryFreeList.empty())
|
||||
return new TreeEntry();
|
||||
else
|
||||
{
|
||||
TreeEntry *entry = entryFreeList.back();
|
||||
entryFreeList.pop_back();
|
||||
return entry;
|
||||
}
|
||||
}
|
||||
|
||||
void ISOFileSystem::ReleaseTreeEntry(ISOFileSystem::TreeEntry *entry)
|
||||
{
|
||||
entry->name.clear();
|
||||
entry->children.clear();
|
||||
entryFreeList.push_back(entry);
|
||||
}
|
||||
|
||||
void ISOFileSystem::DoState(PointerWrap &p)
|
||||
{
|
||||
int n = (int) entries.size();
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <list>
|
||||
#include <vector>
|
||||
|
||||
#include "FileSystem.h"
|
||||
|
||||
|
@ -28,7 +30,7 @@
|
|||
class ISOFileSystem : public IFileSystem
|
||||
{
|
||||
public:
|
||||
ISOFileSystem(IHandleAllocator *_hAlloc, BlockDevice *_blockDevice);
|
||||
ISOFileSystem(IHandleAllocator *_hAlloc, BlockDevice *_blockDevice, std::string _restrictPath = "");
|
||||
~ISOFileSystem();
|
||||
void DoState(PointerWrap &p);
|
||||
std::vector<PSPFileInfo> GetDirListing(std::string path);
|
||||
|
@ -53,7 +55,7 @@ private:
|
|||
~TreeEntry()
|
||||
{
|
||||
for (unsigned int i=0; i<children.size(); i++)
|
||||
delete children[i];
|
||||
ISOFileSystem::ReleaseTreeEntry(children[i]);
|
||||
children.clear();
|
||||
}
|
||||
|
||||
|
@ -86,7 +88,14 @@ private:
|
|||
|
||||
TreeEntry entireISO;
|
||||
|
||||
void ReadDirectory(u32 startsector, u32 dirsize, TreeEntry *root);
|
||||
// Don't use this in the emu, not savestated.
|
||||
std::vector<std::string> restrictTree;
|
||||
|
||||
void ReadDirectory(u32 startsector, u32 dirsize, TreeEntry *root, size_t level);
|
||||
TreeEntry *GetFromPath(std::string path, bool catchError=true);
|
||||
std::string EntryFullPath(TreeEntry *e);
|
||||
|
||||
static std::list<ISOFileSystem::TreeEntry *> entryFreeList;
|
||||
static TreeEntry *GetTreeEntry();
|
||||
static void ReleaseTreeEntry(TreeEntry *entry);
|
||||
};
|
||||
|
|
|
@ -123,7 +123,7 @@ again:
|
|||
BlockDevice *bd = constructBlockDevice(gamePath.c_str());
|
||||
if (!bd)
|
||||
return 0; // nothing to do here..
|
||||
ISOFileSystem umd(&handles, bd);
|
||||
ISOFileSystem umd(&handles, bd, "/PSP_GAME");
|
||||
|
||||
GameInfo *info = new GameInfo();
|
||||
info->wantBG = wantBG;
|
||||
|
|
Loading…
Add table
Reference in a new issue