From 8dacb22049d9748e27462712248a81b65bb9507c Mon Sep 17 00:00:00 2001 From: csoler Date: Thu, 3 Nov 2016 22:32:27 +0100 Subject: [PATCH] reducing linear cost of allocateNewIndex to constant. Should improve huge lags when receiving big file lists for the first time --- .../src/file_sharing/dir_hierarchy.cc | 57 +++++++++++-------- .../src/file_sharing/dir_hierarchy.h | 5 ++ libretroshare/src/file_sharing/p3filelists.cc | 4 +- 3 files changed, 39 insertions(+), 27 deletions(-) diff --git a/libretroshare/src/file_sharing/dir_hierarchy.cc b/libretroshare/src/file_sharing/dir_hierarchy.cc index 07e395455..54bd13cd1 100644 --- a/libretroshare/src/file_sharing/dir_hierarchy.cc +++ b/libretroshare/src/file_sharing/dir_hierarchy.cc @@ -299,8 +299,7 @@ bool InternalFileHierarchyStorage::updateSubFilesList(const DirectoryStorage::En std::cerr << "[directory storage] removing non existing file " << f.file_name << " at index " << d.subfiles[i] << std::endl; #endif - delete mNodes[d.subfiles[i]] ; - mNodes[d.subfiles[i]] = NULL ; + deleteNode(d.subfiles[i]) ; d.subfiles[i] = d.subfiles[d.subfiles.size()-1] ; d.subfiles.pop_back(); @@ -374,23 +373,29 @@ bool InternalFileHierarchyStorage::updateFile(const DirectoryStorage::EntryIndex return true; } +void InternalFileHierarchyStorage::deleteNode(uint32_t index) +{ + if(mNodes[index] != NULL) + { + delete mNodes[index] ; + mFreeNodes.push_back(index) ; + mNodes[index] = NULL ; + } +} + DirectoryStorage::EntryIndex InternalFileHierarchyStorage::allocateNewIndex() { - int found = -1; - for(uint32_t j=0;j& subdirs_hash,const std::vector& subfiles_array) @@ -534,8 +539,7 @@ bool InternalFileHierarchyStorage::updateDirEntry(const DirectoryStorage::EntryI std::cerr << "(EE) Cannot delete node of index " << it->second << " because it is not a file. Inconsistency error!" << std::endl; continue ; } - delete mNodes[it->second] ; - mNodes[it->second] = NULL ; + deleteNode(it->second) ; } // now update row and parent index for all subnodes @@ -749,6 +753,8 @@ bool InternalFileHierarchyStorage::check(std::string& error_string) // checks co std::vector hits(mNodes.size(),0) ; // count hits of children. Should be 1 for all in the end. Otherwise there's an error. hits[0] = 1 ; // because 0 is never the child of anyone + mFreeNodes.clear(); + for(uint32_t i=0;itype() == FileStorageNode::TYPE_DIR) { @@ -796,13 +802,15 @@ bool InternalFileHierarchyStorage::check(std::string& error_string) // checks co } } } + else if(mNodes[i] == NULL) + mFreeNodes.push_back(i) ; for(uint32_t i=0;i mFreeNodes ; // keeps a list of free nodes in order to make insert effcieint std::vector mNodes;// uses pointers to keep information about valid/invalid objects. void compress() ; // use empty space in the vector, mostly due to deleted entries. This is a complicated operation, mostly due to @@ -159,6 +160,10 @@ private: DirectoryStorage::EntryIndex allocateNewIndex(); + // Deletes an existing entry in mNodes, and keeps record of the indices that get freed. + + void deleteNode(DirectoryStorage::EntryIndex); + // Removes the given subdirectory from the parent node and all its pendign subdirs. Files are kept, and will go during the cleaning // phase. That allows to keep file information when moving them around. diff --git a/libretroshare/src/file_sharing/p3filelists.cc b/libretroshare/src/file_sharing/p3filelists.cc index 21875efad..211eca2e7 100644 --- a/libretroshare/src/file_sharing/p3filelists.cc +++ b/libretroshare/src/file_sharing/p3filelists.cc @@ -543,7 +543,7 @@ uint32_t p3FileDatabase::locked_getFriendIndex(const RsPeerId& pid) mUpdateFlags |= P3FILELISTS_UPDATE_FLAG_REMOTE_MAP_CHANGED ; #ifdef DEBUG_P3FILELISTS - P3FILELISTS_DEBUG() << " adding missing remote dir entry for friend " << *it << ", with index " << friend_index << std::endl; + P3FILELISTS_DEBUG() << " adding missing remote dir entry for friend " << pid << ", with index " << it->second << std::endl; #endif } @@ -570,7 +570,7 @@ uint32_t p3FileDatabase::locked_getFriendIndex(const RsPeerId& pid) mUpdateFlags |= P3FILELISTS_UPDATE_FLAG_REMOTE_MAP_CHANGED ; #ifdef DEBUG_P3FILELISTS - P3FILELISTS_DEBUG() << " adding missing remote dir entry for friend " << *it << ", with index " << friend_index << std::endl; + P3FILELISTS_DEBUG() << " adding missing remote dir entry for friend " << pid << ", with index " << it->second << std::endl; #endif }