added serialisation of dir entries for exchange with friends. Fixed a few bugs in row and ref calculation

This commit is contained in:
mr-alice 2016-08-26 16:29:02 +02:00
parent 99ea8af015
commit d8a24c8c3a
7 changed files with 298 additions and 35 deletions

View File

@ -2,6 +2,7 @@
#include "util/rsdir.h" #include "util/rsdir.h"
#include "util/rsstring.h" #include "util/rsstring.h"
#include "directory_storage.h" #include "directory_storage.h"
#include "filelist_io.h"
#define DEBUG_DIRECTORY_STORAGE 1 #define DEBUG_DIRECTORY_STORAGE 1
@ -53,7 +54,7 @@ class InternalFileHierarchyStorage
class DirEntry: public FileStorageNode class DirEntry: public FileStorageNode
{ {
public: public:
DirEntry(const std::string& name) : dir_name(name), dir_modtime(0),most_recent_time(0) {} DirEntry(const std::string& name) : dir_name(name), dir_modtime(0),most_recent_time(0),dir_update_time(0) {}
virtual ~DirEntry() {} virtual ~DirEntry() {}
virtual uint32_t type() const { return FileStorageNode::TYPE_DIR ; } virtual uint32_t type() const { return FileStorageNode::TYPE_DIR ; }
@ -67,6 +68,8 @@ class InternalFileHierarchyStorage
time_t dir_modtime ; // this accounts for deleted files, etc. time_t dir_modtime ; // this accounts for deleted files, etc.
time_t most_recent_time; // recursive most recent modification time, including files and subdirs in the entire hierarchy below. time_t most_recent_time; // recursive most recent modification time, including files and subdirs in the entire hierarchy below.
time_t dir_update_time; // last time the information was updated for that directory. Includes subdirs indexes and subfile info.
}; };
// class stuff // class stuff
@ -246,6 +249,36 @@ class InternalFileHierarchyStorage
return true; return true;
} }
bool getDirUpdateTS(const DirectoryStorage::EntryIndex& index,time_t& recurs_max_modf_TS,time_t& local_update_TS)
{
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;
return false;
}
DirEntry& d(*static_cast<DirEntry*>(mNodes[index])) ;
recurs_max_modf_TS = d.most_recent_time ;
local_update_TS = d.dir_update_time ;
return true;
}
bool setDirUpdateTS(const DirectoryStorage::EntryIndex& index,time_t& recurs_max_modf_TS,time_t& local_update_TS)
{
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;
return false;
}
DirEntry& d(*static_cast<DirEntry*>(mNodes[index])) ;
d.most_recent_time = recurs_max_modf_TS ;
d.dir_update_time = local_update_TS ;
return true;
}
// 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. // 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.
@ -340,8 +373,57 @@ class InternalFileHierarchyStorage
return false; return false;
} }
bool check() // checks consistency of storage. bool check(std::string& error_string) const // checks consistency of storage.
{ {
// recurs go through all entries, check that all
std::vector<uint32_t> 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
for(uint32_t i=0;i<mNodes.size();++i)
if(mNodes[i]->type() == FileStorageNode::TYPE_DIR)
{
// stamp the kids
const DirEntry& de = *static_cast<DirEntry*>(mNodes[i]) ;
for(uint32_t j=0;j<de.subdirs.size();++j)
{
if(de.subdirs[j] >= mNodes.size())
{
error_string = "Node child out of tab!" ;
return false ;
}
if(hits[de.subdirs[j]] != 0)
{
error_string = "Double hit on a single node" ;
return false;
}
hits[de.subdirs[j]] = 1;
}
for(uint32_t j=0;j<de.subfiles.size();++j)
{
if(de.subfiles[j] >= mNodes.size())
{
error_string = "Node child out of tab!" ;
return false ;
}
if(hits[de.subfiles[j]] != 0)
{
error_string = "Double hit on a single node" ;
return false;
}
hits[de.subfiles[j]] = 1;
}
}
for(uint32_t i=0;i<hits.size();++i)
if(hits[i] == 0)
{
error_string = "Orphean node!" ;
return false;
}
return true; return true;
} }
@ -507,21 +589,45 @@ uint32_t DirectoryStorage::getEntryType(const EntryIndex& indx)
return DIR_TYPE_UNKNOWN; 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::updateSubDirectoryList(const EntryIndex& indx,const std::set<std::string>& subdirs) bool DirectoryStorage::updateSubDirectoryList(const EntryIndex& indx,const std::set<std::string>& subdirs)
{ {
RS_STACK_MUTEX(mDirStorageMtx) ; RS_STACK_MUTEX(mDirStorageMtx) ;
return mFileHierarchy->updateSubDirectoryList(indx,subdirs) ; bool res = mFileHierarchy->updateSubDirectoryList(indx,subdirs) ;
locked_check() ;
return res ;
} }
bool DirectoryStorage::updateSubFilesList(const EntryIndex& indx,const std::map<std::string,FileTS>& subfiles,std::map<std::string,FileTS>& new_files) bool DirectoryStorage::updateSubFilesList(const EntryIndex& indx,const std::map<std::string,FileTS>& subfiles,std::map<std::string,FileTS>& new_files)
{ {
RS_STACK_MUTEX(mDirStorageMtx) ; RS_STACK_MUTEX(mDirStorageMtx) ;
return mFileHierarchy->updateSubFilesList(indx,subfiles,new_files) ; bool res = mFileHierarchy->updateSubFilesList(indx,subfiles,new_files) ;
locked_check() ;
return res ;
} }
bool DirectoryStorage::removeDirectory(const EntryIndex& indx) bool DirectoryStorage::removeDirectory(const EntryIndex& indx)
{ {
RS_STACK_MUTEX(mDirStorageMtx) ; RS_STACK_MUTEX(mDirStorageMtx) ;
return mFileHierarchy->removeDirectory(indx); bool res = mFileHierarchy->removeDirectory(indx);
locked_check();
return res ;
}
void DirectoryStorage::locked_check()
{
std::string error ;
if(!mFileHierarchy->check(error))
std::cerr << "Check error: " << error << std::endl;
} }
bool DirectoryStorage::updateFile(const EntryIndex& index,const RsFileHash& hash,const std::string& fname, uint64_t size,time_t modf_time) bool DirectoryStorage::updateFile(const EntryIndex& index,const RsFileHash& hash,const std::string& fname, uint64_t size,time_t modf_time)
@ -773,8 +879,95 @@ bool LocalDirectoryStorage::extractData(const EntryIndex& indx,DirDetails& d)
/* find parent pointer, and row */ /* find parent pointer, and row */
std::cerr << "LocalDirectoryStorage::extractData(): indx=" << indx << " Returning this:" << std::endl; return true;
std::cerr << d << std::endl; }
bool LocalDirectoryStorage::serialiseDirEntry(const EntryIndex& indx,RsTlvBinaryData& bindata)
{
RS_STACK_MUTEX(mDirStorageMtx) ;
const InternalFileHierarchyStorage::DirEntry *dir = mFileHierarchy->getDirEntry(indx);
if(dir == NULL)
{
std::cerr << "(EE) serialiseDirEntry: ERROR. Cannot find entry " << (void*)(intptr_t)indx << std::endl;
return false;
}
unsigned char *section_data = NULL;
uint32_t section_size = 0;
uint32_t section_offset = 0;
// we need to send:
// - the name of the directory, its TS
// - the index entry for each subdir (the updte TS are exchanged at a higher level)
// - the file info for each subfile
//
if(!FileListIO::writeField(section_data,section_size,section_offset,FILE_LIST_IO_TAG_DIR_NAME ,dir->dir_name )) return false ;
if(!FileListIO::writeField(section_data,section_size,section_offset,FILE_LIST_IO_TAG_RECURS_MODIF_TS,dir->most_recent_time)) return false ;
if(!FileListIO::writeField(section_data,section_size,section_offset,FILE_LIST_IO_TAG_MODIF_TS ,dir->dir_modtime )) return false ;
// serialise number of subdirs and number of subfiles
if(!FileListIO::writeField(section_data,section_size,section_offset,FILE_LIST_IO_TAG_RAW_NUMBER,dir->subdirs.size() )) return false ;
if(!FileListIO::writeField(section_data,section_size,section_offset,FILE_LIST_IO_TAG_RAW_NUMBER,dir->subfiles.size() )) return false ;
// serialise subdirs entry indexes
for(uint32_t i=0;i<dir->subdirs.size();++i)
if(!FileListIO::writeField(section_data,section_size,section_offset,FILE_LIST_IO_TAG_ENTRY_INDEX ,dir->subdirs[i] )) return false ;
// serialise directory subfiles, with info for each of them
for(uint32_t i=0;i<dir->subfiles.size();++i)
{
unsigned char *file_section_data = NULL ;
uint32_t file_section_offset = 0 ;
uint32_t file_section_size = 0;
const InternalFileHierarchyStorage::FileEntry *file = mFileHierarchy->getFileEntry(dir->subfiles[i]) ;
if(file == NULL)
{
std::cerr << "(EE) cannot reach file entry " << dir->subfiles[i] << " to get/send file info." << std::endl;
continue ;
}
if(!FileListIO::writeField(file_section_data,file_section_size,file_section_offset,FILE_LIST_IO_TAG_ENTRY_INDEX ,dir->subfiles[i] )) return false ;
if(!FileListIO::writeField(file_section_data,file_section_size,file_section_offset,FILE_LIST_IO_TAG_FILE_NAME ,file->file_name )) return false ;
if(!FileListIO::writeField(file_section_data,file_section_size,file_section_offset,FILE_LIST_IO_TAG_FILE_SIZE ,file->file_size )) return false ;
if(!FileListIO::writeField(file_section_data,file_section_size,file_section_offset,FILE_LIST_IO_TAG_FILE_SHA1_HASH,file->file_hash )) return false ;
if(!FileListIO::writeField(file_section_data,file_section_size,file_section_offset,FILE_LIST_IO_TAG_MODIF_TS ,file->file_modtime)) return false ;
// now write the whole string into a single section in the file
if(!FileListIO::writeField(section_data,section_size,section_offset,FILE_LIST_IO_TAG_REMOTE_FILE_ENTRY,file_section_data,file_section_offset)) return false ;
free(file_section_data) ;
}
std::cerr << "Serialised dir entry to send for entry index " << (void*)(intptr_t)indx << ". Data size is " << section_size << " bytes" << std::endl;
return true ; return true ;
} }
/******************************************************************************************************************/
/* Remote Directory Storage */
/******************************************************************************************************************/
bool RemoteDirectoryStorage::deserialiseDirEntry(const EntryIndex& indx,const RsTlvBinaryData& bindata)
{
RS_STACK_MUTEX(mDirStorageMtx) ;
std::cerr << "RemoteDirectoryStorage::deserialiseDirEntry(): deserialising directory content for friend " << peerId() << ", and directory " << indx << std::endl;
NOT_IMPLEMENTED();
return true ;
}

