fixed a few bugs in hash-based sync. Not there yet.

This commit is contained in:
mr-alice 2016-09-08 23:43:14 +02:00
parent fafe684cc4
commit 0ea695beb3
6 changed files with 91 additions and 24 deletions

View File

@ -1,3 +1,5 @@
#include "util/rsdir.h"
#include "dir_hierarchy.h" #include "dir_hierarchy.h"
#include "filelist_io.h" #include "filelist_io.h"
@ -28,6 +30,36 @@ InternalFileHierarchyStorage::InternalFileHierarchyStorage() : mRoot(0)
de->dir_modtime=0; de->dir_modtime=0;
mNodes.push_back(de) ; mNodes.push_back(de) ;
#warning not very elegant. We should remove the leading /
mDirHashes[computeDirHash("/")] = 0 ;
}
RsFileHash InternalFileHierarchyStorage::computeDirHash(const std::string& dir_path)
{
return RsDirUtil::sha1sum((unsigned char*)dir_path.c_str(),dir_path.length()) ;
}
bool InternalFileHierarchyStorage::getDirHashFromIndex(const DirectoryStorage::EntryIndex& index,RsFileHash& hash) const
{
if(!checkIndex(index,FileStorageNode::TYPE_DIR))
return false ;
DirEntry& d = *static_cast<DirEntry*>(mNodes[index]) ;
hash = computeDirHash( d.dir_parent_path + "/" + d.dir_name ) ;
std::cerr << "Computing dir hash from index " << index << ". Dir=\"" << d.dir_parent_path + "/" + d.dir_name << "\" hash=" << hash << std::endl;
return true;
}
bool InternalFileHierarchyStorage::getIndexFromDirHash(const RsFileHash& hash,DirectoryStorage::EntryIndex& index) const
{
std::map<RsFileHash,DirectoryStorage::EntryIndex>::const_iterator it = mDirHashes.find(hash) ;
if(it == mDirHashes.end())
return false;
index = it->second;
return true;
} }
int InternalFileHierarchyStorage::parentRow(DirectoryStorage::EntryIndex e) int InternalFileHierarchyStorage::parentRow(DirectoryStorage::EntryIndex e)

View File

@ -81,6 +81,13 @@ public:
time_t recursUpdateLastModfTime(const DirectoryStorage::EntryIndex& dir_index); time_t recursUpdateLastModfTime(const DirectoryStorage::EntryIndex& dir_index);
// hash stuff
static RsFileHash computeDirHash(const std::string& dir_path);
bool getDirHashFromIndex(const DirectoryStorage::EntryIndex& index,RsFileHash& hash) const ;
bool getIndexFromDirHash(const RsFileHash& hash,DirectoryStorage::EntryIndex& index) const ;
// file/dir access and modification // file/dir access and modification
bool findSubDirectory(DirectoryStorage::EntryIndex e,const std::string& s) const ; // returns true when s is the name of a sub-directory in the given entry e bool findSubDirectory(DirectoryStorage::EntryIndex e,const std::string& s) const ; // returns true when s is the name of a sub-directory in the given entry e

View File

