summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKatja Marttila <katja.marttila@qt.io>2019-10-07 12:53:19 +0300
committerKatja Marttila <katja.marttila@qt.io>2019-10-31 04:55:27 +0000
commitabf6e847b5cff38b3121623da53b1b590b2af95d (patch)
tree395d7c43027719a7faded44b242e021e20679443 /src
parent64e656846eb11be5aef4ee729ac83e37bd40f207 (diff)
Decrease the dat file file size
Write the filename list to a separate file and only the name of the separate file is in .dat file. This has significant effect on the .dat file size and it also decreases the restart/start time of maintenancetool. Task-number: QTIFW-1448 Change-Id: If03ce1bb91754acfb4e7dd74434f22a6e3fa2554 Reviewed-by: Katja Marttila <katja.marttila@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/libs/installer/extractarchiveoperation.cpp82
-rw-r--r--src/libs/installer/extractarchiveoperation.h3
2 files changed, 82 insertions, 3 deletions
diff --git a/src/libs/installer/extractarchiveoperation.cpp b/src/libs/installer/extractarchiveoperation.cpp
index 12608a0d1..12067a7c6 100644
--- a/src/libs/installer/extractarchiveoperation.cpp
+++ b/src/libs/installer/extractarchiveoperation.cpp
@@ -28,6 +28,8 @@
#include "extractarchiveoperation_p.h"
+#include "constants.h"
+
#include <QEventLoop>
#include <QThreadPool>
#include <QFileInfo>
@@ -83,7 +85,44 @@ bool ExtractArchiveOperation::performOperation()
receiver.runnableFinished(true, QString());
}
- setValue(QLatin1String("files"), m_files);
+ // Write all file names which belongs to a package to a separate file and only the separate
+ // filename to a .dat file. There can be enormous amount of files in a package, which makes
+ // the dat file very slow to read and write. The .dat file is read into memory in startup,
+ // writing the file names to a separate file we don't need to load all the file names into
+ // memory as we need those only in uninstall. This will save a lot of memory.
+ // Parse a file and directorory structure using archivepath syntax
+ // installer://<component_name>/<filename>.7z Resulting structure is:
+ // -installerResources (dir)
+ // -<component_name> (dir)
+ // -<filename>.txt (file)
+
+ QString fileDirectory = targetDir + QLatin1String("/installerResources/") +
+ archivePath.section(QLatin1Char('/'), 1, 1, QString::SectionSkipEmpty) + QLatin1Char('/');
+ QString archiveFileName = archivePath.section(QLatin1Char('/'), 2, 2, QString::SectionSkipEmpty);
+ QFileInfo fileInfo2(archiveFileName);
+ QString suffix = fileInfo2.suffix();
+ archiveFileName.chop(suffix.length() + 1); // removes suffix (e.g. '.7z') from archive filename
+ QString fileName = archiveFileName + QLatin1String(".txt");
+
+ QFileInfo targetDirectoryInfo(fileDirectory);
+
+ QDir dir(targetDirectoryInfo.absolutePath());
+ if (!dir.exists()) {
+ dir.mkpath(targetDirectoryInfo.absolutePath());
+ }
+ QFile file(targetDirectoryInfo.absolutePath() + QLatin1Char('/') + fileName);
+ if (file.open(QIODevice::WriteOnly)) {
+ setDefaultFilePermissions(file.fileName(), DefaultFilePermissions::NonExecutable);
+ QDataStream out (&file);
+ for (int i = 0; i < m_files.count(); ++i) {
+ m_files[i] = replacePath(m_files.at(i), targetDir, QLatin1String(scRelocatable));
+ }
+ out << m_files;
+ setValue(QLatin1String("files"), file.fileName());
+ file.close();
+ } else {
+ qWarning() << "Cannot open file for writing " << file.fileName() << ":" << file.errorString();
+ }
// TODO: Use backups for rollback, too? Doesn't work for uninstallation though.
@@ -102,8 +141,46 @@ bool ExtractArchiveOperation::performOperation()
bool ExtractArchiveOperation::undoOperation()
{
Q_ASSERT(arguments().count() == 2);
- const QStringList files = value(QLatin1String("files")).toStringList();
+ // For backward compatibility, check if "files" can be converted to QStringList.
+ // If yes, files are listed in .dat instead of in a separate file.
+ bool useStringListType(value(QLatin1String("files")).type() == QVariant::StringList);
+ QStringList files;
+ if (useStringListType) {
+ files = value(QLatin1String("files")).toStringList();
+ startUndoProcess(files);
+ } else {
+ const QString filePath = value(QLatin1String("files")).toString();
+ QString target = QCoreApplication::applicationDirPath();
+ // Does not change target on non macOS platforms.
+ if (QInstaller::isInBundle(target, &target))
+ target = QDir::cleanPath(target + QLatin1String("/.."));
+ QString fileName = replacePath(filePath, QLatin1String(scRelocatable), target);
+ QFile file(fileName);
+
+ if (file.open(QIODevice::ReadOnly)) {
+ QDataStream in(&file);
+ in >> files;
+ for (int i = 0; i < files.count(); ++i)
+ files[i] = replacePath(files.at(i), QLatin1String(scRelocatable), target);
+ startUndoProcess(files);
+ QFileInfo fileInfo(file);
+ file.remove();
+ QDir directory(fileInfo.absoluteDir());
+ if (directory.exists() && directory.isEmpty())
+ directory.rmdir(directory.path());
+ } else {
+ setError(UserDefinedError);
+ setErrorString(tr("Cannot open file \"%1\" for reading: %2")
+ .arg(QDir::toNativeSeparators(file.fileName())).arg(file.errorString()));
+ return false;
+ }
+ }
+ return true;
+}
+
+void ExtractArchiveOperation::startUndoProcess(const QStringList &files)
+{
WorkerThread *const thread = new WorkerThread(this, files);
connect(thread, &WorkerThread::currentFileChanged, this,
&ExtractArchiveOperation::outputTextChanged);
@@ -115,7 +192,6 @@ bool ExtractArchiveOperation::undoOperation()
thread->start();
loop.exec();
thread->deleteLater();
- return true;
}
bool ExtractArchiveOperation::testOperation()
diff --git a/src/libs/installer/extractarchiveoperation.h b/src/libs/installer/extractarchiveoperation.h
index 3e75a9bb9..0f584dc0a 100644
--- a/src/libs/installer/extractarchiveoperation.h
+++ b/src/libs/installer/extractarchiveoperation.h
@@ -52,6 +52,9 @@ Q_SIGNALS:
void outputTextChanged(const QString &progress);
void progressChanged(double);
+private:
+ void startUndoProcess(const QStringList &files);
+
private Q_SLOTS:
void fileFinished(const QString &progress);