summaryrefslogtreecommitdiffstats
path: root/src/libs
diff options
context:
space:
mode:
authorArttu Tarkiainen <arttu.tarkiainen@qt.io>2022-12-12 16:52:08 +0200
committerArttu Tarkiainen <arttu.tarkiainen@qt.io>2022-12-16 11:42:46 +0200
commit77a90fdd09ad72f9919900e141cc9bfb8a533a12 (patch)
tree12c1ab61fdf600d79c00e8e73b5ae9d4357aaa53 /src/libs
parentc02d33db5723b7605dc953de078c26d54f284d5e (diff)
Metadatajob: optimize checking for repository updates
The Updates.xml files from repositories may contain 'RepositoryUpdate' elements that list actions for existing or new repositories. We need to parse these updates and restart the metadata job if necessary. However this was done by parsing the XML file with the Qt XML modules QDom* classes, which gets expensive as not all of the files contain any repository updates. This is the most time consuming step left in case the cache is fully populated and up-to-date. Instead attempt to make the process faster by filtering out Updates.xml files that do not contain the 'RepositoryUpdate' element with a string search, before properly parsing the files. Change-Id: I87894fdc51f37095e46415a238c9da99624f4f44 Reviewed-by: Leena Miettinen <riitta-leena.miettinen@qt.io> Reviewed-by: Katja Marttila <katja.marttila@qt.io>
Diffstat (limited to 'src/libs')
-rw-r--r--src/libs/installer/metadata.cpp29
-rw-r--r--src/libs/installer/metadata.h2
-rw-r--r--src/libs/installer/metadatajob.cpp16
3 files changed, 40 insertions, 7 deletions
diff --git a/src/libs/installer/metadata.cpp b/src/libs/installer/metadata.cpp
index 0469ed8b1..c9fa0a0f1 100644
--- a/src/libs/installer/metadata.cpp
+++ b/src/libs/installer/metadata.cpp
@@ -36,6 +36,7 @@
#include <QDir>
#include <QDomDocument>
#include <QFile>
+#include <QByteArrayMatcher>
namespace QInstaller {
@@ -254,4 +255,32 @@ QString Metadata::persistentRepositoryPath()
return m_persistentRepositoryPath;
}
+/*!
+ Checks whether the updates document of this metadata contains the repository
+ update element, which can include actions to \c add, \c remove, and \c replace
+ repositories.
+
+ \note This function does not check that the repository updates are actually
+ valid, only that the updates document contains the \c RepositoryUpdate element.
+*/
+bool Metadata::containsRepositoryUpdates() const
+{
+ QFile updateFile(path() + QLatin1String("/Updates.xml"));
+ if (!updateFile.open(QIODevice::ReadOnly)) {
+ qCWarning(QInstaller::lcInstallerInstallLog)
+ << "Cannot open" << updateFile.fileName()
+ << "for reading:" << updateFile.errorString();
+ return false;
+ }
+
+ static const auto matcher = qMakeStaticByteArrayMatcher("<RepositoryUpdate>");
+ while (!updateFile.atEnd()) {
+ const QByteArray line = updateFile.readLine().simplified();
+ if (matcher.indexIn(line) != -1)
+ return true;
+ }
+
+ return false;
+}
+
} // namespace QInstaller
diff --git a/src/libs/installer/metadata.h b/src/libs/installer/metadata.h
index af7acf6b9..3063be829 100644
--- a/src/libs/installer/metadata.h
+++ b/src/libs/installer/metadata.h
@@ -61,6 +61,8 @@ public:
void setPersistentRepositoryPath(const QUrl &url);
QString persistentRepositoryPath();
+ bool containsRepositoryUpdates() const;
+
private:
Repository m_repository;
QString m_persistentRepositoryPath;
diff --git a/src/libs/installer/metadatajob.cpp b/src/libs/installer/metadatajob.cpp
index 5a7aa66f4..33aabd268 100644
--- a/src/libs/installer/metadatajob.cpp
+++ b/src/libs/installer/metadatajob.cpp
@@ -862,13 +862,15 @@ MetadataJob::Status MetadataJob::refreshCacheItem(const FileTaskResult &result,
cachedMetadata->setPersistentRepositoryPath(repository.url());
// search for additional repositories that we might need to check
- QDomDocument doc = cachedMetadata->updatesDocument();
- const Status status = parseRepositoryUpdates(doc.documentElement(), result, cachedMetadata);
- if (status == XmlDownloadRetry) {
- // The repository update may have removed or replaced current repositories,
- // clear repository information from cached items and refresh on next fetch run.
- resetCacheRepositories();
- return status;
+ if (cachedMetadata->containsRepositoryUpdates()) {
+ QDomDocument doc = cachedMetadata->updatesDocument();
+ const Status status = parseRepositoryUpdates(doc.documentElement(), result, cachedMetadata);
+ if (status == XmlDownloadRetry) {
+ // The repository update may have removed or replaced current repositories,
+ // clear repository information from cached items and refresh on next fetch run.
+ resetCacheRepositories();
+ return status;
+ }
}
*refreshed = true;
return XmlDownloadSuccess;