mirror of
https://github.com/RetroShare/RetroShare.git
synced 2024-10-01 02:35:48 -04:00
finished implementing hash-based transactions. To be tested.
This commit is contained in:
parent
eaa8ad883a
commit
fafe684cc4
@ -227,7 +227,7 @@ bool InternalFileHierarchyStorage::updateFile(const DirectoryStorage::EntryIndex
|
||||
return true;
|
||||
}
|
||||
|
||||
bool InternalFileHierarchyStorage::updateDirEntry(const DirectoryStorage::EntryIndex& indx,const std::string& dir_name,time_t most_recent_time,time_t dir_modtime,const std::vector<DirectoryStorage::EntryIndex>& subdirs_array,const std::vector<DirectoryStorage::EntryIndex>& subfiles_array)
|
||||
bool InternalFileHierarchyStorage::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<RsFileHash>& subfiles_hash)
|
||||
{
|
||||
if(!checkIndex(indx,FileStorageNode::TYPE_DIR))
|
||||
{
|
||||
@ -241,47 +241,103 @@ bool InternalFileHierarchyStorage::updateDirEntry(const DirectoryStorage::EntryI
|
||||
d.dir_update_time = time(NULL);
|
||||
d.dir_name = dir_name;
|
||||
|
||||
d.subfiles = subfiles_array ;
|
||||
d.subdirs = subdirs_array ;
|
||||
d.subdirs.clear();
|
||||
d.subfiles.clear();
|
||||
|
||||
// check that all subdirs already exist. If not, create.
|
||||
for(uint32_t i=0;i<subdirs_array.size();++i)
|
||||
for(uint32_t i=0;i<subdirs_hash.size();++i)
|
||||
{
|
||||
if(subdirs_array[i] >= mNodes.size() )
|
||||
mNodes.resize(subdirs_array[i]+1,NULL);
|
||||
DirectoryStorage::EntryIndex dir_index = 0;
|
||||
std::map<RsFileHash,DirectoryStorage::EntryIndex>::const_iterator it = mDirHashes.find(subdirs_hash[i]) ;
|
||||
|
||||
FileStorageNode *& node(mNodes[subdirs_array[i]]);
|
||||
|
||||
if(node != NULL && node->type() != FileStorageNode::TYPE_DIR)
|
||||
if(it == mDirHashes.end() || it->second >= mNodes.size())
|
||||
{
|
||||
delete node ;
|
||||
node = NULL ;
|
||||
}
|
||||
// find an epty slot
|
||||
int found = -1 ;
|
||||
|
||||
if(node == NULL)
|
||||
for(uint32_t j=0;j<mNodes.size();++j)
|
||||
if(mNodes[i] == NULL)
|
||||
{
|
||||
found = j;
|
||||
break;
|
||||
}
|
||||
|
||||
if(found < 0)
|
||||
{
|
||||
dir_index = mNodes.size() ;
|
||||
mNodes.push_back(NULL) ;
|
||||
}
|
||||
else
|
||||
dir_index = found;
|
||||
|
||||
mDirHashes[subdirs_hash[i]] = dir_index ;
|
||||
}
|
||||
else
|
||||
{
|
||||
dir_index = it->second;
|
||||
|
||||
if(mNodes[dir_index] != NULL && mNodes[dir_index]->type() != FileStorageNode::TYPE_DIR)
|
||||
{
|
||||
delete mNodes[dir_index] ;
|
||||
mNodes[dir_index] = NULL ;
|
||||
}
|
||||
}
|
||||
FileStorageNode *& node(mNodes[dir_index]);
|
||||
if(!node)
|
||||
node = new DirEntry("");
|
||||
|
||||
d.subdirs.push_back(dir_index) ;
|
||||
|
||||
((DirEntry*&)node)->dir_parent_path = d.dir_parent_path + "/" + dir_name ;
|
||||
node->row = i ;
|
||||
node->parent_index = indx ;
|
||||
}
|
||||
for(uint32_t i=0;i<subfiles_array.size();++i)
|
||||
for(uint32_t i=0;i<subfiles_hash.size();++i)
|
||||
{
|
||||
if(subfiles_array[i] >= mNodes.size() )
|
||||
mNodes.resize(subfiles_array[i]+1,NULL);
|
||||
DirectoryStorage::EntryIndex file_index = 0;
|
||||
std::map<RsFileHash,DirectoryStorage::EntryIndex>::const_iterator it = mFileHashes.find(subfiles_hash[i]) ;
|
||||
|
||||
FileStorageNode *& node(mNodes[subfiles_array[i]]);
|
||||
|
||||
if(node != NULL && node->type() != FileStorageNode::TYPE_FILE)
|
||||
if(it == mFileHashes.end())
|
||||
{
|
||||
delete node ;
|
||||
node = NULL ;
|
||||
// find an epty slot
|
||||
int found = -1;
|
||||
|
||||
for(uint32_t j=0;j<mNodes.size();++j)
|
||||
if(mNodes[i] == NULL)
|
||||
{
|
||||
found = j;
|
||||
break;
|
||||
}
|
||||
|
||||
if(found < 0)
|
||||
{
|
||||
file_index = mNodes.size() ;
|
||||
mNodes.push_back(NULL) ;
|
||||
}
|
||||
else
|
||||
file_index = found;
|
||||
|
||||
mFileHashes[subfiles_hash[i]] = file_index ;
|
||||
}
|
||||
else
|
||||
{
|
||||
file_index = it->second ;
|
||||
|
||||
if(node == NULL)
|
||||
node = new FileEntry("",0,0);
|
||||
if(mNodes[file_index] != NULL && mNodes[file_index]->type() != FileStorageNode::TYPE_FILE)
|
||||
{
|
||||
delete mNodes[file_index] ;
|
||||
mNodes[file_index] = NULL ;
|
||||
}
|
||||
|
||||
node->row = subdirs_array.size()+i ;
|
||||
file_index = it->second;
|
||||
}
|
||||
FileStorageNode *& node(mNodes[file_index]);
|
||||
if(!node)
|
||||
node = new FileEntry("",0,0,subfiles_hash[i]);
|
||||
|
||||
d.subfiles.push_back(file_index) ;
|
||||
|
||||
node->row = subdirs_hash.size()+i ;
|
||||
node->parent_index = indx ;
|
||||
}
|
||||
|
||||
|
@ -73,7 +73,7 @@ public:
|
||||
bool updateSubFilesList(const DirectoryStorage::EntryIndex& indx,const std::map<std::string,DirectoryStorage::FileTS>& subfiles,std::map<std::string,DirectoryStorage::FileTS>& new_files);
|
||||
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<DirectoryStorage::EntryIndex>& subdirs_array,const std::vector<DirectoryStorage::EntryIndex>& subfiles_array);
|
||||
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<RsFileHash> &subfiles_hash);
|
||||
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);
|
||||
|
||||
|
@ -466,7 +466,7 @@ bool LocalDirectoryStorage::serialiseDirEntry(const EntryIndex& indx,RsTlvBinary
|
||||
}
|
||||
|
||||
// compute list of allowed subdirs
|
||||
std::vector<EntryIndex> allowed_subdirs ;
|
||||
std::vector<RsFileHash> allowed_subdirs ;
|
||||
FileStorageFlags node_flags ;
|
||||
std::list<RsNodeGroupId> node_groups ;
|
||||
|
||||
@ -474,7 +474,16 @@ bool LocalDirectoryStorage::serialiseDirEntry(const EntryIndex& indx,RsTlvBinary
|
||||
|
||||
for(uint32_t i=0;i<dir->subdirs.size();++i)
|
||||
if(indx != 0 || (locked_getFileSharingPermissions(dir->subdirs[i],node_flags,node_groups) && (rsPeers->computePeerPermissionFlags(client_id,node_flags,node_groups) & RS_FILE_HINTS_BROWSABLE)))
|
||||
allowed_subdirs.push_back(dir->subdirs[i]) ;
|
||||
{
|
||||
RsFileHash hash ;
|
||||
|
||||
if(!getHashFromIndex(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;
|
||||
continue ;
|
||||
}
|
||||
allowed_subdirs.push_back(hash) ;
|
||||
}
|
||||
|
||||
unsigned char *section_data = NULL;
|
||||
uint32_t section_size = 0;
|
||||
@ -498,7 +507,7 @@ bool LocalDirectoryStorage::serialiseDirEntry(const EntryIndex& indx,RsTlvBinary
|
||||
// serialise subdirs entry indexes
|
||||
|
||||
for(uint32_t i=0;i<allowed_subdirs.size();++i)
|
||||
if(!FileListIO::writeField(section_data,section_size,section_offset,FILE_LIST_IO_TAG_ENTRY_INDEX ,(uint32_t)allowed_subdirs[i] )) return false ;
|
||||
if(!FileListIO::writeField(section_data,section_size,section_offset,FILE_LIST_IO_TAG_ENTRY_INDEX ,allowed_subdirs[i] )) return false ;
|
||||
|
||||
// serialise directory subfiles, with info for each of them
|
||||
|
||||
@ -516,7 +525,6 @@ bool LocalDirectoryStorage::serialiseDirEntry(const EntryIndex& indx,RsTlvBinary
|
||||
continue ;
|
||||
}
|
||||
|
||||
if(!FileListIO::writeField(file_section_data,file_section_size,file_section_offset,FILE_LIST_IO_TAG_ENTRY_INDEX ,(uint32_t)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 ;
|
||||
@ -594,14 +602,14 @@ bool RemoteDirectoryStorage::deserialiseUpdateDirEntry(const EntryIndex& indx,co
|
||||
|
||||
// serialise subdirs entry indexes
|
||||
|
||||
std::vector<EntryIndex> subdirs_array ;
|
||||
uint32_t subdir_index ;
|
||||
std::vector<RsFileHash> subdirs_hashes ;
|
||||
RsFileHash subdir_hash ;
|
||||
|
||||
for(uint32_t i=0;i<n_subdirs;++i)
|
||||
{
|
||||
if(!FileListIO::readField(section_data,section_size,section_offset,FILE_LIST_IO_TAG_ENTRY_INDEX ,subdir_index)) return false ;
|
||||
if(!FileListIO::readField(section_data,section_size,section_offset,FILE_LIST_IO_TAG_ENTRY_INDEX ,subdir_hash)) return false ;
|
||||
|
||||
subdirs_array.push_back(EntryIndex(subdir_index)) ;
|
||||
subdirs_hashes.push_back(subdir_hash) ;
|
||||
}
|
||||
|
||||
// deserialise directory subfiles, with info for each of them
|
||||
@ -622,13 +630,11 @@ bool RemoteDirectoryStorage::deserialiseUpdateDirEntry(const EntryIndex& indx,co
|
||||
|
||||
uint32_t file_section_offset = 0 ;
|
||||
|
||||
uint32_t entry_index ;
|
||||
std::string entry_name ;
|
||||
uint64_t entry_size ;
|
||||
RsFileHash entry_hash ;
|
||||
uint32_t entry_modtime ;
|
||||
|
||||
if(!FileListIO::readField(file_section_data,file_section_size,file_section_offset,FILE_LIST_IO_TAG_ENTRY_INDEX ,entry_index )) return false ;
|
||||
if(!FileListIO::readField(file_section_data,file_section_size,file_section_offset,FILE_LIST_IO_TAG_FILE_NAME ,entry_name )) return false ;
|
||||
if(!FileListIO::readField(file_section_data,file_section_size,file_section_offset,FILE_LIST_IO_TAG_FILE_SIZE ,entry_size )) return false ;
|
||||
if(!FileListIO::readField(file_section_data,file_section_size,file_section_offset,FILE_LIST_IO_TAG_FILE_SHA1_HASH,entry_hash )) return false ;
|
||||
@ -636,7 +642,6 @@ bool RemoteDirectoryStorage::deserialiseUpdateDirEntry(const EntryIndex& indx,co
|
||||
|
||||
free(file_section_data) ;
|
||||
|
||||
subfiles_array.push_back(entry_index) ;
|
||||
subfiles_name.push_back(entry_name) ;
|
||||
subfiles_size.push_back(entry_size) ;
|
||||
subfiles_hash.push_back(entry_hash) ;
|
||||
@ -647,20 +652,27 @@ bool RemoteDirectoryStorage::deserialiseUpdateDirEntry(const EntryIndex& indx,co
|
||||
|
||||
std::cerr << " updating dir entry..." << std::endl;
|
||||
|
||||
// first create the entries for each subdir and each subfile.
|
||||
if(!mFileHierarchy->updateDirEntry(indx,dir_name,most_recent_time,dir_modtime,subdirs_array,subfiles_array))
|
||||
// First create the entries for each subdir and each subfile, if needed.
|
||||
if(!mFileHierarchy->updateDirEntry(indx,dir_name,most_recent_time,dir_modtime,subdirs_hashes,subfiles_hash))
|
||||
{
|
||||
std::cerr << "(EE) Cannot update dir entry with index " << indx << ": entry does not exist." << std::endl;
|
||||
return false ;
|
||||
}
|
||||
|
||||
// then update the subfiles
|
||||
for(uint32_t i=0;i<subfiles_array.size();++i)
|
||||
// Then update the subfiles
|
||||
for(uint32_t i=0;i<subfiles_hash.size();++i)
|
||||
{
|
||||
DirectoryStorage::EntryIndex file_index ;
|
||||
|
||||
if(!getIndexFromHash(subfiles_hash[i],file_index))
|
||||
{
|
||||
std::cerr << "(EE) Cannot optain file entry index for hash " << subfiles_hash[i] << ". This is very unexpected." << std::endl;
|
||||
continue;
|
||||
}
|
||||
std::cerr << " updating file entry " << subfiles_hash[i] << std::endl;
|
||||
|
||||
if(!mFileHierarchy->updateFile(subfiles_array[i],subfiles_hash[i],subfiles_name[i],subfiles_size[i],subfiles_modtime[i]))
|
||||
std::cerr << "(EE) Cannot update file with index " << subfiles_array[i] << ". This is very weird. Entry should have just been created and therefore should exist. Skipping." << std::endl;
|
||||
if(!mFileHierarchy->updateFile(file_index,subfiles_hash[i],subfiles_name[i],subfiles_size[i],subfiles_modtime[i]))
|
||||
std::cerr << "(EE) Cannot update file with index " << file_index <<" and hash " << subfiles_hash[i] << ". This is very weird. Entry should have just been created and therefore should exist. Skipping." << std::endl;
|
||||
}
|
||||
mChanged = true ;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user