aboutsummaryrefslogtreecommitdiff
path: root/src/core/kconfig.cpp
diff options
context:
space:
mode:
authorAleix Pol <aleixpol@kde.org>2021-07-01 02:50:55 +0200
committerAleix Pol <aleixpol@kde.org>2021-07-04 17:22:45 +0200
commit93c9398cdcf147c5c5e1a89662ffd047e36927ac (patch)
tree52b09ee245368e799a2c1b60028fd2d99f484adb /src/core/kconfig.cpp
parent74a861c5617621663b1d5d8a1cd79c7a0eef9d8a (diff)
downloadkconfig-93c9398cdcf147c5c5e1a89662ffd047e36927ac.tar.gz
kconfig-93c9398cdcf147c5c5e1a89662ffd047e36927ac.tar.bz2
Cache global config files
Whenever we read a config file, we are first parsing kdeglobalsrc. This caches the parsed entries so that they can be reused as long as it hasn't changed. This reduces the parseConfig calls (which is mostly prominent at early process startup) from 18 to 12 (33%) ksmserver-logout-greeter. This also means there's better cache locality as well as less memory allocated as a lot of objects are shared but I have not measured this.
Diffstat (limited to 'src/core/kconfig.cpp')
-rw-r--r--src/core/kconfig.cpp32
1 files changed, 30 insertions, 2 deletions
diff --git a/src/core/kconfig.cpp b/src/core/kconfig.cpp
index cc3700e1..9b8d2e62 100644
--- a/src/core/kconfig.cpp
+++ b/src/core/kconfig.cpp
@@ -21,6 +21,7 @@
#include <QBasicMutex>
#include <QByteArray>
+#include <QCache>
#include <QCoreApplication>
#include <QDir>
#include <QFile>
@@ -28,6 +29,7 @@
#include <QMutexLocker>
#include <QProcess>
#include <QSet>
+#include <QThreadStorage>
#if KCONFIG_USE_DBUS
#include <QDBusConnection>
@@ -44,6 +46,14 @@ Q_GLOBAL_STATIC(QStringList, s_globalFiles) // For caching purposes.
static QBasicMutex s_globalFilesMutex;
Q_GLOBAL_STATIC_WITH_ARGS(QString, sGlobalFileName, (QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + QLatin1String("/kdeglobals")))
+using ParseCacheKey = std::pair<QStringList, QString>;
+struct ParseCacheValue {
+ KEntryMap entries;
+ QDateTime parseTime;
+};
+using ParseCache = QThreadStorage<QCache<ParseCacheKey, ParseCacheValue>>;
+Q_GLOBAL_STATIC(ParseCache, sGlobalParse)
+
#ifndef Q_OS_WIN
static const Qt::CaseSensitivity sPathCaseSensitivity = Qt::CaseSensitive;
#else
@@ -687,8 +697,25 @@ void KConfigPrivate::parseGlobalFiles()
const QStringList globalFiles = getGlobalFiles();
// qDebug() << "parsing global files" << globalFiles;
- // TODO: can we cache the values in etc_kderc / other global files
- // on a per-application basis?
+ Q_ASSERT(entryMap.isEmpty());
+ const ParseCacheKey key = {globalFiles, locale};
+ auto data = sGlobalParse->localData().object(key);
+ QDateTime newest;
+ for (const auto &file : globalFiles) {
+ const auto fileDate = QFileInfo(file).lastModified();
+ if (fileDate > newest) {
+ newest = fileDate;
+ }
+ }
+ if (data) {
+ if (data->parseTime < newest) {
+ data = nullptr;
+ } else {
+ entryMap = data->entries;
+ return;
+ }
+ }
+
const QByteArray utf8Locale = locale.toUtf8();
for (const QString &file : globalFiles) {
KConfigBackend::ParseOptions parseOpts = KConfigBackend::ParseGlobal | KConfigBackend::ParseExpansions;
@@ -701,6 +728,7 @@ void KConfigPrivate::parseGlobalFiles()
break;
}
}
+ sGlobalParse->localData().insert(key, new ParseCacheValue({entryMap, newest}));
}
void KConfigPrivate::parseConfigFiles()