fixed terrible cost of calling requestDirDetails before createIndex

This commit is contained in:
MrAlice 2016-09-15 10:41:40 +02:00
parent f58e9c1a73
commit ca30b0da44
10 changed files with 90 additions and 35 deletions

View File

@ -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<DirEntry*>(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)

View File

@ -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<std::string,time_t>& subdirs);
bool removeDirectory(DirectoryStorage::EntryIndex indx) ;
bool checkIndex(DirectoryStorage::EntryIndex indx,uint8_t type) const;

View File

@ -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)
{

View File

@ -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<std::string, time_t> &subdirs) ;
bool updateSubFilesList(const EntryIndex& indx, const std::map<std::string, FileTS> &subfiles, std::map<std::string, FileTS> &new_files) ;

View File

@ -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;i<mRemoteDirectories.size();++i)
{
convertEntryIndexToPointer(mRemoteDirectories[i]->root(),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

View File

@ -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.

View File

@ -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) ;

View File

@ -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<std::string> keywords, std::list<DirDetails> &results,FileSearchFlags flags);

View File

@ -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<std::string> keywords, std::list<DirDetails> &results,FileSearchFlags flags) = 0;
virtual int SearchKeywords(std::list<std::string> keywords, std::list<DirDetails> &results,FileSearchFlags flags,const RsPeerId& peer_id) = 0;

View File

@ -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);