Iproved file list handling:

- Implemented correct cacheData send to clients usign constant subid value.
- At start, the association between peers and available file list is always recomputed
- overloaded cacheAvailable() and refreshCache() in FileIndexMonitor
- added callback in rsFiles to force re-generating cache items when group layout has changed
- force re-sent file lists when moving peers between groups in the GUI
(Fixes group leaking problem) Needs full recompilation of libretroshare.


git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@5813 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
csoler 2012-11-12 22:51:27 +00:00
parent 03dbf7bc1b
commit 454daf1981
10 changed files with 133 additions and 43 deletions

View File

@ -92,7 +92,7 @@ bool CacheSource::loadLocalCache(const CacheData &data)
}
/* control Caches available */
bool CacheSource::refreshCache(const CacheData &data,const std::list<std::string>& destination_peers)
bool CacheSource::refreshCache(const CacheData &data,const std::set<std::string>& destination_peers)
{
bool ret = false;
{
@ -599,23 +599,27 @@ void CacheStrapper::statusChange(const std::list<pqipeer> &plist)
/**************** from pqimonclient ********************/
void CacheStrapper::refreshCache(const CacheData &data,const std::list<std::string>& destination_peers)
void CacheStrapper::refreshCache(const CacheData &data,const std::set<std::string>& destination_peers)
{
/* we've received an update
* send to all online peers + self
* send to all online peers + self intersected with online peers.
*/
#ifdef CS_DEBUG
std::cerr << "CacheStrapper::refreshCache() : " << data << std::endl;
#endif
std::list<std::string> ids;
mLinkMgr->getOnlineList(ids);
ids.push_back(mLinkMgr->getOwnId()) ;
RsStackMutex stack(csMtx); /******* LOCK STACK MUTEX *********/
for(std::list<std::string>::const_iterator it = destination_peers.begin(); it != destination_peers.end(); ++it)
{
for(std::list<std::string>::const_iterator it = ids.begin(); it != ids.end(); ++it)
if(destination_peers.find(*it) != destination_peers.end())
{
#ifdef CS_DEBUG
std::cerr << "CacheStrapper::refreshCache() Send To: " << *it << std::endl;
std::cerr << "CacheStrapper::refreshCache() Send To: " << *it << std::endl;
#endif
mCacheUpdates.push_back(std::make_pair(*it, data));
}
mCacheUpdates.push_back(std::make_pair(*it, data));
}
IndicateConfigChanged(); /**** INDICATE MSG CONFIG CHANGED! *****/
}
@ -633,7 +637,12 @@ void CacheStrapper::refreshCache(const CacheData &data)
mLinkMgr->getOnlineList(ids);
ids.push_back(mLinkMgr->getOwnId()) ;
refreshCache(data,ids) ;
{
RsStackMutex stack(csMtx); /******* LOCK STACK MUTEX *********/
for(std::list<std::string>::const_iterator it = ids.begin(); it != ids.end(); ++it)
mCacheUpdates.push_back(std::make_pair(*it, data));
}
IndicateConfigChanged(); /**** INDICATE MSG CONFIG CHANGED! *****/
}
void CacheStrapper::refreshCacheStore(const CacheData & /* data */ )

View File

@ -29,6 +29,7 @@
#include "util/rsthreads.h"
#include <list>
#include <set>
#include <map>
#include <string>
#include <iostream>
@ -181,7 +182,7 @@ class CacheSource
virtual bool loadLocalCache(const CacheData &data);
/* control Caches available */
bool refreshCache(const CacheData &data,const std::list<std::string>& destination_peers);
bool refreshCache(const CacheData &data,const std::set<std::string>& destination_peers);
bool refreshCache(const CacheData &data);
bool clearCache(CacheId id);
@ -400,7 +401,7 @@ virtual void statusChange(const std::list<pqipeer> &plist);
*
*/
void refreshCache(const CacheData &data);
void refreshCache(const CacheData &data,const std::list<std::string>& destination_peers); // specify a particular list of destination peers (self not added!)
void refreshCache(const CacheData &data,const std::set<std::string>& destination_peers); // specify a particular list of destination peers (self not added!)
/*!
* forces config savelist

View File

@ -46,7 +46,7 @@
#include <fstream>
//***********
//#define FIM_DEBUG 1
#define FIM_DEBUG 1
// ***********/
FileIndexMonitor::FileIndexMonitor(CacheStrapper *cs, NotifyBase *cb_in,std::string cachedir, std::string pid,const std::string& config_dir)
@ -342,7 +342,7 @@ bool FileIndexMonitor::findLocalFile(std::string hash,FileSearchFlags hint_flags
RsStackMutex stackM(fiMutex) ;/* LOCKED DIRS */
#ifdef FIM_DEBUG
std::cerr << "FileIndexMonitor::findLocalFile() Hash: " << hash << std::endl;
// std::cerr << "FileIndexMonitor::findLocalFile() Hash: " << hash << std::endl;
#endif
/* search through the fileIndex */
fi.searchHash(hash, results);
@ -435,18 +435,16 @@ bool FileIndexMonitor::loadLocalCache(const CacheData &data) /* called with sto
{
bool ok = false;
{
std::cerr << "FileIndexMonitor::loadLocalCache(): subid = " << data.cid.subid << ", filename=" << data.name << ", peer id = " << data.pid << std::endl;
if(!strcmp(data.name.c_str()+data.name.size()-5,".rsfc"))// this trick allows to load the complete file. Not the one being shared.
{ // other files are discarded and re-created in case permissions have changed.
RsStackMutex mtx(fiMutex) ; /* LOCKED DIRS */
/* More error checking needed here! */
std::string name = data.name ;
name[name.length()-4] = 'r' ;// this trick allows to load the complete file. Not the one being shared.
name[name.length()-3] = 's' ;
name[name.length()-2] = 'f' ;
name[name.length()-1] = 'c' ;
if ((ok = fi.loadIndex(data.path + '/' + name, "", data.size)))
{
#ifdef FIM_DEBUG
@ -465,17 +463,22 @@ bool FileIndexMonitor::loadLocalCache(const CacheData &data) /* called with sto
}
fi.updateMaxModTime() ;
locked_saveFileIndexes(false) ;
}
else
std::cerr << "FileIndexMonitor:: not loading cache item " << data.name << std::endl;
#ifdef REMOVED
if (ok)
{
return updateCache(data);
}
#endif
return false;
}
bool FileIndexMonitor::updateCache(const CacheData &data,const std::list<std::string>& destination_peers) /* we call this one */
bool FileIndexMonitor::updateCache(const CacheData &data,const std::set<std::string>& destination_peers) /* we call this one */
{
return refreshCache(data,destination_peers);
}
@ -836,7 +839,7 @@ void FileIndexMonitor::updateCycle()
}
if (fiMods)
locked_saveFileIndexes() ;
locked_saveFileIndexes(true) ;
fi.updateMaxModTime() ; // Update modification times for proper display.
@ -987,7 +990,7 @@ void FileIndexMonitor::hashFiles(const std::vector<DirContentToHash>& to_hash)
sleep(1) ;
#endif
RsStackMutex stack(fiMutex); /**** LOCKED DIRS ****/
FileIndexMonitor::locked_saveFileIndexes() ;
FileIndexMonitor::locked_saveFileIndexes(true) ;
last_save_size = hashed_size ;
if(useHashCache)
@ -1002,7 +1005,7 @@ void FileIndexMonitor::hashFiles(const std::vector<DirContentToHash>& to_hash)
}
void FileIndexMonitor::locked_saveFileIndexes()
void FileIndexMonitor::locked_saveFileIndexes(bool update_cache)
{
/* store to the cacheDirectory */
@ -1020,12 +1023,16 @@ void FileIndexMonitor::locked_saveFileIndexes()
// To figure out which sets are different, we index them by the set of forbidden indexes from the directory list.
// This is probably a bit costly, but we can't suppose that the number of shared directories is bounded.
//
std::list<std::string> online_ids ;
rsPeers->getOnlineList(online_ids);
std::list<std::string> all_friend_ids ;
rsPeers->getFriendList(all_friend_ids);
std::map<std::set<std::string>, std::list<std::string> > peers_per_directory_combination ;
std::cerr << "FileIndexMonitor::updateCycle(): got list of all friends." << std::endl ;
for(std::list<std::string>::const_iterator it(all_friend_ids.begin());it!=all_friend_ids.end();++it)
std::cerr << " " << *it << std::endl;
for(std::list<std::string>::const_iterator it(online_ids.begin());it!=online_ids.end();++it)
std::map<std::set<std::string>, std::set<std::string> > peers_per_directory_combination ;
for(std::list<std::string>::const_iterator it(all_friend_ids.begin());it!=all_friend_ids.end();++it)
{
std::cerr << "About to save, with the following restrictions:" << std::endl ;
std::cerr << "Peer : " << *it << std::endl;
@ -1052,15 +1059,15 @@ void FileIndexMonitor::locked_saveFileIndexes()
std::cerr << "autorized" << std::endl;
}
peers_per_directory_combination[forbidden_dirs].push_back(*it) ;
peers_per_directory_combination[forbidden_dirs].insert(*it) ;
}
std::string ownId = rsPeers->getOwnId() ;
peers_per_directory_combination[std::set<std::string>()].push_back(ownId) ; // add full configuration to self, i.e. no forbidden directories.
peers_per_directory_combination[std::set<std::string>()].insert(ownId) ; // add full configuration to self, i.e. no forbidden directories.
int n=0 ;
time_t now = time(NULL) ;
for(std::map<std::set<std::string>, std::list<std::string> >::const_iterator it(peers_per_directory_combination.begin());
for(std::map<std::set<std::string>, std::set<std::string> >::const_iterator it(peers_per_directory_combination.begin());
it!=peers_per_directory_combination.end();++it,++n)
{
std::string tmpname_browsable;
@ -1076,7 +1083,7 @@ void FileIndexMonitor::locked_saveFileIndexes()
std::cerr << "Sending file list: " << std::endl;
std::cerr << " filename : " << tmpname_browsable << std::endl;
std::cerr << " to peers : " << std::endl;
for(std::list<std::string>::const_iterator itt(it->second.begin());itt!= it->second.end();++itt)
for(std::set<std::string>::const_iterator itt(it->second.begin());itt!= it->second.end();++itt)
std::cerr << " " << *itt << std::endl;
std::cerr << " forbidden : " << std::endl;
for(std::set<std::string>::const_iterator itt(it->first.begin());itt!= it->first.end();++itt)
@ -1100,14 +1107,20 @@ void FileIndexMonitor::locked_saveFileIndexes()
CacheData data;
data.pid = fi.root->id;
data.cid.type = getCacheType();
data.cid.subid = 0;
data.cid.subid = n;
data.path = path;
data.name = tmpname_browsable;
data.hash = hash;
data.size = size;
data.recvd = time(NULL);
updateCache(data,it->second);
for(std::set<std::string>::const_iterator ff(it->second.begin());ff!=it->second.end();++ff)
_cache_items_per_peer[*ff] = data ;
data.cid.subid = 0;
if(update_cache)
updateCache(data,it->second);
}
}
@ -1117,6 +1130,37 @@ void FileIndexMonitor::locked_saveFileIndexes()
#endif
}
bool FileIndexMonitor::cachesAvailable(RsPeerId pid,std::map<CacheId, CacheData> &ids)
{
lockData() ;
std::cerr << "In cachesAvailable..." << std::endl;
// Go through the list of saved cache items for that particular peer.
//
ids.clear() ;
std::map<RsPeerId,CacheData>::const_iterator it(_cache_items_per_peer.find(pid)) ;
std::string ownId = rsPeers->getOwnId() ;
if(it != _cache_items_per_peer.end())
{
ids[it->second.cid] = it->second ;
if(pid != ownId)
ids[it->second.cid].cid.subid = 0 ; // Force subid to be 0, so that it's
// not going to be mixed up at the client with other files received if the
// subid changes for that peer.
//
std::cerr << "FileIndexMonitor: caches available for peer " << pid << ": " << it->second.name << std::endl ;
}
else
std::cerr << "No cache item for peer " << pid << std::endl;
unlockData() ;
return true ;
}
void FileIndexMonitor::updateShareFlags(const SharedDirInfo& dir)
{
cb->notifyListPreChange(NOTIFY_LIST_DIRLIST_LOCAL, 0);
@ -1156,7 +1200,7 @@ void FileIndexMonitor::updateShareFlags(const SharedDirInfo& dir)
if(fimods)
{
RsStackMutex stack(fiMutex) ; /* LOCKED DIRS */
locked_saveFileIndexes() ;
locked_saveFileIndexes(true) ;
}
cb->notifyListChange(NOTIFY_LIST_DIRLIST_LOCAL, 0);
}
@ -1241,6 +1285,12 @@ void FileIndexMonitor::forceDirectoryCheck()
}
void FileIndexMonitor::forceDirListsRebuildAndSend()
{
RsStackMutex stack(fiMutex) ; /* LOCKED DIRS */
locked_saveFileIndexes(true) ;
}
/* interface */
bool FileIndexMonitor::inDirectoryCheck()
{
@ -1321,7 +1371,7 @@ bool FileIndexMonitor::internal_setSharedDirectories()
fi.setRootDirectories(topdirs, 0);
locked_saveFileIndexes() ;
locked_saveFileIndexes(true) ;
return true;
}

