From d86b89b15acd2428603ad259e7b25ff6ea722360 Mon Sep 17 00:00:00 2001 From: mr-alice Date: Wed, 27 Jul 2016 21:22:59 +0200 Subject: [PATCH] fixed compilation/running of directory updater --- .../src/file_sharing/directory_storage.cc | 166 ++++++++++++------ .../src/file_sharing/directory_storage.h | 16 +- .../src/file_sharing/directory_updater.cc | 24 ++- .../src/file_sharing/directory_updater.h | 8 +- libretroshare/src/file_sharing/hash_cache.cc | 124 +++++++++++++ libretroshare/src/file_sharing/hash_cache.h | 65 ++++--- 6 files changed, 309 insertions(+), 94 deletions(-) diff --git a/libretroshare/src/file_sharing/directory_storage.cc b/libretroshare/src/file_sharing/directory_storage.cc index a955df832..813b0c38d 100644 --- a/libretroshare/src/file_sharing/directory_storage.cc +++ b/libretroshare/src/file_sharing/directory_storage.cc @@ -22,8 +22,9 @@ class InternalFileHierarchyStorage class FileStorageNode { public: - static const uint32_t TYPE_FILE = 0x0001 ; - static const uint32_t TYPE_DIR = 0x0002 ; + static const uint32_t TYPE_UNKNOWN = 0x0000 ; + static const uint32_t TYPE_FILE = 0x0001 ; + static const uint32_t TYPE_DIR = 0x0002 ; virtual ~FileStorageNode() {} virtual uint32_t type() const =0; @@ -45,7 +46,7 @@ class InternalFileHierarchyStorage class DirEntry: public FileStorageNode { public: - DirEntry(const std::string& name,DirectoryStorage::EntryIndex parent) : dir_name(name),parent_index(parent) {} + DirEntry(const std::string& name,DirectoryStorage::EntryIndex parent) : dir_name(name),parent_index(DirectoryStorage::NO_INDEX) {} virtual ~DirEntry() {} virtual uint32_t type() const { return FileStorageNode::TYPE_DIR ; } @@ -66,18 +67,15 @@ class InternalFileHierarchyStorage // high level modification routines - bool isIndexValid(DirectoryStorage::EntryIndex e) + bool isIndexValid(DirectoryStorage::EntryIndex e) const { return e < mNodes.size() && mNodes[e] != NULL ; } bool updateSubDirectoryList(const DirectoryStorage::EntryIndex& indx,const std::set& subdirs) { - if(indx >= mNodes.size() || mNodes[indx] == NULL) - return nodeAccessError("updateSubDirectoryList(): Node does not exist") ; - - if(mNodes[indx]->type() != FileStorageNode::TYPE_DIR) - return nodeAccessError("updateSubDirectoryList(): Node is not a directory") ; + if(!checkIndex(indx,FileStorageNode::TYPE_DIR)) + return false; DirEntry& d(*static_cast(mNodes[indx])) ; @@ -104,14 +102,11 @@ class InternalFileHierarchyStorage { // check that it's a directory - if(indx >= mNodes.size() || mNodes[indx] == NULL) - return nodeAccessError("removeDirectory(): Node does not exist") ; - - if(mNodes[indx]->type() != FileStorageNode::TYPE_DIR) - return nodeAccessError("removeDirectory(): Node is not a directory") ; + if(!checkIndex(indx,FileStorageNode::TYPE_DIR)) + return false; if(indx == 0) - return nodeAccessError("removeDirectory(): Cannot remove top level directory") ; + return nodeAccessError("checkIndex(): Cannot remove top level directory") ; // remove from parent @@ -125,13 +120,21 @@ class InternalFileHierarchyStorage return nodeAccessError("removeDirectory(): inconsistency!!") ; } + bool checkIndex(DirectoryStorage::EntryIndex indx,uint8_t type) const + { + if(mNodes.empty() || indx==DirectoryStorage::NO_INDEX || indx >= mNodes.size() || mNodes[indx] == NULL) + return nodeAccessError("checkIndex(): Node does not exist") ; + + if(mNodes[indx]->type() != type) + return nodeAccessError("checkIndex(): Node is of wrong type") ; + + return true; + } + bool updateSubFilesList(const DirectoryStorage::EntryIndex& indx,const std::set& subfiles,std::set& new_files) { - if(indx >= mNodes.size() || mNodes[indx] == NULL) - return nodeAccessError("updateSubFilesList(): Node does not exist") ; - - if(mNodes[indx]->type() != FileStorageNode::TYPE_DIR) - return nodeAccessError("updateSubFilesList(): Node is not a directory") ; + if(!checkIndex(indx,FileStorageNode::TYPE_DIR)) + return false; DirEntry& d(*static_cast(mNodes[indx])) ; new_files = subfiles ; @@ -155,14 +158,32 @@ class InternalFileHierarchyStorage } return true; } - void updateFile(const DirectoryStorage::EntryIndex& parent_dir,const RsFileHash& hash, const std::string& fname, const uint32_t modf_time) ; - void updateDirectory(const DirectoryStorage::EntryIndex& parent_dir,const std::string& dname) ; + bool updateHash(const DirectoryStorage::EntryIndex& file_index,const RsFileHash& hash) + { + if(!checkIndex(file_index,FileStorageNode::TYPE_FILE)) + return false; + + static_cast(mNodes[file_index])->file_hash = hash ; + return true; + } + bool updateFile(const DirectoryStorage::EntryIndex& file_index,const RsFileHash& hash, const std::string& fname,uint64_t size, const uint32_t modf_time) + { + if(!checkIndex(file_index,FileStorageNode::TYPE_FILE)) + return false; + + FileEntry& fe(*static_cast(mNodes[file_index])) ; + + fe.file_hash = hash; + fe.file_size = size; + fe.file_modtime = modf_time; + + return true; + } // file/dir access and modification bool findSubDirectory(DirectoryStorage::EntryIndex e,const std::string& s) const ; // returns true when s is the name of a sub-directory in the given entry e uint32_t mRoot ; - std::vector mNodes;// uses pointers to keep information about valid/invalid objects. void compress() ; // use empty space in the vector, mostly due to deleted entries. This is a complicated operation, mostly due to @@ -171,11 +192,25 @@ class InternalFileHierarchyStorage friend class DirectoryStorage ; // only class that can use this. - // low level stuff. Should normally not be used externally. + // Low level stuff. Should normally not be used externally. + const DirEntry *getDirEntry(DirectoryStorage::EntryIndex indx) const + { + if(!checkIndex(indx,FileStorageNode::TYPE_DIR)) + return NULL ; + + return static_cast(mNodes[indx]) ; + } + const FileEntry *getFileEntry(DirectoryStorage::EntryIndex indx) const + { + if(!checkIndex(indx,FileStorageNode::TYPE_FILE)) + return NULL ; + + return static_cast(mNodes[indx]) ; + } DirectoryStorage::EntryIndex getSubFileIndex(DirectoryStorage::EntryIndex parent_index,uint32_t file_tab_index) { - if(parent_index >= mNodes.size() || mNodes[parent_index] == NULL || mNodes[parent_index]->type() != FileStorageNode::TYPE_DIR) + if(!checkIndex(parent_index,FileStorageNode::TYPE_DIR)) return DirectoryStorage::NO_INDEX; if(static_cast(mNodes[parent_index])->subfiles.size() <= file_tab_index) @@ -185,7 +220,7 @@ class InternalFileHierarchyStorage } DirectoryStorage::EntryIndex getSubDirIndex(DirectoryStorage::EntryIndex parent_index,uint32_t dir_tab_index) { - if(parent_index >= mNodes.size() || mNodes[parent_index] == NULL || mNodes[parent_index]->type() != FileStorageNode::TYPE_DIR) + if(!checkIndex(parent_index,FileStorageNode::TYPE_DIR)) return DirectoryStorage::NO_INDEX; if(static_cast(mNodes[parent_index])->subdirs.size() <= dir_tab_index) @@ -203,7 +238,7 @@ class InternalFileHierarchyStorage { } private: - bool nodeAccessError(const std::string& s) + static bool nodeAccessError(const std::string& s) { std::cerr << "(EE) InternalDirectoryStructure: ERROR: " << s << std::endl; return false ; @@ -256,46 +291,58 @@ DirectoryStorage::FileIterator& DirectoryStorage::FileIterator::operator++() return *this; } -DirectoryStorage::EntryIndex DirectoryStorage::DirIterator::operator*() const -{ - return mStorage->getSubDirIndex(mParentIndex,mDirTabIndex) ; -} -DirectoryStorage::EntryIndex DirectoryStorage::FileIterator::operator*() const -{ - return mStorage->getSubFileIndex(mParentIndex,mFileTabIndex) ; -} -DirectoryStorage::DirIterator::operator bool() const -{ - return **this != DirectoryStorage::NO_INDEX; -} -DirectoryStorage::FileIterator::operator bool() const -{ - return **this != DirectoryStorage::NO_INDEX; -} +DirectoryStorage::EntryIndex DirectoryStorage::FileIterator::operator*() const { return mStorage->getSubFileIndex(mParentIndex,mFileTabIndex) ; } +DirectoryStorage::EntryIndex DirectoryStorage::DirIterator ::operator*() const { return mStorage->getSubDirIndex(mParentIndex,mDirTabIndex) ; } + +DirectoryStorage::FileIterator::operator bool() const { return **this != DirectoryStorage::NO_INDEX; } +DirectoryStorage::DirIterator ::operator bool() const { return **this != DirectoryStorage::NO_INDEX; } + +RsFileHash DirectoryStorage::FileIterator::hash() const { const InternalFileHierarchyStorage::FileEntry *f = mStorage->getFileEntry(**this) ; return f?(f->file_hash):RsFileHash(); } +uint64_t DirectoryStorage::FileIterator::size() const { const InternalFileHierarchyStorage::FileEntry *f = mStorage->getFileEntry(**this) ; return f?(f->file_size):0; } +std::string DirectoryStorage::FileIterator::name() const { const InternalFileHierarchyStorage::FileEntry *f = mStorage->getFileEntry(**this) ; return f?(f->file_name):std::string(); } +std::string DirectoryStorage::FileIterator::fullpath() const { const InternalFileHierarchyStorage::FileEntry *f = mStorage->getFileEntry(**this) ; return f?(f->file_name):std::string(); } +time_t DirectoryStorage::FileIterator::modtime() const { const InternalFileHierarchyStorage::FileEntry *f = mStorage->getFileEntry(**this) ; return f?(f->file_modtime):0; } /******************************************************************************************************************/ /* Directory Storage */ /******************************************************************************************************************/ -DirectoryStorage::DirIterator DirectoryStorage::root() +DirectoryStorage::DirectoryStorage(const std::string& local_file_name) + : mFileName(local_file_name), mDirStorageMtx("Directory storage "+local_file_name) { - return DirIterator(this,EntryIndex(0)) ; + mFileHierarchy = new InternalFileHierarchyStorage(); } -void DirectoryStorage::updateSubDirectoryList(const EntryIndex& indx,const std::set& subdirs) +DirectoryStorage::EntryIndex DirectoryStorage::root() const { - RS_STACK_MUTEX(mDirStorageMtx) ; - mFileHierarchy->updateSubDirectoryList(indx,subdirs) ; + return EntryIndex(0) ; } -void DirectoryStorage::updateSubFilesList(const EntryIndex& indx,const std::set& subfiles,std::set& new_files) + +bool DirectoryStorage::updateSubDirectoryList(const EntryIndex& indx,const std::set& subdirs) { RS_STACK_MUTEX(mDirStorageMtx) ; - mFileHierarchy->updateSubFilesList(indx,subfiles,new_files) ; + return mFileHierarchy->updateSubDirectoryList(indx,subdirs) ; } -void DirectoryStorage::removeDirectory(const EntryIndex& indx) +bool DirectoryStorage::updateSubFilesList(const EntryIndex& indx,const std::set& subfiles,std::set& new_files) { RS_STACK_MUTEX(mDirStorageMtx) ; - mFileHierarchy->removeDirectory(indx); + return mFileHierarchy->updateSubFilesList(indx,subfiles,new_files) ; +} +bool DirectoryStorage::removeDirectory(const EntryIndex& indx) +{ + RS_STACK_MUTEX(mDirStorageMtx) ; + return mFileHierarchy->removeDirectory(indx); +} + +bool DirectoryStorage::updateFile(const EntryIndex& index,const RsFileHash& hash,const std::string& fname, uint64_t size,time_t modf_time) +{ + RS_STACK_MUTEX(mDirStorageMtx) ; + return mFileHierarchy->updateFile(index,hash,fname,size,modf_time); +} +bool DirectoryStorage::updateHash(const EntryIndex& index,const RsFileHash& hash) +{ + RS_STACK_MUTEX(mDirStorageMtx) ; + return mFileHierarchy->updateHash(index,hash); } // static const uint8_t DIRECTORY_STORAGE_TAG_FILE_HASH = 0x01 ; @@ -321,3 +368,18 @@ void DirectoryStorage::save(const std::string& local_file_name) { // first write the header, than all fields. } + +/******************************************************************************************************************/ +/* Local Directory Storage */ +/******************************************************************************************************************/ + +void LocalDirectoryStorage::setSharedDirectoryList(const std::list& lst) +{ + RS_STACK_MUTEX(mDirStorageMtx) ; + mLocalDirs = lst ; +} +void LocalDirectoryStorage::getSharedDirectoryList(std::list& lst) +{ + RS_STACK_MUTEX(mDirStorageMtx) ; + lst = mLocalDirs ; +} diff --git a/libretroshare/src/file_sharing/directory_storage.h b/libretroshare/src/file_sharing/directory_storage.h index 90a0a889e..fe7307d6d 100644 --- a/libretroshare/src/file_sharing/directory_storage.h +++ b/libretroshare/src/file_sharing/directory_storage.h @@ -84,14 +84,14 @@ class DirectoryStorage InternalFileHierarchyStorage *mStorage ; }; - virtual DirIterator root() ; // returns the index of the root directory entry. + EntryIndex root() const ; // returns the index of the root directory entry. - void updateSubDirectoryList(const EntryIndex& indx,const std::set& subdirs) ; - void updateSubFilesList(const EntryIndex& indx,const std::set& subfiles,std::set& new_files) ; - void removeDirectory(const EntryIndex& indx) ; + bool updateSubDirectoryList(const EntryIndex& indx,const std::set& subdirs) ; + bool updateSubFilesList(const EntryIndex& indx,const std::set& subfiles,std::set& new_files) ; + bool removeDirectory(const EntryIndex& indx) ; - void updateFile(const EntryIndex& parent_dir,const RsFileHash& hash, const std::string& fname, const uint32_t modf_time) ; - void updateDirectory(const EntryIndex& parent_dir,const std::string& dname) ; + bool updateFile(const EntryIndex& index,const RsFileHash& hash, const std::string& fname, uint64_t size, time_t modf_time) ; + bool updateHash(const EntryIndex& index,const RsFileHash& hash); void cleanup(); @@ -105,7 +105,9 @@ class DirectoryStorage // storage of internal structure. Totally hidden from the outside. EntryIndex is simply the index of the entry in the vector. InternalFileHierarchyStorage *mFileHierarchy ; + std::string mFileName; + protected: RsMutex mDirStorageMtx ; }; @@ -119,7 +121,7 @@ public: class LocalDirectoryStorage: public DirectoryStorage { public: - LocalDirectoryStorage() ; + LocalDirectoryStorage(const std::string& fname) : DirectoryStorage(fname) {} virtual ~LocalDirectoryStorage() {} void setSharedDirectoryList(const std::list& lst) ; diff --git a/libretroshare/src/file_sharing/directory_updater.cc b/libretroshare/src/file_sharing/directory_updater.cc index c80968d8b..3d6c5bb74 100644 --- a/libretroshare/src/file_sharing/directory_updater.cc +++ b/libretroshare/src/file_sharing/directory_updater.cc @@ -10,9 +10,10 @@ void RemoteDirectoryUpdater::tick() // use the stored iterator } -LocalDirectoryUpdater::LocalDirectoryUpdater(HashCache *hc) +LocalDirectoryUpdater::LocalDirectoryUpdater(HashStorage *hc) : mHashCache(hc) { + mSharedDirectories = new LocalDirectoryStorage("local_storage.txt"); } void LocalDirectoryUpdater::tick() @@ -35,11 +36,11 @@ void LocalDirectoryUpdater::tick() // make sure that entries in stored_dir_it are the same than paths in real_dir_it, and in the same order. - mSharedDirectories->updateSubDirectoryList(*mSharedDirectories->root(),sub_dir_list) ; + mSharedDirectories->updateSubDirectoryList(mSharedDirectories->root(),sub_dir_list) ; // now for each of them, go recursively and match both files and dirs - DirectoryStorage::DirIterator stored_dir_it(mSharedDirectories->root()) ; + DirectoryStorage::DirIterator stored_dir_it(mSharedDirectories,mSharedDirectories->root()) ; for(std::list::const_iterator real_dir_it(shared_directory_list.begin());real_dir_it!=shared_directory_list.end();++real_dir_it, ++stored_dir_it) recursUpdateSharedDir(real_dir_it->filename, *stored_dir_it) ; @@ -66,7 +67,7 @@ void LocalDirectoryUpdater::recursUpdateSharedDir(const std::string& cumulated_p std::set subfiles ; std::set subdirs ; - while(dirIt.readdir()) + for(;dirIt.isValid();dirIt.next()) { switch(dirIt.file_type()) { @@ -91,18 +92,27 @@ void LocalDirectoryUpdater::recursUpdateSharedDir(const std::string& cumulated_p // now go through list of subfiles and request the hash to hashcache - for(DirectoryStorage::FileIterator dit(indx);dit;++dit) + for(DirectoryStorage::FileIterator dit(mSharedDirectories,indx);dit;++dit) { // ask about the hash. If not present, ask HashCache. If not present, or different, the callback will update it. - mHashCache->requestHash(dit.fullpath(),dit.size(),dit.modtime(),dit.hash(),this) ; + RsFileHash hash ; + + if(mHashCache->requestHash(dit.fullpath(),dit.size(),dit.modtime(),hash,this,*dit) && dit.hash() != hash) + mSharedDirectories->updateHash(*dit,hash); } // go through the list of sub-dirs and recursively update - DirectoryStorage::DirIterator stored_dir_it(indx) ; + DirectoryStorage::DirIterator stored_dir_it(mSharedDirectories,indx) ; for(std::set::const_iterator real_dir_it(subdirs.begin());real_dir_it!=subdirs.end();++real_dir_it, ++stored_dir_it) recursUpdateSharedDir(*real_dir_it, *stored_dir_it) ; } +void LocalDirectoryUpdater::hash_callback(uint32_t client_param, const std::string& name, const RsFileHash& hash, uint64_t size) +{ + if(!mSharedDirectories->updateHash(DirectoryStorage::EntryIndex(client_param),hash)) + std::cerr << "(EE) Cannot update file. Something's wrong." << std::endl; +} + diff --git a/libretroshare/src/file_sharing/directory_updater.h b/libretroshare/src/file_sharing/directory_updater.h index 74795ae14..b70164bdd 100644 --- a/libretroshare/src/file_sharing/directory_updater.h +++ b/libretroshare/src/file_sharing/directory_updater.h @@ -20,20 +20,20 @@ class DirectoryUpdater // }; -class LocalDirectoryUpdater: public DirectoryUpdater, public HashCacheClient +class LocalDirectoryUpdater: public DirectoryUpdater, public HashStorageClient { public: - LocalDirectoryUpdater(HashCache *hash_cache) ; + LocalDirectoryUpdater(HashStorage *hash_cache) ; virtual ~LocalDirectoryUpdater() {} virtual void tick() ; protected: - virtual void hash_callback(const std::string& full_name,const RsFileHash& hash) ; + virtual void hash_callback(uint32_t client_param, const std::string& name, const RsFileHash& hash, uint64_t size); void recursUpdateSharedDir(const std::string& cumulated_path,DirectoryStorage::EntryIndex indx); private: - HashCache *mHashCache ; + HashStorage *mHashCache ; LocalDirectoryStorage *mSharedDirectories ; }; diff --git a/libretroshare/src/file_sharing/hash_cache.cc b/libretroshare/src/file_sharing/hash_cache.cc index e69de29bb..25af17984 100644 --- a/libretroshare/src/file_sharing/hash_cache.cc +++ b/libretroshare/src/file_sharing/hash_cache.cc @@ -0,0 +1,124 @@ +#include "util/rsdir.h" +#include "hash_cache.h" + +#define HASHSTORAGE_DEBUG 1 + +HashStorage::HashStorage(const std::string& save_file_name) + : mFilePath(save_file_name), mHashMtx("Hash Storage mutex") +{ +} + +void HashStorage::data_tick() +{ + std::cerr << "Ticking hash thread." << std::endl; + + FileHashJob job; + + { + RS_STACK_MUTEX(mHashMtx) ; + + if(mFilesToHash.empty()) + return ; + + job = mFilesToHash.begin()->second ; + } + + std::cerr << "Hashing file " << job.full_path << "..." ; std::cerr.flush(); + + RsFileHash hash; + uint64_t size ; + + if(!RsDirUtil::getFileHash(job.full_path, hash,size, this)) + { + std::cerr << "ERROR" << std::endl; + return; + } + // update the hash storage + + + // call the client + + job.client->hash_callback(job.client_param, job.full_path, hash, size); + + std::cerr << "done."<< std::endl; + + if(mFilesToHash.empty()) + { + std::cerr << "Starting hashing thread." << std::endl; + fullstop(); + std::cerr << "done." << std::endl; + } +} + +bool HashStorage::requestHash(const std::string& full_path,uint64_t size,time_t mod_time,RsFileHash& known_hash,HashStorageClient *c,uint32_t client_param) +{ + // check if the hash is up to date w.r.t. cache. + + RS_STACK_MUTEX(mHashMtx) ; + + time_t now = time(NULL) ; + std::map::iterator it = mFiles.find(full_path) ; + + if(it != mFiles.end() && (uint64_t)mod_time == it->second.modf_stamp && size == it->second.size) + { + it->second.time_stamp = now ; +#ifdef HASHCACHE_DEBUG + std::cerr << "Found in cache." << std::endl ; +#endif + return true ; + } + + // we need to schedule a re-hashing + + if(mFilesToHash.find(full_path) != mFilesToHash.end()) + return false ; + + FileHashJob job ; + + job.client = c ; + job.client_param = client_param ; + job.full_path = full_path ; + + mFilesToHash[full_path] = job; + + if(!isRunning()) + { + std::cerr << "Starting hashing thread." << std::endl; + start() ; + } + + return false; +} + +void HashStorage::clean() +{ +#ifdef HASHSTORAGE_DEBUG + std::cerr << "Cleaning HashStorage..." << std::endl ; +#endif + time_t now = time(NULL) ; + time_t duration = mMaxStorageDurationDays * 24 * 3600 ; // seconds + +#ifdef HASHSTORAGE_DEBUG + std::cerr << "cleaning hash cache." << std::endl ; +#endif + + for(std::map::iterator it(mFiles.begin());it!=mFiles.end();) + if(it->second.time_stamp + duration < (uint64_t)now) + { +#ifdef HASHSTORAGE_DEBUG + std::cerr << " Entry too old: " << it->first << ", ts=" << it->second.time_stamp << std::endl ; +#endif + std::map::iterator tmp(it) ; + ++tmp ; + mFiles.erase(it) ; + it=tmp ; + mChanged = true ; + } + else + ++it ; + +#ifdef HASHSTORAGE_DEBUG + std::cerr << "Done." << std::endl; +#endif +} + diff --git a/libretroshare/src/file_sharing/hash_cache.h b/libretroshare/src/file_sharing/hash_cache.h index f867f6109..fa73797c2 100644 --- a/libretroshare/src/file_sharing/hash_cache.h +++ b/libretroshare/src/file_sharing/hash_cache.h @@ -4,61 +4,78 @@ #include "util/rsthreads.h" #include "retroshare/rsfiles.h" -class HashCacheClient +class HashStorageClient { public: - virtual void hash_callback(const std::string& full_path,const RsFileHash& hash) ; + HashStorageClient() {} + virtual ~HashStorageClient() {} + + virtual void hash_callback(uint32_t client_param, const std::string& name, const RsFileHash& hash, uint64_t size)=0; }; -class FileHashingThread: public RsTickingThread +class HashStorage: public RsTickingThread { public: - FileHashingThread() {} + HashStorage(const std::string& save_file_name) ; - virtual void data_tick() ; -}; + /*! + * \brief requestHash Requests the hash for the given file, assuming size and mod_time are the same. + * + * \param full_path Full path to reach the file + * \param size Actual file size + * \param mod_time Actual file modification time + * \param known_hash Returned hash for the file. + * \param c Hash cache client to which the hash should be sent once calculated + * \param client_param Param to be passed to the client callback + * + * \return true if the supplied hash info is up to date. + */ + bool requestHash(const std::string& full_path, uint64_t size, time_t mod_time, RsFileHash& known_hash, HashStorageClient *c, uint32_t client_param) ; -class HashCache -{ -public: - HashCache(const std::string& save_file_name) ; - - bool requestHash(const std::string& full_path,uint64_t size,time_t mod_time,const RsFileHash& known_hash,HashCacheClient *c) ; - - struct HashCacheInfo + struct HashStorageInfo { std::string filename ; uint64_t size ; - uint32_t time_stamp ; + uint32_t time_stamp ; // last time the hash was tested/requested uint32_t modf_stamp ; RsFileHash hash ; } ; // interaction with GUI, called from p3FileLists - void setRememberHashFilesDuration(uint32_t days) { mMaxCacheDurationDays = days ; } - uint32_t rememberHashFilesDuration() const { return mMaxCacheDurationDays ; } + void setRememberHashFilesDuration(uint32_t days) { mMaxStorageDurationDays = days ; } + uint32_t rememberHashFilesDuration() const { return mMaxStorageDurationDays ; } void clear() { mFiles.clear(); } bool empty() const { return mFiles.empty() ; } + // Functions called by the thread + + virtual void data_tick() ; private: void clean() ; void save() ; void load() ; - // threaded stuff - FileHashingThread mHashingThread ; - RsMutex mHashMtx ; - // Local configuration and storage - uint32_t mMaxCacheDurationDays ; // maximum duration of un-requested cache entries - std::map mFiles ; + uint32_t mMaxStorageDurationDays ; // maximum duration of un-requested cache entries + std::map mFiles ; // stored as (full_path, hash_info) std::string mFilePath ; bool mChanged ; + struct FileHashJob + { + std::string full_path; + HashStorageClient *client; + uint32_t client_param ; + }; + // current work - std::map mFilesToHash ; + std::map mFilesToHash ; + + // thread/mutex stuff + + RsMutex mHashMtx ; };