From a575b7f7b9b480733091732a4dc302661300cc79 Mon Sep 17 00:00:00 2001 From: liyigang Date: Thu, 25 Jul 2024 16:09:45 +0800 Subject: [PATCH] fix: The folder opens and loads slowly (it takes a few minutes to load) Add the basic properties of SortFileInfo iterated using fts Log: The folder opens and loads slowly (it takes a few minutes to load) Bug: https://pms.uniontech.com/bug-view-259869.html --- include/dfm-io/dfm-io/denumerator.h | 19 ++++++++++ src/dfm-io/dfm-io/denumerator.cpp | 46 +++++++++++++---------- src/dfm-io/dfm-io/private/denumerator_p.h | 2 + src/dfm-io/dfm-io/utils/dlocalhelper.cpp | 44 ++++++++++++---------- src/dfm-io/dfm-io/utils/dlocalhelper.h | 1 - 5 files changed, 73 insertions(+), 39 deletions(-) diff --git a/include/dfm-io/dfm-io/denumerator.h b/include/dfm-io/dfm-io/denumerator.h index 27d0e24..69438d0 100644 --- a/include/dfm-io/dfm-io/denumerator.h +++ b/include/dfm-io/dfm-io/denumerator.h @@ -71,6 +71,22 @@ class DEnumerator : public QEnableSharedFromThis bool isReadable { false }; bool isWriteable { false }; bool isExecutable { false }; + ino_t inode { 0 }; + QUrl symlinkUrl; + uint gid { 0 }; + uint uid { 0 }; + qint64 lastRead { 0 }; + qint64 lastReadNs { 0 }; + qint64 lastModifed { 0 }; + qint64 lastModifedNs { 0 }; + qint64 create { 0 }; + qint64 createNs { 0 }; + }; + + enum class EnumeratorType : uint8_t{ + kEnumeratorGio = 0, // enumerator by gio + kEnumeratorFts = 0, // enumerator by fts + kEnumeratorSystem = 0, // enumerator by system dirent }; public: @@ -100,6 +116,9 @@ class DEnumerator : public QEnableSharedFromThis void setSortMixed(bool mix); bool isSortMixed() const; + void setQueryAttributes(const QString &attributes); + QString queryAttributes() const; + public: bool cancel(); bool hasNext() const; diff --git a/src/dfm-io/dfm-io/denumerator.cpp b/src/dfm-io/dfm-io/denumerator.cpp index 9d56075..7ea7909 100644 --- a/src/dfm-io/dfm-io/denumerator.cpp +++ b/src/dfm-io/dfm-io/denumerator.cpp @@ -30,6 +30,7 @@ USING_IO_NAMESPACE DEnumeratorPrivate::DEnumeratorPrivate(DEnumerator *q) : q(q) { + queryAttributes = FILE_DEFAULT_ATTRIBUTES; } DEnumeratorPrivate::~DEnumeratorPrivate() @@ -89,7 +90,7 @@ bool DEnumeratorPrivate::createEnumerator(const QUrl &url, QPointercode)); if (error.code() == DFMIOErrorCode::DFM_IO_ERROR_FAILED) error.setMessage(gerror->message); @@ -266,29 +266,22 @@ bool DEnumeratorPrivate::openDirByfts() void DEnumeratorPrivate::insertSortFileInfoList(QList> &fileList, QList> &dirList, FTSENT *ent, FTS *fts, const QSet &hideList) { - QSharedPointer info(nullptr); - bool isDir = S_ISDIR(ent->fts_statp->st_mode); - if (S_ISLNK(ent->fts_statp->st_mode)) { - const QUrl &url = QUrl::fromLocalFile(ent->fts_path); - info = DLocalHelper::createFileInfoByUri(url); - isDir = info->attribute(DFileInfo::AttributeID::kStandardIsDir).toBool(); - } - - if (isDir) + auto sortInfo = DLocalHelper::createSortFileInfo(ent, hideList); + if (sortInfo->isDir && !sortInfo->isSymLink) fts_set(fts, ent, FTS_SKIP); - if (isDir && !isMixDirAndFile) { + if (sortInfo->isDir && !isMixDirAndFile) { if (sortOrder == Qt::DescendingOrder) - dirList.push_front(DLocalHelper::createSortFileInfo(ent, info, hideList)); + dirList.push_front(sortInfo); else - dirList.push_back(DLocalHelper::createSortFileInfo(ent, info, hideList)); + dirList.push_back(sortInfo); return; } if (sortOrder == Qt::DescendingOrder) - fileList.push_front(DLocalHelper::createSortFileInfo(ent, info, hideList)); + fileList.push_front(sortInfo); else - fileList.push_back(DLocalHelper::createSortFileInfo(ent, info, hideList)); + fileList.push_back(sortInfo); } void DEnumeratorPrivate::enumUriAsyncOvered(GList *files) @@ -316,7 +309,7 @@ void DEnumeratorPrivate::startAsyncIterator() EnumUriData *userData = new EnumUriData(); userData->pointer = sharedFromThis(); g_file_enumerate_children_async(gfile, - FILE_DEFAULT_ATTRIBUTES, + queryAttributes.toStdString().c_str(), G_FILE_QUERY_INFO_NONE, G_PRIORITY_DEFAULT, cancellable, @@ -341,7 +334,7 @@ bool DEnumeratorPrivate::hasNext() uri.path() + "/" + QString(g_file_info_get_name(gfileInfo)); nextUrl = QUrl::fromLocalFile(path); - dfileInfoNext = DLocalHelper::createFileInfoByUri(nextUrl, g_file_info_dup(gfileInfo), FILE_DEFAULT_ATTRIBUTES, + dfileInfoNext = DLocalHelper::createFileInfoByUri(nextUrl, g_file_info_dup(gfileInfo), queryAttributes.toStdString().c_str(), enumLinks ? DFileInfo::FileQueryInfoFlags::kTypeNone : DFileInfo::FileQueryInfoFlags::kTypeNoFollowSymlinks); g_object_unref(gfileInfo); @@ -361,7 +354,7 @@ QList> DEnumeratorPrivate::fileInfoList() continue; auto url = QUrl::fromLocalFile(uri.path() + "/" + QString(g_file_info_get_name(gfileInfo))); - infoList.append(DLocalHelper::createFileInfoByUri(url, g_file_info_dup(gfileInfo), FILE_DEFAULT_ATTRIBUTES, + infoList.append(DLocalHelper::createFileInfoByUri(url, g_file_info_dup(gfileInfo), queryAttributes.toStdString().c_str(), enumLinks ? DFileInfo::FileQueryInfoFlags::kTypeNone : DFileInfo::FileQueryInfoFlags::kTypeNoFollowSymlinks)); g_object_unref(gfileInfo); @@ -370,6 +363,11 @@ QList> DEnumeratorPrivate::fileInfoList() return infoList; } +void DEnumeratorPrivate::setQueryAttributes(const QString &attributes) +{ + queryAttributes = attributes; +} + void DEnumeratorPrivate::enumUriAsyncCallBack(GObject *sourceObject, GAsyncResult *res, gpointer userData) { EnumUriData *data = static_cast(userData); @@ -548,6 +546,16 @@ bool DEnumerator::isSortMixed() const return d->isMixDirAndFile; } +void DEnumerator::setQueryAttributes(const QString &attributes) +{ + return d->setQueryAttributes(attributes); +} + +QString DEnumerator::queryAttributes() const +{ + return d->queryAttributes; +} + bool DEnumerator::cancel() { if (d->cancellable && !g_cancellable_is_cancelled(d->cancellable)) diff --git a/src/dfm-io/dfm-io/private/denumerator_p.h b/src/dfm-io/dfm-io/private/denumerator_p.h index b35d265..5c72996 100644 --- a/src/dfm-io/dfm-io/private/denumerator_p.h +++ b/src/dfm-io/dfm-io/private/denumerator_p.h @@ -54,6 +54,7 @@ class DEnumeratorPrivate : public QObject, public QEnableSharedFromThis> fileInfoList(); + void setQueryAttributes(const QString &attributes); static void enumUriAsyncCallBack(GObject *sourceObject, GAsyncResult *res, @@ -78,6 +79,7 @@ class DEnumeratorPrivate : public QObject, public QEnableSharedFromThis> hideListMap; QList> infoList; QList asyncInfos; + QString queryAttributes; QStringList nameFilters; DEnumerator::DirFilters dirFilters { DEnumerator::DirFilter::kNoFilter }; diff --git a/src/dfm-io/dfm-io/utils/dlocalhelper.cpp b/src/dfm-io/dfm-io/utils/dlocalhelper.cpp index b87216a..4bba097 100644 --- a/src/dfm-io/dfm-io/utils/dlocalhelper.cpp +++ b/src/dfm-io/dfm-io/utils/dlocalhelper.cpp @@ -902,37 +902,43 @@ int DLocalHelper::compareByLastRead(const FTSENT **left, const FTSENT **right) return (*left)->fts_statp->st_atim.tv_sec > (*right)->fts_statp->st_atim.tv_sec; } -QSharedPointer DLocalHelper::createSortFileInfo(const FTSENT *ent, const QSharedPointer &info, +QSharedPointer DLocalHelper::createSortFileInfo(const FTSENT *ent, const QSet hidList) { auto sortPointer = QSharedPointer(new DEnumerator::SortFileInfo); auto name = QString(ent->fts_name); - auto path = QString(ent->fts_path); - if (info) { - sortPointer->filesize = info->attribute(DFileInfo::AttributeID::kStandardSize).toLongLong(); - sortPointer->isDir = info->attribute(DFileInfo::AttributeID::kStandardIsDir).toBool(); - sortPointer->isFile = !sortPointer->isDir; - sortPointer->isSymLink = info->attribute(DFileInfo::AttributeID::kStandardIsSymlink).toBool(); - auto fileName = info->attribute(DFileInfo::AttributeID::kStandardFileName).toString(); - sortPointer->isHide = name.startsWith(".") - ? true - : hidList.contains(name); - sortPointer->isReadable = info->attribute(DFileInfo::AttributeID::kAccessCanRead).toBool(); - sortPointer->isWriteable = info->attribute(DFileInfo::AttributeID::kAccessCanWrite).toBool(); - sortPointer->isExecutable = info->attribute(DFileInfo::AttributeID::kAccessCanExecute).toBool(); - sortPointer->url = QUrl::fromLocalFile(path); - return sortPointer; + sortPointer->filesize = ent->fts_statp->st_size; + sortPointer->isSymLink = S_ISLNK(ent->fts_statp->st_mode); + if (sortPointer->isSymLink) { + char buffer[4096]{0}; + auto size = readlink(ent->fts_path, buffer, sizeof(buffer)); + if (size > 0) { + QString symlinkTagetPath = QString::fromUtf8(buffer, static_cast(size)); + sortPointer->symlinkUrl = QUrl::fromLocalFile(symlinkTagetPath); + struct stat st; + if (stat(symlinkTagetPath.toStdString().c_str(),&st) == 0) + sortPointer->isDir = S_ISDIR(st.st_mode); + } + } else { + sortPointer->isDir = S_ISDIR(ent->fts_statp->st_mode); } - sortPointer->filesize = ent->fts_statp->st_size; - sortPointer->isDir = S_ISDIR(ent->fts_statp->st_mode); sortPointer->isFile = !sortPointer->isDir; - sortPointer->isSymLink = S_ISLNK(ent->fts_statp->st_mode); sortPointer->isHide = name.startsWith(".") ? true : hidList.contains(name); sortPointer->isReadable = ent->fts_statp->st_mode & S_IREAD; sortPointer->isWriteable = ent->fts_statp->st_mode & S_IWRITE; sortPointer->isExecutable = ent->fts_statp->st_mode & S_IEXEC; sortPointer->url = QUrl::fromLocalFile(ent->fts_path); + sortPointer->inode = ent->fts_statp->st_ino; + sortPointer->gid = ent->fts_statp->st_gid; + sortPointer->uid = ent->fts_statp->st_uid; + sortPointer->lastRead = ent->fts_statp->st_atim.tv_sec; + sortPointer->lastReadNs = ent->fts_statp->st_atim.tv_nsec; + sortPointer->lastModifed = ent->fts_statp->st_mtim.tv_sec; + sortPointer->lastModifedNs = ent->fts_statp->st_mtim.tv_nsec; + sortPointer->create = ent->fts_statp->st_ctim.tv_sec; + sortPointer->createNs = ent->fts_statp->st_ctim.tv_nsec; + return sortPointer; } diff --git a/src/dfm-io/dfm-io/utils/dlocalhelper.h b/src/dfm-io/dfm-io/utils/dlocalhelper.h index b530c73..176ee45 100644 --- a/src/dfm-io/dfm-io/utils/dlocalhelper.h +++ b/src/dfm-io/dfm-io/utils/dlocalhelper.h @@ -68,7 +68,6 @@ class DLocalHelper static int compareByLastModifed(const FTSENT **left, const FTSENT **right); static int compareByLastRead(const FTSENT **left, const FTSENT **right); static QSharedPointer createSortFileInfo(const FTSENT *ent, - const QSharedPointer &info, const QSet hidList); private: static QVariant getGFileInfoIcon(GFileInfo *gfileinfo, const char *key, DFMIOErrorCode &errorcode);