View File

@ -126,7 +126,7 @@ class FileIndexMonitor: public CacheSource, public RsThread
/* Interacting with CacheSource */
/* overloaded from CacheSource */
virtual bool loadLocalCache(const CacheData &data); /* called with stored data */
bool updateCache(const CacheData &data,const std::list<std::string>& dest_peers); /* we call when we have a new cache for others */
bool updateCache(const CacheData &data,const std::set<std::string>& dest_peers); /* we call when we have a new cache for others */
/* the FileIndexMonitor inner workings */
@ -145,11 +145,15 @@ class FileIndexMonitor: public CacheSource, public RsThread
void getSharedDirectories(std::list<SharedDirInfo>& dirs);
void updateShareFlags(const SharedDirInfo& info) ;
void forceDirectoryCheck();
void forceDirectoryCheck(); // Force re-sweep the directories and see what's changed
void forceDirListsRebuildAndSend() ; // Force re-build dir lists because groups have changed. Does not re-check files.
bool inDirectoryCheck();
/* util fns */
// from CacheSource
virtual bool cachesAvailable(RsPeerId /* pid */, std::map<CacheId, CacheData> &ids) ;
protected:
// Sets/gets the duration period within which already hashed files are remembered.
//
@ -168,7 +172,7 @@ class FileIndexMonitor: public CacheSource, public RsThread
/* the mutex should be locked before calling these 3. */
// saves file indexs and update the cache.
void locked_saveFileIndexes() ;
void locked_saveFileIndexes(bool update_cache) ;
// Finds the share flags associated with this file entry.
void locked_findShareFlagsAndParentGroups(FileEntry *fe,FileStorageFlags& shareflags,std::list<std::string>& parent_groups) const ;
@ -202,6 +206,8 @@ class FileIndexMonitor: public CacheSource, public RsThread
HashCache hashCache ;
bool useHashCache ;
std::map<RsPeerId,CacheData> _cache_items_per_peer ; // stored the cache items to be sent to each peer.
};

