summaryrefslogtreecommitdiffstats
path: root/src/libs
diff options
context:
space:
mode:
authorArttu Tarkiainen <arttu.tarkiainen@qt.io>2022-03-31 09:38:27 +0300
committerArttu Tarkiainen <arttu.tarkiainen@qt.io>2022-04-21 17:24:31 +0300
commit2dd3c7d62a7f7e2e4b9cae4aedb9c1c952dcb4d6 (patch)
treecebd672f41aa8611b73110b12ad87cb70f10baef /src/libs
parentd14b1b34bafc7cc82383e8032f3adb626747849b (diff)
Use archive sizes for sorting and calculating progress of Extract ops
This makes the progress appear smoother when the archives to extract differ in size. The sorting based on the archive sizes provides some improvement to optimal thread utilization, as the larger archives get more time to complete from the start. We are less likely to find ourselves in a situation where any of the last operations left to be run with less than ideal thread count take significantly more time to complete than the others. Task-number: QTIFW-2431 Change-Id: I2534b6f18997d73c4ce1fb8b26900e30e1c6a76f Reviewed-by: Katja Marttila <katja.marttila@qt.io>
Diffstat (limited to 'src/libs')
-rw-r--r--src/libs/installer/extractarchiveoperation.cpp18
-rw-r--r--src/libs/installer/extractarchiveoperation.h2
-rw-r--r--src/libs/installer/packagemanagercore_p.cpp23
-rw-r--r--src/libs/kdtools/updateoperation.cpp12
-rw-r--r--src/libs/kdtools/updateoperation.h2
5 files changed, 54 insertions, 3 deletions
diff --git a/src/libs/installer/extractarchiveoperation.cpp b/src/libs/installer/extractarchiveoperation.cpp
index 17dfc7dfb..17d521b9f 100644
--- a/src/libs/installer/extractarchiveoperation.cpp
+++ b/src/libs/installer/extractarchiveoperation.cpp
@@ -329,6 +329,24 @@ bool ExtractArchiveOperation::testOperation()
return true;
}
+quint64 ExtractArchiveOperation::sizeHint()
+{
+ if (!checkArgumentCount(2))
+ return UpdateOperation::sizeHint();
+
+ if (hasValue(QLatin1String("sizeHint")))
+ return value(QLatin1String("sizeHint")).toULongLong();
+
+ const QString archivePath = arguments().at(0);
+ const quint64 compressedSize = QFileInfo(archivePath).size();
+
+ setValue(QLatin1String("sizeHint"), QString::number(compressedSize));
+
+ // A rough estimate of how much time it takes to extract this archive. Other
+ // affecting parameters are the archive format, compression filter and -level.
+ return compressedSize;
+}
+
bool ExtractArchiveOperation::readDataFileContents(QString &targetDir, QStringList *resultList)
{
const QString filePath = value(QLatin1String("files")).toString();
diff --git a/src/libs/installer/extractarchiveoperation.h b/src/libs/installer/extractarchiveoperation.h
index 7df472348..b1a696788 100644
--- a/src/libs/installer/extractarchiveoperation.h
+++ b/src/libs/installer/extractarchiveoperation.h
@@ -48,6 +48,8 @@ public:
bool undoOperation() override;
bool testOperation() override;
+ quint64 sizeHint() override;
+
bool readDataFileContents(QString &targetDir, QStringList *resultList);
Q_SIGNALS:
diff --git a/src/libs/installer/packagemanagercore_p.cpp b/src/libs/installer/packagemanagercore_p.cpp
index 3a786b082..35d881f80 100644
--- a/src/libs/installer/packagemanagercore_p.cpp
+++ b/src/libs/installer/packagemanagercore_p.cpp
@@ -2178,6 +2178,8 @@ void PackageManagerCorePrivate::unpackComponents(const QList<Component *> &compo
ProgressCoordinator::instance()->emitLabelAndDetailTextChanged(tr("\nUnpacking components..."));
+ // 1. Collect operations
+ quint64 totalOperationsSizeHint = 0;
for (auto *component : components) {
const OperationList operations = component->operations(Operation::Unpack);
if (!component->operationsCreatedSuccessfully())
@@ -2188,17 +2190,26 @@ void PackageManagerCorePrivate::unpackComponents(const QList<Component *> &compo
throw Error(tr("Installation canceled by user"));
unpackOperations.append(op);
+ totalOperationsSizeHint += op->sizeHint();
// There's currently no way to control this on a per-operation basis, so
// any op requesting execution as admin means all extracts are done as admin.
if (!adminRightsGained && !becameAdmin && op->value(QLatin1String("admin")).toBool())
becameAdmin = m_core->gainAdminRights();
-
- connectOperationToInstaller(op, progressOperationSize);
- connectOperationCallMethodRequest(op);
}
}
+ // 2. Calculate proportional progress sizes
+ const double totalOperationsSize = progressOperationSize * unpackOperations.size();
+ for (auto *op : unpackOperations) {
+ const double ratio = static_cast<double>(op->sizeHint()) / totalOperationsSizeHint;
+ const double proportionalProgressOperationSize = totalOperationsSize * ratio;
+
+ connectOperationToInstaller(op, proportionalProgressOperationSize);
+ connectOperationCallMethodRequest(op);
+ }
+
+ // 3. Backup operations
ConcurrentOperationRunner runner(&unpackOperations, Operation::Backup);
connect(m_core, &PackageManagerCore::installationInterrupted,
&runner, &ConcurrentOperationRunner::cancel);
@@ -2225,6 +2236,12 @@ void PackageManagerCorePrivate::unpackComponents(const QList<Component *> &compo
if (statusCanceledOrFailed())
throw Error(tr("Installation canceled by user"));
+ // 4. Perform operations
+ std::sort(unpackOperations.begin(), unpackOperations.end(), [](Operation *lhs, Operation *rhs) {
+ // We want to run the longest taking operations first
+ return lhs->sizeHint() > rhs->sizeHint();
+ });
+
runner.setType(Operation::Perform);
const QHash<Operation *, bool> results = runner.run();
const OperationList performedOperations = backupResults.keys();
diff --git a/src/libs/kdtools/updateoperation.cpp b/src/libs/kdtools/updateoperation.cpp
index e56c72228..8c242e96d 100644
--- a/src/libs/kdtools/updateoperation.cpp
+++ b/src/libs/kdtools/updateoperation.cpp
@@ -640,6 +640,18 @@ bool UpdateOperation::fromXml(const QDomDocument &doc)
}
/*!
+ Returns a numerical representation of how this operation compares to
+ other operations in size, and in time it takes to perform the operation.
+
+ The default returned value is \c 1. Subclasses may override this method to
+ implement custom size hints.
+*/
+quint64 UpdateOperation::sizeHint()
+{
+ return 1;
+}
+
+/*!
\overload
Restores operation arguments and values from the XML file at path \a xml. Returns \c true on
diff --git a/src/libs/kdtools/updateoperation.h b/src/libs/kdtools/updateoperation.h
index 3bde3e945..0e1c0fbec 100644
--- a/src/libs/kdtools/updateoperation.h
+++ b/src/libs/kdtools/updateoperation.h
@@ -100,6 +100,8 @@ public:
virtual bool fromXml(const QString &xml);
virtual bool fromXml(const QDomDocument &doc);
+ virtual quint64 sizeHint();
+
protected:
void setName(const QString &name);
void setGroup(const OperationGroup &group);