diff --git a/libretroshare/src/file_sharing/dir_hierarchy.cc b/libretroshare/src/file_sharing/dir_hierarchy.cc index fe5f67d5c..cbe6eeab6 100644 --- a/libretroshare/src/file_sharing/dir_hierarchy.cc +++ b/libretroshare/src/file_sharing/dir_hierarchy.cc @@ -94,6 +94,27 @@ bool InternalFileHierarchyStorage::getIndexFromFileHash(const RsFileHash& hash,D return true; } +bool InternalFileHierarchyStorage::getChildIndex(DirectoryStorage::EntryIndex e,int row,DirectoryStorage::EntryIndex& c) const +{ + if(!checkIndex(e,FileStorageNode::TYPE_DIR)) + return false ; + + const DirEntry& d = *static_cast(mNodes[e]) ; + + if((uint32_t)row < d.subdirs.size()) + { + c = d.subdirs[row] ; + return true ; + } + + if((uint32_t)row < d.subdirs.size() + d.subfiles.size()) + { + c = d.subfiles[row - (int)d.subdirs.size()] ; + return true ; + } + return false; +} + int InternalFileHierarchyStorage::parentRow(DirectoryStorage::EntryIndex e) { if(!checkIndex(e,FileStorageNode::TYPE_DIR | FileStorageNode::TYPE_FILE) || e==0) diff --git a/libretroshare/src/file_sharing/dir_hierarchy.h b/libretroshare/src/file_sharing/dir_hierarchy.h index fb83e5d9d..905fe0552 100644 --- a/libretroshare/src/file_sharing/dir_hierarchy.h +++ b/libretroshare/src/file_sharing/dir_hierarchy.h @@ -95,6 +95,7 @@ public: int parentRow(DirectoryStorage::EntryIndex e); bool isIndexValid(DirectoryStorage::EntryIndex e) const; bool stampDirectory(const DirectoryStorage::EntryIndex& indx); + bool getChildIndex(DirectoryStorage::EntryIndex e,int row,DirectoryStorage::EntryIndex& c) const; bool updateSubDirectoryList(const DirectoryStorage::EntryIndex& indx,const std::map& subdirs); bool removeDirectory(DirectoryStorage::EntryIndex indx) ; bool checkIndex(DirectoryStorage::EntryIndex indx,uint8_t type) const; diff --git a/libretroshare/src/file_sharing/directory_storage.cc b/libretroshare/src/file_sharing/directory_storage.cc index 2a7cd8f91..faa3ceaee 100644 --- a/libretroshare/src/file_sharing/directory_storage.cc +++ b/libretroshare/src/file_sharing/directory_storage.cc @@ -96,6 +96,12 @@ int DirectoryStorage::parentRow(EntryIndex e) const return mFileHierarchy->parentRow(e) ; } +bool DirectoryStorage::getChildIndex(EntryIndex e,int row,EntryIndex& c) const +{ + RS_STACK_MUTEX(mDirStorageMtx) ; + + return mFileHierarchy->getChildIndex(e,row,c) ; +} uint32_t DirectoryStorage::getEntryType(const EntryIndex& indx) { diff --git a/libretroshare/src/file_sharing/directory_storage.h b/libretroshare/src/file_sharing/directory_storage.h index be420f618..dd1202726 100644 --- a/libretroshare/src/file_sharing/directory_storage.h +++ b/libretroshare/src/file_sharing/directory_storage.h @@ -118,6 +118,7 @@ class DirectoryStorage EntryIndex root() const ; // returns the index of the root directory entry. const RsPeerId& peerId() const { return mPeerId ; } int parentRow(EntryIndex e) const ; + bool getChildIndex(EntryIndex e,int row,EntryIndex& c) const; bool updateSubDirectoryList(const EntryIndex& indx, const std::map &subdirs) ; bool updateSubFilesList(const EntryIndex& indx, const std::map &subfiles, std::map &new_files) ; diff --git a/libretroshare/src/file_sharing/p3filelists.cc b/libretroshare/src/file_sharing/p3filelists.cc index 0a51b72dd..5a7621b17 100644 --- a/libretroshare/src/file_sharing/p3filelists.cc +++ b/libretroshare/src/file_sharing/p3filelists.cc @@ -598,6 +598,51 @@ void p3FileDatabase::requestDirUpdate(void *ref) P3FILELISTS_DEBUG() << " Succeed." << std::endl; } +bool p3FileDatabase::findChildPointer(void *ref, int row, void *& result, FileSearchFlags flags) const +{ + RS_STACK_MUTEX(mFLSMtx) ; + + result = NULL ; + + if (ref == NULL) + if(flags & RS_FILE_HINTS_LOCAL) + { + if(row != 0) + return false ; + + convertEntryIndexToPointer(0,0,result); + + return true ; + } + else for(uint32_t i=0;iroot(),i+1,result); + + return true; + } + + uint32_t fi; + DirectoryStorage::EntryIndex e ; + + convertPointerToEntryIndex(ref,e,fi); + + // check consistency + if( (fi == 0 && !(flags & RS_FILE_HINTS_LOCAL)) || (fi > 0 && (flags & RS_FILE_HINTS_LOCAL))) + { + P3FILELISTS_ERROR() << "(EE) remote request on local index or local request on remote index. This should not happen." << std::endl; + return false ; + } + DirectoryStorage *storage = (fi==0)? ((DirectoryStorage*)mLocalSharedDirs) : ((DirectoryStorage*)mRemoteDirectories[fi-1]); + + // Case where the index is the top of a single person. Can be us, or a friend. + + EntryIndex c = 0; + bool res = storage->getChildIndex(e,row,c); + + convertEntryIndexToPointer(c,fi,result) ; + + return res; +} // This function converts a pointer into directory details, to be used by the AbstractItemModel for browsing the files. int p3FileDatabase::RequestDirDetails(void *ref, DirDetails& d, FileSearchFlags flags) const diff --git a/libretroshare/src/file_sharing/p3filelists.h b/libretroshare/src/file_sharing/p3filelists.h index f832dfc53..f72628877 100644 --- a/libretroshare/src/file_sharing/p3filelists.h +++ b/libretroshare/src/file_sharing/p3filelists.h @@ -116,6 +116,7 @@ class p3FileDatabase: public p3Service, public p3Config, public ftSearch //, pub int RequestDirDetails(const RsPeerId& uid, const std::string& path, DirDetails &details)const; int RequestDirDetails(const std::string& path, DirDetails &details) const ; + bool findChildPointer(void *ref, int row, void *& result, FileSearchFlags flags) const; // void * here is the type expected by the abstract model index from Qt. It gets turned into a DirectoryStorage::EntryIndex internally. diff --git a/libretroshare/src/ft/ftserver.cc b/libretroshare/src/ft/ftserver.cc index 06c538a70..6d6547884 100644 --- a/libretroshare/src/ft/ftserver.cc +++ b/libretroshare/src/ft/ftserver.cc @@ -535,6 +535,10 @@ int ftServer::RequestDirDetails(const RsPeerId& uid, const std::string& path, Di return mFileDatabase->RequestDirDetails(uid, path, details); } +bool ftServer::findChildPointer(void *ref, int row, void *& result, FileSearchFlags flags) +{ + return mFileDatabase->findChildPointer(ref,row,result,flags) ; +} int ftServer::RequestDirDetails(void *ref, DirDetails &details, FileSearchFlags flags) { return mFileDatabase->RequestDirDetails(ref,details,flags) ; diff --git a/libretroshare/src/ft/ftserver.h b/libretroshare/src/ft/ftserver.h index e61a72e49..cc4004263 100644 --- a/libretroshare/src/ft/ftserver.h +++ b/libretroshare/src/ft/ftserver.h @@ -173,6 +173,7 @@ public: ***/ virtual int RequestDirDetails(const RsPeerId& uid, const std::string& path, DirDetails &details); virtual int RequestDirDetails(void *ref, DirDetails &details, FileSearchFlags flags); + virtual bool findChildPointer(void *ref, int row, void *& result, FileSearchFlags flags) ; virtual uint32_t getType(void *ref,FileSearchFlags flags) ; virtual int SearchKeywords(std::list keywords, std::list &results,FileSearchFlags flags); diff --git a/libretroshare/src/retroshare/rsfiles.h b/libretroshare/src/retroshare/rsfiles.h index 247270007..7f6de8be9 100644 --- a/libretroshare/src/retroshare/rsfiles.h +++ b/libretroshare/src/retroshare/rsfiles.h @@ -182,7 +182,8 @@ class RsFiles */ virtual int RequestDirDetails(const RsPeerId& uid, const std::string& path, DirDetails &details) = 0; virtual int RequestDirDetails(void *ref, DirDetails &details, FileSearchFlags flags) = 0; - virtual uint32_t getType(void *ref,FileSearchFlags flags) = 0; + virtual bool findChildPointer(void *ref, int row, void *& result, FileSearchFlags flags) =0; + virtual uint32_t getType(void *ref,FileSearchFlags flags) = 0; virtual int SearchKeywords(std::list keywords, std::list &results,FileSearchFlags flags) = 0; virtual int SearchKeywords(std::list keywords, std::list &results,FileSearchFlags flags,const RsPeerId& peer_id) = 0; diff --git a/retroshare-gui/src/gui/RemoteDirModel.cpp b/retroshare-gui/src/gui/RemoteDirModel.cpp index 1afdc94ef..a2f3fd09b 100644 --- a/retroshare-gui/src/gui/RemoteDirModel.cpp +++ b/retroshare-gui/src/gui/RemoteDirModel.cpp @@ -710,6 +710,9 @@ QModelIndex TreeStyle_RDM::index(int row, int column, const QModelIndex & parent std::cerr << ": row:" << row << " col:" << column << " "; #endif + // This function is used extensively. There's no way we can use requestDirDetails() in it, which would + // cause far too much overhead. So we use a dedicated function that only grabs the required information. + if(row < 0) return QModelIndex() ; @@ -722,44 +725,15 @@ QModelIndex TreeStyle_RDM::index(int row, int column, const QModelIndex & parent } ********/ - DirDetails details ; + void *result ; - if (! requestDirDetails(ref, RemoteMode,details)) - { -#ifdef RDM_DEBUG - std::cerr << "lookup failed -> invalid"; - std::cerr << std::endl; -#endif + if(rsFiles->findChildPointer(ref, row, result, ((RemoteMode) ? RS_FILE_HINTS_REMOTE : RS_FILE_HINTS_LOCAL))) + return createIndex(row, column, result) ; + else return QModelIndex(); - } - - - /* now iterate through the details to - * get the reference number - */ - - if (row >= (int) details.children.size()) - { -#ifdef RDM_DEBUG - std::cerr << "wrong number of children -> invalid"; - std::cerr << std::endl; -#endif - return QModelIndex(); - } - -#ifdef RDM_DEBUG - std::cerr << "success index(" << row << "," << column << "," << details->childrenVector[row].ref << ")"; - std::cerr << std::endl; -#endif - - /* we can just grab the reference now */ - -#ifdef RDM_DEBUG - std::cerr << "Creating index 1 row=" << row << ", column=" << column << ", ref=" << (void*)details.children[row].ref << std::endl; -#endif - return createIndex(row, column, details.children[row].ref); } + QModelIndex FlatStyle_RDM::index(int row, int column, const QModelIndex & parent) const { Q_UNUSED(parent);