View File

@ -593,6 +593,10 @@ bool ftServer::ConvertSharedFilePath(std::string path, std::string &fullpath)
return mFiMon->convertSharedFilePath(path, fullpath);
}
void ftServer::updateSinceGroupPermissionsChanged()
{
mFiMon->forceDirListsRebuildAndSend();
}
void ftServer::ForceDirectoryCheck()
{
mFiMon->forceDirectoryCheck();

View File

@ -186,6 +186,7 @@ virtual int SearchBoolExp(Expression * exp, std::list<DirDetails> &results,FileS
***/
virtual bool ConvertSharedFilePath(std::string path, std::string &fullpath);
virtual void ForceDirectoryCheck();
virtual void updateSinceGroupPermissionsChanged() ;
virtual bool InDirectoryCheck();
virtual bool CopyFile(const std::string& source, const std::string& dest);

View File

@ -158,7 +158,7 @@ class RsFiles
/***
* Extra List Access
***/
virtual bool ExtraFileAdd(std::string fname, std::string hash, uint64_t size, uint32_t period, TransferRequestFlags flags) = 0;
//virtual bool ExtraFileAdd(std::string fname, std::string hash, uint64_t size, uint32_t period, TransferRequestFlags flags) = 0;
virtual bool ExtraFileRemove(std::string hash, TransferRequestFlags flags) = 0;
virtual bool ExtraFileHash(std::string localpath, uint32_t period, TransferRequestFlags flags) = 0;
virtual bool ExtraFileStatus(std::string localpath, FileInfo &info) = 0;
@ -184,6 +184,7 @@ class RsFiles
***/
virtual bool ConvertSharedFilePath(std::string path, std::string &fullpath) = 0;
virtual void ForceDirectoryCheck() = 0;
virtual void updateSinceGroupPermissionsChanged() = 0;
virtual bool InDirectoryCheck() = 0;
virtual bool CopyFile(const std::string& source,const std::string& dest) = 0;

View File

@ -36,6 +36,7 @@
#include "pqi/authssl.h"
#include "pqi/authgpg.h"
#include "retroshare/rsinit.h"
#include "retroshare/rsfiles.h"
#include "pgp/rscertificate.h"
@ -1044,7 +1045,9 @@ bool p3Peers::addGroup(RsGroupInfo &groupInfo)
std::cerr << "p3Peers::addGroup()" << std::endl;
#endif
return mPeerMgr->addGroup(groupInfo);
bool res = mPeerMgr->addGroup(groupInfo);
rsFiles->updateSinceGroupPermissionsChanged() ;
return res ;
}
bool p3Peers::editGroup(const std::string &groupId, RsGroupInfo &groupInfo)
@ -1053,7 +1056,10 @@ bool p3Peers::editGroup(const std::string &groupId, RsGroupInfo &groupInfo)
std::cerr << "p3Peers::editGroup()" << std::endl;
#endif
return mPeerMgr->editGroup(groupId, groupInfo);
bool res = mPeerMgr->editGroup(groupId, groupInfo);
rsFiles->updateSinceGroupPermissionsChanged() ;
return res ;
}
bool p3Peers::removeGroup(const std::string &groupId)
@ -1062,7 +1068,9 @@ bool p3Peers::removeGroup(const std::string &groupId)
std::cerr << "p3Peers::removeGroup()" << std::endl;
#endif
return mPeerMgr->removeGroup(groupId);
bool res = mPeerMgr->removeGroup(groupId);
rsFiles->updateSinceGroupPermissionsChanged() ;
return res ;
}
bool p3Peers::getGroupInfo(const std::string &groupId, RsGroupInfo &groupInfo)
@ -1097,7 +1105,10 @@ bool p3Peers::assignPeersToGroup(const std::string &groupId, const std::list<std
std::cerr << "p3Peers::assignPeersToGroup()" << std::endl;
#endif
return mPeerMgr->assignPeersToGroup(groupId, peerIds, assign);
bool res = mPeerMgr->assignPeersToGroup(groupId, peerIds, assign);
rsFiles->updateSinceGroupPermissionsChanged() ;
return res ;
}
FileSearchFlags p3Peers::computePeerPermissionFlags(const std::string& peer_ssl_id,

View File

@ -77,6 +77,7 @@ ShareDialog::ShareDialog(std::string filename, QWidget *parent)
updateInfoMessage() ;
connect(groupselectionbox,SIGNAL(itemSelectionChanged()),this,SLOT(updateInfoMessage())) ;
connect(groupselectionbox,SIGNAL(itemSelectionChanged()),this,SLOT(groupSelectionChanged())) ;
connect(groupflagsbox,SIGNAL(flagsChanged(FileStorageFlags)),this,SLOT(updateInfoMessage())) ;
if (!filename.empty())
@ -105,6 +106,11 @@ ShareDialog::ShareDialog(std::string filename, QWidget *parent)
}
}
void ShareDialog::groupSelectionChanged()
{
rsFiles->updateSinceGroupPermissionsChanged() ;
}
void ShareDialog::updateInfoMessage()
{
QList<QString> selectedGroupNames;

View File

@ -42,6 +42,7 @@ class ShareDialog : public QDialog
void browseDirectory();
void addDirectory();
void updateInfoMessage() ;
void groupSelectionChanged();
private:
/** Qt Designer generated object */