merged modifications from origin

This commit is contained in:
mr-alice 2016-09-15 21:45:00 +02:00
parent ca30b0da44
commit d3b46221ff
9 changed files with 96 additions and 64 deletions

View File

@ -129,14 +129,6 @@ bool InternalFileHierarchyStorage::isIndexValid(DirectoryStorage::EntryIndex e)
{
return e < mNodes.size() && mNodes[e] != NULL ;
}
bool InternalFileHierarchyStorage::stampDirectory(const DirectoryStorage::EntryIndex& indx)
{
if(!checkIndex(indx,FileStorageNode::TYPE_DIR))
return false;
static_cast<DirEntry*>(mNodes[indx])->dir_modtime = time(NULL) ;
return true;
}
bool InternalFileHierarchyStorage::updateSubDirectoryList(const DirectoryStorage::EntryIndex& indx,const std::map<std::string,time_t>& subdirs)
{
@ -504,33 +496,32 @@ bool InternalFileHierarchyStorage::updateDirEntry(const DirectoryStorage::EntryI
return true;
}
bool InternalFileHierarchyStorage::getDirUpdateTS(const DirectoryStorage::EntryIndex& index,time_t& recurs_max_modf_TS,time_t& local_update_TS)
bool InternalFileHierarchyStorage::getTS(const DirectoryStorage::EntryIndex& index,time_t& TS,time_t DirEntry::* m) const
{
if(!checkIndex(index,FileStorageNode::TYPE_DIR))
{
std::cerr << "[directory storage] (EE) cannot update TS for index " << index << ". Not a valid index or not a directory." << std::endl;
std::cerr << "[directory storage] (EE) cannot get TS for index " << index << ". Not a valid index or not a directory." << std::endl;
return false;
}
DirEntry& d(*static_cast<DirEntry*>(mNodes[index])) ;
recurs_max_modf_TS = d.dir_most_recent_time ;
local_update_TS = d.dir_update_time ;
TS = d.*m ;
return true;
}
bool InternalFileHierarchyStorage::setDirUpdateTS(const DirectoryStorage::EntryIndex& index,time_t& recurs_max_modf_TS,time_t& local_update_TS)
bool InternalFileHierarchyStorage::setTS(const DirectoryStorage::EntryIndex& index,time_t& TS,time_t DirEntry::* m)
{
if(!checkIndex(index,FileStorageNode::TYPE_DIR))
{
std::cerr << "[directory storage] (EE) cannot update TS for index " << index << ". Not a valid index or not a directory." << std::endl;
std::cerr << "[directory storage] (EE) cannot get TS for index " << index << ". Not a valid index or not a directory." << std::endl;
return false;
}
DirEntry& d(*static_cast<DirEntry*>(mNodes[index])) ;
d.dir_most_recent_time = recurs_max_modf_TS ;
d.dir_update_time = local_update_TS ;
d.*m = TS;
return true;
}

View File

@ -94,7 +94,6 @@ 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) ;
@ -103,8 +102,11 @@ public:
bool updateHash(const DirectoryStorage::EntryIndex& file_index,const RsFileHash& hash);
bool updateFile(const DirectoryStorage::EntryIndex& file_index,const RsFileHash& hash, const std::string& fname,uint64_t size, const time_t modf_time);
bool updateDirEntry(const DirectoryStorage::EntryIndex& indx, const std::string& dir_name, time_t most_recent_time, time_t dir_modtime, const std::vector<RsFileHash> &subdirs_hash, const std::vector<FileEntry> &subfiles_array);
bool getDirUpdateTS(const DirectoryStorage::EntryIndex& index,time_t& recurs_max_modf_TS,time_t& local_update_TS);
bool setDirUpdateTS(const DirectoryStorage::EntryIndex& index,time_t& recurs_max_modf_TS,time_t& local_update_TS);
// TS get/set functions. Take one of the class members as argument.
bool getTS(const DirectoryStorage::EntryIndex& index,time_t& TS,time_t DirEntry::* ) const;
bool setTS(const DirectoryStorage::EntryIndex& index,time_t& TS,time_t DirEntry::* ) ;
// Do a complete recursive sweep over sub-directories and files, and update the lst modf TS. This could be also performed by a cleanup method.