View File

@ -9,7 +9,9 @@
#define NOT_IMPLEMENTED() { std::cerr << __PRETTY_FUNCTION__ << ": not yet implemented." << std::endl; } #define NOT_IMPLEMENTED() { std::cerr << __PRETTY_FUNCTION__ << ": not yet implemented." << std::endl; }
class RsTlvBinaryData ;
class InternalFileHierarchyStorage ; class InternalFileHierarchyStorage ;
class RsTlvBinaryData ;
class DirectoryStorage class DirectoryStorage
{ {
@ -26,8 +28,8 @@ class DirectoryStorage
virtual int searchHash(const RsFileHash& hash, std::list<EntryIndex> &results) const ; virtual int searchHash(const RsFileHash& hash, std::list<EntryIndex> &results) const ;
virtual int searchBoolExp(Expression * exp, std::list<EntryIndex> &results) const { NOT_IMPLEMENTED() ; return 0; } virtual int searchBoolExp(Expression * exp, std::list<EntryIndex> &results) const { NOT_IMPLEMENTED() ; return 0; }
bool getUpdateTS(EntryIndex index,time_t& recurs_max_modf_TS,time_t& local_update_TS) ; bool getDirUpdateTS(EntryIndex index,time_t& recurs_max_modf_TS,time_t& local_update_TS) ;
bool setUpdateTS(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) ;
uint32_t getEntryType(const EntryIndex& indx) ; // returns DIR_TYPE_*, not the internal directory storage stuff. uint32_t getEntryType(const EntryIndex& indx) ; // returns DIR_TYPE_*, not the internal directory storage stuff.
virtual bool extractData(const EntryIndex& indx,DirDetails& d); virtual bool extractData(const EntryIndex& indx,DirDetails& d);
@ -109,6 +111,9 @@ class DirectoryStorage
void loadNextTag(const unsigned char *data, uint32_t& offset, uint8_t& entry_tag, uint32_t& entry_size) ; void loadNextTag(const unsigned char *data, uint32_t& offset, uint8_t& entry_tag, uint32_t& entry_size) ;
void saveNextTag(unsigned char *data,uint32_t& offset,uint8_t entry_tag,uint32_t entry_size) ; void saveNextTag(unsigned char *data,uint32_t& offset,uint8_t entry_tag,uint32_t entry_size) ;
// debug
void locked_check();
// storage of internal structure. Totally hidden from the outside. EntryIndex is simply the index of the entry in the vector. // storage of internal structure. Totally hidden from the outside. EntryIndex is simply the index of the entry in the vector.
std::string mFileName; std::string mFileName;
@ -125,6 +130,17 @@ class RemoteDirectoryStorage: public DirectoryStorage
public: public:
RemoteDirectoryStorage(const RsPeerId& pid,const std::string& fname) : DirectoryStorage(fname,pid) {} RemoteDirectoryStorage(const RsPeerId& pid,const std::string& fname) : DirectoryStorage(fname,pid) {}
virtual ~RemoteDirectoryStorage() {} virtual ~RemoteDirectoryStorage() {}
/*!
* \brief deserialiseDirEntry
* Loads a serialised directory content coming from a friend. The directory entry needs to exist already,
* as it is created when updating the parent.
*
* \param indx index of the directory to update
* \param bindata binary data to deserialise from
* \return false when the directory cannot be found.
*/
bool deserialiseDirEntry(const EntryIndex& indx,const RsTlvBinaryData& data) ;
}; };
class LocalDirectoryStorage: public DirectoryStorage class LocalDirectoryStorage: public DirectoryStorage
@ -150,6 +166,16 @@ public:
virtual bool extractData(const EntryIndex& indx,DirDetails& d) ; virtual bool extractData(const EntryIndex& indx,DirDetails& d) ;
/*!
* \brief serialiseDirEntry
* Produced a serialised directory content listing suitable for export to friends.
*
* \param indx index of the directory to serialise
* \param bindata binary data created by serialisation
* \return false when the directory cannot be found.
*/
bool serialiseDirEntry(const EntryIndex& indx,RsTlvBinaryData& bindata) ;
private: private:
std::string locked_findRealRootFromVirtualFilename(const std::string& virtual_rootdir) const; std::string locked_findRealRootFromVirtualFilename(const std::string& virtual_rootdir) const;

