cleaned the code in fimonitor, modified the order of file hashing, and put a more explicit progress message while hashing.

git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@2438 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
csoler 2010-02-26 23:05:07 +00:00
parent b7cd4c0627
commit b50b33b573
2 changed files with 134 additions and 147 deletions

View File

@ -195,10 +195,8 @@ bool FileIndexMonitor::loadLocalCache(const CacheData &data) /* called with sto
{
bool ok = false;
fiMutex.lock();
{ /* LOCKED DIRS */
//fi.root->name = data.pid;
{
RsStackMutex mtx(fiMutex) ; /* LOCKED DIRS */
/* More error checking needed here! */
@ -223,8 +221,7 @@ bool FileIndexMonitor::loadLocalCache(const CacheData &data) /* called with sto
}
fi.updateMaxModTime() ;
} fiMutex.unlock(); /* UNLOCKED DIRS */
}
if (ok)
{
@ -286,7 +283,6 @@ void FileIndexMonitor::run()
}
}
//void FileIndexMonitor::updateCycle(std::string& current_job)
void FileIndexMonitor::updateCycle()
{
@ -301,6 +297,8 @@ void FileIndexMonitor::updateCycle()
mInCheck = true;
}
std::vector<DirContentToHash> to_hash ;
while(moretodo)
{
/* sleep a bit for each loop */
@ -308,31 +306,26 @@ void FileIndexMonitor::updateCycle()
#ifndef WINDOWS_SYS
usleep(100000); /* 1/10 sec */
#else
Sleep(100);
#endif
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
/* check if directories have been updated */
if (internal_setSharedDirectories())
{
/* reset start time */
if (internal_setSharedDirectories()) /* reset start time */
startstamp = time(NULL);
}
/* Handle a Single out-of-date directory */
time_t stamp = time(NULL);
/* lock dirs */
fiMutex.lock();
/* lock dirs from now on */
RsStackMutex mtx(fiMutex) ;
DirEntry *olddir = fi.findOldDirectory(startstamp);
if (!olddir)
{
/* finished */
fiMutex.unlock();
moretodo = false;
continue;
}
@ -342,26 +335,19 @@ void FileIndexMonitor::updateCycle()
std::cerr << " Checking: " << olddir->path << std::endl;
#endif
FileEntry fe;
/* entries that need to be checked properly */
std::list<FileEntry> filesToHash;
std::list<FileEntry>::iterator hit;
/* determine the full root path */
std::string dirpath = olddir->path;
std::string rootdir = RsDirUtil::getRootDir(olddir->path);
std::string remdir = RsDirUtil::removeRootDir(olddir->path);
std::string realroot = locked_findRealRoot(rootdir);
std::string realpath = realroot;
if (remdir != "")
{
realpath += "/" + remdir;
}
#ifdef FIM_DEBUG
std::cerr << "FileIndexMonitor::updateCycle()";
@ -385,8 +371,6 @@ void FileIndexMonitor::updateCycle()
std::cerr << "FileIndexMonitor::updateCycle()";
std::cerr << "ERROR Failed to Remove: " << olddir->path << std::endl;
}
fiMutex.unlock();
continue;
}
@ -414,6 +398,10 @@ void FileIndexMonitor::updateCycle()
struct dirent *dent;
struct stat64 buf;
to_hash.push_back(DirContentToHash()) ;
to_hash.back().realpath = realpath ;
to_hash.back().dirpath = dirpath ;
while(NULL != (dent = readdir(dir)))
{
/* check entry type */
@ -472,8 +460,7 @@ void FileIndexMonitor::updateCycle()
else
{
/* check size / modtime are the same */
if ((fe.size != (fit->second)->size) ||
(fe.modtime != (fit->second)->modtime))
if ((fe.size != (fit->second)->size) || (fe.modtime != (fit->second)->modtime))
{
#ifdef FIM_DEBUG
std::cerr << "File ModTime/Size changed:" << fname << std::endl;
@ -481,10 +468,7 @@ void FileIndexMonitor::updateCycle()
toadd = true;
}
else
{
/* keep old info */
fe.hash = (fit->second)->hash;
}
fe.hash = (fit->second)->hash; /* keep old info */
}
if (toadd)
{
@ -494,22 +478,17 @@ void FileIndexMonitor::updateCycle()
std::cerr << olddir->path;
std::cerr << fname << std::endl;
#endif
filesToHash.push_back(fe);
to_hash.back().fentries.push_back(fe);
fiMods = true ;
}
else
else /* update with new time */
{
/* update with new time */
#ifdef FIM_DEBUG
std::cerr << "File Hasn't Changed:" << fname << std::endl;
#endif
fi.updateFileEntry(olddir->path, fe, stamp);
}
}
else
{
/* unknown , ignore */
continue;
}
}
#ifdef FIM_DEBUG
else
@ -517,6 +496,8 @@ void FileIndexMonitor::updateCycle()
#endif
}
if(to_hash.back().fentries.empty())
to_hash.pop_back() ;
/* now we unlock the lock, and iterate through the
* next files - hashing them, before adding into the system.
@ -526,86 +507,26 @@ void FileIndexMonitor::updateCycle()
/* close directory */
closedir(dir);
/* unlock dirs */
fiMutex.unlock();
if (filesToHash.size() > 0)
{
#ifdef FIM_DEBUG
std::cerr << "List of Files to rehash in: " << dirpath << std::endl;
#endif
fiMods = true;
cb->notifyListPreChange(NOTIFY_LIST_DIRLIST_LOCAL, 0);
}
#ifdef FIM_DEBUG
for(hit = filesToHash.begin(); hit != filesToHash.end(); hit++)
{
std::cerr << "\t" << hit->name << std::endl;
}
// Now, hash all files at once.
//
if(!to_hash.empty())
hashFiles(to_hash) ;
if (filesToHash.size() > 0)
{
std::cerr << std::endl;
}
#endif
/* update files */
for(hit = filesToHash.begin(); hit != filesToHash.end(); hit++)
{
// currentJob = "Hashing file " + realpath ;
if (hashFile(realpath, (*hit)))
{
/* lock dirs */
fiMutex.lock();
/* update fileIndex with new time */
/* update with new time */
fi.updateFileEntry(dirpath, *hit, stamp);
/* unlock dirs */
fiMutex.unlock();
}
else
{
std::cerr << "Failed to Hash File!" << std::endl;
}
/* don't hit the disk too hard! */
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
#ifndef WINDOWS_SYS
usleep(10000); /* 1/100 sec */
#else
Sleep(10);
#endif
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
}
if (filesToHash.size() > 0)
cb->notifyListChange(NOTIFY_LIST_DIRLIST_LOCAL, 0);
}
fiMutex.lock(); { /* LOCKED DIRS */
{ /* LOCKED DIRS */
RsStackMutex stack(fiMutex); /**** LOCKED DIRS ****/
/* finished update cycle - cleanup extra dirs/files that
* have not had their timestamps updated.
*/
if (fi.cleanOldEntries(startstamp))
{
//fiMods = true;
}
/* print out the new directory structure */
fi.cleanOldEntries(startstamp) ;
#ifdef FIM_DEBUG
/* print out the new directory structure */
fi.printFileIndex(std::cerr);
#endif
/* now if we have changed things -> restore file/hash it/and
* tell the CacheSource
*/
@ -616,18 +537,80 @@ void FileIndexMonitor::updateCycle()
fiMods = true;
}
}
if (fiMods)
locked_saveFileIndexes() ;
fiMutex.unlock(); /* UNLOCKED DIRS */
fi.updateMaxModTime() ; // Update modification times for proper display.
{
RsStackMutex stack(fiMutex); /**** LOCKED DIRS ****/
mInCheck = false;
}
}
void FileIndexMonitor::hashFiles(const std::vector<DirContentToHash>& to_hash)
{
cb->notifyListPreChange(NOTIFY_LIST_DIRLIST_LOCAL, 0);
time_t stamp = time(NULL);
// compute total size of files to hash
uint64_t total_size = 0 ;
uint32_t n_files = 0 ;
for(uint32_t i=0;i<to_hash.size();++i)
for(uint32_t j=0;j<to_hash[i].fentries.size();++j,++n_files)
total_size += to_hash[i].fentries[j].size ;
#ifdef FIM_DEBUG
std::cerr << "Hashing content of " << to_hash.size() << " different directories." << std::endl ;
std::cerr << "Total number of files: " << n_files << std::endl;
std::cerr << "Total size: " << total_size << " bytes"<< std::endl;
#endif
uint32_t cnt=0 ;
uint64_t size=0 ;
/* update files */
for(uint32_t i=0;i<to_hash.size();++i)
for(uint32_t j=0;j<to_hash[i].fentries.size();++j,++cnt)
{
// This is a very basic progress notification. To be more complete and user friendly, one would
// rather send a completion ratio based on the size of files vs/ total size.
//
std::ostringstream tmpout;
tmpout << cnt+1 << "/" << n_files << " (" << int(size/double(total_size)*100.0) << "%) : " << to_hash[i].fentries[j].name ;
cb->notifyHashingInfo(tmpout.str()) ;
FileEntry fe(to_hash[i].fentries[j]) ; // copied, because hashFile updates the hash member
if (hashFile(to_hash[i].realpath, fe))
{
RsStackMutex stack(fiMutex); /**** LOCKED DIRS ****/
/* update fileIndex with new time */
/* update with new time */
fi.updateFileEntry(to_hash[i].dirpath,fe,stamp);
}
else
std::cerr << "Failed to Hash File " << to_hash[i].fentries[j].name << std::endl;
size += to_hash[i].fentries[j].size ;
/* don't hit the disk too hard! */
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
#ifndef WINDOWS_SYS
usleep(40000); /* 40 msec */
#else
Sleep(40);
#endif
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
}
cb->notifyHashingInfo("") ;
cb->notifyListChange(NOTIFY_LIST_DIRLIST_LOCAL, 0);
}
@ -910,9 +893,6 @@ bool FileIndexMonitor::internal_setSharedDirectories()
return true;
}
/* lookup directory function */
std::string FileIndexMonitor::locked_findRealRoot(std::string rootdir) const
{
@ -944,8 +924,6 @@ bool FileIndexMonitor::hashFile(std::string fullpath, FileEntry &fent)
unsigned char sha_buf[SHA_DIGEST_LENGTH];
unsigned char gblBuf[512];
cb->notifyHashingInfo(fent.name) ;
#ifdef FIM_DEBUG
std::cerr << "File to hash = " << f_hash << std::endl;
#endif

View File

@ -62,6 +62,14 @@ std::string FileIndexMonitor::findRealRoot(std::string base);
class NotifyBase ;
class DirContentToHash
{
public:
std::vector<FileEntry> fentries ;
std::string realpath ;
std::string dirpath ;
};
/******************************************************************************************
* FileIndexMonitor
@ -117,6 +125,7 @@ class FileIndexMonitor: public CacheSource, public RsThread
/* the mutex should be locked before calling... these. */
std::string locked_findRealRoot(std::string base) const;
void hashFiles(const std::vector<DirContentToHash>& to_hash) ;
bool hashFile(std::string path, FileEntry &fi); /* To Implement */
/* data */