From ae2df43b8a77ed8a3641f3b16b7a3828e0e574f0 Mon Sep 17 00:00:00 2001 From: drbob Date: Tue, 24 Sep 2013 15:31:15 +0000 Subject: [PATCH] re-wrote cleanupDirectory() function. As this a cause of the slow startup. Startup time is massively improved! Please test on Windows! git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@6757 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/dbase/cachestrapper.cc | 12 +-- libretroshare/src/util/rsdir.cc | 126 ++++++++++++++++++++++- libretroshare/src/util/rsdir.h | 5 +- 3 files changed, 133 insertions(+), 10 deletions(-) diff --git a/libretroshare/src/dbase/cachestrapper.cc b/libretroshare/src/dbase/cachestrapper.cc index 4a4075aa1..917b42dee 100644 --- a/libretroshare/src/dbase/cachestrapper.cc +++ b/libretroshare/src/dbase/cachestrapper.cc @@ -961,8 +961,8 @@ bool CacheStrapper::loadList(std::list& load) //mPeerMgr->getOwnNetStatus(ownState); //std::string ownName = ownState.name+" ("+ownState.location+")"; - std::map > saveFiles; - std::map >::iterator sit; + std::map > saveFiles; + std::map >::iterator sit; for(it = load.begin(); it != load.end(); it++) { @@ -1001,7 +1001,7 @@ bool CacheStrapper::loadList(std::list& load) cd.recvd = rscc->recvd; /* store files that we want to keep */ - (saveFiles[cd.path]).push_back(cd.name); + (saveFiles[cd.path]).insert(cd.name); std::map::iterator it2; if (caches.end() == (it2 = caches.find(cd.cid.type))) @@ -1107,7 +1107,7 @@ bool CacheStrapper::loadList(std::list& load) } #endif - std::list emptyList; + std::set emptySet; for(dit = cacheDirs.begin(); dit != cacheDirs.end(); dit++) { #ifdef CS_DEBUG @@ -1122,14 +1122,14 @@ bool CacheStrapper::loadList(std::list& load) std::cerr << "CacheStrapper::loadList() Keeping File: " << *fit << std::endl; } #endif - RsDirUtil::cleanupDirectory(*dit, sit->second); + RsDirUtil::cleanupDirectoryFaster(*dit, sit->second); } else { #ifdef CS_DEBUG std::cerr << "CacheStrapper::loadList() No Files to save here!" << std::endl; #endif - RsDirUtil::cleanupDirectory(*dit, emptyList); + RsDirUtil::cleanupDirectoryFaster(*dit, emptySet); } } diff --git a/libretroshare/src/util/rsdir.cc b/libretroshare/src/util/rsdir.cc index a13742015..edc3bbaef 100644 --- a/libretroshare/src/util/rsdir.cc +++ b/libretroshare/src/util/rsdir.cc @@ -487,7 +487,8 @@ bool RsDirUtil::checkCreateDirectory(const std::string& dir) return 1; } -bool RsDirUtil::cleanupDirectory(const std::string& cleandir, const std::list &keepFiles) + +bool RsDirUtil::cleanupDirectory(const std::string& cleandir, const std::set &keepFiles) { /* check for the dir existance */ @@ -499,7 +500,6 @@ bool RsDirUtil::cleanupDirectory(const std::string& cleandir, const std::list::const_iterator it; if (!dir) { @@ -541,7 +541,7 @@ bool RsDirUtil::cleanupDirectory(const std::string& cleandir, const std::list &keepFiles) +{ + + /* check for the dir existance */ +#ifdef WINDOWS_SYS + std::map fileMap; + std::map::const_iterator fit; + + std::wstring wcleandir; + librs::util::ConvertUtf8ToUtf16(cleandir, wcleandir); + _WDIR *dir = _wopendir(wcleandir.c_str()); +#else + std::map fileMap; + std::map::const_iterator fit; + + DIR *dir = opendir(cleandir.c_str()); +#endif + + if (!dir) + { + return false; + } + +#ifdef WINDOWS_SYS + struct _wdirent *dent; + struct _stat buf; + + while(NULL != (dent = _wreaddir(dir))) + { + const std::wstring &wfname = dent -> d_name; + std::wstring wfullname = wcleandir + L"/" + wfname; + + if (-1 != _wstat(wfullname.c_str(), &buf)) + { + /* only worry about files */ + if (S_ISREG(buf.st_mode)) + { + std::string fname; + librs::util::ConvertUtf16ToUtf8(wfname, fname); + fileMap[fname] = wfullname; + } + } + } +#else + struct dirent *dent; + struct stat buf; + + while(NULL != (dent = readdir(dir))) + { + const std::string &fname = dent -> d_name; + std::string fullname = cleandir + "/" + fname; + + if (-1 != stat(fullname.c_str(), &buf)) + { + /* only worry about files */ + if (S_ISREG(buf.st_mode)) + { + fileMap[fname] = fullname; + } + } + } +#endif + + + + std::set::const_iterator kit; + + fit = fileMap.begin(); + kit = keepFiles.begin(); + + while(fit != fileMap.end() && kit != keepFiles.end()) + { + if (fit->first < *kit) // fit is not in keep list; + { +#ifdef WINDOWS_SYS + _wremove(fit->second..c_str()); +#else + remove(fit->second.c_str()); +#endif + ++fit; + } + else if (*kit < fit->first) // keepitem doesn't exist. + { + ++kit; + } + else // in keep list. + { + ++fit; + ++kit; + } + } + + // cleanup extra that aren't in keep list. + while(fit != fileMap.end()) + { +#ifdef WINDOWS_SYS + _wremove(fit->second..c_str()); +#else + remove(fit->second.c_str()); +#endif + ++fit; + } + + /* close directory */ +#ifdef WINDOWS_SYS + _wclosedir(dir); +#else + closedir(dir); +#endif + + return true; +} + + + + + /* slightly nicer helper function */ bool RsDirUtil::hashFile(const std::string& filepath, std::string &name, std::string &hash, uint64_t &size) diff --git a/libretroshare/src/util/rsdir.h b/libretroshare/src/util/rsdir.h index 41736dc21..c99a01ee8 100644 --- a/libretroshare/src/util/rsdir.h +++ b/libretroshare/src/util/rsdir.h @@ -30,6 +30,7 @@ #include #include +#include #include class RsThread; @@ -85,7 +86,9 @@ bool fileExists(const std::string& file); bool checkFile(const std::string& filename,bool disallow_empty_file = false); bool checkDirectory(const std::string& dir); bool checkCreateDirectory(const std::string& dir); -bool cleanupDirectory(const std::string& dir, const std::list &keepFiles); + +bool cleanupDirectory(const std::string& dir, const std::set &keepFiles); +bool cleanupDirectoryFaster(const std::string& dir, const std::set &keepFiles); bool hashFile(const std::string& filepath, std::string &name, std::string &hash, uint64_t &size); bool getFileHash(const std::string& filepath,std::string &hash, uint64_t &size, RsThread *thread = NULL);