Optimize mime type matching

Don't count "*", don't search for "[" and for "?"
inside m_pattern on every call to matchFileName().
Do it once, when constructing the MimeGlobPattern.

Fix matching the pattern for names without any
wildcard: index of question mark should be -1, not
just different from 0.

This shortens loading a Qt6 project by about 500 ms.

Change-Id: I868fa5c024233467c8e717a8482268da8e9e4a66
Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
Jarek Kobus
2021-10-11 13:23:34 +02:00
parent d1b62588c5
commit 797bcb3007
2 changed files with 20 additions and 13 deletions

View File

@@ -104,12 +104,10 @@ bool MimeGlobPattern::matchFileName(const QString &inputFilename) const
return false;
const int len = filename.length();
const int starCount = m_pattern.count(QLatin1Char('*'));
// Patterns like "*~", "*.extension"
if (m_pattern[0] == QLatin1Char('*') && m_pattern.indexOf(QLatin1Char('[')) == -1 && starCount == 1)
{
if (len + 1 < pattern_len) return false;
if (m_pattern[0] == QLatin1Char('*') && m_openingSquareBracketPos == -1 && m_starCount == 1) {
if (len + 1 < pattern_len)
return false;
const QChar *c1 = m_pattern.unicode() + pattern_len - 1;
const QChar *c2 = filename.unicode() + len - 1;
@@ -120,8 +118,9 @@ bool MimeGlobPattern::matchFileName(const QString &inputFilename) const
}
// Patterns like "README*" (well this is currently the only one like that...)
if (starCount == 1 && m_pattern.at(pattern_len - 1) == QLatin1Char('*')) {
if (len + 1 < pattern_len) return false;
if (m_starCount == 1 && m_pattern.at(pattern_len - 1) == QLatin1Char('*')) {
if (len + 1 < pattern_len)
return false;
if (m_pattern.at(0) == QLatin1Char('*'))
return filename.indexOf(QStringView(m_pattern).mid(1, pattern_len - 2)) != -1;
@@ -134,7 +133,7 @@ bool MimeGlobPattern::matchFileName(const QString &inputFilename) const
}
// Names without any wildcards like "README"
if (m_pattern.indexOf(QLatin1Char('[')) == -1 && starCount == 0 && m_pattern.indexOf(QLatin1Char('?')))
if (m_openingSquareBracketPos == -1 && m_starCount == 0 && m_questionMarkPos == -1)
return (m_pattern == filename);
// Other (quite rare) patterns, like "*.anim[1-9j]": use slow but correct method

View File

@@ -73,12 +73,17 @@ public:
static const unsigned DefaultWeight = 50;
static const unsigned MinWeight = 1;
explicit MimeGlobPattern(const QString &thePattern, const QString &theMimeType, unsigned theWeight = DefaultWeight, Qt::CaseSensitivity s = Qt::CaseInsensitive) :
m_pattern(thePattern), m_mimeType(theMimeType), m_weight(theWeight), m_caseSensitivity(s)
explicit MimeGlobPattern(const QString &thePattern, const QString &theMimeType,
unsigned theWeight = DefaultWeight,
Qt::CaseSensitivity s = Qt::CaseInsensitive) :
m_pattern(s == Qt::CaseInsensitive ? thePattern.toLower() : thePattern),
m_mimeType(theMimeType),
m_weight(theWeight),
m_starCount(m_pattern.count(QLatin1Char('*'))),
m_openingSquareBracketPos(m_pattern.indexOf(QLatin1Char('['))),
m_questionMarkPos(m_pattern.indexOf(QLatin1Char('?'))),
m_caseSensitivity(s)
{
if (s == Qt::CaseInsensitive) {
m_pattern = m_pattern.toLower();
}
}
~MimeGlobPattern() {}
@@ -93,6 +98,9 @@ private:
QString m_pattern;
QString m_mimeType;
int m_weight;
int m_starCount;
int m_openingSquareBracketPos;
int m_questionMarkPos;
Qt::CaseSensitivity m_caseSensitivity;
};