diff options
author | Thiago Macieira <thiago.macieira@intel.com> | 2023-09-22 13:36:12 -0700 |
---|---|---|
committer | Thiago Macieira <thiago.macieira@intel.com> | 2023-10-16 08:41:21 -0700 |
commit | c82ed8b2795cbf6d82dfe3857fec7c16688137a4 (patch) | |
tree | 6e0fde832a6acbae54457eb48d6748ea4de43828 | |
parent | 3f2b54f0a1749eb8a52e99dbba6af4839e36cb90 (diff) |
QStorageInfo/Linux: avoid parsing /proc/self/mountinfo N+1 times
Mine has 41 lines, of which 22 are returned by parseMountInfo with
filtering. That meant the file was parsed once to get the listing, then
22 times more to create a QStorageInfo for each entry. Now
QStorageInfo::mountedVolumes() opens the file and parses it only once.
Pick-to: 6.6
Change-Id: I9d43e5b91eb142d6945cfffd178752ef6c2122f2
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
-rw-r--r-- | src/corelib/io/qstorageinfo.cpp | 5 | ||||
-rw-r--r-- | src/corelib/io/qstorageinfo.h | 1 | ||||
-rw-r--r-- | src/corelib/io/qstorageinfo_linux.cpp | 8 | ||||
-rw-r--r-- | src/corelib/io/qstorageinfo_linux_p.h | 11 | ||||
-rw-r--r-- | src/corelib/io/qstorageinfo_p.h | 37 |
5 files changed, 37 insertions, 25 deletions
diff --git a/src/corelib/io/qstorageinfo.cpp b/src/corelib/io/qstorageinfo.cpp index 2a12c2cd85..4f206bc907 100644 --- a/src/corelib/io/qstorageinfo.cpp +++ b/src/corelib/io/qstorageinfo.cpp @@ -37,6 +37,11 @@ QT_IMPL_METATYPE_EXTERN(QStorageInfo) \snippet code/src_corelib_io_qstorageinfo.cpp 2 */ +QStorageInfo::QStorageInfo(QStorageInfoPrivate &dd) + : d(&dd) +{ +} + /*! Constructs an empty QStorageInfo object. diff --git a/src/corelib/io/qstorageinfo.h b/src/corelib/io/qstorageinfo.h index d25eee1840..45869519bc 100644 --- a/src/corelib/io/qstorageinfo.h +++ b/src/corelib/io/qstorageinfo.h @@ -56,6 +56,7 @@ public: static QStorageInfo root(); private: + explicit QStorageInfo(QStorageInfoPrivate &dd); friend class QStorageInfoPrivate; friend inline bool operator==(const QStorageInfo &first, const QStorageInfo &second) { diff --git a/src/corelib/io/qstorageinfo_linux.cpp b/src/corelib/io/qstorageinfo_linux.cpp index 0bf6b9e238..8b53629e25 100644 --- a/src/corelib/io/qstorageinfo_linux.cpp +++ b/src/corelib/io/qstorageinfo_linux.cpp @@ -164,12 +164,12 @@ QList<QStorageInfo> QStorageInfoPrivate::mountedVolumes() QList<QStorageInfo> volumes; for (MountInfo &info : infos) { - QStorageInfo storage(info.mountPoint); - storage.d->device = info.device; - storage.d->fileSystemType = info.fsType; - storage.d->subvolume = info.fsRoot; + QStorageInfoPrivate d(std::move(info)); + d.retrieveVolumeInfo(); + QStorageInfo storage(*new QStorageInfoPrivate(std::move(d))); if (storage.bytesTotal() == 0 && storage != root()) continue; + storage.d->name = retrieveLabel(storage.d->device); volumes.push_back(storage); } return volumes; diff --git a/src/corelib/io/qstorageinfo_linux_p.h b/src/corelib/io/qstorageinfo_linux_p.h index 1033d78f73..1a59ee910f 100644 --- a/src/corelib/io/qstorageinfo_linux_p.h +++ b/src/corelib/io/qstorageinfo_linux_p.h @@ -29,6 +29,7 @@ QT_BEGIN_NAMESPACE using namespace Qt::StringLiterals; +using MountInfo = QStorageInfoPrivate::MountInfo; static const char MountInfoPath[] = "/proc/self/mountinfo"; @@ -152,16 +153,6 @@ static void tokenizeLine(std::array<QByteArrayView, FieldCount> &fields, QByteAr } } -namespace { -struct MountInfo { - QString mountPoint; - QByteArray fsType; - QByteArray device; - QByteArray fsRoot; - dev_t stDev = 0; -}; -} - // parseMountInfo() is called from: // - QStorageInfoPrivate::initRootPath(), where a list of all mounted volumes is needed // - QStorageInfoPrivate::mountedVolumes(), where some filesystem types are ignored diff --git a/src/corelib/io/qstorageinfo_p.h b/src/corelib/io/qstorageinfo_p.h index ae4ff02f0b..92bcdaac3d 100644 --- a/src/corelib/io/qstorageinfo_p.h +++ b/src/corelib/io/qstorageinfo_p.h @@ -28,10 +28,7 @@ inline Q_LOGGING_CATEGORY(lcStorageInfo, "qt.core.qstorageinfo", QtWarningMsg) class QStorageInfoPrivate : public QSharedData { public: - inline QStorageInfoPrivate() : QSharedData(), - bytesTotal(-1), bytesFree(-1), bytesAvailable(-1), blockSize(-1), - readOnly(false), ready(false), valid(false) - {} + QStorageInfoPrivate() = default; void initRootPath(); void doStat(); @@ -59,6 +56,24 @@ protected: void retrieveLabel(); #elif defined(Q_OS_UNIX) void retrieveVolumeInfo(); + +# ifdef Q_OS_LINUX +public: + struct MountInfo { + QString mountPoint; + QByteArray fsType; + QByteArray device; + QByteArray fsRoot; + dev_t stDev = 0; + }; + QStorageInfoPrivate(MountInfo &&info) + : rootPath(std::move(info.mountPoint)), + device(std::move(info.device)), + subvolume(std::move(info.fsRoot)), + fileSystemType(std::move(info.fsType)) + { + } +# endif #endif public: @@ -68,14 +83,14 @@ public: QByteArray fileSystemType; QString name; - qint64 bytesTotal; - qint64 bytesFree; - qint64 bytesAvailable; - ulong blockSize; + qint64 bytesTotal = -1; + qint64 bytesFree = -1; + qint64 bytesAvailable = -1; + ulong blockSize = ulong(-1); - bool readOnly; - bool ready; - bool valid; + bool readOnly = false; + bool ready = false; + bool valid = false; }; // Common helper functions |