ZipFile - speedup initialization for zip archive by 30-50%

unzip.h/.cpp - unzGoToFirstFile/unzGoToNextFile retrieves information
about the current file, so it is possible to remove redundant calls
to unzGetCurrentFileInfo and speed up general execution.

unzip.h/.cpp are modified accordingly by creation unzGoToFirstFile64
and unzGoToNextFile64 with file info (unz_file_info64) and name as
possible output parameters.

ZipFile::setFilter (it is used to create a file list at ZipFile
constructor) - redundant calls to unzGetCurrentFileInfo64 are removed,
so briefly the time required to generate a zip file list is something
like 1 average old unzLocateFile call.
This commit is contained in:
Denis Mingulov 2012-11-11 15:04:41 +02:00
parent 83cf8aaf29
commit 869168a884
3 changed files with 77 additions and 25 deletions

View File

@ -300,7 +300,7 @@ public:
unzFile zipFile;
// std::unordered_map is faster if available on the platform
typedef std::map<std::string, ZipEntryInfo> FileListContainer;
typedef std::map<std::string, struct ZipEntryInfo> FileListContainer;
FileListContainer fileList;
};
@ -334,35 +334,33 @@ bool ZipFile::setFilter(const std::string &filter)
// clear existing file list
m_data->fileList.clear();
// UNZ_MAXFILENAMEINZIP + 1 - it is done so in unzLocateFile
char szCurrentFileName[UNZ_MAXFILENAMEINZIP + 1];
unz_file_info64 fileInfo;
// go through all files and store position information about the required files
int err = unzGoToFirstFile(m_data->zipFile);
int err = unzGoToFirstFile64(m_data->zipFile, &fileInfo,
szCurrentFileName, sizeof(szCurrentFileName) - 1);
while (err == UNZ_OK)
{
unz_file_pos posInfo;
int posErr = unzGetFilePos(m_data->zipFile, &posInfo);
if (posErr == UNZ_OK)
{
// UNZ_MAXFILENAMEINZIP + 1 - it is done so in unzLocateFile
char szCurrentFileName[UNZ_MAXFILENAMEINZIP + 1];
unz_file_info64 fileInfo;
int nameErr = unzGetCurrentFileInfo64(m_data->zipFile, &fileInfo,
szCurrentFileName, sizeof(szCurrentFileName) - 1,
NULL, 0, NULL, 0);
std::string currentFileName = szCurrentFileName;
if (nameErr == UNZ_OK)
// cache info about filtered files only (like 'assets/')
if (filter.empty()
|| currentFileName.substr(0, filter.length()) == filter)
{
// cache info about filtered files only (like 'assets/')
if (filter.empty()
|| currentFileName.substr(0, filter.length()) == filter)
{
ZipEntryInfo entry;
entry.pos = posInfo;
entry.uncompressed_size = (uLong)fileInfo.uncompressed_size;
m_data->fileList[currentFileName] = entry;
}
ZipEntryInfo entry;
entry.pos = posInfo;
entry.uncompressed_size = (uLong)fileInfo.uncompressed_size;
m_data->fileList[currentFileName] = entry;
}
}
err = unzGoToNextFile(m_data->zipFile);
// next file - also get the information about it
err = unzGoToNextFile64(m_data->zipFile, &fileInfo,
szCurrentFileName, sizeof(szCurrentFileName) - 1);
}
ret = true;

View File

@ -1172,11 +1172,16 @@ int ZEXPORT unzGetCurrentFileInfo (unzFile file,
}
return err;
}
/*
Set the current file of the zipfile to the first file.
Set the current file of the zipfile to the first file
with retrieving an information about the file.
return UNZ_OK if there is no problem
*/
int ZEXPORT unzGoToFirstFile (unzFile file)
int ZEXPORT unzGoToFirstFile64 (unzFile file,
unz_file_info64 *pfile_info,
char *szFileName,
uLong fileNameBufferSize)
{
int err=UNZ_OK;
unz64_s* s;
@ -1187,17 +1192,32 @@ int ZEXPORT unzGoToFirstFile (unzFile file)
s->num_file=0;
err=unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,
&s->cur_file_info_internal,
NULL,0,NULL,0,NULL,0);
szFileName,fileNameBufferSize,NULL,0,NULL,0);
s->current_file_ok = (err == UNZ_OK);
if (pfile_info)
*pfile_info = s->cur_file_info;
return err;
}
/*
Set the current file of the zipfile to the next file.
Set the current file of the zipfile to the first file.
return UNZ_OK if there is no problem
*/
int ZEXPORT unzGoToFirstFile (unzFile file)
{
return unzGoToFirstFile64(file, NULL, NULL, 0);
}
/*
Set the current file of the zipfile to the next file
with retrieving an information about the file.
return UNZ_OK if there is no problem
return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
*/
int ZEXPORT unzGoToNextFile (unzFile file)
int ZEXPORT unzGoToNextFile64 (unzFile file,
unz_file_info64 *pfile_info,
char *szFileName,
uLong fileNameBufferSize)
{
unz64_s* s;
int err;
@ -1216,11 +1236,23 @@ int ZEXPORT unzGoToNextFile (unzFile file)
s->num_file++;
err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,
&s->cur_file_info_internal,
NULL,0,NULL,0,NULL,0);
szFileName,fileNameBufferSize,NULL,0,NULL,0);
s->current_file_ok = (err == UNZ_OK);
if (pfile_info)
*pfile_info = s->cur_file_info;
return err;
}
/*
Set the current file of the zipfile to the next file.
return UNZ_OK if there is no problem
return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
*/
int ZEXPORT unzGoToNextFile (unzFile file)
{
return unzGoToNextFile64(file, NULL, NULL, 0);
}
/*
Try locate the file szFileName in the zipfile.

View File

@ -225,11 +225,22 @@ int ZEXPORT unzGetGlobalComment OF((unzFile file,
/* Unzip package allow you browse the directory of the zipfile */
int ZEXPORT unzGoToFirstFile OF((unzFile file));
/*
Set the current file of the zipfile to the first file.
return UNZ_OK if there is no problem
*/
int ZEXPORT unzGoToFirstFile64 OF((unzFile file,
unz_file_info64 *pfile_info,
char *szFileName,
uLong fileNameBufferSize));
/*
Set the current file of the zipfile to the first file
with retrieving an information about the file.
return UNZ_OK if there is no problem
*/
int ZEXPORT unzGoToNextFile OF((unzFile file));
/*
Set the current file of the zipfile to the next file.
@ -237,6 +248,17 @@ int ZEXPORT unzGoToNextFile OF((unzFile file));
return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
*/
int ZEXPORT unzGoToNextFile64 OF((unzFile file,
unz_file_info64 *pfile_info,
char *szFileName,
uLong fileNameBufferSize));
/*
Set the current file of the zipfile to the next file
with retrieving an information about the file.
return UNZ_OK if there is no problem
return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
*/
int ZEXPORT unzLocateFile OF((unzFile file,
const char *szFileName,
int iCaseSensitivity));