Add regex cache in string matcher

This commit is contained in:
Paul Carroll 2025-08-19 10:37:29 -04:00
parent aa2c7402e3
commit 6c6e36a89e

View file

@ -4,10 +4,16 @@
#include <QByteArray> #include <QByteArray>
#include <QDebug> #include <QDebug>
#include <QHash>
#include <QMutex>
#include <QRegularExpression> #include <QRegularExpression>
#include <QString> #include <QString>
#include <functional> #include <functional>
// Static cache for compiled regexes to avoid recompilation
static QHash<QString, QRegularExpression> regexCache;
static QMutex regexCacheMutex;
static peg::parser search(R"( static peg::parser search(R"(
Start <- QueryPartList Start <- QueryPartList
~ws <- [ ]+ ~ws <- [ ]+
@ -189,10 +195,24 @@ static void setupParserRules()
}; };
search["StringValue"] = [](const peg::SemanticValues &sv) -> StringMatcher { search["StringValue"] = [](const peg::SemanticValues &sv) -> StringMatcher {
// Helper function for word boundary matching // Helper function for word boundary matching with caching
auto createWordBoundaryMatcher = [](const QString &target) { auto createWordBoundaryMatcher = [](const QString &target) -> std::function<bool(const QString &)> {
QString pattern = QString("\\b%1\\b").arg(QRegularExpression::escape(target)); QString pattern = QString("\\b%1\\b").arg(QRegularExpression::escape(target));
// Check cache first with thread safety
QMutexLocker locker(&regexCacheMutex);
auto it = regexCache.find(pattern);
if (it != regexCache.end()) {
QRegularExpression cachedRegex = it.value();
locker.unlock();
return [cachedRegex](const QString &s) { return cachedRegex.match(s).hasMatch(); };
}
// Compile new regex and add to cache
QRegularExpression regex(pattern, QRegularExpression::CaseInsensitiveOption); QRegularExpression regex(pattern, QRegularExpression::CaseInsensitiveOption);
regexCache.insert(pattern, regex);
locker.unlock();
return [regex](const QString &s) { return regex.match(s).hasMatch(); }; return [regex](const QString &s) { return regex.match(s).hasMatch(); };
}; };