/******************************************************************************* * libretroshare/src/file_sharing: hash_cache.h * * * * libretroshare: retroshare core library * * * * Copyright 2018 by Mr.Alice * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as * * published by the Free Software Foundation, either version 3 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU Lesser General Public License for more details. * * * * You should have received a copy of the GNU Lesser General Public License * * along with this program. If not, see . * * * ******************************************************************************/ #pragma once #include #include "util/rsthreads.h" #include "retroshare/rsfiles.h" #include "util/rstime.h" /*! * \brief The HashStorageClient class * Used by clients of the hash cache for receiving hash results when done. This is asynchrone of course since hashing * might be quite costly. */ class HashStorageClient { public: HashStorageClient() {} virtual ~HashStorageClient() {} // the result of the hashing info is sent to this method virtual void hash_callback(uint32_t client_param, const std::string& name, const RsFileHash& hash, uint64_t size)=0; // this method is used to check that the client param is still valid just before hashing. This avoids hashing files // that are still in queue while removed from shared lists. virtual bool hash_confirm(uint32_t client_param)=0 ; }; class HashStorage: public RsTickingThread { public: explicit HashStorage(const std::string& save_file_name) ; /*! * \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. Useful if the client needs a file ID. * * \return true if the supplied hash info is up to date. */ bool requestHash(const std::string& full_path, uint64_t size, rstime_t mod_time, RsFileHash& known_hash, HashStorageClient *c, uint32_t client_param) ; struct HashStorageInfo { std::string filename ; // full path of the file uint64_t size ; 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) { mMaxStorageDurationDays = days ; } // duration for which the hash is kept even if the file is not shared anymore uint32_t rememberHashFilesDuration() const { return mMaxStorageDurationDays ; } void clear() { mFiles.clear(); mChanged=true; } // drop all known hashes. Not something to do, except if you want to rehash the entire database bool empty() const { return mFiles.empty() ; } void togglePauseHashingProcess() ; bool hashingProcessPaused(); void threadTick() override; /// @see RsTickingThread friend std::ostream& operator<<(std::ostream& o,const HashStorageInfo& info) ; private: /*! * \brief clean * This function is responsible for removing old hashes, etc */ void clean() ; void startHashThread(); void stopHashThread(); // loading/saving the entire hash database to a file void locked_save() ; bool locked_load() ; bool try_load_import_old_hash_cache(); bool readHashStorageInfo(const unsigned char *data,uint32_t total_size,uint32_t& offset,HashStorageInfo& info) const; bool writeHashStorageInfo(unsigned char *& data,uint32_t& total_size,uint32_t& offset,const HashStorageInfo& info) const; // Local configuration and storage uint32_t mMaxStorageDurationDays ; // maximum duration of un-requested cache entries std::map mFiles ; // stored as (full_path, hash_info) std::string mFilePath ; // file where the hash database is stored bool mChanged ; bool mHashingProcessPaused ; struct FileHashJob { std::string full_path; // canonicalized file name (means: symlinks removed, loops removed, etc) std::string real_path; // path supplied by the client. uint64_t size ; HashStorageClient *client; uint32_t client_param ; rstime_t ts; }; // current work std::map mFilesToHash ; // thread/mutex stuff RsMutex mHashMtx ; bool mRunning; uint64_t mHashCounter; uint32_t mInactivitySleepTime ; uint64_t mTotalSizeToHash ; uint64_t mTotalHashedSize ; uint64_t mTotalFilesToHash ; rstime_t mLastSaveTime ; // The following is used to estimate hashing speed. double mHashingTime ; uint64_t mHashedBytes ; uint32_t mCurrentHashingSpeed ; // in MB/s };