@ -193,6 +193,8 @@ bool LocalDirectoryStorage::getFileInfo(DirectoryStorage::EntryIndex i,FileInfo&
bool DirectoryStorage::extractData(const EntryIndex& indx,DirDetails& d) bool DirectoryStorage::extractData(const EntryIndex& indx,DirDetails& d)
{ {
RS_STACK_MUTEX(mDirStorageMtx) ;
d.children.clear() ; d.children.clear() ;
time_t now = time(NULL) ; time_t now = time(NULL) ;
@ -266,6 +268,18 @@ bool DirectoryStorage::extractData(const EntryIndex& indx,DirDetails& d)
return true; return true;
} }
bool DirectoryStorage::getDirHashFromIndex(const EntryIndex& index,RsFileHash& hash) const
{
RS_STACK_MUTEX(mDirStorageMtx) ;
return mFileHierarchy->getDirHashFromIndex(index,hash) ;
}
bool DirectoryStorage::getIndexFromDirHash(const RsFileHash& hash,EntryIndex& index) const
{
RS_STACK_MUTEX(mDirStorageMtx) ;
return mFileHierarchy->getIndexFromDirHash(hash,index) ;
}
/******************************************************************************************************************/ /******************************************************************************************************************/
/* Local Directory Storage */ /* Local Directory Storage */
/******************************************************************************************************************/ /******************************************************************************************************************/
@ -477,7 +491,7 @@ bool LocalDirectoryStorage::serialiseDirEntry(const EntryIndex& indx,RsTlvBinary
{ {
RsFileHash hash ; RsFileHash hash ;
if(!getHashFromIndex(dir->subdirs[i],hash)) if(!mFileHierarchy->getDirHashFromIndex(dir->subdirs[i],hash))
{ {
std::cerr << "(EE) cannot get hash from index for subdir " << dir->subdirs[i] << " at position " << i << " in subdirs list. Weird." << std::endl; std::cerr << "(EE) cannot get hash from index for subdir " << dir->subdirs[i] << " at position " << i << " in subdirs list. Weird." << std::endl;
continue ; continue ;
@ -664,7 +678,7 @@ bool RemoteDirectoryStorage::deserialiseUpdateDirEntry(const EntryIndex& indx,co
{ {
DirectoryStorage::EntryIndex file_index ; DirectoryStorage::EntryIndex file_index ;
if(!getIndexFromHash(subfiles_hash[i],file_index)) if(!getIndexFromDirHash(subfiles_hash[i],file_index))
{ {
std::cerr << "(EE) Cannot optain file entry index for hash " << subfiles_hash[i] << ". This is very unexpected." << std::endl; std::cerr << "(EE) Cannot optain file entry index for hash " << subfiles_hash[i] << ". This is very unexpected." << std::endl;
continue; continue;

View File

@ -101,8 +101,8 @@ class DirectoryStorage
bool updateFile(const EntryIndex& index,const RsFileHash& hash, const std::string& fname, uint64_t size, time_t modf_time) ; bool updateFile(const EntryIndex& index,const RsFileHash& hash, const std::string& fname, uint64_t size, time_t modf_time) ;
bool updateHash(const EntryIndex& index,const RsFileHash& hash); bool updateHash(const EntryIndex& index,const RsFileHash& hash);
bool getHashFromIndex(const EntryIndex& index,RsFileHash& hash) const { NOT_IMPLEMENTED() ; return false; } bool getDirHashFromIndex(const EntryIndex& index,RsFileHash& hash) const ;
bool getIndexFromHash(const RsFileHash& hash,EntryIndex& index) const { NOT_IMPLEMENTED() ; return false; } bool getIndexFromDirHash(const RsFileHash& hash,EntryIndex& index) const ;
void print(); void print();
void cleanup(); void cleanup();

View File

@ -12,7 +12,7 @@
#include "rsserver/p3face.h" #include "rsserver/p3face.h"
#define P3FILELISTS_DEBUG() std::cerr << "p3FileLists: " #define P3FILELISTS_DEBUG() std::cerr << time(NULL) << ": p3FileLists: "
static const uint32_t P3FILELISTS_UPDATE_FLAG_NOTHING_CHANGED = 0x0000 ; static const uint32_t P3FILELISTS_UPDATE_FLAG_NOTHING_CHANGED = 0x0000 ;
static const uint32_t P3FILELISTS_UPDATE_FLAG_REMOTE_MAP_CHANGED = 0x0001 ; static const uint32_t P3FILELISTS_UPDATE_FLAG_REMOTE_MAP_CHANGED = 0x0001 ;
@ -187,7 +187,7 @@ int p3FileDatabase::tick()
{ {
if(online_peers.find(mRemoteDirectories[i]->peerId()) != online_peers.end()) if(online_peers.find(mRemoteDirectories[i]->peerId()) != online_peers.end())
{ {
std::cerr << "Launching recurs sweep of friend directory " << mRemoteDirectories[i]->peerId() << ". Content currently is:" << std::endl; P3FILELISTS_DEBUG() << "Launching recurs sweep of friend directory " << mRemoteDirectories[i]->peerId() << ". Content currently is:" << std::endl;
#ifdef DEBUG_FILE_HIERARCHY #ifdef DEBUG_FILE_HIERARCHY
mRemoteDirectories[i]->print(); mRemoteDirectories[i]->print();
#endif #endif
@ -210,20 +210,20 @@ int p3FileDatabase::tick()
void p3FileDatabase::startThreads() void p3FileDatabase::startThreads()
{ {
RS_STACK_MUTEX(mFLSMtx) ; RS_STACK_MUTEX(mFLSMtx) ;
std::cerr << "Starting directory watcher thread..." ; P3FILELISTS_DEBUG() << "Starting directory watcher thread..." ;
mLocalDirWatcher->start(); mLocalDirWatcher->start();
std::cerr << "Done." << std::endl; P3FILELISTS_DEBUG() << "Done." << std::endl;
} }
void p3FileDatabase::stopThreads() void p3FileDatabase::stopThreads()
{ {
RS_STACK_MUTEX(mFLSMtx) ; RS_STACK_MUTEX(mFLSMtx) ;
std::cerr << "Stopping hash cache thread..." ; std::cerr.flush() ; P3FILELISTS_DEBUG() << "Stopping hash cache thread..." ; std::cerr.flush() ;
mHashCache->fullstop(); mHashCache->fullstop();
std::cerr << "Done." << std::endl; P3FILELISTS_DEBUG() << "Done." << std::endl;
std::cerr << "Stopping directory watcher thread..." ; std::cerr.flush() ; P3FILELISTS_DEBUG() << "Stopping directory watcher thread..." ; std::cerr.flush() ;
mLocalDirWatcher->fullstop(); mLocalDirWatcher->fullstop();
std::cerr << "Done." << std::endl; P3FILELISTS_DEBUG() << "Done." << std::endl;
} }
void p3FileDatabase::tickWatchers() void p3FileDatabase::tickWatchers()
@ -367,7 +367,7 @@ void p3FileDatabase::cleanup()
{ {
RS_STACK_MUTEX(mFLSMtx) ; RS_STACK_MUTEX(mFLSMtx) ;
std::cerr << "p3FileDatabase::cleanup()" << std::endl; P3FILELISTS_DEBUG() << "p3FileDatabase::cleanup()" << std::endl;
// look through the list of friend directories. Remove those who are not our friends anymore. // look through the list of friend directories. Remove those who are not our friends anymore.
// //
@ -429,7 +429,7 @@ void p3FileDatabase::cleanup()
for(std::map<DirSyncRequestId,DirSyncRequestData>::iterator it = mPendingSyncRequests.begin();it!=mPendingSyncRequests.end();) for(std::map<DirSyncRequestId,DirSyncRequestData>::iterator it = mPendingSyncRequests.begin();it!=mPendingSyncRequests.end();)
if(online_peers.find(it->second.peer_id) == online_peers.end() || it->second.request_TS + DELAY_BEFORE_DROP_REQUEST < now) if(online_peers.find(it->second.peer_id) == online_peers.end() || it->second.request_TS + DELAY_BEFORE_DROP_REQUEST < now)
{ {
std::cerr << " removing pending request " << std::hex << it->first << std::dec << " for peer " << it->second.peer_id << ", because peer is offline or request is too old." << std::endl; P3FILELISTS_DEBUG() << " removing pending request " << std::hex << it->first << std::dec << " for peer " << it->second.peer_id << ", because peer is offline or request is too old." << std::endl;
std::map<DirSyncRequestId,DirSyncRequestData>::iterator tmp(it); std::map<DirSyncRequestId,DirSyncRequestData>::iterator tmp(it);
++tmp; ++tmp;
@ -438,7 +438,7 @@ void p3FileDatabase::cleanup()
} }
else else
{ {
std::cerr << " keeping request " << std::hex << it->first << std::dec << " for peer " << it->second.peer_id << std::endl; P3FILELISTS_DEBUG() << " keeping request " << std::hex << it->first << std::dec << " for peer " << it->second.peer_id << std::endl;
++it ; ++it ;
} }
} }
@ -905,7 +905,7 @@ void p3FileDatabase::handleDirSyncRequest(RsFileListsSyncRequestItem *item)
EntryIndex entry_index = DirectoryStorage::NO_INDEX; EntryIndex entry_index = DirectoryStorage::NO_INDEX;
if(!mLocalSharedDirs->getIndexFromHash(item->entry_hash,entry_index)) if(!mLocalSharedDirs->getIndexFromDirHash(item->entry_hash,entry_index))
{ {
std::cerr << " (EE) Cannot find entry index for hash " << item->entry_hash << ": cannot respond to sync request." << std::endl; std::cerr << " (EE) Cannot find entry index for hash " << item->entry_hash << ": cannot respond to sync request." << std::endl;
return; return;
@ -970,12 +970,6 @@ void p3FileDatabase::handleDirSyncResponse(RsFileListsSyncResponseItem *item)
{ {
RS_STACK_MUTEX(mFLSMtx) ; RS_STACK_MUTEX(mFLSMtx) ;
if(entry_index == DirectoryStorage::NO_INDEX)
{
std::cerr << " (EE) Cannot find entry index for hash " << item->entry_hash << ": cannot respond to sync request." << std::endl;
return;
}
std::map<DirSyncRequestId,DirSyncRequestData>::iterator it = mPendingSyncRequests.find(item->request_id) ; std::map<DirSyncRequestId,DirSyncRequestData>::iterator it = mPendingSyncRequests.find(item->request_id) ;
if(it == mPendingSyncRequests.end()) if(it == mPendingSyncRequests.end())
@ -1004,7 +998,7 @@ void p3FileDatabase::handleDirSyncResponse(RsFileListsSyncResponseItem *item)
if(mRemoteDirectories[fi] == NULL) if(mRemoteDirectories[fi] == NULL)
mRemoteDirectories[fi] = new RemoteDirectoryStorage(item->PeerId(),makeRemoteFileName(item->PeerId())); mRemoteDirectories[fi] = new RemoteDirectoryStorage(item->PeerId(),makeRemoteFileName(item->PeerId()));
if(!mRemoteDirectories[fi]->getIndexFromHash(item->entry_hash,entry_index)) if(!mRemoteDirectories[fi]->getIndexFromDirHash(item->entry_hash,entry_index))
{ {
std::cerr << std::endl << " (EE) cannot find index from hash " << item->entry_hash << ". Dropping the response." << std::endl; std::cerr << std::endl << " (EE) cannot find index from hash " << item->entry_hash << ". Dropping the response." << std::endl;
return ; return ;
@ -1078,7 +1072,7 @@ void p3FileDatabase::locked_recursSweepRemoteDirectory(RemoteDirectoryStorage *r
RsFileListsSyncRequestItem *item = new RsFileListsSyncRequestItem ; RsFileListsSyncRequestItem *item = new RsFileListsSyncRequestItem ;
if(!rds->getHashFromIndex(e,item->entry_hash) ) if(!rds->getDirHashFromIndex(e,item->entry_hash) )
{ {
std::cerr << "(EE) cannot find hash for entry index " << e << ". This is very unexpected." << std::endl; std::cerr << "(EE) cannot find hash for entry index " << e << ". This is very unexpected." << std::endl;
return; return;

View File

@ -85,6 +85,8 @@
// //
#define DONT_USE_SEARCH_IN_TREE_VIEW 1 #define DONT_USE_SEARCH_IN_TREE_VIEW 1
//#define DEBUG_SHARED_FILES_DIALOG 1
const QString Image_AddNewAssotiationForFile = ":/images/kcmsystem24.png"; const QString Image_AddNewAssotiationForFile = ":/images/kcmsystem24.png";
class SFDSortFilterProxyModel : public QSortFilterProxyModel class SFDSortFilterProxyModel : public QSortFilterProxyModel
@ -842,7 +844,9 @@ void SharedFilesDialog::saveExpandedPaths(std::set<std::string>& expanded_indexe
if(ui.dirTreeView->model() == NULL) if(ui.dirTreeView->model() == NULL)
return ; return ;
#ifdef DEBUG_SHARED_FILES_DIALOG
std::cerr << "Saving expanded items. " << std::endl; std::cerr << "Saving expanded items. " << std::endl;
#endif
for(int row = 0; row < ui.dirTreeView->model()->rowCount(); ++row) for(int row = 0; row < ui.dirTreeView->model()->rowCount(); ++row)
{ {
std::string path = ui.dirTreeView->model()->index(row,0).data(Qt::DisplayRole).toString().toStdString(); std::string path = ui.dirTreeView->model()->index(row,0).data(Qt::DisplayRole).toString().toStdString();
@ -855,7 +859,9 @@ void SharedFilesDialog::restoreExpandedPaths(const std::set<std::string>& expand
if(ui.dirTreeView->model() == NULL) if(ui.dirTreeView->model() == NULL)
return ; return ;
#ifdef DEBUG_SHARED_FILES_DIALOG
std::cerr << "Restoring expanded items. " << std::endl; std::cerr << "Restoring expanded items. " << std::endl;
#endif
for(int row = 0; row < ui.dirTreeView->model()->rowCount(); ++row) for(int row = 0; row < ui.dirTreeView->model()->rowCount(); ++row)
{ {
std::string path = ui.dirTreeView->model()->index(row,0).data(Qt::DisplayRole).toString().toStdString(); std::string path = ui.dirTreeView->model()->index(row,0).data(Qt::DisplayRole).toString().toStdString();
@ -866,29 +872,39 @@ void SharedFilesDialog::restoreExpandedPaths(const std::set<std::string>& expand
void SharedFilesDialog::recursSaveExpandedItems(const QModelIndex& index,const std::string& path,std::set<std::string>& exp) void SharedFilesDialog::recursSaveExpandedItems(const QModelIndex& index,const std::string& path,std::set<std::string>& exp)
{ {
std::string local_path = path+"/"+index.data(Qt::DisplayRole).toString().toStdString(); std::string local_path = path+"/"+index.data(Qt::DisplayRole).toString().toStdString();
#ifdef DEBUG_SHARED_FILES_DIALOG
std::cerr << "at index " << index.row() << ". data[1]=" << local_path << std::endl; std::cerr << "at index " << index.row() << ". data[1]=" << local_path << std::endl;
#endif
if(ui.dirTreeView->isExpanded(index)) if(ui.dirTreeView->isExpanded(index))
{ {
#ifdef DEBUG_SHARED_FILES_DIALOG
std::cerr << "Index " << local_path << " is expanded." << std::endl; std::cerr << "Index " << local_path << " is expanded." << std::endl;
#endif
if(index.isValid()) if(index.isValid())
exp.insert(local_path) ; exp.insert(local_path) ;
for(int row=0;row<ui.dirTreeView->model()->rowCount(index);++row) for(int row=0;row<ui.dirTreeView->model()->rowCount(index);++row)
recursSaveExpandedItems(index.child(row,0),local_path,exp) ; recursSaveExpandedItems(index.child(row,0),local_path,exp) ;
} }
#ifdef DEBUG_SHARED_FILES_DIALOG
else else
std::cerr << "Index is not expanded." << std::endl; std::cerr << "Index is not expanded." << std::endl;
#endif
} }
void SharedFilesDialog::recursRestoreExpandedItems(const QModelIndex& index, const std::string &path, const std::set<std::string>& exp) void SharedFilesDialog::recursRestoreExpandedItems(const QModelIndex& index, const std::string &path, const std::set<std::string>& exp)
{ {
std::string local_path = path+"/"+index.data(Qt::DisplayRole).toString().toStdString(); std::string local_path = path+"/"+index.data(Qt::DisplayRole).toString().toStdString();
#ifdef DEBUG_SHARED_FILES_DIALOG
std::cerr << "at index " << index.row() << ". data[1]=" << local_path << std::endl; std::cerr << "at index " << index.row() << ". data[1]=" << local_path << std::endl;
#endif
if(exp.find(local_path) != exp.end()) if(exp.find(local_path) != exp.end())
{ {
#ifdef DEBUG_SHARED_FILES_DIALOG
std::cerr << "re expanding index " << local_path << std::endl; std::cerr << "re expanding index " << local_path << std::endl;
#endif
ui.dirTreeView->setExpanded(index,true) ; ui.dirTreeView->setExpanded(index,true) ;
for(int row=0;row<ui.dirTreeView->model()->rowCount(index);++row) for(int row=0;row<ui.dirTreeView->model()->rowCount(index);++row)
@ -904,7 +920,9 @@ void SharedFilesDialog::postModDirectories(bool local)
} }
std::set<std::string> expanded_indexes; std::set<std::string> expanded_indexes;
saveExpandedPaths(expanded_indexes) ; saveExpandedPaths(expanded_indexes) ;
#ifdef DEBUG_SHARED_FILES_DIALOG
std::cerr << "Saving expanded items. " << expanded_indexes.size() << " items found" << std::endl; std::cerr << "Saving expanded items. " << expanded_indexes.size() << " items found" << std::endl;
#endif
/* Notify both models, only one is visible */ /* Notify both models, only one is visible */
tree_model->postMods(); tree_model->postMods();
@ -916,7 +934,9 @@ void SharedFilesDialog::postModDirectories(bool local)
if (ui.filterPatternLineEdit->text().isEmpty() == false) if (ui.filterPatternLineEdit->text().isEmpty() == false)
FilterItems(); FilterItems();
#ifdef DEBUG_SHARED_FILES_DIALOG
std::cerr << "****** updated directories! ******" << std::endl; std::cerr << "****** updated directories! ******" << std::endl;
#endif
QCoreApplication::flush(); QCoreApplication::flush();
} }