diff --git a/libretroshare/src/file_sharing/dir_hierarchy.cc b/libretroshare/src/file_sharing/dir_hierarchy.cc index 7d7864165..31ba93eb3 100644 --- a/libretroshare/src/file_sharing/dir_hierarchy.cc +++ b/libretroshare/src/file_sharing/dir_hierarchy.cc @@ -638,6 +638,23 @@ bool InternalFileHierarchyStorage::setTS(const DirectoryStorage::EntryIndex& ind return true; } +// Do a complete recursive sweep of directory hierarchy and update cumulative size of directories + +uint64_t InternalFileHierarchyStorage::recursUpdateCumulatedSize(const DirectoryStorage::EntryIndex& dir_index) +{ + DirEntry& d(*static_cast(mNodes[dir_index])) ; + + uint64_t local_cumulative_size = 0; + + for(uint32_t i=0;i(mNodes[d.subfiles[i]])->file_size; + + for(uint32_t i=0;i subdirs ; std::vector subfiles ; @@ -108,6 +109,10 @@ public: rstime_t recursUpdateLastModfTime(const DirectoryStorage::EntryIndex& dir_index, bool &unfinished_files_present); + // Do a complete recursive sweep over sub-directories and files, and update the cumulative size. + + uint64_t recursUpdateCumulatedSize(const DirectoryStorage::EntryIndex& dir_index); + // hash stuff bool getDirHashFromIndex(const DirectoryStorage::EntryIndex& index,RsFileHash& hash) const ; diff --git a/libretroshare/src/file_sharing/directory_storage.cc b/libretroshare/src/file_sharing/directory_storage.cc index fbbb27e4a..b574c4a2a 100644 --- a/libretroshare/src/file_sharing/directory_storage.cc +++ b/libretroshare/src/file_sharing/directory_storage.cc @@ -35,7 +35,7 @@ # include "deep_search/filesindex.hpp" #endif // def RS_DEEP_FILES_INDEX -//#define DEBUG_REMOTE_DIRECTORY_STORAGE 1 +#define DEBUG_REMOTE_DIRECTORY_STORAGE 1 /******************************************************************************************************************/ /* Iterators */ @@ -235,7 +235,7 @@ bool DirectoryStorage::extractData(const EntryIndex& indx,DirDetails& d) d.type = DIR_TYPE_DIR; d.hash.clear() ; - d.count = dir_entry->subdirs.size() + dir_entry->subfiles.size(); + d.count = dir_entry->dir_cumulated_size;//dir_entry->subdirs.size() + dir_entry->subfiles.size(); d.max_mtime = dir_entry->dir_most_recent_time ; d.mtime = dir_entry->dir_modtime ; d.name = dir_entry->dir_name; @@ -292,6 +292,8 @@ void DirectoryStorage::checkSave() if(mChanged && mLastSavedTime + MIN_INTERVAL_BETWEEN_REMOTE_DIRECTORY_SAVE < now) { + mFileHierarchy->recursUpdateCumulatedSize(mFileHierarchy->mRoot); + { RS_STACK_MUTEX(mDirStorageMtx) ; locked_check(); diff --git a/libretroshare/src/file_sharing/directory_updater.cc b/libretroshare/src/file_sharing/directory_updater.cc index 406c44024..828d1ee2c 100644 --- a/libretroshare/src/file_sharing/directory_updater.cc +++ b/libretroshare/src/file_sharing/directory_updater.cc @@ -224,7 +224,7 @@ void LocalDirectoryUpdater::recursUpdateSharedDir(const std::string& cumulated_p { some_files_not_ready = true ; - std::cerr << "(WW) file " << dirIt.file_fullpath() << " is probably being modified. Keeping it for later." << std::endl; + std::cerr << "(WW) file " << dirIt.file_fullpath() << " is probably being written to. Keeping it for later." << std::endl; } break; diff --git a/libretroshare/src/file_sharing/p3filelists.h b/libretroshare/src/file_sharing/p3filelists.h index 41e8cbeaf..f9a97e47b 100644 --- a/libretroshare/src/file_sharing/p3filelists.h +++ b/libretroshare/src/file_sharing/p3filelists.h @@ -22,25 +22,40 @@ // // This class is responsible for -// - maintaining a list of shared file hierarchies for each known friends -// - talking to the GUI -// - providing handles for the directory tree listing GUI -// - providing search handles for FT -// - keeping these lists up to date -// - sending our own file list to friends depending on the defined access rights -// - serving file search requests from other services such as file transfer +// - maintaining a list of shared file hierarchies for each known friends +// - talking to the GUI +// - providing handles for the directory tree listing GUI +// - providing search handles for FT +// - keeping these lists up to date +// - sending our own file list to friends depending on the defined access rights +// - serving file search requests from other services such as file transfer // -// p3FileList does the following micro-tasks: -// - tick the watchers -// - get incoming info from the service layer, which can be: -// - directory content request => the directory content is shared to the friend -// - directory content => the directory watcher is notified -// - keep two queues of update requests: -// - fast queue that is handled in highest priority. This one is used for e.g. updating while browsing. -// - slow queue that is handled slowly. Used in background update of shared directories. +// p3FileList does the following micro-tasks: +// - tick the watchers +// - get incoming info from the service layer, which can be: +// - directory content request => the directory content is shared to the friend +// - directory content => the directory watcher is notified +// - keep two queues of update requests: +// - fast queue that is handled in highest priority. This one is used for e.g. updating while browsing. +// - slow queue that is handled slowly. Used in background update of shared directories. // -// The file lists are not directry updated. A FileListWatcher class is responsible for this -// in every case. +// The list of local shared files is maintained by FileListWatcher. +// +// p3FileLists is organised as follows: +// +// p3FileDatabase +// | +// +---- HashStorage // Handles known hashes. Serves as a reference when new files are hashed. +// | +// +---- RemoteDirectoryStorage // Stores the list of shared files at friends +// | | +// | +---- InternalFileHierarchyStorage +// | +// +---- LocalDirectoryStorage // Stores the list of locally shared files +// | | +// | +---- InternalFileHierarchyStorage +// | +// +---- LocalDirectoryUpdater // Keeps the local lists up to date, by regularly crawling directories // #pragma once diff --git a/retroshare-gui/src/gui/RemoteDirModel.cpp b/retroshare-gui/src/gui/RemoteDirModel.cpp index f989a2ec5..a5f4db8af 100644 --- a/retroshare-gui/src/gui/RemoteDirModel.cpp +++ b/retroshare-gui/src/gui/RemoteDirModel.cpp @@ -205,7 +205,7 @@ bool TreeStyle_RDM::hasChildren(const QModelIndex &parent) const std::cerr << "lookup PER/DIR #" << details.count; std::cerr << std::endl; #endif - return (details.count > 0); /* do we have children? */ + return (details.children.size() > 0); /* do we have children? */ } bool FlatStyle_RDM::hasChildren(const QModelIndex &parent) const { @@ -270,14 +270,14 @@ int TreeStyle_RDM::rowCount(const QModelIndex &parent) const //Scan all children to know if they are empty. //And save their real row index //Prefer do like that than modify requestDirDetails with a new flag (rsFiles->RequestDirDetails) - for(uint64_t i = 0; i < details.count; ++i) + for(uint64_t i = 0; i < details.children.size(); ++i) { - if (requestDirDetails(details.children[i].ref, RemoteMode,childDetails) && (childDetails.count > 0)) + if (requestDirDetails(details.children[i].ref, RemoteMode,childDetails) && (childDetails.children.size() > 0)) _parentRow.push_back(i); } return _parentRow.size(); } - return details.count; + return details.children.size(); } int FlatStyle_RDM::rowCount(const QModelIndex &parent) const { @@ -504,7 +504,7 @@ QVariant TreeStyle_RDM::displayRole(const DirDetails& details,int coln) const else if(details.id == rsPeers->getOwnId()) rsFiles->getSharedDirStatistics(rsPeers->getOwnId(),stats) ; else - stats.total_number_of_files = details.count; + stats.total_number_of_files = details.children.size(); if(stats.total_number_of_files > 0) { @@ -583,14 +583,14 @@ QVariant TreeStyle_RDM::displayRole(const DirDetails& details,int coln) const return QString::fromUtf8(details.name.c_str()); break; case COLUMN_FILENB: - if (details.count > 1) + if (details.children.size() > 1) { - return QString::number(details.count) + " " + tr("Files"); + return QString::number(details.children.size()) + " " + tr("Files"); } - return QString::number(details.count) + " " + tr("File"); + return QString::number(details.children.size()) + " " + tr("File"); case COLUMN_SIZE: - return QVariant(); - case COLUMN_AGE: + return misc::friendlyUnit(details.count); + case COLUMN_AGE: return misc::timeRelativeToNow(details.max_mtime); case COLUMN_FRIEND_ACCESS: return QVariant(); @@ -734,7 +734,7 @@ QVariant TreeStyle_RDM::sortRole(const QModelIndex& /*index*/,const DirDetails& case COLUMN_NAME: return QString::fromUtf8(details.name.c_str()); case COLUMN_FILENB: - return (qulonglong) details.count; + return (qulonglong) details.children.size(); case COLUMN_SIZE: return (qulonglong) 0; case COLUMN_AGE: @@ -1286,8 +1286,7 @@ void RetroshareDirModel::downloadSelected(const QModelIndexList &list,bool inter std::cerr << std::endl; std::list srcIds; srcIds.push_back(details.id); - rsFiles -> FileRequest(details.name, details.hash, - details.count, "", RS_FILE_REQ_ANONYMOUS_ROUTING, srcIds); + rsFiles -> FileRequest(details.name, details.hash, details.count, "", RS_FILE_REQ_ANONYMOUS_ROUTING, srcIds); } /* if it is a dir, copy all files included*/ else if (details.type == DIR_TYPE_DIR) @@ -1611,8 +1610,7 @@ QMimeData * RetroshareDirModel::mimeData ( const QModelIndexList & indexes ) con continue; /* duplicate */ } - drags[details.hash] = details.count; - + drags[details.hash] = details.children.size(); QString line = QString("%1/%2/%3/").arg(QString::fromUtf8(details.name.c_str()), QString::fromStdString(details.hash.toStdString()), QString::number(details.count)); if (RemoteMode)