Browse Source

zip unordered map

[email protected] 8 years ago
parent
commit
cb737900a2
2 changed files with 61 additions and 60 deletions
  1. 52 50
      oxygine/src/core/ZipFileSystem.cpp
  2. 9 10
      oxygine/src/core/ZipFileSystem.h

+ 52 - 50
oxygine/src/core/ZipFileSystem.cpp

@@ -40,7 +40,7 @@ namespace oxygine
             return true;
             return true;
         }
         }
 
 
-        Zips::Zips(): _sort(false), _lock(true)
+        Zips::Zips(): _lock(true)
         {
         {
 
 
         }
         }
@@ -61,15 +61,22 @@ namespace oxygine
 
 
                 file_entry entry;
                 file_entry entry;
                 unzGetCurrentFileInfo(zp, 0, entry.name, sizeof(entry.name) - 1, 0, 0, 0, 0);
                 unzGetCurrentFileInfo(zp, 0, entry.name, sizeof(entry.name) - 1, 0, 0, 0, 0);
+                entry.refs = 0;
                 entry.pos = pos;
                 entry.pos = pos;
                 entry.zp = zp;
                 entry.zp = zp;
+                
+                char *str = entry.name;
+                for (int i = 0; str[i]; i++)
+                    str[i] = tolower(str[i]);
 
 
-                _files.push_back(entry);
+
+                OX_ASSERT(_files.find(entry.name) == _files.end());
+
+                _files[entry.name] = entry;
 
 
             }
             }
             while (unzGoToNextFile(zp) != UNZ_END_OF_LIST_OF_FILE);
             while (unzGoToNextFile(zp) != UNZ_END_OF_LIST_OF_FILE);
 
 
-            _sort = true;
         }
         }
 
 
         void Zips::add(const unsigned char* data, unsigned int size)
         void Zips::add(const unsigned char* data, unsigned int size)
@@ -168,15 +175,16 @@ namespace oxygine
                 zpitem& item = _zps[i];
                 zpitem& item = _zps[i];
                 if (!strcmp(item.name, name))
                 if (!strcmp(item.name, name))
                 {
                 {
-                    for (size_t n = 0; n < _files.size();)
+                    for (files::iterator it = _files.begin(); it != _files.end();)
                     {
                     {
-                        file_entry& entry = _files[n];
+                        file_entry& entry = it->second;
                         if (entry.zp == item.handle)
                         if (entry.zp == item.handle)
                         {
                         {
-                            _files.erase(_files.begin() + n);
+                            OX_ASSERT(entry.refs == 0);
+                            it = _files.erase(it);
                         }
                         }
                         else
                         else
-                            ++n;
+                            ++it;
                     }
                     }
 
 
                     unzClose(item.handle);
                     unzClose(item.handle);
@@ -217,18 +225,6 @@ namespace oxygine
             read(zp);
             read(zp);
         }
         }
 
 
-        void Zips::update()
-        {
-            std::sort(_files.begin(), _files.end(), sortFiles);
-#ifdef OX_DEBUG
-            for (int i = 0; i < (int)_files.size() - 1; ++i)
-            {
-                OX_ASSERT(strcmp(_files[i].name, _files[i + 1].name) != 0);
-            }
-#endif
-            log::messageln("ZipFS, total files: %d", _files.size());
-        }
-
         bool Zips::isExists(const char* name)
         bool Zips::isExists(const char* name)
         {
         {
             MutexAutoLock al(_lock);
             MutexAutoLock al(_lock);
@@ -260,43 +256,40 @@ namespace oxygine
                 unzClose(f.handle);
                 unzClose(f.handle);
             }
             }
 
 
-            _zps.clear();
-            _files.clear();
-        }
 
 
+#ifdef OX_DEBUG
+            for (files::iterator i = _files.begin(); i != _files.end(); ++i)
+            {
+                OX_ASSERT(i->second.refs == 0);
+            }
 
 
-        bool findEntry(const file_entry& g, const char* name)
-        {
-            return strcmp_cns(g.name, name) < 0;
+#endif
+            _zps.clear();
+            _files.clear();
         }
         }
 
 
