Faster ZIP access by indexing all files
This commit is contained in:
parent
18f8405aae
commit
2fbc7b573c
@ -304,6 +304,31 @@ namespace spades {
|
||||
}
|
||||
|
||||
currentStream = NULL;
|
||||
|
||||
if(unzGoToFirstFile(zip) != UNZ_OK) {
|
||||
SPRaise("There was a problem while seeking the zip file to the first file.");
|
||||
}
|
||||
|
||||
// create list of files
|
||||
do{
|
||||
char buf[513];
|
||||
buf[512] = 0;
|
||||
unzGetCurrentFileInfo(zip, nullptr,
|
||||
buf, 512, nullptr, 0, nullptr, 0);
|
||||
|
||||
for(char *ptr = buf; *ptr; ptr++) {
|
||||
if(*ptr == '\\') *ptr = '/';
|
||||
else
|
||||
*ptr = tolower(*ptr);
|
||||
}
|
||||
|
||||
unz_file_pos pos;
|
||||
if(unzGetFilePos(zip, &pos) != UNZ_OK) {
|
||||
SPRaise("unzGetFilePos failed");
|
||||
}
|
||||
files.insert(std::make_pair(buf, pos));
|
||||
}while(unzGoToNextFile(zip) == UNZ_OK);
|
||||
|
||||
}
|
||||
|
||||
ZipFileSystem::~ZipFileSystem() {
|
||||
@ -322,7 +347,7 @@ namespace spades {
|
||||
currentStream->ForceCloseUnzipFile();
|
||||
}
|
||||
|
||||
if(unzLocateFile(zip, fn, 2) != UNZ_OK){
|
||||
if(!MoveToFile(fn)) {
|
||||
SPFileNotFound(fn);
|
||||
}
|
||||
|
||||
@ -389,6 +414,7 @@ namespace spades {
|
||||
SPRaise("There was a problem while seeking the zip file to the first file.");
|
||||
}
|
||||
|
||||
// FIXME: use `files` for faster search?
|
||||
std::vector<std::string> lst;
|
||||
size_t ln = strlen(path);
|
||||
do{
|
||||
@ -419,17 +445,36 @@ namespace spades {
|
||||
return lst;
|
||||
}
|
||||
|
||||
bool ZipFileSystem::FileExists(const char *fn) {
|
||||
bool ZipFileSystem::MoveToFile(const char *fn) {
|
||||
SPADES_MARK_FUNCTION();
|
||||
|
||||
if(currentStream){
|
||||
currentStream->ForceCloseUnzipFile();
|
||||
std::string f = fn;
|
||||
for(std::size_t i = 0; i < f.size(); i++) {
|
||||
if(f[i] == '\\') f[i] = '/';
|
||||
else f[i] = tolower(f[i]);
|
||||
}
|
||||
|
||||
if(unzLocateFile(zip, fn, 2) != UNZ_OK){
|
||||
auto it = files.find(f);
|
||||
if(it == files.end()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(unzGoToFilePos(zip, &it->second) != UNZ_OK) {
|
||||
SPRaise("Failed to seek to the requested file.");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ZipFileSystem::FileExists(const char *fn) {
|
||||
SPADES_MARK_FUNCTION();
|
||||
|
||||
std::string f = fn;
|
||||
for(std::size_t i = 0; i < f.size(); i++) {
|
||||
if(f[i] == '\\') f[i] = '/';
|
||||
else f[i] = tolower(f[i]);
|
||||
}
|
||||
|
||||
return files.find(f) != files.end();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -22,11 +22,14 @@
|
||||
|
||||
#include "IFileSystem.h"
|
||||
#include <stdint.h>
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
extern "C"{
|
||||
typedef void *unzFile;
|
||||
struct zlib_filefunc_def_s;
|
||||
typedef struct zlib_filefunc_def_s zlib_filefunc_def;
|
||||
struct unz_file_pos_s;
|
||||
}
|
||||
|
||||
namespace spades {
|
||||
@ -38,6 +41,8 @@ namespace spades {
|
||||
bool autoClose;
|
||||
unzFile zip;
|
||||
|
||||
std::map<std::string, unz_file_pos_s> files;
|
||||
|
||||
ZipFileInputStream *currentStream;
|
||||
|
||||
uint64_t cursorPos;
|
||||
@ -63,6 +68,7 @@ namespace spades {
|
||||
ZipFileHandle *h);
|
||||
|
||||
zlib_filefunc_def CreateZLibFileFunc();
|
||||
bool MoveToFile(const char *);
|
||||
public:
|
||||
ZipFileSystem(IStream *, bool autoClose = true);
|
||||
virtual ~ZipFileSystem();
|
||||
|
Loading…
x
Reference in New Issue
Block a user