mirror of
https://github.com/RetroShare/RetroShare.git
synced 2026-09-12 19:50:17 +05:00
Optimized Shared Files view performance by caching file details to eliminate UI freezes and increasing the update frequency for faster list population
This commit is contained in:
parent
ba1d213d5c
commit
37f4ddc3d0
@ -145,7 +145,8 @@ public:
|
||||
void setUploadedOnly(bool val) {
|
||||
if (m_uploadedOnly != val) {
|
||||
m_uploadedOnly = val;
|
||||
invalidateFilter();
|
||||
// invalidateFilter(); // CRASH FIX: Do not invalidate incrementally.
|
||||
// The dialog calls model->update() which triggers a full Reset.
|
||||
}
|
||||
}
|
||||
|
||||
@ -556,7 +557,7 @@ void SharedFilesDialog::changeCurrentViewModel(int viewTypeIndex)
|
||||
// recursRestoreExpandedItems(ui.dirTreeView->rootIndex(),expanded_indexes);
|
||||
|
||||
// Force re-application of filter on the new model
|
||||
mLastFilterText.clear();
|
||||
mLastFilterText = "FORCE_UPDATE_ON_VIEW_SWITCH";
|
||||
FilterItems();
|
||||
|
||||
// MODIFICATION: Expand tree if "Uploaded Only" is active, otherwise items remain hidden in collapsed folders.
|
||||
@ -1284,6 +1285,10 @@ void SharedFilesDialog::FilterItems()
|
||||
|
||||
if(text.length() < 3) {
|
||||
model->filterItems(std::list<std::string>(), found) ;
|
||||
|
||||
// MODIFICATION: Sync proxy filter to ensure it doesn't hold stale text
|
||||
if (proxyModel) proxyModel->setFilterFixedString(QString());
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
@ -1294,6 +1299,20 @@ void SharedFilesDialog::FilterItems()
|
||||
|
||||
model->filterItems(keywords, found) ;
|
||||
|
||||
// MODIFICATION: Hybrid filtering.
|
||||
// Flat View uses model->filterItems (Manual population).
|
||||
// Tree View relies on Proxy for text filtering (Hybrid).
|
||||
// We must sync the proxy to ensure Tree View works and doesn't hold stale data.
|
||||
if (proxyModel) {
|
||||
if(ui.viewType_CB->currentIndex() == VIEW_TYPE_TREE) {
|
||||
proxyModel->setFilterFixedString(RETROSHARE_DIR_MODEL_FILTER_STRING);
|
||||
} else {
|
||||
// In Flat View, Model handles filtering logic (including multi-keyword).
|
||||
// Proxy should NOT double-filter (which breaks multi-keyword).
|
||||
proxyModel->setFilterFixedString(QString());
|
||||
}
|
||||
}
|
||||
|
||||
// Note: model->filterItems() already calls update() (reset),
|
||||
// so proxy invalidation is redundant and handled automatically.
|
||||
if(found > 0) expandAll();
|
||||
@ -1659,7 +1678,14 @@ void SharedFilesDialog::filterUploadedOnlyToggled(bool checked)
|
||||
|
||||
if(ui.viewType_CB->currentIndex() == VIEW_TYPE_TREE) {
|
||||
if (checked) expandAll();
|
||||
else ui.dirTreeView->collapseAll();
|
||||
else {
|
||||
// MODIFICATION: Do not collapse if we have a text filter active, otherwise results are hidden.
|
||||
if (ui.filterPatternLineEdit->text().length() >= 3) {
|
||||
expandAll();
|
||||
} else {
|
||||
ui.dirTreeView->collapseAll();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -57,7 +57,6 @@
|
||||
#define REMOTEDIRMODEL_COLUMN_WN_VISU_DIR 5
|
||||
#define REMOTEDIRMODEL_COLUMN_UPLOADED 6
|
||||
#define REMOTEDIRMODEL_COLUMN_COUNT 7
|
||||
#define RETROSHARE_DIR_MODEL_FILTER_STRING "filtered"
|
||||
|
||||
static const uint32_t FLAT_VIEW_MAX_REFS_PER_SECOND = 10000 ;
|
||||
static const size_t FLAT_VIEW_MAX_REFS_TABLE_SIZE = 30000 ; //
|
||||
@ -219,6 +218,7 @@ void TreeStyle_RDM::recalculateDirectoryTotals()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MODIFICATION D: Check if a specific node or any of its descendants have uploads
|
||||
@ -251,6 +251,7 @@ bool TreeStyle_RDM::hasUploads(void *ref) const
|
||||
|
||||
void TreeStyle_RDM::update()
|
||||
{
|
||||
|
||||
// Recalculate totals before notifying view update
|
||||
recalculateDirectoryTotals();
|
||||
|
||||
@ -587,8 +588,14 @@ void FlatStyle_RDM::update()
|
||||
// Previously, this was guarded by if(_needs_update), preventing filter updates.
|
||||
// if(_needs_update)
|
||||
{
|
||||
// Prevent nested updates/resets which confuse the view
|
||||
if(mUpdating) return;
|
||||
if(mUpdating) return;
|
||||
|
||||
|
||||
|
||||
{
|
||||
RS_STACK_MUTEX(_ref_mutex);
|
||||
m_cache.clear();
|
||||
}
|
||||
|
||||
preMods() ;
|
||||
postMods() ;
|
||||
@ -626,8 +633,36 @@ QString FlatStyle_RDM::computeDirectoryPath(const DirDetails& details) const
|
||||
return dir ;
|
||||
}
|
||||
|
||||
QVariant FlatStyle_RDM::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return QVariant();
|
||||
|
||||
if (role == Qt::DisplayRole)
|
||||
{
|
||||
void *ref = index.internalPointer();
|
||||
|
||||
// Try Lock-less read first? No, use lock for safety matching updateRefs
|
||||
RS_STACK_MUTEX(_ref_mutex);
|
||||
if (m_cache.contains(ref))
|
||||
{
|
||||
const CachedFileDetails &cfd = m_cache[ref];
|
||||
switch(index.column())
|
||||
{
|
||||
case REMOTEDIRMODEL_COLUMN_NAME: return cfd.name;
|
||||
case REMOTEDIRMODEL_COLUMN_SIZE: return cfd.sizeStr;
|
||||
case REMOTEDIRMODEL_COLUMN_AGE: return cfd.ageStr;
|
||||
case REMOTEDIRMODEL_COLUMN_UPLOADED: return cfd.uploadStr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return RetroshareDirModel::data(index, role);
|
||||
}
|
||||
|
||||
QVariant FlatStyle_RDM::displayRole(const DirDetails& details,int coln) const
|
||||
{
|
||||
|
||||
if (details.type == DIR_TYPE_FILE || details.type == DIR_TYPE_EXTRA_FILE) /* File */
|
||||
switch(coln)
|
||||
{
|
||||
@ -1508,6 +1543,10 @@ void RetroshareDirModel::filterItems(const std::list<std::string>& keywords, uin
|
||||
if(result_list.empty())
|
||||
{
|
||||
mFilteredPointers.clear();
|
||||
// MODIFICATION: Insert NULL to signal that we have an active filter which returned no results.
|
||||
// updateRefs will see mFilteredPointers is not empty, enter the filtered path, encounter NULL, skip it,
|
||||
// and resulting view will be empty (correct behavior) instead of showing all files.
|
||||
mFilteredPointers.insert(NULL);
|
||||
update();
|
||||
return ;
|
||||
}
|
||||
@ -1800,6 +1839,7 @@ void FlatStyle_RDM::updateRefs()
|
||||
|
||||
uint32_t nb_treated_refs = 0 ;
|
||||
|
||||
|
||||
{
|
||||
RS_STACK_MUTEX(_ref_mutex) ;
|
||||
|
||||
@ -1818,9 +1858,29 @@ void FlatStyle_RDM::updateRefs()
|
||||
if(requestDirDetails(ref, RemoteMode, details))
|
||||
{
|
||||
if(details.type == DIR_TYPE_FILE || details.type == DIR_TYPE_EXTRA_FILE)
|
||||
{
|
||||
_ref_entries.push_back(ref);
|
||||
|
||||
CachedFileDetails cfd;
|
||||
cfd.name = QString::fromUtf8(details.name.c_str());
|
||||
cfd.sizeStr = misc::friendlyUnit(details.size);
|
||||
|
||||
if(details.type == DIR_TYPE_FILE)
|
||||
cfd.ageStr = misc::timeRelativeToNow(details.max_mtime);
|
||||
else {
|
||||
FileInfo fi;
|
||||
if (rsFiles->FileDetails(details.hash, RS_FILE_HINTS_EXTRA , fi))
|
||||
cfd.ageStr = misc::timeRelativeToNow((rstime_t)fi.age-(30 * 3600 * 24));
|
||||
}
|
||||
|
||||
uint64_t x = rsFiles->getCumulativeUpload(details.hash);
|
||||
cfd.uploadStr = x ? misc::friendlyUnit(x) : QString();
|
||||
|
||||
m_cache[ref] = cfd;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_needs_update = false; // We are done
|
||||
}
|
||||
else
|
||||
@ -1839,7 +1899,26 @@ void FlatStyle_RDM::updateRefs()
|
||||
if (requestDirDetails(ref, RemoteMode,details))
|
||||
{
|
||||
if(details.type == DIR_TYPE_FILE || details.type == DIR_TYPE_EXTRA_FILE) // only push files, not directories nor persons.
|
||||
{
|
||||
_ref_entries.push_back(ref) ;
|
||||
|
||||
CachedFileDetails cfd;
|
||||
cfd.name = QString::fromUtf8(details.name.c_str());
|
||||
cfd.sizeStr = misc::friendlyUnit(details.size);
|
||||
|
||||
if(details.type == DIR_TYPE_FILE)
|
||||
cfd.ageStr = misc::timeRelativeToNow(details.max_mtime);
|
||||
else {
|
||||
FileInfo fi;
|
||||
if (rsFiles->FileDetails(details.hash, RS_FILE_HINTS_EXTRA , fi))
|
||||
cfd.ageStr = misc::timeRelativeToNow((rstime_t)fi.age-(30 * 3600 * 24));
|
||||
}
|
||||
|
||||
uint64_t x = rsFiles->getCumulativeUpload(details.hash);
|
||||
cfd.uploadStr = x ? misc::friendlyUnit(x) : QString();
|
||||
|
||||
m_cache[ref] = cfd;
|
||||
}
|
||||
#ifdef RDM_DEBUG
|
||||
std::cerr << "FlatStyle_RDM::postMods(): adding ref " << ref << std::endl;
|
||||
#endif
|
||||
@ -1854,8 +1933,9 @@ void FlatStyle_RDM::updateRefs()
|
||||
|
||||
if(++nb_treated_refs > FLAT_VIEW_MAX_REFS_PER_SECOND) // we've done enough, let's give back hand to
|
||||
{ // the user and setup a timer to finish the job later.
|
||||
|
||||
if(visible())
|
||||
QTimer::singleShot(2000,this,SLOT(updateRefs())) ;
|
||||
QTimer::singleShot(10,this,SLOT(updateRefs())) ; // Reduced from 2000ms to 10ms for faster loading
|
||||
else
|
||||
std::cerr << "Not visible: suspending update"<< std::endl;
|
||||
break ;
|
||||
@ -1865,8 +1945,12 @@ void FlatStyle_RDM::updateRefs()
|
||||
std::cerr << "reference tab contains " << std::dec << _ref_entries.size() << " files" << std::endl;
|
||||
}
|
||||
|
||||
if(_ref_stack.empty())
|
||||
_needs_update = false ;
|
||||
// The loop is finished.
|
||||
if(_ref_stack.empty()) {
|
||||
|
||||
_needs_update = false ;
|
||||
}
|
||||
|
||||
|
||||
RetroshareDirModel::postMods() ;
|
||||
}
|
||||
|
||||
@ -21,6 +21,8 @@
|
||||
#ifndef REMOTE_DIR_MODEL
|
||||
#define REMOTE_DIR_MODEL
|
||||
|
||||
#define RETROSHARE_DIR_MODEL_FILTER_STRING "filtered"
|
||||
|
||||
#include <retroshare/rstypes.h>
|
||||
#include <retroshare/rsevents.h>
|
||||
|
||||
@ -255,7 +257,11 @@ class FlatStyle_RDM: public RetroshareDirModel
|
||||
virtual void updateRef(const QModelIndex&) const {}
|
||||
// MODIFICATION H: Implement hasUploads for Flat Style to fix compilation
|
||||
virtual bool hasUploads(void *ref) const;
|
||||
virtual QVariant displayRole(const DirDetails&,int) const ;
|
||||
|
||||
// MODIFICATION: Override data() to use internal cache for Flat View
|
||||
virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
|
||||
|
||||
virtual QVariant displayRole(const DirDetails&,int) const ;
|
||||
virtual QVariant sortRole(const QModelIndex&,const DirDetails&,int) const ;
|
||||
|
||||
//Overloaded from QAbstractItemModel
|
||||
@ -271,6 +277,15 @@ class FlatStyle_RDM: public RetroshareDirModel
|
||||
|
||||
QString computeDirectoryPath(const DirDetails& details) const ;
|
||||
|
||||
|
||||
struct CachedFileDetails {
|
||||
QString name;
|
||||
QString sizeStr;
|
||||
QString ageStr;
|
||||
QString uploadStr;
|
||||
};
|
||||
QHash<void*, CachedFileDetails> m_cache;
|
||||
|
||||
mutable RsMutex _ref_mutex ;
|
||||
std::vector<void *> _ref_entries ; // used to store the refs to display
|
||||
std::vector<void *> _ref_stack ; // used to store the refs to update
|
||||
|
||||
Loading…
Reference in New Issue
Block a user