diff --git a/libretroshare/src/file_sharing/directory_storage.h b/libretroshare/src/file_sharing/directory_storage.h index 28ba00401..a3a084612 100644 --- a/libretroshare/src/file_sharing/directory_storage.h +++ b/libretroshare/src/file_sharing/directory_storage.h @@ -121,8 +121,13 @@ class DirectoryStorage class RemoteDirectoryStorage: public DirectoryStorage { public: - RemoteDirectoryStorage(const std::string& fname) : DirectoryStorage(fname) {} + RemoteDirectoryStorage(const RsPeerId& pid,const std::string& fname) : DirectoryStorage(fname),mPeerId(pid) {} virtual ~RemoteDirectoryStorage() {} + + const RsPeerId& peerId() const { return mPeerId ; } + +private: + RsPeerId mPeerId; }; class LocalDirectoryStorage: public DirectoryStorage diff --git a/libretroshare/src/file_sharing/p3filelists.cc b/libretroshare/src/file_sharing/p3filelists.cc index ffc3d401f..597c9292e 100644 --- a/libretroshare/src/file_sharing/p3filelists.cc +++ b/libretroshare/src/file_sharing/p3filelists.cc @@ -14,6 +14,10 @@ static const uint32_t P3FILELISTS_UPDATE_FLAG_REMOTE_MAP_CHANGED = 0x0001 ; static const uint32_t P3FILELISTS_UPDATE_FLAG_LOCAL_DIRS_CHANGED = 0x0002 ; static const uint32_t P3FILELISTS_UPDATE_FLAG_REMOTE_DIRS_CHANGED = 0x0004 ; +static const uint32_t NB_FRIEND_INDEX_BITS = 10 ; +static const uint32_t NB_ENTRY_INDEX_BITS = 22 ; +static const uint32_t ENTRY_INDEX_BIT_MASK = 0x003fffff ; // used for storing (EntryIndex,Friend) couples into a 32bits pointer. + p3FileDatabase::p3FileDatabase(p3ServiceControl *mpeers) : mServCtrl(mpeers), mFLSMtx("p3FileLists") { @@ -49,8 +53,8 @@ p3FileDatabase::~p3FileDatabase() { RS_STACK_MUTEX(mFLSMtx) ; - for(std::map::const_iterator it(mRemoteDirectories.begin());it!=mRemoteDirectories.end();++it) - delete it->second ; + for(uint32_t i=0;i friend_set ; - mServCtrl->getPeersConnected(getServiceInfo().mServiceType, friend_set); + { + std::list friend_lst ; - for(std::map::iterator it(mRemoteDirectories.begin());it!=mRemoteDirectories.end();) - if(friend_set.find(it->first) == friend_set.end()) + rsPeers->getFriendList(friend_lst); + + for(std::list::const_iterator it(friend_lst.begin());it!=friend_lst.end();++it) + friend_set.insert(*it) ; + } + + for(uint32_t i=0;ipeerId()) == friend_set.end()) { - P3FILELISTS_DEBUG() << " removing file list of non friend " << it->first << std::endl; + P3FILELISTS_DEBUG() << " removing file list of non friend " << mRemoteDirectories[i]->peerId() << std::endl; - delete it->second ; - std::map::iterator tmp(it) ; - ++tmp ; - mRemoteDirectories.erase(it) ; - it=tmp ; + delete mRemoteDirectories[i]; + mRemoteDirectories[i] = NULL ; mUpdateFlags |= P3FILELISTS_UPDATE_FLAG_REMOTE_MAP_CHANGED ; - } - else - ++it ; - // look through the list of friends, and add a directory storage when it's missing + friend_set.erase(mRemoteDirectories[i]->peerId()); + + mFriendIndexMap.erase(mRemoteDirectories[i]->peerId()); + mFriendIndexTab[i].clear(); + } + + // look through the remaining list of friends, which are the ones for which no remoteDirectoryStorage class has been allocated. // for(std::set::const_iterator it(friend_set.begin());it!=friend_set.end();++it) - if(mRemoteDirectories.find(*it) == mRemoteDirectories.end()) - { - P3FILELISTS_DEBUG() << " adding missing remote dir entry for friend " << *it << std::endl; + { + P3FILELISTS_DEBUG() << " adding missing remote dir entry for friend " << *it << std::endl; - mRemoteDirectories[*it] = new RemoteDirectoryStorage(makeRemoteFileName(*it)); + uint32_t i; + for(i=0;i::const_iterator it = mFriendIndexMap.find(pid) ; + + if(it == mFriendIndexMap.end()) + { + // allocate a new index for that friend, and tell that we should save. + uint32_t found = 0 ; + for(uint32_t i=1;isecond; +} + +const RsPeerId& p3FileDatabase::getFriendFromIndex(uint32_t indx) const +{ + static const RsPeerId null_id ; + + if(indx >= mFriendIndexTab.size()) + return null_id ; + + if(mFriendIndexTab[indx].isNull()) + { + std::cerr << "(EE) null friend id requested from index " << indx << ": this is a bug, most likely" << std::endl; + return null_id ; + } + + return mFriendIndexTab[indx]; +} +bool p3FileDatabase::convertPointerToEntryIndex(void *p, EntryIndex& e, uint32_t& friend_index) +{ + // trust me, I can do this ;-) + + e = EntryIndex( *reinterpret_cast(&p) & ENTRY_INDEX_BIT_MASK ) ; + friend_index = (*reinterpret_cast(&p)) >> NB_ENTRY_INDEX_BITS ; + + return true; +} +bool p3FileDatabase::convertEntryIndexToPointer(EntryIndex& e, uint32_t fi, void *& p) +{ + // the pointer is formed the following way: + // + // [ 10 bits | 22 bits ] + // + // This means that the whoel software has the following build-in limitation: + // * 1024 friends + // * 4M shared files. + + uint32_t fe = (uint32_t)e ; + + if(fi >= (1<= (1<< NB_ENTRY_INDEX_BITS)) + { + std::cerr << "(EE) cannot convert entry index " << e << " of friend with index " << fi << " to pointer." << std::endl; + return false ; + } + + p = reinterpret_cast( (fi << NB_ENTRY_INDEX_BITS ) + (fe & ENTRY_INDEX_BIT_MASK)) ; + + return true; +} int p3FileDatabase::RequestDirDetails(void *ref, DirDetails&, FileSearchFlags) const { - NOT_IMPLEMENTED(); + uint32_t fi; + EntryIndex e ; + + convertPointerToEntryIndex(ref,e,fi) ; +#warning code needed here + return 0; } -int p3FileDatabase::RequestDirDetails(const RsPeerId& uid,const std::string& path, DirDetails &details) +int p3FileDatabase::RequestDirDetails(const RsPeerId& uid,const std::string& path, DirDetails &details) const { NOT_IMPLEMENTED(); return 0; @@ -285,11 +386,13 @@ bool p3FileDatabase::search(const RsFileHash &hash, FileSearchFlags hintflags, F EntryIndex indx = *res.begin() ; // no need to report dupicates mLocalSharedDirs->getFileInfo(indx,info) ; + + return true; } else { NOT_IMPLEMENTED(); - return 0; + return false; } } diff --git a/libretroshare/src/file_sharing/p3filelists.h b/libretroshare/src/file_sharing/p3filelists.h index 0d631cdbd..d7c8e2250 100644 --- a/libretroshare/src/file_sharing/p3filelists.h +++ b/libretroshare/src/file_sharing/p3filelists.h @@ -84,7 +84,7 @@ class p3FileDatabase: public p3Service, public p3Config, public ftSearch //, pub void stopThreads() ; void startThreads() ; - int RequestDirDetails(const RsPeerId& uid, const std::string& path, DirDetails &details); + int RequestDirDetails(const RsPeerId& uid, const std::string& path, DirDetails &details)const; int RequestDirDetails(const std::string& path, DirDetails &details) const ; // void * here is the type expected by the abstract model index from Qt. It gets turned into a DirectoryStorage::EntryIndex internally. @@ -144,13 +144,26 @@ class p3FileDatabase: public p3Service, public p3Config, public ftSearch //, pub // Directory storage hierarchies // - std::map mRemoteDirectories ; + // The remote one is the reference for the PeerId index below: + // RemoteDirectories[ getFriendIndex(pid) - 1] = RemoteDirectoryStorage(pid) + + std::vector mRemoteDirectories ; LocalDirectoryStorage *mLocalSharedDirs ; RemoteDirectoryUpdater *mRemoteDirWatcher ; LocalDirectoryUpdater *mLocalDirWatcher ; - // We use a shared file cache as well, to avoid re-hashing files with known modification TS and equal name. + // utility functions to make/get a pointer out of an (EntryIndex,PeerId) pair. This is further documented in the .cc + + static bool convertEntryIndexToPointer(EntryIndex& e,uint32_t friend_index,void *& p); + static bool convertPointerToEntryIndex(void *p, EntryIndex& e, uint32_t& friend_index) ; + uint32_t getFriendIndex(const RsPeerId& pid); + const RsPeerId& getFriendFromIndex(uint32_t indx) const; + + std::map mFriendIndexMap ; + std::vector mFriendIndexTab; + + // We use a shared file cache as well, to avoid re-hashing files with known modification TS and equal name. // HashStorage *mHashCache ;