added comments in the file lists code. Removed unused functions. Added a few missing mutexes.

This commit is contained in:
mr-alice 2016-09-22 21:47:58 +02:00
parent 7f99bc2b70
commit 0cc4ebd89c
7 changed files with 108 additions and 45 deletions

View File

@ -142,14 +142,18 @@ bool InternalFileHierarchyStorage::updateSubDirectoryList(const DirectoryStorage
for(uint32_t i=0;i<d.subdirs.size();) for(uint32_t i=0;i<d.subdirs.size();)
if(subdirs.find(static_cast<DirEntry*>(mNodes[d.subdirs[i]])->dir_name) == subdirs.end()) if(subdirs.find(static_cast<DirEntry*>(mNodes[d.subdirs[i]])->dir_name) == subdirs.end())
{ {
#ifdef DEBUG_DIRECTORY_STORAGE
std::cerr << "[directory storage] Removing subdirectory " << static_cast<DirEntry*>(mNodes[d.subdirs[i]])->dir_name << " with index " << d.subdirs[i] << std::endl; std::cerr << "[directory storage] Removing subdirectory " << static_cast<DirEntry*>(mNodes[d.subdirs[i]])->dir_name << " with index " << d.subdirs[i] << std::endl;
#endif
if( !removeDirectory(d.subdirs[i])) if( !removeDirectory(d.subdirs[i]))
i++ ; i++ ;
} }
else else
{ {
#ifdef DEBUG_DIRECTORY_STORAGE
std::cerr << "[directory storage] Keeping existing subdirectory " << static_cast<DirEntry*>(mNodes[d.subdirs[i]])->dir_name << " with index " << d.subdirs[i] << std::endl; std::cerr << "[directory storage] Keeping existing subdirectory " << static_cast<DirEntry*>(mNodes[d.subdirs[i]])->dir_name << " with index " << d.subdirs[i] << std::endl;
#endif
should_create.erase(static_cast<DirEntry*>(mNodes[d.subdirs[i]])->dir_name) ; should_create.erase(static_cast<DirEntry*>(mNodes[d.subdirs[i]])->dir_name) ;
++i; ++i;
@ -157,7 +161,9 @@ bool InternalFileHierarchyStorage::updateSubDirectoryList(const DirectoryStorage
for(std::map<std::string,time_t>::const_iterator it(should_create.begin());it!=should_create.end();++it) for(std::map<std::string,time_t>::const_iterator it(should_create.begin());it!=should_create.end();++it)
{ {
#ifdef DEBUG_DIRECTORY_STORAGE
std::cerr << "[directory storage] adding new subdirectory " << it->first << " at index " << mNodes.size() << std::endl; std::cerr << "[directory storage] adding new subdirectory " << it->first << " at index " << mNodes.size() << std::endl;
#endif
DirEntry *de = new DirEntry(it->first) ; DirEntry *de = new DirEntry(it->first) ;
@ -258,7 +264,9 @@ bool InternalFileHierarchyStorage::updateSubFilesList(const DirectoryStorage::En
if(it == subfiles.end()) // file does not exist anymore => delete if(it == subfiles.end()) // file does not exist anymore => delete
{ {
#ifdef DEBUG_DIRECTORY_STORAGE
std::cerr << "[directory storage] removing non existing file " << f.file_name << " at index " << d.subfiles[i] << std::endl; std::cerr << "[directory storage] removing non existing file " << f.file_name << " at index " << d.subfiles[i] << std::endl;
#endif
delete mNodes[d.subfiles[i]] ; delete mNodes[d.subfiles[i]] ;
mNodes[d.subfiles[i]] = NULL ; mNodes[d.subfiles[i]] = NULL ;
@ -281,7 +289,9 @@ bool InternalFileHierarchyStorage::updateSubFilesList(const DirectoryStorage::En
for(std::map<std::string,DirectoryStorage::FileTS>::const_iterator it(new_files.begin());it!=new_files.end();++it) for(std::map<std::string,DirectoryStorage::FileTS>::const_iterator it(new_files.begin());it!=new_files.end();++it)
{ {
#ifdef DEBUG_DIRECTORY_STORAGE
std::cerr << "[directory storage] adding new file " << it->first << " at index " << mNodes.size() << std::endl; std::cerr << "[directory storage] adding new file " << it->first << " at index " << mNodes.size() << std::endl;
#endif
d.subfiles.push_back(mNodes.size()) ; d.subfiles.push_back(mNodes.size()) ;
mNodes.push_back(new FileEntry(it->first,it->second.size,it->second.modtime)); mNodes.push_back(new FileEntry(it->first,it->second.size,it->second.modtime));
@ -297,8 +307,9 @@ bool InternalFileHierarchyStorage::updateHash(const DirectoryStorage::EntryIndex
std::cerr << "[directory storage] (EE) cannot update file at index " << file_index << ". Not a valid index, or not a file." << std::endl; std::cerr << "[directory storage] (EE) cannot update file at index " << file_index << ". Not a valid index, or not a file." << std::endl;
return false; return false;
} }
#ifdef DEBUG_DIRECTORY_STORAGE
std::cerr << "[directory storage] updating hash at index " << file_index << ", hash=" << hash << std::endl; std::cerr << "[directory storage] updating hash at index " << file_index << ", hash=" << hash << std::endl;
#endif
RsFileHash& old_hash (static_cast<FileEntry*>(mNodes[file_index])->file_hash) ; RsFileHash& old_hash (static_cast<FileEntry*>(mNodes[file_index])->file_hash) ;
mFileHashes[hash] = file_index ; mFileHashes[hash] = file_index ;
@ -317,7 +328,9 @@ bool InternalFileHierarchyStorage::updateFile(const DirectoryStorage::EntryIndex
FileEntry& fe(*static_cast<FileEntry*>(mNodes[file_index])) ; FileEntry& fe(*static_cast<FileEntry*>(mNodes[file_index])) ;
#ifdef DEBUG_DIRECTORY_STORAGE
std::cerr << "[directory storage] updating file entry at index " << file_index << ", name=" << fe.file_name << " size=" << fe.file_size << ", hash=" << fe.file_hash << std::endl; std::cerr << "[directory storage] updating file entry at index " << file_index << ", name=" << fe.file_name << " size=" << fe.file_size << ", hash=" << fe.file_hash << std::endl;
#endif
fe.file_hash = hash; fe.file_hash = hash;
fe.file_size = size; fe.file_size = size;
@ -358,7 +371,9 @@ bool InternalFileHierarchyStorage::updateDirEntry(const DirectoryStorage::EntryI
} }
DirEntry& d(*static_cast<DirEntry*>(mNodes[indx])) ; DirEntry& d(*static_cast<DirEntry*>(mNodes[indx])) ;
#ifdef DEBUG_DIRECTORY_STORAGE
std::cerr << "Updating dir entry: name=\"" << dir_name << "\", most_recent_time=" << most_recent_time << ", modtime=" << dir_modtime << std::endl; std::cerr << "Updating dir entry: name=\"" << dir_name << "\", most_recent_time=" << most_recent_time << ", modtime=" << dir_modtime << std::endl;
#endif
d.dir_most_recent_time = most_recent_time; d.dir_most_recent_time = most_recent_time;
d.dir_modtime = dir_modtime; d.dir_modtime = dir_modtime;
@ -375,7 +390,9 @@ bool InternalFileHierarchyStorage::updateDirEntry(const DirectoryStorage::EntryI
// check that all subdirs already exist. If not, create. // check that all subdirs already exist. If not, create.
for(uint32_t i=0;i<subdirs_hash.size();++i) for(uint32_t i=0;i<subdirs_hash.size();++i)
{ {
#ifdef DEBUG_DIRECTORY_STORAGE
std::cerr << " subdir hash = " << subdirs_hash[i] << ": " ; std::cerr << " subdir hash = " << subdirs_hash[i] << ": " ;
#endif
std::map<RsFileHash,DirectoryStorage::EntryIndex>::iterator it = existing_subdirs.find(subdirs_hash[i]) ; std::map<RsFileHash,DirectoryStorage::EntryIndex>::iterator it = existing_subdirs.find(subdirs_hash[i]) ;
DirectoryStorage::EntryIndex dir_index = 0; DirectoryStorage::EntryIndex dir_index = 0;
@ -384,7 +401,9 @@ bool InternalFileHierarchyStorage::updateDirEntry(const DirectoryStorage::EntryI
{ {
dir_index = it->second ; dir_index = it->second ;
#ifdef DEBUG_DIRECTORY_STORAGE
std::cerr << " already exists, at index " << dir_index << std::endl; std::cerr << " already exists, at index " << dir_index << std::endl;
#endif
existing_subdirs.erase(it) ; existing_subdirs.erase(it) ;
} }
@ -401,7 +420,9 @@ bool InternalFileHierarchyStorage::updateDirEntry(const DirectoryStorage::EntryI
mDirHashes[subdirs_hash[i]] = dir_index ; mDirHashes[subdirs_hash[i]] = dir_index ;
#ifdef DEBUG_DIRECTORY_STORAGE
std::cerr << " created, at new index " << dir_index << std::endl; std::cerr << " created, at new index " << dir_index << std::endl;
#endif
} }
d.subdirs.push_back(dir_index) ; d.subdirs.push_back(dir_index) ;
@ -411,7 +432,9 @@ bool InternalFileHierarchyStorage::updateDirEntry(const DirectoryStorage::EntryI
for(std::map<RsFileHash,DirectoryStorage::EntryIndex>::const_iterator it = existing_subdirs.begin();it!=existing_subdirs.end();++it) for(std::map<RsFileHash,DirectoryStorage::EntryIndex>::const_iterator it = existing_subdirs.begin();it!=existing_subdirs.end();++it)
{ {
#ifdef DEBUG_DIRECTORY_STORAGE
std::cerr << " removing existing subfile that is not in the dirctory anymore: name=" << it->first << " index=" << it->second << std::endl; std::cerr << " removing existing subfile that is not in the dirctory anymore: name=" << it->first << " index=" << it->second << std::endl;
#endif
if(!checkIndex(it->second,FileStorageNode::TYPE_DIR)) if(!checkIndex(it->second,FileStorageNode::TYPE_DIR))
{ {
@ -436,13 +459,17 @@ bool InternalFileHierarchyStorage::updateDirEntry(const DirectoryStorage::EntryI
const FileEntry& f(subfiles_array[i]) ; const FileEntry& f(subfiles_array[i]) ;
DirectoryStorage::EntryIndex file_index ; DirectoryStorage::EntryIndex file_index ;
#ifdef DEBUG_DIRECTORY_STORAGE
std::cerr << " subfile name = " << subfiles_array[i].file_name << ": " ; std::cerr << " subfile name = " << subfiles_array[i].file_name << ": " ;
#endif
if(it != existing_subfiles.end() && mNodes[it->second] != NULL && mNodes[it->second]->type() == FileStorageNode::TYPE_FILE) if(it != existing_subfiles.end() && mNodes[it->second] != NULL && mNodes[it->second]->type() == FileStorageNode::TYPE_FILE)
{ {
file_index = it->second ; file_index = it->second ;
#ifdef DEBUG_DIRECTORY_STORAGE
std::cerr << " already exists, at index " << file_index << std::endl; std::cerr << " already exists, at index " << file_index << std::endl;
#endif
if(!updateFile(file_index,f.file_hash,f.file_name,f.file_size,f.file_modtime)) if(!updateFile(file_index,f.file_hash,f.file_name,f.file_size,f.file_modtime))
std::cerr << "(EE) Cannot update file with index " << it->second <<" and hash " << f.file_hash << ". This is very weird. Entry should have just been created and therefore should exist. Skipping." << std::endl; std::cerr << "(EE) Cannot update file with index " << it->second <<" and hash " << f.file_hash << ". This is very weird. Entry should have just been created and therefore should exist. Skipping." << std::endl;
@ -456,7 +483,9 @@ bool InternalFileHierarchyStorage::updateDirEntry(const DirectoryStorage::EntryI
mNodes[file_index] = new FileEntry(f.file_name,f.file_size,f.file_modtime,f.file_hash) ; mNodes[file_index] = new FileEntry(f.file_name,f.file_size,f.file_modtime,f.file_hash) ;
mFileHashes[f.file_hash] = file_index ; mFileHashes[f.file_hash] = file_index ;
#ifdef DEBUG_DIRECTORY_STORAGE
std::cerr << " created, at new index " << file_index << std::endl; std::cerr << " created, at new index " << file_index << std::endl;
#endif
} }
d.subfiles.push_back(file_index) ; d.subfiles.push_back(file_index) ;
@ -465,7 +494,9 @@ bool InternalFileHierarchyStorage::updateDirEntry(const DirectoryStorage::EntryI
for(std::map<std::string,DirectoryStorage::EntryIndex>::const_iterator it = existing_subfiles.begin();it!=existing_subfiles.end();++it) for(std::map<std::string,DirectoryStorage::EntryIndex>::const_iterator it = existing_subfiles.begin();it!=existing_subfiles.end();++it)
{ {
#ifdef DEBUG_DIRECTORY_STORAGE
std::cerr << " removing existing subfile that is not in the dirctory anymore: name=" << it->first << " index=" << it->second << std::endl; std::cerr << " removing existing subfile that is not in the dirctory anymore: name=" << it->first << " index=" << it->second << std::endl;
#endif
if(!checkIndex(it->second,FileStorageNode::TYPE_FILE)) if(!checkIndex(it->second,FileStorageNode::TYPE_FILE))
{ {

View File

@ -173,21 +173,6 @@ int DirectoryStorage::searchHash(const RsFileHash& hash, std::list<EntryIndex> &
return mFileHierarchy->searchHash(hash,results); return mFileHierarchy->searchHash(hash,results);
} }
// static const uint8_t DIRECTORY_STORAGE_TAG_FILE_HASH = 0x01 ;
// static const uint8_t DIRECTORY_STORAGE_TAG_FILE_NAME = 0x02 ;
// static const uint8_t DIRECTORY_STORAGE_TAG_FILE_SIZE = 0x03 ;
// static const uint8_t DIRECTORY_STORAGE_TAG_DIR_NAME = 0x04 ;
// static const uint8_t DIRECTORY_STORAGE_TAG_MODIF_TS = 0x05 ;
// static const uint8_t DIRECTORY_STORAGE_TAG_RECURS_MODIF_TS = 0x06 ;
void DirectoryStorage::loadNextTag(const unsigned char *data,uint32_t& offset,uint8_t& entry_tag,uint32_t& entry_size)
{
entry_tag = data[offset++] ;
}
void DirectoryStorage::saveNextTag(unsigned char *data, uint32_t& offset, uint8_t entry_tag, uint32_t entry_size)
{
}
void DirectoryStorage::load(const std::string& local_file_name) void DirectoryStorage::load(const std::string& local_file_name)
{ {
RS_STACK_MUTEX(mDirStorageMtx) ; RS_STACK_MUTEX(mDirStorageMtx) ;

View File

@ -49,23 +49,28 @@ class DirectoryStorage
void save() const ; void save() const ;
// These functions are to be used by file transfer and file search.
virtual int searchTerms(const std::list<std::string>& terms, std::list<EntryIndex> &results) const ; virtual int searchTerms(const std::list<std::string>& terms, std::list<EntryIndex> &results) const ;
virtual int searchBoolExp(RsRegularExpression::Expression * exp, std::list<EntryIndex> &results) const ; virtual int searchBoolExp(RsRegularExpression::Expression * exp, std::list<EntryIndex> &results) const ;
virtual int searchHash(const RsFileHash& hash, std::list<EntryIndex> &results) const ; virtual int searchHash(const RsFileHash& hash, std::list<EntryIndex> &results) const ;
bool getDirectoryRecursModTime(EntryIndex index,time_t& recurs_max_modf_TS) const ; // gets/sets the various time stamps:
bool getDirectoryLocalModTime (EntryIndex index,time_t& motime_TS) const ; //
bool getDirectoryUpdateTime (EntryIndex index,time_t& update_TS) const ; bool getDirectoryRecursModTime(EntryIndex index,time_t& recurs_max_modf_TS) const ; // last modification time, computed recursively over all subfiles and directories
bool getDirectoryLocalModTime (EntryIndex index,time_t& motime_TS) const ; // last modification time for that index only
bool getDirectoryUpdateTime (EntryIndex index,time_t& update_TS) const ; // last time the entry was updated. This is only used on the RemoteDirectoryStorage side.
bool setDirectoryRecursModTime(EntryIndex index,time_t recurs_max_modf_TS) ; bool setDirectoryRecursModTime(EntryIndex index,time_t recurs_max_modf_TS) ;
bool setDirectoryLocalModTime (EntryIndex index,time_t modtime_TS) ; bool setDirectoryLocalModTime (EntryIndex index,time_t modtime_TS) ;
bool setDirectoryUpdateTime (EntryIndex index,time_t update_TS) ; bool setDirectoryUpdateTime (EntryIndex index,time_t update_TS) ;
uint32_t getEntryType(const EntryIndex& indx) ; // returns DIR_TYPE_*, not the internal directory storage stuff. uint32_t getEntryType(const EntryIndex& indx) ; // WARNING: returns DIR_TYPE_*, not the internal directory storage stuff.
virtual bool extractData(const EntryIndex& indx,DirDetails& d); virtual bool extractData(const EntryIndex& indx,DirDetails& d);
// This class allows to abstractly browse the stored directory hierarchy in a depth-first manner. // This class allows to abstractly browse the stored directory hierarchy in a depth-first manner.
// It gives access to sub-files and sub-directories below. // It gives access to sub-files and sub-directories below. When using it, the client should make sure
// that the DirectoryStorage is properly locked, since the iterator cannot lock it.
// //
class DirIterator class DirIterator
{ {
@ -120,20 +125,28 @@ class DirectoryStorage
time_t modtime; time_t modtime;
}; };
EntryIndex root() const ; // returns the index of the root directory entry. EntryIndex root() const ; // returns the index of the root directory entry. This is generally 0.
const RsPeerId& peerId() const { return mPeerId ; } const RsPeerId& peerId() const { return mPeerId ; } // peer ID of who owns that file list.
int parentRow(EntryIndex e) const ; int parentRow(EntryIndex e) const ; // position of the current node, in the array of children at its parent node. Used by GUI for display.
bool getChildIndex(EntryIndex e,int row,EntryIndex& c) const; bool getChildIndex(EntryIndex e,int row,EntryIndex& c) const; // returns the index of the children node at position "row" in the children nodes. Used by GUI for display.
// Sets the subdirectory/subfiles list of entry indx the supplied one, possible adding and removing directories (resp.files). New directories are set empty with
// just a name and need to be updated later on. New files are returned in a list so that they can be sent to hash cache.
//
bool updateSubDirectoryList(const EntryIndex& indx, const std::map<std::string, time_t> &subdirs) ; bool updateSubDirectoryList(const EntryIndex& indx, const std::map<std::string, time_t> &subdirs) ;
bool updateSubFilesList(const EntryIndex& indx, const std::map<std::string, FileTS> &subfiles, std::map<std::string, FileTS> &new_files) ; bool updateSubFilesList(const EntryIndex& indx, const std::map<std::string, FileTS> &subfiles, std::map<std::string, FileTS> &new_files) ;
bool removeDirectory(const EntryIndex& indx) ; bool removeDirectory(const EntryIndex& indx) ;
// Updates relevant information for the file at the given index.
bool updateFile(const EntryIndex& index,const RsFileHash& hash, const std::string& fname, uint64_t size, time_t modf_time) ; 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); bool updateHash(const EntryIndex& index,const RsFileHash& hash);
bool getDirHashFromIndex(const EntryIndex& index,RsFileHash& hash) const ; // Returns the hash of the directory at the given index and reverse. This hash is set as random the first time it is used (when updating directories). It will be
bool getIndexFromDirHash(const RsFileHash& hash,EntryIndex& index) const ; // used by the sync system to designate the directory without referring to index (index could be used to figure out the existance of hidden directories)
bool getDirHashFromIndex(const EntryIndex& index,RsFileHash& hash) const ; // constant cost
bool getIndexFromDirHash(const RsFileHash& hash,EntryIndex& index) const ; // log cost.
void print(); void print();
void cleanup(); void cleanup();
@ -144,9 +157,6 @@ class DirectoryStorage
private: private:
void loadNextTag(const unsigned char *data, uint32_t& offset, uint8_t& entry_tag, uint32_t& entry_size) ;
void saveNextTag(unsigned char *data,uint32_t& offset,uint8_t entry_tag,uint32_t entry_size) ;
// debug // debug
void locked_check(); void locked_check();
@ -195,6 +205,11 @@ public:
LocalDirectoryStorage(const std::string& fname,const RsPeerId& own_id) : DirectoryStorage(own_id),mFileName(fname) {} LocalDirectoryStorage(const std::string& fname,const RsPeerId& own_id) : DirectoryStorage(own_id),mFileName(fname) {}
virtual ~LocalDirectoryStorage() {} virtual ~LocalDirectoryStorage() {}
/*!
* \brief [gs]etSharedDirectoryList
* Gets/sets the list of shared directories. Each directory is supplied with a virtual name (the name the friends will see), and sharing flags/groups.
* \param lst
*/
void setSharedDirectoryList(const std::list<SharedDirInfo>& lst) ; void setSharedDirectoryList(const std::list<SharedDirInfo>& lst) ;
void getSharedDirectoryList(std::list<SharedDirInfo>& lst) ; void getSharedDirectoryList(std::list<SharedDirInfo>& lst) ;

View File

@ -30,6 +30,11 @@
#include "util/rsthreads.h" #include "util/rsthreads.h"
#include "retroshare/rsfiles.h" #include "retroshare/rsfiles.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 class HashStorageClient
{ {
public: public:
@ -59,7 +64,7 @@ public:
* \param mod_time Actual file modification time * \param mod_time Actual file modification time
* \param known_hash Returned hash for the file. * \param known_hash Returned hash for the file.
* \param c Hash cache client to which the hash should be sent once calculated * \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 * \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. * \return true if the supplied hash info is up to date.
*/ */
@ -75,9 +80,9 @@ public:
} ; } ;
// interaction with GUI, called from p3FileLists // interaction with GUI, called from p3FileLists
void setRememberHashFilesDuration(uint32_t days) { mMaxStorageDurationDays = days ; } 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 ; } uint32_t rememberHashFilesDuration() const { return mMaxStorageDurationDays ; }
void clear() { mFiles.clear(); mChanged=true; } 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() ; } bool empty() const { return mFiles.empty() ; }
// Functions called by the thread // Functions called by the thread
@ -86,8 +91,14 @@ public:
friend std::ostream& operator<<(std::ostream& o,const HashStorageInfo& info) ; friend std::ostream& operator<<(std::ostream& o,const HashStorageInfo& info) ;
private: private:
/*!
* \brief clean
* This function is responsible for removing old hashes, etc
*/
void clean() ; void clean() ;
// loading/saving the entire hash database to a file
void locked_save() ; void locked_save() ;
void locked_load() ; void locked_load() ;
@ -98,7 +109,7 @@ private:
uint32_t mMaxStorageDurationDays ; // maximum duration of un-requested cache entries uint32_t mMaxStorageDurationDays ; // maximum duration of un-requested cache entries
std::map<std::string, HashStorageInfo> mFiles ; // stored as (full_path, hash_info) std::map<std::string, HashStorageInfo> mFiles ; // stored as (full_path, hash_info)
std::string mFilePath ; std::string mFilePath ; // file where the hash database is stored
bool mChanged ; bool mChanged ;
struct FileHashJob struct FileHashJob

View File

@ -223,7 +223,9 @@ int p3FileDatabase::tick()
mLastRemoteDirSweepTS = now; mLastRemoteDirSweepTS = now;
#warning hack to make loaded directories show up in the GUI, because the GUI isn_t ready at the time they are actually loaded up. // This is a hash to make loaded directories show up in the GUI, because the GUI generally isn't ready at the time they are actually loaded up,
// so the first notify is ignored, and no other notify will happen next.
RsServer::notify()->notifyListChange(NOTIFY_LIST_DIRLIST_FRIENDS, 0); RsServer::notify()->notifyListChange(NOTIFY_LIST_DIRLIST_FRIENDS, 0);
} }
@ -614,7 +616,9 @@ void p3FileDatabase::requestDirUpdate(void *ref)
P3FILELISTS_DEBUG() << "Trying to force sync of entry ndex " << e << " to friend " << mRemoteDirectories[fi-1]->peerId() << std::endl; P3FILELISTS_DEBUG() << "Trying to force sync of entry ndex " << e << " to friend " << mRemoteDirectories[fi-1]->peerId() << std::endl;
#endif #endif
if(generateAndSendSyncRequest(mRemoteDirectories[fi-1],e)) RS_STACK_MUTEX(mFLSMtx) ;
if(locked_generateAndSendSyncRequest(mRemoteDirectories[fi-1],e))
{ {
#ifdef DEBUG_P3FILELISTS #ifdef DEBUG_P3FILELISTS
P3FILELISTS_DEBUG() << " Succeed." << std::endl; P3FILELISTS_DEBUG() << " Succeed." << std::endl;
@ -638,7 +642,7 @@ bool p3FileDatabase::findChildPointer(void *ref, int row, void *& result, FileSe
return true ; return true ;
} }
else if(row < mRemoteDirectories.size()) else if((uint32_t)row < mRemoteDirectories.size())
{ {
convertEntryIndexToPointer(mRemoteDirectories[row]->root(),row+1,result); convertEntryIndexToPointer(mRemoteDirectories[row]->root(),row+1,result);
return true; return true;
@ -752,7 +756,11 @@ int p3FileDatabase::RequestDirDetails(void *ref, DirDetails& d, FileSearchFlags
// Case where the index is the top of a single person. Can be us, or a friend. // Case where the index is the top of a single person. Can be us, or a friend.
bool res = storage->extractData(e,d); if(!storage->extractData(e,d))
{
P3FILELISTS_ERROR() << "(EE) request on index " << e << ", for directory ID=" << storage->peerId() << " failed. This should not happen." << std::endl;
return false ;
}
// update indexes. This is a bit hacky, but does the job. The cast to intptr_t is the proper way to convert // update indexes. This is a bit hacky, but does the job. The cast to intptr_t is the proper way to convert
// a pointer into an int. // a pointer into an int.
@ -824,6 +832,7 @@ void p3FileDatabase::forceDirectoryCheck() // Force re-sweep the di
} }
bool p3FileDatabase::inDirectoryCheck() bool p3FileDatabase::inDirectoryCheck()
{ {
RS_STACK_MUTEX(mFLSMtx) ;
return mLocalDirWatcher->inDirectoryCheck(); return mLocalDirWatcher->inDirectoryCheck();
} }
void p3FileDatabase::setWatchEnabled(bool b) void p3FileDatabase::setWatchEnabled(bool b)
@ -975,8 +984,9 @@ bool p3FileDatabase::convertSharedFilePath(const std::string& path,std::string&
// - because the hash is performed late, the last modf time upward is updated only when the hash is obtained. // - because the hash is performed late, the last modf time upward is updated only when the hash is obtained.
// //
// Remote dirs store // Remote dirs store
// 1 - recursive modif time of the files/dir in the friend's time // 1 - recursive max modif time of the files/dir in the friend's time
// 2 - update TS in the local time // 2 - modif time of the files/dir in the friend's time
// 3 - update TS in the local time
// //
// The update algorithm is the following: // The update algorithm is the following:
// //
@ -1275,20 +1285,29 @@ void p3FileDatabase::handleDirSyncResponse(RsFileListsSyncResponseItem *sitem)
if(item->flags & RsFileListsItem::FLAGS_ENTRY_WAS_REMOVED) if(item->flags & RsFileListsItem::FLAGS_ENTRY_WAS_REMOVED)
{ {
RS_STACK_MUTEX(mFLSMtx) ;
#ifdef DEBUG_P3FILELISTS
std::cerr << " removing directory with index " << entry_index << " because it does not exist." << std::endl; std::cerr << " removing directory with index " << entry_index << " because it does not exist." << std::endl;
#endif
mRemoteDirectories[fi]->removeDirectory(entry_index); mRemoteDirectories[fi]->removeDirectory(entry_index);
mRemoteDirectories[fi]->print(); mRemoteDirectories[fi]->print();
} }
else if(item->flags & RsFileListsItem::FLAGS_ENTRY_UP_TO_DATE) else if(item->flags & RsFileListsItem::FLAGS_ENTRY_UP_TO_DATE)
{ {
RS_STACK_MUTEX(mFLSMtx) ;
#ifdef DEBUG_P3FILELISTS
std::cerr << " Directory is up to date. Setting local TS." << std::endl; std::cerr << " Directory is up to date. Setting local TS." << std::endl;
#endif
mRemoteDirectories[fi]->setDirectoryUpdateTime(entry_index,time(NULL)) ; mRemoteDirectories[fi]->setDirectoryUpdateTime(entry_index,time(NULL)) ;
} }
else if(item->flags & RsFileListsItem::FLAGS_SYNC_DIR_CONTENT) else if(item->flags & RsFileListsItem::FLAGS_SYNC_DIR_CONTENT)
{ {
#ifdef DEBUG_P3FILELISTS
std::cerr << " Item contains directory data. Deserialising/Updating." << std::endl; std::cerr << " Item contains directory data. Deserialising/Updating." << std::endl;
#endif
RS_STACK_MUTEX(mFLSMtx) ;
if(mRemoteDirectories[fi]->deserialiseUpdateDirEntry(entry_index,item->directory_content_data)) if(mRemoteDirectories[fi]->deserialiseUpdateDirEntry(entry_index,item->directory_content_data))
RsServer::notify()->notifyListChange(NOTIFY_LIST_DIRLIST_FRIENDS, 0); // notify the GUI if the hierarchy has changed RsServer::notify()->notifyListChange(NOTIFY_LIST_DIRLIST_FRIENDS, 0); // notify the GUI if the hierarchy has changed
@ -1328,7 +1347,7 @@ void p3FileDatabase::locked_recursSweepRemoteDirectory(RemoteDirectoryStorage *r
// compare TS // compare TS
if((e == 0 && now > local_update_TS + DELAY_BETWEEN_REMOTE_DIRECTORY_SYNC_REQ) || local_update_TS == 0) // we need to compare local times only. We cannot compare local (now) with remote time. if((e == 0 && now > local_update_TS + DELAY_BETWEEN_REMOTE_DIRECTORY_SYNC_REQ) || local_update_TS == 0) // we need to compare local times only. We cannot compare local (now) with remote time.
if(generateAndSendSyncRequest(rds,e)) if(locked_generateAndSendSyncRequest(rds,e))
{ {
#ifdef DEBUG_P3FILELISTS #ifdef DEBUG_P3FILELISTS
P3FILELISTS_DEBUG() << " Asking for sync of directory " << e << " to peer " << rds->peerId() << " because it's " << (now - local_update_TS) << " secs old since last check." << std::endl; P3FILELISTS_DEBUG() << " Asking for sync of directory " << e << " to peer " << rds->peerId() << " because it's " << (now - local_update_TS) << " secs old since last check." << std::endl;
@ -1363,7 +1382,7 @@ p3FileDatabase::DirSyncRequestId p3FileDatabase::makeDirSyncReqId(const RsPeerId
return r ^ random_bias; return r ^ random_bias;
} }
bool p3FileDatabase::generateAndSendSyncRequest(RemoteDirectoryStorage *rds,const DirectoryStorage::EntryIndex& e) bool p3FileDatabase::locked_generateAndSendSyncRequest(RemoteDirectoryStorage *rds,const DirectoryStorage::EntryIndex& e)
{ {
RsFileHash entry_hash ; RsFileHash entry_hash ;
time_t now = time(NULL) ; time_t now = time(NULL) ;

View File

@ -117,7 +117,7 @@ class p3FileDatabase: public p3Service, public p3Config, public ftSearch //, pub
int RequestDirDetails(void *, DirDetails&, FileSearchFlags) const ; int RequestDirDetails(void *, DirDetails&, FileSearchFlags) const ;
uint32_t getType(void *) const ; uint32_t getType(void *) const ;
// proxy method used by the web UI. // proxy method used by the web UI. Dont't delete!
int RequestDirDetails(const RsPeerId& uid, const std::string& path, DirDetails &details)const; int RequestDirDetails(const RsPeerId& uid, const std::string& path, DirDetails &details)const;
// set/update shared directories // set/update shared directories
@ -173,7 +173,7 @@ class p3FileDatabase: public p3Service, public p3Config, public ftSearch //, pub
* \param e Entry index to update * \param e Entry index to update
* \return true if the request is correctly sent. * \return true if the request is correctly sent.
*/ */
bool generateAndSendSyncRequest(RemoteDirectoryStorage *rds,const DirectoryStorage::EntryIndex& e); bool locked_generateAndSendSyncRequest(RemoteDirectoryStorage *rds,const DirectoryStorage::EntryIndex& e);
// File sync request queues. The fast one is used for online browsing when friends are connected. // File sync request queues. The fast one is used for online browsing when friends are connected.
// The slow one is used for background update of file lists. // The slow one is used for background update of file lists.

View File

@ -522,7 +522,9 @@ QModelIndexList SharedFilesDialog::getSelected()
void RemoteSharedFilesDialog::expanded(const QModelIndex& indx) void RemoteSharedFilesDialog::expanded(const QModelIndex& indx)
{ {
#ifdef DEBUG_SHARED_FILES_DIALOG
std::cerr << "Expanding at " << indx.row() << " and " << indx.column() << " ref=" << indx.internalPointer() << ", pointer at 1: " << proxyModel->mapToSource(indx).internalPointer() << std::endl; std::cerr << "Expanding at " << indx.row() << " and " << indx.column() << " ref=" << indx.internalPointer() << ", pointer at 1: " << proxyModel->mapToSource(indx).internalPointer() << std::endl;
#endif
model->updateRef(proxyModel->mapToSource(indx)) ; model->updateRef(proxyModel->mapToSource(indx)) ;
} }