aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@qt.io>2017-06-29 14:56:05 +0200
committerSimon Hausmann <simon.hausmann@qt.io>2017-08-02 18:15:17 +0000
commita4be64a06c94765f995d49be00eb8fc9bed83958 (patch)
tree07df008d0e22c955050a3b6f174bba2945b9efa6
parentd28e7e47e0ddcbb889ced731f8666996caf045b1 (diff)
Reduce memory consumption of stat() cache in QML type loader
The m_importDirCache caches the result of QDir/File::exists across paths. By changing the data structure to a QCache we impose a limit on the size of the entries and thus the memory consumption for long running programs that access many qml files. Task-number: QTBUG-61536 Change-Id: I20c4dc77260fe353c13da570b7e1bbd3f47d4b79 Reviewed-by: Lars Knoll <lars.knoll@qt.io>
-rw-r--r--src/qml/qml/qqmltypeloader.cpp40
-rw-r--r--src/qml/qml/qqmltypeloader_p.h4
2 files changed, 20 insertions, 24 deletions
diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp
index 2825e0d698..efa4ed2f79 100644
--- a/src/qml/qml/qqmltypeloader.cpp
+++ b/src/qml/qml/qqmltypeloader.cpp
@@ -1778,23 +1778,21 @@ QString QQmlTypeLoader::absoluteFilePath(const QString &path)
#endif
int lastSlash = path.lastIndexOf(QLatin1Char('/'));
- QStringRef dirPath(&path, 0, lastSlash);
+ QString dirPath(path.left(lastSlash));
- StringSet **fileSet = m_importDirCache.value(QHashedStringRef(dirPath.constData(), dirPath.length()));
- if (!fileSet) {
- QHashedString dirPathString(dirPath.toString());
- bool exists = QDir(dirPathString).exists();
- QStringHash<bool> *files = exists ? new QStringHash<bool> : 0;
- m_importDirCache.insert(dirPathString, files);
- fileSet = m_importDirCache.value(dirPathString);
+ if (!m_importDirCache.contains(dirPath)) {
+ bool exists = QDir(dirPath).exists();
+ QCache<QString, bool> *entry = exists ? new QCache<QString, bool> : 0;
+ m_importDirCache.insert(dirPath, entry);
}
- if (!(*fileSet))
+ QCache<QString, bool> *fileSet = m_importDirCache.object(dirPath);
+ if (!fileSet)
return QString();
QString absoluteFilePath;
- QHashedStringRef fileName(path.constData()+lastSlash+1, path.length()-lastSlash-1);
+ QString fileName(path.mid(lastSlash+1, path.length()-lastSlash-1));
- bool *value = (*fileSet)->value(fileName);
+ bool *value = fileSet->object(fileName);
if (value) {
if (*value)
absoluteFilePath = path;
@@ -1808,7 +1806,7 @@ QString QQmlTypeLoader::absoluteFilePath(const QString &path)
#else
exists = QFile::exists(path);
#endif
- (*fileSet)->insert(fileName.toString(), exists);
+ fileSet->insert(fileName, new bool(exists));
if (exists)
absoluteFilePath = path;
}
@@ -1843,18 +1841,16 @@ bool QQmlTypeLoader::directoryExists(const QString &path)
int length = path.length();
if (path.endsWith(QLatin1Char('/')))
--length;
- QStringRef dirPath(&path, 0, length);
+ QString dirPath(path.left(length));
- StringSet **fileSet = m_importDirCache.value(QHashedStringRef(dirPath.constData(), dirPath.length()));
- if (!fileSet) {
- QHashedString dirPathString(dirPath.toString());
- bool exists = QDir(dirPathString).exists();
- QStringHash<bool> *files = exists ? new QStringHash<bool> : 0;
- m_importDirCache.insert(dirPathString, files);
- fileSet = m_importDirCache.value(dirPathString);
+ if (!m_importDirCache.contains(dirPath)) {
+ bool exists = QDir(dirPath).exists();
+ QCache<QString, bool> *files = exists ? new QCache<QString, bool> : 0;
+ m_importDirCache.insert(dirPath, files);
}
- return (*fileSet);
+ QCache<QString, bool> *fileSet = m_importDirCache.object(dirPath);
+ return fileSet != 0;
}
@@ -1938,7 +1934,7 @@ void QQmlTypeLoader::clearCache()
(*iter)->release();
for (QmldirCache::Iterator iter = m_qmldirCache.begin(), end = m_qmldirCache.end(); iter != end; ++iter)
(*iter)->release();
- qDeleteAll(m_importDirCache);
+
qDeleteAll(m_importQmlDirCache);
m_typeCache.clear();
diff --git a/src/qml/qml/qqmltypeloader_p.h b/src/qml/qml/qqmltypeloader_p.h
index 762fcdac65..05923f77e8 100644
--- a/src/qml/qml/qqmltypeloader_p.h
+++ b/src/qml/qml/qqmltypeloader_p.h
@@ -55,6 +55,7 @@
#include <QtCore/qobject.h>
#include <QtCore/qatomic.h>
#include <QtCore/qfileinfo.h>
+#include <QtCore/qcache.h>
#if QT_CONFIG(qml_network)
#include <QtNetwork/qnetworkreply.h>
#endif
@@ -362,8 +363,7 @@ private:
typedef QHash<QUrl, QQmlTypeData *> TypeCache;
typedef QHash<QUrl, QQmlScriptBlob *> ScriptCache;
typedef QHash<QUrl, QQmlQmldirData *> QmldirCache;
- typedef QStringHash<bool> StringSet;
- typedef QStringHash<StringSet*> ImportDirCache;
+ typedef QCache<QString, QCache<QString, bool> > ImportDirCache;
typedef QStringHash<QQmlTypeLoaderQmldirContent *> ImportQmlDirCache;
QQmlEngine *m_engine;