2018-05-21 20:50:38 +02:00
/*******************************************************************************
* libretroshare / src / file_sharing : hash_cache . h *
* *
* libretroshare : retroshare core library *
* *
* Copyright 2018 by Mr . Alice < mralice @ users . sourceforge . net > *
* *
* This program is free software : you can redistribute it and / or modify *
2018-05-28 22:03:39 +02:00
* it under the terms of the GNU Lesser General Public License as *
2018-05-21 20:50:38 +02:00
* 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 *
2018-05-28 22:03:39 +02:00
* GNU Lesser General Public License for more details . *
2018-05-21 20:50:38 +02:00
* *
2018-05-28 22:03:39 +02:00
* You should have received a copy of the GNU Lesser General Public License *
2018-05-21 20:50:38 +02:00
* along with this program . If not , see < https : //www.gnu.org/licenses/>. *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2016-09-13 00:01:26 +02:00
2016-07-21 00:16:12 -04:00
# pragma once
# include <map>
# include "util/rsthreads.h"
2016-07-23 22:14:43 -04:00
# include "retroshare/rsfiles.h"
2018-10-07 01:34:05 +02:00
# include "util/rstime.h"
2016-07-23 22:14:43 -04:00
2016-09-22 21:47:58 +02:00
/*!
* \ 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 .
*/
2016-07-27 21:22:59 +02:00
class HashStorageClient
2016-07-23 22:14:43 -04:00
{
public :
2016-07-27 21:22:59 +02:00
HashStorageClient ( ) { }
virtual ~ HashStorageClient ( ) { }
2016-07-23 22:14:43 -04:00
2016-09-18 18:34:39 +02:00
// the result of the hashing info is sent to this method
2016-07-27 21:22:59 +02:00
virtual void hash_callback ( uint32_t client_param , const std : : string & name , const RsFileHash & hash , uint64_t size ) = 0 ;
2016-09-18 18:34:39 +02:00
// 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 ;
2016-07-23 22:14:43 -04:00
} ;
2016-07-21 00:16:12 -04:00
2016-07-27 21:22:59 +02:00
class HashStorage : public RsTickingThread
2016-07-18 21:52:44 -04:00
{
2016-07-21 00:16:12 -04:00
public :
2017-07-21 12:39:05 +02:00
explicit HashStorage ( const std : : string & save_file_name ) ;
2016-07-27 21:22:59 +02:00
/*!
* \ 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
2016-09-22 21:47:58 +02:00
* \ param client_param Param to be passed to the client callback . Useful if the client needs a file ID .
2016-07-27 21:22:59 +02:00
*
* \ return true if the supplied hash info is up to date .
*/
2018-10-07 01:34:05 +02:00
bool requestHash ( const std : : string & full_path , uint64_t size , rstime_t mod_time , RsFileHash & known_hash , HashStorageClient * c , uint32_t client_param ) ;
2016-07-27 21:22:59 +02:00
struct HashStorageInfo
2016-07-21 00:16:12 -04:00
{
2016-08-09 15:07:02 +02:00
std : : string filename ; // full path of the file
2016-07-21 00:16:12 -04:00
uint64_t size ;
2016-07-27 21:22:59 +02:00
uint32_t time_stamp ; // last time the hash was tested/requested
2016-07-21 00:16:12 -04:00
uint32_t modf_stamp ;
RsFileHash hash ;
} ;
// interaction with GUI, called from p3FileLists
2016-09-22 21:47:58 +02:00
void setRememberHashFilesDuration ( uint32_t days ) { mMaxStorageDurationDays = days ; } // duration for which the hash is kept even if the file is not shared anymore
2016-07-27 21:22:59 +02:00
uint32_t rememberHashFilesDuration ( ) const { return mMaxStorageDurationDays ; }
2016-09-22 21:47:58 +02:00
void clear ( ) { mFiles . clear ( ) ; mChanged = true ; } // drop all known hashes. Not something to do, except if you want to rehash the entire database
2016-07-23 22:14:43 -04:00
bool empty ( ) const { return mFiles . empty ( ) ; }
2017-09-10 22:07:36 +02:00
void togglePauseHashingProcess ( ) ;
bool hashingProcessPaused ( ) ;
2016-07-21 00:16:12 -04:00
2016-07-27 21:22:59 +02:00
// Functions called by the thread
virtual void data_tick ( ) ;
2016-08-09 15:07:02 +02:00
friend std : : ostream & operator < < ( std : : ostream & o , const HashStorageInfo & info ) ;
2016-07-21 00:16:12 -04:00
private :
2016-09-22 21:47:58 +02:00
/*!
* \ brief clean
* This function is responsible for removing old hashes , etc
*/
2016-07-21 00:16:12 -04:00
void clean ( ) ;
2019-04-06 00:15:01 +02:00
void startHashThread ( ) ;
void stopHashThread ( ) ;
2016-09-22 21:47:58 +02:00
// loading/saving the entire hash database to a file
2016-09-02 21:49:43 +02:00
void locked_save ( ) ;
2016-09-26 21:12:13 +02:00
bool locked_load ( ) ;
bool try_load_import_old_hash_cache ( ) ;
2016-07-21 00:16:12 -04:00
2016-08-09 15:07:02 +02:00
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 ;
2016-07-21 00:16:12 -04:00
// Local configuration and storage
2016-07-27 21:22:59 +02:00
uint32_t mMaxStorageDurationDays ; // maximum duration of un-requested cache entries
2016-09-18 18:34:39 +02:00
std : : map < std : : string , HashStorageInfo > mFiles ; // stored as (full_path, hash_info)
2016-09-22 21:47:58 +02:00
std : : string mFilePath ; // file where the hash database is stored
2016-07-21 00:16:12 -04:00
bool mChanged ;
2017-09-10 22:07:36 +02:00
bool mHashingProcessPaused ;
2016-07-21 00:16:12 -04:00
2016-07-27 21:22:59 +02:00
struct FileHashJob
{
2017-10-02 22:23:26 +02:00
std : : string full_path ; // canonicalized file name (means: symlinks removed, loops removed, etc)
std : : string real_path ; // path supplied by the client.
2016-09-15 21:40:53 +02:00
uint64_t size ;
2016-07-27 21:22:59 +02:00
HashStorageClient * client ;
uint32_t client_param ;
2018-10-07 01:34:05 +02:00
rstime_t ts ;
2016-07-27 21:22:59 +02:00
} ;
2016-07-21 00:16:12 -04:00
// current work
2016-07-27 21:22:59 +02:00
std : : map < std : : string , FileHashJob > mFilesToHash ;
// thread/mutex stuff
RsMutex mHashMtx ;
2016-07-28 00:48:28 +02:00
bool mRunning ;
2016-09-23 21:56:41 +02:00
uint64_t mHashCounter ;
2016-08-16 13:46:55 +02:00
uint32_t mInactivitySleepTime ;
2016-09-15 21:40:53 +02:00
uint64_t mTotalSizeToHash ;
uint64_t mTotalHashedSize ;
uint64_t mTotalFilesToHash ;
2018-10-07 01:34:05 +02:00
rstime_t mLastSaveTime ;
2017-10-29 21:24:34 +01:00
// The following is used to estimate hashing speed.
double mHashingTime ;
uint64_t mHashedBytes ;
uint32_t mCurrentHashingSpeed ; // in MB/s
2016-07-18 21:52:44 -04:00
} ;