-        const file_entry* Zips::getEntryByName(const char* name)
+        file_entry* Zips::getEntryByName(const char* name)
         {
         {
-            if (_sort)
+            char str[255];
+            char *p = str;
+            while (*name)
             {
             {
-                update();
-                _sort = false;
+                *p = tolower(*name);
+                name++;
+                ++p;
             }
             }
+            *p = 0;
 
 
-            files::const_iterator it = std::lower_bound(_files.begin(), _files.end(), name, findEntry);
-            if (it != _files.end())
-            {
-                const file_entry& g = *it;
-                if (!strcmp_cns(g.name, name))
-                    return &g;
-            }
+            files::iterator it = _files.find(str);
+            if (it != _files.end())            
+                return &it->second;
 
 
             return 0;
             return 0;
         }
         }
 
 
+        /*
         const file_entry* Zips::getEntry(int index)
         const file_entry* Zips::getEntry(int index)
         {
         {
-            if (_sort)
-            {
-                update();
-                _sort = false;
-            }
-
             return &_files[index];
             return &_files[index];
         }
         }
 
 
@@ -304,25 +297,30 @@ namespace oxygine
         {
         {
             return _files.size();
             return _files.size();
         }
         }
+        */
 
 
 
 
         class fileHandleZip: public fileHandle
         class fileHandleZip: public fileHandle
         {
         {
         public:
         public:
 
 
-            fileHandleZip(FileSystem* fs, const file_entry* entry): fileHandle(fs), _entry(entry)
+            fileHandleZip(FileSystem* fs, file_entry* entry): fileHandle(fs), _entry(entry)
             {
             {
-                int r = 0;
-                r = unzGoToFilePos(entry->zp, const_cast<unz_file_pos*>(&entry->pos));
+                int r = unzGoToFilePos(entry->zp, const_cast<unz_file_pos*>(&entry->pos));
                 OX_ASSERT(r == UNZ_OK);
                 OX_ASSERT(r == UNZ_OK);
                 r = unzOpenCurrentFile(entry->zp);
                 r = unzOpenCurrentFile(entry->zp);
                 OX_ASSERT(r == UNZ_OK);
                 OX_ASSERT(r == UNZ_OK);
+                _entry->refs++;
             }
             }
 
 
             void release()
             void release()
             {
             {
+                ZipFileSystem *zfs = static_cast<ZipFileSystem *>(_fs);
+                MutexAutoLock lock(zfs->_zips.getMutex());
+                _entry->refs--;
+
                 int r = unzCloseCurrentFile(_entry->zp);
                 int r = unzCloseCurrentFile(_entry->zp);
-                OX_ASSERT(r == UNZ_OK);
+                OX_ASSERT(r == UNZ_OK);                
                 delete this;
                 delete this;
             }
             }
 
 
@@ -355,7 +353,7 @@ namespace oxygine
                 return (unsigned int) file_info.uncompressed_size;
                 return (unsigned int) file_info.uncompressed_size;
             }
             }
 
 
-            const file_entry* _entry;
+            file_entry* _entry;
         };
         };
 
 
         class fileHandleZipStreaming : public fileHandle
         class fileHandleZipStreaming : public fileHandle
@@ -365,8 +363,9 @@ namespace oxygine
             z_off_t _pos;
             z_off_t _pos;
             z_off_t _size;
             z_off_t _size;
             long _cpos;
             long _cpos;
