Skip to content

Commit

Permalink
fix: Copying a large number of files within the vault caused the docu…
Browse files Browse the repository at this point in the history
…ment management to lag

Too frequent file creation signals result in too many inserts in the model, which the main thread cannot process. Modify and merge monitor signal sending, send merge once every 200ms

Log: Copying a large number of files within the vault caused the document management to lag
Bug: https://pms.uniontech.com/bug-view-236221.html
  • Loading branch information
liyigang1 committed Jan 3, 2024
1 parent 70dec41 commit 9174913
Show file tree
Hide file tree
Showing 8 changed files with 101 additions and 23 deletions.
2 changes: 1 addition & 1 deletion src/dfm-base/utils/thumbnail/thumbnailworker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ QString ThumbnailWorkerPrivate::createThumbnail(const QUrl &url, Global::Thumbna
return "";

if (!thumbHelper.canGenerateThumbnail(url)) {
qCWarning(logDFMBase) << "thumbnail: the file does not support generate thumbnails: " << url;
qCDebug(logDFMBase) << "thumbnail: the file does not support generate thumbnails: " << url;
return "";
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ void FileViewModel::doExpand(const QModelIndex &index)
connect(expandRoot, &RootInfo::watcherAddFiles, filterSortWorker.data(), &FileSortWorker::handleWatcherAddChildren, Qt::QueuedConnection);
connect(expandRoot, &RootInfo::watcherRemoveFiles, filterSortWorker.data(), &FileSortWorker::handleWatcherRemoveChildren, Qt::QueuedConnection);
connect(expandRoot, &RootInfo::watcherUpdateFile, filterSortWorker.data(), &FileSortWorker::handleWatcherUpdateFile, Qt::QueuedConnection);
connect(expandRoot, &RootInfo::watcherUpdateFiles, filterSortWorker.data(), &FileSortWorker::handleWatcherUpdateFiles, Qt::QueuedConnection);
connect(expandRoot, &RootInfo::watcherUpdateHideFile, filterSortWorker.data(), &FileSortWorker::handleWatcherUpdateHideFile, Qt::QueuedConnection);
connect(expandRoot, &RootInfo::traversalFinished, filterSortWorker.data(), &FileSortWorker::handleTraversalFinish, Qt::QueuedConnection);
connect(expandRoot, &RootInfo::requestSort, filterSortWorker.data(), &FileSortWorker::handleSortDir, Qt::QueuedConnection);
Expand Down Expand Up @@ -846,6 +847,7 @@ void FileViewModel::connectRootAndFilterSortWork(const RootInfo *root)
connect(root, &RootInfo::watcherAddFiles, filterSortWorker.data(), &FileSortWorker::handleWatcherAddChildren, Qt::QueuedConnection);
connect(root, &RootInfo::watcherRemoveFiles, filterSortWorker.data(), &FileSortWorker::handleWatcherRemoveChildren, Qt::QueuedConnection);
connect(root, &RootInfo::watcherUpdateFile, filterSortWorker.data(), &FileSortWorker::handleWatcherUpdateFile, Qt::QueuedConnection);
connect(root, &RootInfo::watcherUpdateFiles, filterSortWorker.data(), &FileSortWorker::handleWatcherUpdateFiles, Qt::QueuedConnection);
connect(root, &RootInfo::watcherUpdateHideFile, filterSortWorker.data(), &FileSortWorker::handleWatcherUpdateHideFile, Qt::QueuedConnection);
connect(root, &RootInfo::traversalFinished, filterSortWorker.data(), &FileSortWorker::handleTraversalFinish, Qt::QueuedConnection);
connect(root, &RootInfo::requestSort, filterSortWorker.data(), &FileSortWorker::handleSortDir, Qt::QueuedConnection);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

#include <QApplication>
#include <QtConcurrent>
#include <QElapsedTimer>

using namespace dfmbase;
using namespace dfmplugin_workspace;
Expand Down Expand Up @@ -212,7 +213,38 @@ void RootInfo::doWatcherEvent()
return;

processFileEventRuning = true;
while (checkFileEventQueue()) {
QElapsedTimer timer;
timer.start();
QList<QUrl> adds, updates, removes;
qint64 oldtime = 0;
while (checkFileEventQueue() || timer.elapsed() < 200) {
//检查超时,重新设置起始时间
if (timer.elapsed() - oldtime >= 200) {
// 处理添加文件
if (!adds.isEmpty())
addChildren(adds);
if (!updates.isEmpty())
updateChildren(updates);
if (!removes.isEmpty())
removeChildren(removes);

adds.clear();
updates.clear();
removes.clear();

oldtime = timer.elapsed();
}

if (cancelWatcherEvent)
return;

if (!checkFileEventQueue()) {
QThread::msleep(10);
if (adds.isEmpty() && updates.isEmpty() && removes.isEmpty())
oldtime = timer.elapsed();
continue;
}

QPair<QUrl, EventType> event = dequeueEvent();
const QUrl &fileUrl = event.first;

Expand Down Expand Up @@ -240,18 +272,35 @@ void RootInfo::doWatcherEvent()
return;

if (event.second == kAddFile) {
addChildren({ fileUrl });
// 判断update和remove中是否存在存在就移除
updates.removeOne(fileUrl);
removes.removeOne(fileUrl);
if (adds.contains(fileUrl))
continue;

adds.append(fileUrl);
} else if (event.second == kUpdateFile) {
updateChild(fileUrl);
// 如果在增加或者移除中就不添加
if (adds.contains(fileUrl) || removes.contains(fileUrl) || updates.contains(fileUrl))
continue;
updates.append(fileUrl);
} else {
removeChildren({ fileUrl });
emit InfoCacheController::instance().removeCacheFileInfo({ fileUrl });
WatcherCache::instance().removeCacheWatcherByParent(fileUrl);
emit requestCloseTab(fileUrl);
adds.removeOne(fileUrl);
updates.removeOne(fileUrl);
if (removes.contains(fileUrl))
continue;
removes.append(fileUrl);
}
}

Q_EMIT childrenUpdate(url);

// 处理添加文件
if (!adds.isEmpty())
addChildren(adds);
if (!updates.isEmpty())
updateChildren(updates);
if (!removes.isEmpty())
removeChildren(removes);
processFileEventRuning = false;
}

Expand Down Expand Up @@ -431,7 +480,10 @@ void RootInfo::removeChildren(const QList<QUrl> &urlList)
QList<SortInfoPointer> removeChildren {};
int childIndex = -1;
QList<QUrl> removeUrls;
emit InfoCacheController::instance().removeCacheFileInfo(urlList);
for (QUrl url : urlList) {
WatcherCache::instance().removeCacheWatcherByParent(url);
emit requestCloseTab(url);
url.setPath(url.path());
auto child = fileInfo(url);
if (!child)
Expand Down Expand Up @@ -462,31 +514,43 @@ bool RootInfo::containsChild(const QUrl &url)
return childrenUrlList.contains(url);
}

void RootInfo::updateChild(const QUrl &url)
SortInfoPointer RootInfo::updateChild(const QUrl &url)
{
SortInfoPointer sort { nullptr };

auto info = fileInfo(url);
if (info.isNull())
return;
return nullptr;

auto realUrl = info->urlOf(UrlInfoType::kUrl);

QWriteLocker lk(&childrenLock);
if (!childrenUrlList.contains(realUrl))
return;
return nullptr;
sort = sortFileInfo(info);
if (sort.isNull())
return;
return nullptr;
sourceDataList.replace(childrenUrlList.indexOf(realUrl), sort);

if (sort)
emit watcherUpdateFile(sort);

// NOTE: GlobalEventType::kHideFiles event is watched in fileview, but this can be used to notify update view
// when the file is modified in other way.
if (UniversalUtils::urlEquals(hiddenFileUrl, url))
Q_EMIT watcherUpdateHideFile(url);

return sort;
}

void RootInfo::updateChildren(const QList<QUrl> &urls)
{
QList<SortInfoPointer> updates;
for (auto url : urls) {
auto sort = updateChild(url);
if (sort)
updates.append(sort);
}
if (updates.isEmpty())
return;
emit watcherUpdateFiles(updates);
}

bool RootInfo::checkFileEventQueue()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ class RootInfo : public QObject
void reset();

Q_SIGNALS:
void childrenUpdate(const QUrl &url);

void itemAdded();
void iteratorLocalFiles(const QString &key,
Expand All @@ -61,8 +60,8 @@ class RootInfo : public QObject
const bool isMixDirAndFile);
void iteratorAddFile(const QString &key, const SortInfoPointer sortInfo, const FileInfoPointer info);
void iteratorAddFiles(const QString &key, const QList<SortInfoPointer> sortInfos, const QList<FileInfoPointer> infos);

Check warning on line 62 in src/plugins/filemanager/core/dfmplugin-workspace/models/rootinfo.h

View workflow job for this annotation

GitHub Actions / cppcheck

Parameter 'sortInfos' is passed by value. It could be passed as a const reference which is usually faster and recommended in C++.

Check warning on line 62 in src/plugins/filemanager/core/dfmplugin-workspace/models/rootinfo.h

View workflow job for this annotation

GitHub Actions / cppcheck

Parameter 'infos' is passed by value. It could be passed as a const reference which is usually faster and recommended in C++.
void watcherAddFiles(const QList<SortInfoPointer> children);
void watcherRemoveFiles(const QList<SortInfoPointer> children);
void watcherAddFiles(const QList<SortInfoPointer> &children);
void watcherRemoveFiles(const QList<SortInfoPointer> &children);
void traversalFinished(const QString &key);
void sourceDatas(const QString &key,
const QList<SortInfoPointer> children,

Check warning on line 67 in src/plugins/filemanager/core/dfmplugin-workspace/models/rootinfo.h

View workflow job for this annotation

GitHub Actions / cppcheck

Parameter 'children' is passed by value. It could be passed as a const reference which is usually faster and recommended in C++.
Expand All @@ -71,6 +70,7 @@ class RootInfo : public QObject
const bool isMixDirAndFile,
const bool isFinished);
void watcherUpdateFile(const SortInfoPointer sortInfo);
void watcherUpdateFiles(const QList<SortInfoPointer> &sortInfos);
void watcherUpdateHideFile(const QUrl &hidUrl);
void requestSort(const QString &key, const QUrl &dirUrl);
void requestCloseTab(const QUrl &url);
Expand Down Expand Up @@ -108,7 +108,8 @@ public Q_SLOTS:
SortInfoPointer sortFileInfo(const FileInfoPointer &info);
void removeChildren(const QList<QUrl> &urlList);
bool containsChild(const QUrl &url);
void updateChild(const QUrl &url);
SortInfoPointer updateChild(const QUrl &url);
void updateChildren(const QList<QUrl> &urls);

bool checkFileEventQueue();
void enqueueEvent(const QPair<QUrl, EventType> &e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@ void FileSortWorker::onShowHiddenFileChanged(bool isShow)
handleFilters(newFilters);
}

void FileSortWorker::handleWatcherAddChildren(const QList<SortInfoPointer> children)
void FileSortWorker::handleWatcherAddChildren(const QList<SortInfoPointer> &children)
{
for (const auto &sortInfo : children) {
if (isCanceled)
Expand Down Expand Up @@ -365,6 +365,15 @@ void FileSortWorker::handleWatcherUpdateFile(const SortInfoPointer child)
handleUpdateFile(child->fileUrl());
}

void FileSortWorker::handleWatcherUpdateFiles(const QList<SortInfoPointer> &children)
{
for(auto sort : children) {
if (isCanceled)
return;
handleWatcherUpdateFile(sort);
}
}

void FileSortWorker::handleWatcherUpdateHideFile(const QUrl &hidUrl)
{
if (isCanceled)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,9 +113,10 @@ public slots:
void onToggleHiddenFiles();
void onShowHiddenFileChanged(bool isShow);

void handleWatcherAddChildren(const QList<SortInfoPointer> children);
void handleWatcherAddChildren(const QList<SortInfoPointer> &children);
void handleWatcherRemoveChildren(const QList<SortInfoPointer> children);
void handleWatcherUpdateFile(const SortInfoPointer child);
void handleWatcherUpdateFiles(const QList<SortInfoPointer> &children);
void handleWatcherUpdateHideFile(const QUrl &hidUrl);

void handleResort(const Qt::SortOrder order, const Global::ItemRoles sortRole, const bool isMixDirAndFile);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -347,7 +347,7 @@ QStringList WorkspaceHelper::getNameFilter(const quint64 windowId)

void WorkspaceHelper::laterRequestSelectFiles(const QList<QUrl> &urls)
{
QTimer::singleShot(qMin(800, qMax(urls.count() * (10 + urls.count() / 150), 200)), this, [=] {
QTimer::singleShot(qMin(800, qMax(urls.count() * (10 + urls.count() / 150), 300)), this, [=] {
emit requestSelectFiles(urls);
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,7 @@ TEST_F(UT_RootInfo, DoWatcherEvent)
[&removeUrls](RootInfo *, const QList<QUrl> &urlList) { removeUrls.append(urlList); });
stub.set_lamda(ADDR(RootInfo, updateChild), [&updateUrls](RootInfo *, const QUrl &updateUrl) {
updateUrls.append(updateUrl);
return nullptr;
});

rootInfoObj->doWatcherEvent();
Expand Down

0 comments on commit 9174913

Please sign in to comment.