Merge pull request #1145 from unknownbrackets/perf

Speed up ISO reading for the gameinfocache
This commit is contained in:
Henrik Rydgård 2013-03-31 23:44:50 -07:00
commit 53cdfbef86
3 changed files with 62 additions and 12 deletions

View file

@ -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();

View file

@ -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);
};

View file

@ -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;