From 0633ac93b762405400de39000813e41a237cf7e7 Mon Sep 17 00:00:00 2001 From: Waqar Ahmed Date: Sat, 22 Jan 2022 14:27:01 +0500 Subject: [PATCH] Optimize FileFilter When Underline Files is enabled and you 'ls' into a big directory, then hovering / selection becomes really slow. --- src/filterHotSpots/FileFilter.cpp | 44 +++++++++++++++++------- src/filterHotSpots/FileFilter.h | 2 +- src/filterHotSpots/FileFilterHotspot.cpp | 8 +++-- src/filterHotSpots/FileFilterHotspot.h | 5 ++- 4 files changed, 42 insertions(+), 17 deletions(-) diff --git a/src/filterHotSpots/FileFilter.cpp b/src/filterHotSpots/FileFilter.cpp index f479dc14..6a00c558 100644 --- a/src/filterHotSpots/FileFilter.cpp +++ b/src/filterHotSpots/FileFilter.cpp @@ -85,10 +85,10 @@ QSharedPointer FileFilter::newHotSpot(int startLine, int startColumn, i return nullptr; } - QString filename = capturedTexts.first(); + const QString &filenameRef = capturedTexts.first(); + QStringView filename = filenameRef; if (filename.startsWith(QLatin1Char('\'')) && filename.endsWith(QLatin1Char('\''))) { - filename.remove(0, 1); - filename.chop(1); + filename = filename.mid(1, filename.size() - 2); } // '.' and '..' could be valid hotspots, but '..................' most likely isn't @@ -98,15 +98,31 @@ QSharedPointer FileFilter::newHotSpot(int startLine, int startColumn, i } if (filename.startsWith(QLatin1String("[/"))) { // ctest error output - filename.remove(0, 1); + filename = filename.mid(1); } const bool absolute = filename.startsWith(QLatin1Char('/')); if (!absolute) { - auto match = std::find_if(_currentDirContents.cbegin(), _currentDirContents.cend(), [&filename](const QString &s) { - return filename == s // It's a direct child file or dir - || filename.startsWith(s + QLatin1Char{':'}) // filename:lineNumber (output of grep -n) - || filename.startsWith(s + QLatin1Char{'/'}); // It's inside a child dir + auto match = std::find_if(_currentDirContents.cbegin(), _currentDirContents.cend(), [filename](const QString &s) { + // early out if first char doesn't match + if (!s.isEmpty() && filename.at(0) != s.at(0)) { + return false; + } + + const bool startsWith = filename.startsWith(s); + if (startsWith) { + // are we equal ? + if (filename.size() == s.size()) { + return true; + } + int onePast = s.size(); + if (onePast < filename.size()) { + if (filename.at(onePast) == QLatin1Char(':') || filename.at(onePast) == QLatin1Char('/')) { + return true; + } + } + } + return false; }); if (match == _currentDirContents.cend()) { @@ -114,8 +130,13 @@ QSharedPointer FileFilter::newHotSpot(int startLine, int startColumn, i } } - return QSharedPointer( - new FileFilterHotSpot(startLine, startColumn, endLine, endColumn, capturedTexts, !absolute ? _dirPath + filename : filename, _session)); + return QSharedPointer(new FileFilterHotSpot(startLine, + startColumn, + endLine, + endColumn, + capturedTexts, + !absolute ? _dirPath + filename.toString() : filename.toString(), + _session)); } void FileFilter::process() @@ -125,8 +146,7 @@ void FileFilter::process() if (_dirPath != dir.canonicalPath() + QLatin1Char('/')) { _dirPath = dir.canonicalPath() + QLatin1Char('/'); - const auto tmpList = dir.entryList(QDir::Dirs | QDir::Files); - _currentDirContents = QSet(std::begin(tmpList), std::end(tmpList)); + _currentDirContents = dir.entryList(QDir::Dirs | QDir::Files); } RegExpFilter::process(); diff --git a/src/filterHotSpots/FileFilter.h b/src/filterHotSpots/FileFilter.h index a5493bce..2ee278fe 100644 --- a/src/filterHotSpots/FileFilter.h +++ b/src/filterHotSpots/FileFilter.h @@ -41,7 +41,7 @@ private: QPointer _session; QString _dirPath; - QSet _currentDirContents; + QList _currentDirContents; static QRegularExpression _regex; }; diff --git a/src/filterHotSpots/FileFilterHotspot.cpp b/src/filterHotSpots/FileFilterHotspot.cpp index 3263ae6f..ae5cada7 100644 --- a/src/filterHotSpots/FileFilterHotspot.cpp +++ b/src/filterHotSpots/FileFilterHotspot.cpp @@ -181,13 +181,15 @@ QList FileFilterHotSpot::actions() QList FileFilterHotSpot::setupMenu(QMenu *menu) { + if (!_menuActions) + _menuActions = new KFileItemActions; const QList currentActions = menu->actions(); const KFileItem fileItem(QUrl::fromLocalFile(_filePath)); const KFileItemList itemList({fileItem}); const KFileItemListProperties itemProperties(itemList); - _menuActions.setParent(this); - _menuActions.setItemListProperties(itemProperties); + _menuActions->setParent(this); + _menuActions->setItemListProperties(itemProperties); #if KIO_VERSION < QT_VERSION_CHECK(5, 82, 0) _menuActions.addOpenWithActionsTo(menu); @@ -206,7 +208,7 @@ QList FileFilterHotSpot::setupMenu(QMenu *menu) menu->insertAction(firstAction, separator); #else const QList actionList = menu->actions(); - _menuActions.insertOpenWithActionsTo(!actionList.isEmpty() ? actionList.at(0) : nullptr, menu, QStringList()); + _menuActions->insertOpenWithActionsTo(!actionList.isEmpty() ? actionList.at(0) : nullptr, menu, QStringList()); #endif QList addedActions = menu->actions(); diff --git a/src/filterHotSpots/FileFilterHotspot.h b/src/filterHotSpots/FileFilterHotspot.h index 9d8ff9f7..15958eec 100644 --- a/src/filterHotSpots/FileFilterHotspot.h +++ b/src/filterHotSpots/FileFilterHotspot.h @@ -66,7 +66,10 @@ private: void showThumbnail(const KFileItem &item, const QPixmap &preview); QString _filePath; Session *_session = nullptr; - KFileItemActions _menuActions; + + // This is a pointer for performance reasons + // constructing KFileItemActions is super expensive + KFileItemActions *_menuActions = nullptr; QPoint _eventPos; QPoint _thumbnailPos;