mirror of
https://github.com/RetroShare/RetroShare.git
synced 2024-12-28 08:59:37 -05:00
Merge pull request #581 from csoler/v0.6-FileListsOptim
added change in TS for shared directories when virtual name changes
This commit is contained in:
commit
2faefe8c9d
@ -152,14 +152,14 @@ bool InternalFileHierarchyStorage::isIndexValid(DirectoryStorage::EntryIndex e)
|
||||
return e < mNodes.size() && mNodes[e] != NULL ;
|
||||
}
|
||||
|
||||
bool InternalFileHierarchyStorage::updateSubDirectoryList(const DirectoryStorage::EntryIndex& indx,const std::map<std::string,time_t>& subdirs,const RsFileHash& random_hash_seed)
|
||||
bool InternalFileHierarchyStorage::updateSubDirectoryList(const DirectoryStorage::EntryIndex& indx, const std::set<std::string>& subdirs, const RsFileHash& random_hash_seed)
|
||||
{
|
||||
if(!checkIndex(indx,FileStorageNode::TYPE_DIR))
|
||||
return false;
|
||||
|
||||
DirEntry& d(*static_cast<DirEntry*>(mNodes[indx])) ;
|
||||
|
||||
std::map<std::string,time_t> should_create(subdirs);
|
||||
std::set<std::string> should_create(subdirs);
|
||||
|
||||
for(uint32_t i=0;i<d.subdirs.size();)
|
||||
if(subdirs.find(static_cast<DirEntry*>(mNodes[d.subdirs[i]])->dir_name) == subdirs.end())
|
||||
@ -181,13 +181,13 @@ bool InternalFileHierarchyStorage::updateSubDirectoryList(const DirectoryStorage
|
||||
++i;
|
||||
}
|
||||
|
||||
for(std::map<std::string,time_t>::const_iterator it(should_create.begin());it!=should_create.end();++it)
|
||||
for(std::set<std::string>::const_iterator it(should_create.begin());it!=should_create.end();++it)
|
||||
{
|
||||
#ifdef DEBUG_DIRECTORY_STORAGE
|
||||
std::cerr << "[directory storage] adding new subdirectory " << it->first << " at index " << mNodes.size() << std::endl;
|
||||
#endif
|
||||
|
||||
DirEntry *de = new DirEntry(it->first) ;
|
||||
DirEntry *de = new DirEntry(*it) ;
|
||||
|
||||
de->row = mNodes.size();
|
||||
de->parent_index = indx;
|
||||
|
@ -95,7 +95,7 @@ public:
|
||||
int parentRow(DirectoryStorage::EntryIndex e);
|
||||
bool isIndexValid(DirectoryStorage::EntryIndex e) const;
|
||||
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, const RsFileHash &random_hash_seed);
|
||||
bool updateSubDirectoryList(const DirectoryStorage::EntryIndex& indx, const std::set<std::string>& subdirs, const RsFileHash &random_hash_seed);
|
||||
bool removeDirectory(DirectoryStorage::EntryIndex indx) ;
|
||||
bool checkIndex(DirectoryStorage::EntryIndex indx,uint8_t type) const;
|
||||
bool updateSubFilesList(const DirectoryStorage::EntryIndex& indx,const std::map<std::string,DirectoryStorage::FileTS>& subfiles,std::map<std::string,DirectoryStorage::FileTS>& new_files);
|
||||
|
@ -130,7 +130,7 @@ bool DirectoryStorage::setDirectoryUpdateTime (EntryIndex index,time_t update
|
||||
bool DirectoryStorage::setDirectoryRecursModTime(EntryIndex index,time_t rec_md_TS) { RS_STACK_MUTEX(mDirStorageMtx) ; return mFileHierarchy->setTS(index,rec_md_TS,&InternalFileHierarchyStorage::DirEntry::dir_most_recent_time); }
|
||||
bool DirectoryStorage::setDirectoryLocalModTime (EntryIndex index,time_t loc_md_TS) { RS_STACK_MUTEX(mDirStorageMtx) ; return mFileHierarchy->setTS(index,loc_md_TS,&InternalFileHierarchyStorage::DirEntry::dir_modtime ); }
|
||||
|
||||
bool DirectoryStorage::updateSubDirectoryList(const EntryIndex& indx,const std::map<std::string,time_t>& subdirs,const RsFileHash& hash_salt)
|
||||
bool DirectoryStorage::updateSubDirectoryList(const EntryIndex& indx, const std::set<std::string> &subdirs, const RsFileHash& hash_salt)
|
||||
{
|
||||
RS_STACK_MUTEX(mDirStorageMtx) ;
|
||||
bool res = mFileHierarchy->updateSubDirectoryList(indx,subdirs,hash_salt) ;
|
||||
@ -351,38 +351,63 @@ int LocalDirectoryStorage::searchHash(const RsFileHash& hash, RsFileHash& real_h
|
||||
|
||||
void LocalDirectoryStorage::setSharedDirectoryList(const std::list<SharedDirInfo>& lst)
|
||||
{
|
||||
RS_STACK_MUTEX(mDirStorageMtx) ;
|
||||
std::set<std::string> dirs_with_new_virtualname ;
|
||||
|
||||
// Chose virtual name if not supplied, and remove duplicates.
|
||||
{
|
||||
RS_STACK_MUTEX(mDirStorageMtx) ;
|
||||
|
||||
std::set<std::string> virtual_names ; // maps virtual to real name
|
||||
std::list<SharedDirInfo> processed_list ;
|
||||
// Chose virtual name if not supplied, and remove duplicates.
|
||||
|
||||
for(std::list<SharedDirInfo>::const_iterator it(lst.begin());it!= lst.end();++it)
|
||||
{
|
||||
int i=0;
|
||||
std::string candidate_virtual_name = it->virtualname ;
|
||||
std::set<std::string> virtual_names ; // maps virtual to real name
|
||||
std::list<SharedDirInfo> processed_list ;
|
||||
|
||||
if(candidate_virtual_name.empty())
|
||||
candidate_virtual_name = RsDirUtil::getTopDir(it->filename);
|
||||
for(std::list<SharedDirInfo>::const_iterator it(lst.begin());it!= lst.end();++it)
|
||||
{
|
||||
int i=0;
|
||||
std::string candidate_virtual_name = it->virtualname ;
|
||||
|
||||
while(virtual_names.find(candidate_virtual_name) != virtual_names.end())
|
||||
rs_sprintf_append(candidate_virtual_name, "-%d", ++i);
|
||||
if(candidate_virtual_name.empty())
|
||||
candidate_virtual_name = RsDirUtil::getTopDir(it->filename);
|
||||
|
||||
SharedDirInfo d(*it);
|
||||
d.virtualname = candidate_virtual_name ;
|
||||
processed_list.push_back(d) ;
|
||||
while(virtual_names.find(candidate_virtual_name) != virtual_names.end())
|
||||
rs_sprintf_append(candidate_virtual_name, "-%d", ++i);
|
||||
|
||||
virtual_names.insert(candidate_virtual_name) ;
|
||||
}
|
||||
SharedDirInfo d(*it);
|
||||
d.virtualname = candidate_virtual_name ;
|
||||
processed_list.push_back(d) ;
|
||||
|
||||
mLocalDirs.clear();
|
||||
virtual_names.insert(candidate_virtual_name) ;
|
||||
}
|
||||
|
||||
for(std::list<SharedDirInfo>::const_iterator it(processed_list.begin());it!=processed_list.end();++it)
|
||||
mLocalDirs[it->filename] = *it;
|
||||
// now for each member of the processed list, check if it is an existing shared directory that has been changed. If so, we need to update the dir TS of that directory
|
||||
|
||||
mTSChanged = true ;
|
||||
std::map<std::string,SharedDirInfo> new_dirs ;
|
||||
|
||||
for(std::list<SharedDirInfo>::const_iterator it(processed_list.begin());it!=processed_list.end();++it)
|
||||
{
|
||||
std::map<std::string,SharedDirInfo>::iterator it2 = mLocalDirs.find(it->filename) ;
|
||||
|
||||
if(it2 != mLocalDirs.end() && it2->second.virtualname != it->virtualname)
|
||||
dirs_with_new_virtualname.insert(it->filename) ;
|
||||
|
||||
new_dirs[it->filename] = *it;
|
||||
}
|
||||
|
||||
mLocalDirs = new_dirs ;
|
||||
}
|
||||
|
||||
mTSChanged = true ;
|
||||
|
||||
// now update the TS off-mutex.
|
||||
|
||||
for(DirIterator dirit(this,root());dirit;++dirit)
|
||||
if(dirs_with_new_virtualname.find(dirit.name()) != dirs_with_new_virtualname.end())
|
||||
{
|
||||
std::cerr << "Updating TS of local dir \"" << dirit.name() << "\" with changed virtual name" << std::endl;
|
||||
setDirectoryLocalModTime(*dirit,time(NULL));
|
||||
}
|
||||
}
|
||||
|
||||
void LocalDirectoryStorage::getSharedDirectoryList(std::list<SharedDirInfo>& lst)
|
||||
{
|
||||
RS_STACK_MUTEX(mDirStorageMtx) ;
|
||||
@ -392,19 +417,6 @@ void LocalDirectoryStorage::getSharedDirectoryList(std::list<SharedDirInfo>& lst
|
||||
for(std::map<std::string,SharedDirInfo>::iterator it(mLocalDirs.begin());it!=mLocalDirs.end();++it)
|
||||
lst.push_back(it->second) ;
|
||||
}
|
||||
|
||||
static bool sameLists(const std::list<RsNodeGroupId>& l1,const std::list<RsNodeGroupId>& l2)
|
||||
{
|
||||
std::list<RsNodeGroupId>::const_iterator it1(l1.begin()) ;
|
||||
std::list<RsNodeGroupId>::const_iterator it2(l2.begin()) ;
|
||||
|
||||
for(; (it1!=l1.end() && it2!=l2.end());++it1,++it2)
|
||||
if(*it1 != *it2)
|
||||
return false ;
|
||||
|
||||
return it1 == l1.end() && it2 == l2.end() ;
|
||||
}
|
||||
|
||||
void LocalDirectoryStorage::updateShareFlags(const SharedDirInfo& info)
|
||||
{
|
||||
bool changed = false ;
|
||||
@ -423,7 +435,7 @@ void LocalDirectoryStorage::updateShareFlags(const SharedDirInfo& info)
|
||||
// we compare the new info with the old one. If the two group lists have a different order, they will be seen as different. Not a big deal. We just
|
||||
// want to make sure that if they are different, flags get updated.
|
||||
|
||||
if(!sameLists(it->second.parent_groups,info.parent_groups) || it->second.filename != info.filename || it->second.shareflags != info.shareflags || it->second.virtualname != info.virtualname)
|
||||
if(!SharedDirInfo::sameLists(it->second.parent_groups,info.parent_groups) || it->second.filename != info.filename || it->second.shareflags != info.shareflags || it->second.virtualname != info.virtualname)
|
||||
{
|
||||
it->second = info;
|
||||
|
||||
|
@ -132,7 +132,7 @@ class DirectoryStorage
|
||||
// Sets the subdirectory/subfiles list of entry indx the supplied one, possible adding and removing directories (resp.files). New directories are set empty with
|
||||
// just a name and need to be updated later on. New files are returned in a list so that they can be sent to hash cache.
|
||||
//
|
||||
bool updateSubDirectoryList(const EntryIndex& indx, const std::map<std::string, time_t> &subdirs, const RsFileHash &random_hash_salt) ;
|
||||
bool updateSubDirectoryList(const EntryIndex& indx, const std::set<std::string>& subdirs, const RsFileHash &random_hash_salt) ;
|
||||
bool updateSubFilesList(const EntryIndex& indx, const std::map<std::string, FileTS> &subfiles, std::map<std::string, FileTS> &new_files) ;
|
||||
bool removeDirectory(const EntryIndex& indx) ;
|
||||
|
||||
|
@ -108,10 +108,10 @@ void LocalDirectoryUpdater::sweepSharedDirectories()
|
||||
std::list<SharedDirInfo> shared_directory_list ;
|
||||
mSharedDirectories->getSharedDirectoryList(shared_directory_list);
|
||||
|
||||
std::map<std::string,time_t> sub_dir_list ;
|
||||
std::set<std::string> sub_dir_list ;
|
||||
|
||||
for(std::list<SharedDirInfo>::const_iterator real_dir_it(shared_directory_list.begin());real_dir_it!=shared_directory_list.end();++real_dir_it)
|
||||
sub_dir_list[(*real_dir_it).filename] = 0 ;
|
||||
sub_dir_list.insert( (*real_dir_it).filename ) ;
|
||||
|
||||
// make sure that entries in stored_dir_it are the same than paths in real_dir_it, and in the same order.
|
||||
|
||||
@ -150,12 +150,13 @@ void LocalDirectoryUpdater::recursUpdateSharedDir(const std::string& cumulated_p
|
||||
return;
|
||||
}
|
||||
|
||||
if(dirIt.dir_modtime() != dir_local_mod_time)
|
||||
if(dirIt.dir_modtime() > dir_local_mod_time) // the > is because we may have changed the virtual name, and therefore the TS wont match.
|
||||
// we only want to detect when the directory has changed on the disk
|
||||
{
|
||||
// collect subdirs and subfiles
|
||||
|
||||
std::map<std::string,DirectoryStorage::FileTS> subfiles ;
|
||||
std::map<std::string,time_t> subdirs ;
|
||||
std::set<std::string> subdirs ;
|
||||
|
||||
for(;dirIt.isValid();dirIt.next())
|
||||
{
|
||||
@ -168,7 +169,7 @@ void LocalDirectoryUpdater::recursUpdateSharedDir(const std::string& cumulated_p
|
||||
#endif
|
||||
break;
|
||||
|
||||
case librs::util::FolderIterator::TYPE_DIR: subdirs[dirIt.file_name()] = dirIt.file_modtime();
|
||||
case librs::util::FolderIterator::TYPE_DIR: subdirs.insert(dirIt.file_name());
|
||||
#ifdef DEBUG_LOCAL_DIR_UPDATER
|
||||
std::cerr << " adding sub-dir \"" << dirIt.file_name() << "\"" << std::endl;
|
||||
#endif
|
||||
|
@ -100,6 +100,18 @@ const uint32_t RS_FILE_EXTRA_DELETE = 0x0010;
|
||||
|
||||
struct SharedDirInfo
|
||||
{
|
||||
static bool sameLists(const std::list<RsNodeGroupId>& l1,const std::list<RsNodeGroupId>& l2)
|
||||
{
|
||||
std::list<RsNodeGroupId>::const_iterator it1(l1.begin()) ;
|
||||
std::list<RsNodeGroupId>::const_iterator it2(l2.begin()) ;
|
||||
|
||||
for(; (it1!=l1.end() && it2!=l2.end());++it1,++it2)
|
||||
if(*it1 != *it2)
|
||||
return false ;
|
||||
|
||||
return it1 == l1.end() && it2 == l2.end() ;
|
||||
}
|
||||
|
||||
std::string filename ;
|
||||
std::string virtualname ;
|
||||
FileStorageFlags shareflags ; // combnation of DIR_FLAGS_ANONYMOUS_DOWNLOAD | DIR_FLAGS_BROWSABLE | ...
|
||||
|
Loading…
Reference in New Issue
Block a user