+            file_entry* _entry;
 
 
-            fileHandleZipStreaming(FileSystem* fs, const file_entry* entry, const Zips& z): fileHandle(fs), _cpos(0)
+            fileHandleZipStreaming(FileSystem* fs, file_entry* entry, const Zips& z): fileHandle(fs), _cpos(0), _entry(entry)
             {
             {
                 int r = 0;
                 int r = 0;
                 r = unzGoToFilePos(entry->zp, const_cast<unz_file_pos*>(&entry->pos));
                 r = unzGoToFilePos(entry->zp, const_cast<unz_file_pos*>(&entry->pos));
@@ -387,11 +386,14 @@ namespace oxygine
                 file::seek(_h, static_cast<unsigned int>(_pos), SEEK_SET);
                 file::seek(_h, static_cast<unsigned int>(_pos), SEEK_SET);
 
 
                 unzCloseCurrentFile(entry->zp);
                 unzCloseCurrentFile(entry->zp);
+                entry->refs++;
             }
             }
 
 
             ~fileHandleZipStreaming()
             ~fileHandleZipStreaming()
             {
             {
-                int q = 0;
+                ZipFileSystem *zfs = static_cast<ZipFileSystem *>(_fs);
+                MutexAutoLock lock(zfs->_zips.getMutex());
+                _entry->refs--;
             }
             }
 
 
             void release()
             void release()
@@ -489,7 +491,7 @@ namespace oxygine
         {
         {
             MutexAutoLock lock(_zips._lock);
             MutexAutoLock lock(_zips._lock);
 
 
-            const file_entry* entry = _zips.getEntryByName(file);
+            file_entry* entry = _zips.getEntryByName(file);
             if (entry)
             if (entry)
             {
             {
                 if (*mode == 's')
                 if (*mode == 's')

+ 9 - 10
oxygine/src/core/ZipFileSystem.h

@@ -5,6 +5,7 @@
 #include "minizip/unzip.h"
 #include "minizip/unzip.h"
 #include "core/file.h"
 #include "core/file.h"
 #include "core/Mutex.h"
 #include "core/Mutex.h"
+#include <unordered_map>
 
 
 namespace oxygine
 namespace oxygine
 {
 {
@@ -15,6 +16,7 @@ namespace oxygine
             unzFile zp;
             unzFile zp;
             char name[128];
             char name[128];
             unz_file_pos pos;
             unz_file_pos pos;
+            int refs;
         };
         };
 
 
         class Zips
         class Zips
@@ -30,25 +32,19 @@ namespace oxygine
             void add(std::vector<char>& data);
             void add(std::vector<char>& data);
             void remove(const char* name);
             void remove(const char* name);
 
 
-            void update();
-
             bool read(const char* name, file::buffer& bf);
             bool read(const char* name, file::buffer& bf);
             bool read(const file_entry* entry, file::buffer& bf);
             bool read(const file_entry* entry, file::buffer& bf);
             bool isExists(const char* name);
             bool isExists(const char* name);
 
 
-            const file_entry*   getEntryByName(const char* name);
-            const file_entry*   getEntry(int index);
-            size_t              getNumEntries() const;
-
-            const char* getZipFileName(int i) const { return _zps[i].name; }
+            file_entry*         getEntryByName(const char* name);            
+            const char*         getZipFileName(int i) const { return _zps[i].name; }
+            Mutex&              getMutex() { return _lock; }
 
 
         private:
         private:
             friend class ZipFileSystem;
             friend class ZipFileSystem;
             void read(unzFile zp);
             void read(unzFile zp);
 
 
-            bool _sort;
-
-            typedef std::vector<file_entry> files;
+            typedef std::unordered_map<std::string, file_entry> files;
             files _files;
             files _files;
 
 
             struct zpitem
             struct zpitem
@@ -84,6 +80,9 @@ namespace oxygine
 
 
         protected:
         protected:
 
 
+            friend class fileHandleZip;
+            friend class fileHandleZipStreaming;
+
             Zips _zips;
             Zips _zips;
 
 
             status _read(const char* file, file::buffer&, error_policy ep);
             status _read(const char* file, file::buffer&, error_policy ep);