View File

@ -20,6 +20,9 @@ static const uint8_t FILE_LIST_IO_TAG_RECURS_MODIF_TS = 0x06 ;
static const uint8_t FILE_LIST_IO_TAG_HASH_STORAGE_ENTRY = 0x07 ; static const uint8_t FILE_LIST_IO_TAG_HASH_STORAGE_ENTRY = 0x07 ;
static const uint8_t FILE_LIST_IO_TAG_UPDATE_TS = 0x08 ; static const uint8_t FILE_LIST_IO_TAG_UPDATE_TS = 0x08 ;
static const uint8_t FILE_LIST_IO_TAG_BINARY_DATA = 0x09 ; static const uint8_t FILE_LIST_IO_TAG_BINARY_DATA = 0x09 ;
static const uint8_t FILE_LIST_IO_TAG_RAW_NUMBER = 0x0a ;
static const uint8_t FILE_LIST_IO_TAG_ENTRY_INDEX = 0x0b ;
static const uint8_t FILE_LIST_IO_TAG_REMOTE_FILE_ENTRY = 0x0c ;
class FileListIO class FileListIO
{ {

View File

@ -113,7 +113,7 @@ int p3FileDatabase::tick()
last_print_time = now ; last_print_time = now ;
//#warning this should be removed, but it's necessary atm for updating the GUI //#warning this should be removed, but it's necessary atm for updating the GUI
// RsServer::notify()->notifyListChange(NOTIFY_LIST_DIRLIST_FRIENDS, 0); RsServer::notify()->notifyListChange(NOTIFY_LIST_DIRLIST_FRIENDS, 0);
} }
if(mUpdateFlags) if(mUpdateFlags)
@ -129,7 +129,7 @@ int p3FileDatabase::tick()
mUpdateFlags = P3FILELISTS_UPDATE_FLAG_NOTHING_CHANGED ; mUpdateFlags = P3FILELISTS_UPDATE_FLAG_NOTHING_CHANGED ;
} }
if(mLastRemoteDirSweepTS + 5 < now) if(mLastRemoteDirSweepTS + 30 < now)
{ {
RS_STACK_MUTEX(mFLSMtx) ; RS_STACK_MUTEX(mFLSMtx) ;
@ -227,6 +227,9 @@ void p3FileDatabase::cleanup()
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 " << *it << ", with index " << friend_index << std::endl;
if(mRemoteDirectories.size() <= friend_index)
mRemoteDirectories.resize(friend_index+1,NULL) ;
mRemoteDirectories[friend_index] = new RemoteDirectoryStorage(*it,makeRemoteFileName(*it)); mRemoteDirectories[friend_index] = new RemoteDirectoryStorage(*it,makeRemoteFileName(*it));
mUpdateFlags |= P3FILELISTS_UPDATE_FLAG_REMOTE_MAP_CHANGED ; mUpdateFlags |= P3FILELISTS_UPDATE_FLAG_REMOTE_MAP_CHANGED ;
@ -324,7 +327,7 @@ bool p3FileDatabase::convertEntryIndexToPointer(const EntryIndex& e, uint32_t fi
// [ 10 bits | 22 bits ] // [ 10 bits | 22 bits ]
// //
// This means that the whoel software has the following build-in limitation: // This means that the whoel software has the following build-in limitation:
// * 1024 friends // * 1023 friends
// * 4M shared files. // * 4M shared files.
uint32_t fe = (uint32_t)e ; uint32_t fe = (uint32_t)e ;
@ -346,8 +349,21 @@ int p3FileDatabase::RequestDirDetails(void *ref, DirDetails& d, FileSearchFlags
{ {
RS_STACK_MUTEX(mFLSMtx) ; RS_STACK_MUTEX(mFLSMtx) ;
d.children.clear();
// Case where the pointer is NULL, which means we're at the top of the list of shared directories for all friends (including us) // Case where the pointer is NULL, which means we're at the top of the list of shared directories for all friends (including us)
// or at the top of our own list of shred directories, depending on the flags. // or at the top of our own list of shared directories, depending on the flags.
// Friend index is used as follows:
// 0 : own id
// 1...n : other friends
//
// entry_index: starts at 0.
//
// The point is: we cannot use (0,0) because it encodes to NULL. No existing combination should encode to NULL.
// So we need to properly convert the friend index into 0 or into a friend tab index in mRemoteDirectories.
//
// We should also check the consistency between flags and the content of ref.
if (ref == NULL) if (ref == NULL)
{ {
@ -363,7 +379,6 @@ int p3FileDatabase::RequestDirDetails(void *ref, DirDetails& d, FileSearchFlags
d.age = 0; d.age = 0;
d.flags.clear() ; d.flags.clear() ;
d.min_age = 0 ; d.min_age = 0 ;
d.children.clear();
if(flags & RS_FILE_HINTS_LOCAL) if(flags & RS_FILE_HINTS_LOCAL)
{ {
@ -379,7 +394,7 @@ int p3FileDatabase::RequestDirDetails(void *ref, DirDetails& d, FileSearchFlags
else for(uint32_t i=0;i<mRemoteDirectories.size();++i) else for(uint32_t i=0;i<mRemoteDirectories.size();++i)
{ {
void *p; void *p;
convertEntryIndexToPointer(mRemoteDirectories[i]->root(),i,p); convertEntryIndexToPointer(mRemoteDirectories[i]->root(),i+1,p);
DirStub stub; DirStub stub;
stub.type = DIR_TYPE_PERSON; stub.type = DIR_TYPE_PERSON;
@ -390,6 +405,9 @@ int p3FileDatabase::RequestDirDetails(void *ref, DirDetails& d, FileSearchFlags
d.count = d.children.size(); d.count = d.children.size();
std::cerr << "ExtractData: ref=" << ref << ", flags=" << flags << " : returning this: " << std::endl;
std::cerr << d << std::endl;
return true ; return true ;
} }
@ -398,9 +416,17 @@ int p3FileDatabase::RequestDirDetails(void *ref, DirDetails& d, FileSearchFlags
convertPointerToEntryIndex(ref,e,fi); convertPointerToEntryIndex(ref,e,fi);
// check consistency
if( (fi == 0 && !(flags & RS_FILE_HINTS_LOCAL)) || (fi > 0 && (flags & RS_FILE_HINTS_LOCAL)))
{
std::cerr << "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. // Case where the index is the top of a single person. Can be us, or a friend.
bool res = (flags & RS_FILE_HINTS_LOCAL)? (mLocalSharedDirs->extractData(e,d)) : (mRemoteDirectories[fi]->extractData(e,d)) ; bool res = storage->extractData(e,d);
// update indexes. This is a bit hacky, but does the job. The cast to intptr_t is the proper way to convert // update indexes. This is a bit hacky, but does the job. The cast to intptr_t is the proper way to convert
// a pointer into an int. // a pointer into an int.
@ -410,22 +436,18 @@ int p3FileDatabase::RequestDirDetails(void *ref, DirDetails& d, FileSearchFlags
for(uint32_t i=0;i<d.children.size();++i) for(uint32_t i=0;i<d.children.size();++i)
convertEntryIndexToPointer((intptr_t)d.children[i].ref,fi,d.children[i].ref); convertEntryIndexToPointer((intptr_t)d.children[i].ref,fi,d.children[i].ref);
#define Make sure this is right. if(e == 0) // root
if(e == 0)
{ {
d.prow = 0;//fi-1 ; d.prow = 0;//fi-1 ;
d.parent = NULL ; d.parent = NULL ;
} }
else else
{ {
d.prow = mRemoteDirectories[fi]->parentRow(e) ; d.prow = storage->parentRow(e) ;
convertEntryIndexToPointer((intptr_t)d.parent,fi,d.parent) ; convertEntryIndexToPointer((intptr_t)d.parent,fi,d.parent) ;
} }
if(flags & RS_FILE_HINTS_LOCAL) d.id = storage->peerId();
d.id = mOwnId ;
else
d.id = mRemoteDirectories[fi]->peerId();
std::cerr << "ExtractData: ref=" << ref << ", flags=" << flags << " : returning this: " << std::endl; std::cerr << "ExtractData: ref=" << ref << ", flags=" << flags << " : returning this: " << std::endl;
std::cerr << d << std::endl; std::cerr << d << std::endl;
@ -670,7 +692,7 @@ void p3FileDatabase::handleDirSyncRequest(RsFileListsSyncRequestItem *item)
else else
{ {
time_t local_recurs_max_time,local_update_time; time_t local_recurs_max_time,local_update_time;
mLocalSharedDirs->getUpdateTS(item->entry_index,local_recurs_max_time,local_update_time); mLocalSharedDirs->getDirUpdateTS(item->entry_index,local_recurs_max_time,local_update_time);
if(item->last_known_recurs_modf_TS < local_recurs_max_time) if(item->last_known_recurs_modf_TS < local_recurs_max_time)
{ {
@ -686,7 +708,7 @@ void p3FileDatabase::handleDirSyncRequest(RsFileListsSyncRequestItem *item)
P3FILELISTS_DEBUG() << " Directory is up to date w.r.t. what the friend knows. Sending ACK." << std::endl; P3FILELISTS_DEBUG() << " Directory is up to date w.r.t. what the friend knows. Sending ACK." << std::endl;
ritem->flags = RsFileListsItem::FLAGS_SYNC_RESPONSE | RsFileListsItem::FLAGS_ENTRY_UP_TO_DATE ; ritem->flags = RsFileListsItem::FLAGS_SYNC_RESPONSE | RsFileListsItem::FLAGS_ENTRY_UP_TO_DATE ;
ritem->last_known_recurs_modf_TS = local_update_time ; ritem->last_known_recurs_modf_TS = local_recurs_max_time ;
} }
} }
} }
@ -725,14 +747,14 @@ void p3FileDatabase::handleDirSyncResponse(RsFileListsSyncResponseItem *item)
{ {
P3FILELISTS_DEBUG() << " Directory is up to date. Setting local TS." << std::endl; P3FILELISTS_DEBUG() << " Directory is up to date. Setting local TS." << std::endl;
mRemoteDirectories[fi]->setUpdateTS(item->entry_index,item->last_known_recurs_modf_TS,time(NULL)); mRemoteDirectories[fi]->setDirUpdateTS(item->entry_index,item->last_known_recurs_modf_TS,time(NULL));
} }
else if(item->flags & RsFileListsItem::FLAGS_SYNC_DIR_CONTENT) else if(item->flags & RsFileListsItem::FLAGS_SYNC_DIR_CONTENT)
{ {
P3FILELISTS_DEBUG() << " Item contains directory data. Uptating." << std::endl; P3FILELISTS_DEBUG() << " Item contains directory data. Updating." << std::endl;
mRemoteDirectories[fi]->deserialiseUpdateEntry(item->entry_index,item->directory_content_data) ; mRemoteDirectories[fi]->deserialiseDirEntry(item->entry_index,item->directory_content_data) ;
mRemoteDirectories[fi]->setUpdateTS(item->entry_index,item->last_known_recurs_modf_TS,time(NULL)); mRemoteDirectories[fi]->setDirUpdateTS(item->entry_index,item->last_known_recurs_modf_TS,time(NULL));
#warning should notify the GUI here #warning should notify the GUI here
// notify the GUI if the hierarchy has changed // notify the GUI if the hierarchy has changed
@ -750,7 +772,7 @@ void p3FileDatabase::locked_recursSweepRemoteDirectory(RemoteDirectoryStorage *r
time_t recurs_max_modf_TS_remote_time,local_update_TS; time_t recurs_max_modf_TS_remote_time,local_update_TS;
if(!rds->getUpdateTS(e,recurs_max_modf_TS_remote_time,local_update_TS)) if(!rds->getDirUpdateTS(e,recurs_max_modf_TS_remote_time,local_update_TS))
{ {
std::cerr << "(EE) lockec_recursSweepRemoteDirectory(): cannot get update TS for directory with index " << e << ". This is a consistency bug." << std::endl; std::cerr << "(EE) lockec_recursSweepRemoteDirectory(): cannot get update TS for directory with index " << e << ". This is a consistency bug." << std::endl;
return; return;
@ -798,6 +820,18 @@ void p3FileDatabase::locked_recursSweepRemoteDirectory(RemoteDirectoryStorage *r
locked_recursSweepRemoteDirectory(rds,*it); locked_recursSweepRemoteDirectory(rds,*it);
} }
p3FileDatabase::DirSyncRequestId p3FileDatabase::makeDirSyncReqId(const RsPeerId& peer_id,DirectoryStorage::EntryIndex e)
{
uint64_t r = e ;
// This is kind of arbitrary. The important thing is that the same ID needs to be generated for a given (peer_id,e) pair.
for(uint32_t i=0;i<RsPeerId::SIZE_IN_BYTES;++i)
r += (0x3ff92892a94 * peer_id.toByteArray()[i] + r) ^ 0x39e83784378aafe3;
return r;
}

View File

@ -17,7 +17,7 @@ RsItem* RsFileListsSerialiser::deserialise(void *data, uint32_t *size)
{ {
case RS_PKT_SUBTYPE_FILELISTS_SYNC_REQ_ITEM: return deserialFileListsSyncRequestItem(data, size); case RS_PKT_SUBTYPE_FILELISTS_SYNC_REQ_ITEM: return deserialFileListsSyncRequestItem(data, size);
case RS_PKT_SUBTYPE_FILELISTS_SYNC_RSP_ITEM: return deserialFileListsSyncResponseItem(data, size); case RS_PKT_SUBTYPE_FILELISTS_SYNC_RSP_ITEM: return deserialFileListsSyncResponseItem(data, size);
case RS_PKT_SUBTYPE_FILELISTS_CONFIG_ITEM: return deserialFileListsConfigItem (data, size); // case RS_PKT_SUBTYPE_FILELISTS_CONFIG_ITEM: return deserialFileListsConfigItem (data, size);
default: default:
{ {
@ -154,6 +154,13 @@ bool RsFileListsSyncResponseItem::serialise(void *data, uint32_t& size) const
// Deserialisation // // Deserialisation //
//============================================================================================================================// //============================================================================================================================//
//RsFileListsConfigItem* RsFileListsSerialiser::deserialFileListsConfigItem(void *data, uint32_t *size)
//{
// NOT_IMPLEMENTED();
//
// return NULL ;
//}
RsFileListsSyncRequestItem* RsFileListsSerialiser::deserialFileListsSyncRequestItem(void *data, uint32_t *size) RsFileListsSyncRequestItem* RsFileListsSerialiser::deserialFileListsSyncRequestItem(void *data, uint32_t *size)
{ {
bool ok = checkItemHeader(data,size,RS_PKT_SUBTYPE_FILELISTS_SYNC_REQ_ITEM); bool ok = checkItemHeader(data,size,RS_PKT_SUBTYPE_FILELISTS_SYNC_REQ_ITEM);

View File

@ -125,7 +125,7 @@ public:
private: private:
RsFileListsSyncRequestItem *deserialFileListsSyncRequestItem(void *data, uint32_t *size); /* RS_PKT_SUBTYPE_SYNC_GRP */ RsFileListsSyncRequestItem *deserialFileListsSyncRequestItem(void *data, uint32_t *size); /* RS_PKT_SUBTYPE_SYNC_GRP */
RsFileListsSyncResponseItem *deserialFileListsSyncResponseItem(void *data, uint32_t *size); /* RS_PKT_SUBTYPE_SYNC_GRP */ RsFileListsSyncResponseItem *deserialFileListsSyncResponseItem(void *data, uint32_t *size); /* RS_PKT_SUBTYPE_SYNC_GRP */
RsFileListsSyncResponseItem *deserialFileListsConfigItem (void *data, uint32_t *size); /* RS_PKT_SUBTYPE_SYNC_GRP */ // RsFileListsSyncResponseItem *deserialFileListsConfigItem (void *data, uint32_t *size); /* RS_PKT_SUBTYPE_SYNC_GRP */
bool checkItemHeader(void *data, uint32_t *size, uint8_t subservice_type); bool checkItemHeader(void *data, uint32_t *size, uint8_t subservice_type);
}; };

View File

@ -60,7 +60,7 @@ std::ostream &operator<<(std::ostream &out, const DirDetails& d)
std::cerr << " Min age : " << d.min_age << std::endl; std::cerr << " Min age : " << d.min_age << std::endl;
std::cerr << " Flags : " << d.flags << std::endl; std::cerr << " Flags : " << d.flags << std::endl;
std::cerr << " Parent groups : " ; for(std::list<std::string>::const_iterator it(d.parent_groups.begin());it!=d.parent_groups.end();++it) std::cerr << (*it) << " "; std::cerr << std::endl; std::cerr << " Parent groups : " ; for(std::list<std::string>::const_iterator it(d.parent_groups.begin());it!=d.parent_groups.end();++it) std::cerr << (*it) << " "; std::cerr << std::endl;
std::cerr << " Children : " ; for(uint32_t i=0;i<d.children.size();++i) std::cerr << (intptr_t)d.children[i].ref << " "; std::cerr << std::endl; std::cerr << " Children : " ; for(uint32_t i=0;i<d.children.size();++i) std::cerr << (void*)(intptr_t)d.children[i].ref << " "; std::cerr << std::endl;
std::cerr << "===================" << std::endl; std::cerr << "===================" << std::endl;
return out; return out;
} }