Changeset 410


Ignore:
Timestamp:
07/02/15 11:07:42 (9 years ago)
Author:
Maciej Komosinski
Message:

ChainFileSystem? can merge Vopendir() results

Location:
cpp/common/virtfile
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • cpp/common/virtfile/virtfile.cpp

    r302 r410  
    189189        printf("ChainFileSystem::Vfopendir %s (chain=%p)\n",path,chain);
    190190#endif
    191         return (chain != NULL) ? chain->Vopendir(path) : NULL;
     191        if (chain==NULL) return internalopendir(path);
     192        return new Dir(string(path),this,chain);
    192193}
    193194
     
    206207        return (chain != NULL) ? chain->Vdirexists(path, is_writable) : false;
    207208}
     209
     210ChainFileSystem::Dir::~Dir()
     211{
     212if (dir) delete dir;
     213}
     214
     215dirent* ChainFileSystem::Dir::Vreaddir()
     216{
     217dirent *de;
     218  retry:
     219if (!dir)
     220        {
     221        if (first)
     222                {
     223                dir=first->internalopendir(path.c_str());
     224                first=NULL;
     225                }
     226        else if (second)
     227                {
     228                dir=second->Vopendir(path.c_str());
     229                second=NULL;
     230                }
     231        else
     232                return NULL;
     233        }
     234de=dir ? dir->Vreaddir() : NULL;
     235if (de==NULL)
     236        {if (dir) delete dir; dir=NULL; goto retry;}
     237
     238// no need to check for duplicates if no names are saved and scanning the last location (most common case)
     239if (! (duplicates.empty() && (first==NULL) && (second==NULL)) )
     240{
     241string s(de->d_name);
     242if (duplicates.find(s)==duplicates.end())
     243        duplicates.insert(s);
     244else
     245        goto retry;
     246}
     247
     248return de;
     249}
  • cpp/common/virtfile/virtfile.h

    r302 r410  
    1010#include <common/nonstd_dir.h>
    1111#include <string>
     12#include <set>
    1213using std::string;
    1314
     
    108109        bool Vfexists(const char* path);
    109110        VirtDIR *Vopendir(const char* path);
     111        virtual VirtDIR *internalopendir(const char* path) {return NULL;}
    110112        bool Vmkdir(const char* path);
    111113        bool Vmkdirs(const char* path);
    112114        bool Vdirexists(const char* path, bool is_writable);
     115
     116        class Dir: public VirtDIR
     117        {
     118        ChainFileSystem *first;
     119        VirtFileSystem *second;
     120        string path;
     121        std::set<string> duplicates;
     122        VirtDIR *dir;
     123          public:
     124        Dir(string _path,ChainFileSystem *_first,VirtFileSystem *_second):first(_first),second(_second),path(_path),dir(NULL) {}
     125        ~Dir();
     126        dirent* Vreaddir();
     127        };
    113128};
    114129
Note: See TracChangeset for help on using the changeset viewer.