Skip to content

Commit

Permalink
zip: avoid insanly slow zip file listing due to cache thrashing
Browse files Browse the repository at this point in the history
Zip file list extractor kept seeking back and forth from central
file list to header in front of actual file data, causing all
caches to be flushed on read.

Avoid cache thrashing by first reading all central headers, then
extracting data from file headers (technically this could even be
skipped when only a file list is wanted)
  • Loading branch information
elupus committed Nov 3, 2012
1 parent 33d8a35 commit bbe95f8
Showing 1 changed file with 10 additions and 7 deletions.
17 changes: 10 additions & 7 deletions xbmc/filesystem/ZipManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,6 @@ bool CZipManager::GetZipList(const CStdString& strPath, vector<SZipEntry>& items
return false;
}

SZipEntry ze;
unsigned int hdr;
mFile.Read(&hdr, 4);
if( Endian_SwapLE32(hdr) != ZIP_LOCAL_HEADER )
Expand Down Expand Up @@ -168,6 +167,7 @@ bool CZipManager::GetZipList(const CStdString& strPath, vector<SZipEntry>& items
char temp[CHDR_SIZE];
while (mFile.GetPosition() < cdirOffset + cdirSize)
{
SZipEntry ze;
mFile.Read(temp,CHDR_SIZE);
readCHeader(temp, ze);
if (ze.header != ZIP_CENTRAL_HEADER)
Expand All @@ -185,9 +185,16 @@ bool CZipManager::GetZipList(const CStdString& strPath, vector<SZipEntry>& items
ZeroMemory(ze.name, 255);
strncpy(ze.name, strName.c_str(), strName.size()>254 ? 254 : strName.size());

// Save the current position
int64_t savePos = mFile.GetPosition();
// Jump after central file header extra field and file comment
mFile.Seek(ze.eclength + ze.clength,SEEK_CUR);

items.push_back(ze);
}

/* go through list and figure out file header lengths */
for(vector<SZipEntry>::iterator it = items.begin(); it != items.end(); ++it)
{
SZipEntry& ze = *it;
// Go to the local file header to get the extra field length
// !! local header extra field length != central file header extra field length !!
mFile.Seek(ze.lhdrOffset+28,SEEK_SET);
Expand All @@ -197,10 +204,6 @@ bool CZipManager::GetZipList(const CStdString& strPath, vector<SZipEntry>& items
// Compressed data offset = local header offset + size of local header + filename length + local file header extra field length
ze.offset = ze.lhdrOffset + LHDR_SIZE + ze.flength + ze.elength;

// Jump after central file header extra field and file comment
mFile.Seek(savePos + ze.eclength + ze.clength,SEEK_SET);

items.push_back(ze);
}

mZipMap.insert(make_pair(strFile,items));
Expand Down

0 comments on commit bbe95f8

Please sign in to comment.