View File

@ -115,16 +115,14 @@ uint32_t DirectoryStorage::getEntryType(const EntryIndex& indx)
return DIR_TYPE_UNKNOWN;
}
}
bool DirectoryStorage::getDirUpdateTS(EntryIndex index,time_t& recurs_max_modf_TS,time_t& local_update_TS)
{
RS_STACK_MUTEX(mDirStorageMtx) ;
return mFileHierarchy->getDirUpdateTS(index,recurs_max_modf_TS,local_update_TS) ;
}
bool DirectoryStorage::setDirUpdateTS(EntryIndex index,time_t recurs_max_modf_TS,time_t local_update_TS)
{
RS_STACK_MUTEX(mDirStorageMtx) ;
return mFileHierarchy->setDirUpdateTS(index,recurs_max_modf_TS,local_update_TS) ;
}
bool DirectoryStorage::getDirectoryUpdateTime (EntryIndex index,time_t& update_TS) const { RS_STACK_MUTEX(mDirStorageMtx) ; return mFileHierarchy->getTS(index,update_TS,&InternalFileHierarchyStorage::DirEntry::dir_update_time ); }
bool DirectoryStorage::getDirectoryRecursModTime(EntryIndex index,time_t& rec_md_TS) const { RS_STACK_MUTEX(mDirStorageMtx) ; return mFileHierarchy->getTS(index,rec_md_TS,&InternalFileHierarchyStorage::DirEntry::dir_most_recent_time); }
bool DirectoryStorage::getDirectoryLocalModTime (EntryIndex index,time_t& loc_md_TS) const { RS_STACK_MUTEX(mDirStorageMtx) ; return mFileHierarchy->getTS(index,loc_md_TS,&InternalFileHierarchyStorage::DirEntry::dir_modtime ); }
bool DirectoryStorage::setDirectoryUpdateTime (EntryIndex index,time_t update_TS) { RS_STACK_MUTEX(mDirStorageMtx) ; return mFileHierarchy->setTS(index,update_TS,&InternalFileHierarchyStorage::DirEntry::dir_update_time ); }
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)
{
@ -364,26 +362,33 @@ static bool sameLists(const std::list<RsNodeGroupId>& l1,const std::list<RsNodeG
void LocalDirectoryStorage::updateShareFlags(const SharedDirInfo& info)
{
RS_STACK_MUTEX(mDirStorageMtx) ;
bool changed = false ;
std::map<std::string,SharedDirInfo>::iterator it = mLocalDirs.find(info.filename) ;
if(it == mLocalDirs.end())
{
std::cerr << "(EE) LocalDirectoryStorage::updateShareFlags: directory \"" << info.filename << "\" not found" << std::endl;
return ;
RS_STACK_MUTEX(mDirStorageMtx) ;
std::map<std::string,SharedDirInfo>::iterator it = mLocalDirs.find(info.filename) ;
if(it == mLocalDirs.end())
{
std::cerr << "(EE) LocalDirectoryStorage::updateShareFlags: directory \"" << info.filename << "\" not found" << std::endl;
return ;
}
// 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)
{
it->second = info;
std::cerr << "Updating dir mod time because flags at level 0 have changed." << std::endl;
changed = true ;
}
}
// 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)
{
it->second = info;
mFileHierarchy->stampDirectory(0) ;
std::cerr << "Updating dir mod time because flags at level 0 have changed." << std::endl;
}
if(changed)
setDirectoryLocalModTime(0,time(NULL)) ;
}
bool LocalDirectoryStorage::convertSharedFilePath(const std::string& path, std::string& fullpath)

View File

@ -53,8 +53,13 @@ class DirectoryStorage
virtual int searchBoolExp(RsRegularExpression::Expression * exp, std::list<EntryIndex> &results) const ;
virtual int searchHash(const RsFileHash& hash, std::list<EntryIndex> &results) const ;
bool getDirUpdateTS(EntryIndex index,time_t& recurs_max_modf_TS,time_t& local_update_TS) ;
bool setDirUpdateTS(EntryIndex index,time_t recurs_max_modf_TS,time_t local_update_TS) ;
bool getDirectoryRecursModTime(EntryIndex index,time_t& recurs_max_modf_TS) const ;
bool getDirectoryLocalModTime (EntryIndex index,time_t& motime_TS) const ;
bool getDirectoryUpdateTime (EntryIndex index,time_t& update_TS) const ;
bool setDirectoryRecursModTime(EntryIndex index,time_t recurs_max_modf_TS) ;
bool setDirectoryLocalModTime (EntryIndex index,time_t modtime_TS) ;
bool setDirectoryUpdateTime (EntryIndex index,time_t update_TS) ;
uint32_t getEntryType(const EntryIndex& indx) ; // returns DIR_TYPE_*, not the internal directory storage stuff.
virtual bool extractData(const EntryIndex& indx,DirDetails& d);

View File

@ -134,6 +134,10 @@ void LocalDirectoryUpdater::recursUpdateSharedDir(const std::string& cumulated_p
std::cerr << "(EE) Dir entry of unknown type with path \"" << cumulated_path << "/" << dirIt.file_name() << "\"" << std::endl;
}
}
// update folder modificatoin time, which is the only way to detect e.g. removed or renamed files.
mSharedDirectories->setDirectoryLocalModTime(indx,dirIt.dir_modtime()) ;
// update file and dir lists for current directory.
mSharedDirectories->updateSubDirectoryList(indx,subdirs) ;

View File

@ -584,17 +584,9 @@ void p3FileDatabase::requestDirUpdate(void *ref)
if(fi == 0)
return ; // not updating current directory (should we?)
time_t recurs_max_modf_TS_remote_time,local_update_TS;
P3FILELISTS_DEBUG() << "Trying to force sync of entry ndex " << e << " to friend " << mRemoteDirectories[fi-1]->peerId() << std::endl;
if(!mRemoteDirectories[fi-1]->getDirUpdateTS(e,recurs_max_modf_TS_remote_time,local_update_TS))
{
P3FILELISTS_ERROR() << " (EE) Cannot get max known recurs modf time!" << std::endl;
return ;
}
if(generateAndSendSyncRequest(mRemoteDirectories[fi-1],e,recurs_max_modf_TS_remote_time))
if(generateAndSendSyncRequest(mRemoteDirectories[fi-1],e))
P3FILELISTS_DEBUG() << " Succeed." << std::endl;
}
@ -1060,8 +1052,8 @@ void p3FileDatabase::handleDirSyncRequest(RsFileListsSyncRequestItem *item)
}
else
{
time_t local_recurs_max_time,local_update_time;
mLocalSharedDirs->getDirUpdateTS(entry_index,local_recurs_max_time,local_update_time);
time_t local_recurs_max_time ;
mLocalSharedDirs->getDirectoryRecursModTime(entry_index,local_recurs_max_time) ;
if(item->last_known_recurs_modf_TS != local_recurs_max_time) // normally, should be "<", but since we provided the TS it should be equal, so != is more robust.
{
@ -1147,7 +1139,7 @@ void p3FileDatabase::handleDirSyncResponse(RsFileListsSyncResponseItem *item)
{
std::cerr << " Directory is up to date. Setting local TS." << std::endl;
mRemoteDirectories[fi]->setDirUpdateTS(entry_index,item->last_known_recurs_modf_TS,time(NULL));
mRemoteDirectories[fi]->setDirectoryUpdateTime(entry_index,time(NULL)) ;
}
else if(item->flags & RsFileListsItem::FLAGS_SYNC_DIR_CONTENT)
{
@ -1178,9 +1170,9 @@ void p3FileDatabase::locked_recursSweepRemoteDirectory(RemoteDirectoryStorage *r
P3FILELISTS_DEBUG() << "currently at entry index " << e << std::endl;
time_t recurs_max_modf_TS_remote_time,local_update_TS;
time_t local_update_TS;
if(!rds->getDirUpdateTS(e,recurs_max_modf_TS_remote_time,local_update_TS))
if(!rds->getDirectoryUpdateTime(e,local_update_TS))
{
P3FILELISTS_ERROR() << " (EE) lockec_recursSweepRemoteDirectory(): cannot get update TS for directory with index " << e << ". This is a consistency bug." << std::endl;
return;
@ -1189,7 +1181,7 @@ void p3FileDatabase::locked_recursSweepRemoteDirectory(RemoteDirectoryStorage *r
// compare TS
if((e == 0 && now > local_update_TS + DELAY_BETWEEN_REMOTE_DIRECTORY_SYNC_REQ) || local_update_TS == 0) // we need to compare local times only. We cannot compare local (now) with remote time.
if(generateAndSendSyncRequest(rds,e,recurs_max_modf_TS_remote_time))
if(generateAndSendSyncRequest(rds,e))
P3FILELISTS_DEBUG() << " Asking for sync of directory " << e << " to peer " << rds->peerId() << " because it's " << (now - local_update_TS) << " secs old since last check." << std::endl;
for(DirectoryStorage::DirIterator it(rds,e);it;++it)
@ -1220,11 +1212,18 @@ p3FileDatabase::DirSyncRequestId p3FileDatabase::makeDirSyncReqId(const RsPeerId
return r ^ random_bias;
}
bool p3FileDatabase::generateAndSendSyncRequest(RemoteDirectoryStorage *rds,const DirectoryStorage::EntryIndex& e,time_t max_known_recurs_modf_time)
bool p3FileDatabase::generateAndSendSyncRequest(RemoteDirectoryStorage *rds,const DirectoryStorage::EntryIndex& e)
{
RsFileHash entry_hash ;
time_t now = time(NULL) ;
time_t max_known_recurs_modf_time ;
if(!rds->getDirectoryRecursModTime(e,max_known_recurs_modf_time))
{
P3FILELISTS_ERROR() << " (EE) cannot find recurs mod time for entry index " << e << ". This is very unexpected." << std::endl;
return false;
}
if(!rds->getDirHashFromIndex(e,entry_hash) )
{
P3FILELISTS_ERROR() << " (EE) cannot find hash for entry index " << e << ". This is very unexpected." << std::endl;

View File

@ -179,7 +179,7 @@ class p3FileDatabase: public p3Service, public p3Config, public ftSearch //, pub
* \param e Entry index to update
* \return true if the request is correctly sent.
*/
bool generateAndSendSyncRequest(RemoteDirectoryStorage *rds,const DirectoryStorage::EntryIndex& e,time_t max_known_recurs_modf_time);
bool generateAndSendSyncRequest(RemoteDirectoryStorage *rds,const DirectoryStorage::EntryIndex& e);
// File sync request queues. The fast one is used for online browsing when friends are connected.
// The slow one is used for background update of file lists.

View File

@ -13,6 +13,23 @@ namespace librs { namespace util {
FolderIterator::FolderIterator(const std::string& folderName)
: mFolderName(folderName)
{
// Grab the last modification time for the directory
struct stat64 buf ;
#ifdef WINDOWS_SYS
std::wstring wfullname;
librs::util::ConvertUtf8ToUtf16(folderName, wfullname);
if ( 0 == _wstati64(wfullname.c_str(), &buf))
#else
if ( 0 == stat64(folderName.c_str(), &buf))
#endif
{
mFolderModTime = buf.st_mtime ;
}
// Now open directory content and read the first entry
#ifdef WINDOWS_SYS
std::wstring utf16Name;
if(! ConvertUtf8ToUtf16(folderName, utf16Name)) {
@ -123,6 +140,8 @@ bool FolderIterator::d_name(std::string& dest)
return true;
}
time_t FolderIterator::dir_modtime() const { return mFolderModTime ; }
const std::string& FolderIterator::file_fullpath() { return mFullPath ; }
const std::string& FolderIterator::file_name() { return mFileName ; }
uint64_t FolderIterator::file_size() { return mFileSize ; }

View File

@ -30,10 +30,16 @@ public:
TYPE_DIR = 0x02
};
// info about current parent directory
time_t dir_modtime() const ;
// info about directory content
bool isValid() const { return validity; }
bool readdir();
void next();
#warning this one should go, as it reports the same information than file_name()
bool d_name(std::string& dest);
bool closedir();
@ -58,6 +64,7 @@ private:
bool mStatInfoOk ;
time_t mFileModTime ;
time_t mFolderModTime ;
uint64_t mFileSize ;
uint8_t mType ;
std::string mFileName ;