QMimeDatabase: fix performance regression when using the internal XML

That XML was parsed over and over again, because the QMimeXMLProvider
was re-created instead of re-used.

Pick-to: 5.15
Change-Id: I07ff005d3f238afc1490b69a58cf4815e67d418c
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
David Faure 2020-09-15 12:34:52 +02:00
parent 1a3863147d
commit 354ea7bd96
3 changed files with 26 additions and 3 deletions

View File

@ -97,7 +97,7 @@ bool QMimeDatabasePrivate::shouldCheck()
void QMimeDatabasePrivate::loadProviders()
{
// We use QStandardPaths every time to check if new files appeared
QStringList mimeDirs = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QLatin1String("mime"), QStandardPaths::LocateDirectory);
const QStringList mimeDirs = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QLatin1String("mime"), QStandardPaths::LocateDirectory);
const auto fdoIterator = std::find_if(mimeDirs.constBegin(), mimeDirs.constEnd(), [](const QString &mimeDir) -> bool {
return QFileInfo::exists(mimeDir + QStringLiteral("/packages/freedesktop.org.xml")); }
);
@ -108,12 +108,22 @@ void QMimeDatabasePrivate::loadProviders()
if (QMimeXMLProvider::InternalDatabaseAvailable && fdoIterator == mimeDirs.constEnd()) {
m_providers.reserve(mimeDirs.size() + 1);
m_providers.push_back(Providers::value_type(new QMimeXMLProvider(this, QMimeXMLProvider::InternalDatabase)));
// Check if we already have a provider for the InternalDatabase
const auto isInternal = [](const std::unique_ptr<QMimeProviderBase> &prov)
{
return prov && prov->isInternalDatabase();
};
const auto it = std::find_if(currentProviders.begin(), currentProviders.end(), isInternal);
if (it == currentProviders.end()) {
m_providers.push_back(Providers::value_type(new QMimeXMLProvider(this, QMimeXMLProvider::InternalDatabase)));
} else {
m_providers.push_back(std::move(*it));
}
} else {
m_providers.reserve(mimeDirs.size());
}
for (const QString &mimeDir : qAsConst(mimeDirs)) {
for (const QString &mimeDir : mimeDirs) {
const QString cacheFile = mimeDir + QStringLiteral("/mime.cache");
QFileInfo fileInfo(cacheFile);
// Check if we already have a provider for this dir

View File

@ -167,6 +167,11 @@ bool QMimeBinaryProvider::isValid()
return m_cacheFile != nullptr;
}
bool QMimeBinaryProvider::isInternalDatabase() const
{
return false;
}
// Position of the "list offsets" values, at the beginning of the mime.cache file
enum {
PosAliasListOffset = 4,
@ -692,6 +697,11 @@ bool QMimeXMLProvider::isValid()
return true;
}
bool QMimeXMLProvider::isInternalDatabase() const
{
return m_directory == internalMimeFileName();
}
QMimeType QMimeXMLProvider::mimeTypeForName(const QString &name)
{
return m_nameMimeTypeMap.value(name);

View File

@ -71,6 +71,7 @@ public:
virtual ~QMimeProviderBase() {}
virtual bool isValid() = 0;
virtual bool isInternalDatabase() const = 0;
virtual QMimeType mimeTypeForName(const QString &name) = 0;
virtual void addFileNameMatches(const QString &fileName, QMimeGlobMatchResult &result) = 0;
virtual void addParents(const QString &mime, QStringList &result) = 0;
@ -98,6 +99,7 @@ public:
virtual ~QMimeBinaryProvider();
bool isValid() override;
bool isInternalDatabase() const override;
QMimeType mimeTypeForName(const QString &name) override;
void addFileNameMatches(const QString &fileName, QMimeGlobMatchResult &result) override;
void addParents(const QString &mime, QStringList &result) override;
@ -143,6 +145,7 @@ public:
~QMimeXMLProvider();
bool isValid() override;
bool isInternalDatabase() const override;
QMimeType mimeTypeForName(const QString &name) override;
void addFileNameMatches(const QString &fileName, QMimeGlobMatchResult &result) override;
void addParents(const QString &mime, QStringList &result) override;