diff options
author | Eike Ziller <eike.ziller@qt.io> | 2024-05-03 11:26:29 +0200 |
---|---|---|
committer | Eike Ziller <eike.ziller@qt.io> | 2024-05-06 08:42:45 +0000 |
commit | ca3646daba6dd82e5da18080f3d242a6e7256a31 (patch) | |
tree | 305759172fd992063df25e5735b63198baed9832 | |
parent | effb365ab3aca069f594003a3829b09510d4f571 (diff) |
C++: Do not freeze Qt Creator while checking file sizes
Before actually indexing files, the C++ model checks the files against a
file size limit (if set, which is the default).
Do not iterate over all files and check their size in the main thread.
If the files are on a device, this operation is not fast. Move the
filtering to the parsing thread itself.
Change-Id: I2202cc44c28f38159ca593db2399dde30f95f9bd
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
Reviewed-by: Marcus Tillmanns <marcus.tillmanns@qt.io>
Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
-rw-r--r-- | src/plugins/cppeditor/cppindexingsupport.cpp | 38 | ||||
-rw-r--r-- | src/plugins/cppeditor/cppindexingsupport.h | 8 | ||||
-rw-r--r-- | src/plugins/cppeditor/cppmodelmanager.cpp | 21 |
3 files changed, 41 insertions, 26 deletions
diff --git a/src/plugins/cppeditor/cppindexingsupport.cpp b/src/plugins/cppeditor/cppindexingsupport.cpp index b6edade0e2..73e3fafff3 100644 --- a/src/plugins/cppeditor/cppindexingsupport.cpp +++ b/src/plugins/cppeditor/cppindexingsupport.cpp @@ -219,23 +219,22 @@ static void index(QPromise<void> &promise, const ParseParams params) qCDebug(indexerLog) << "Indexing finished."; } -static void parse(QPromise<void> &promise, const ParseParams ¶ms) +static void parse( + QPromise<void> &promise, + const std::function<QSet<QString>()> &sourceFiles, + const ProjectExplorer::HeaderPaths &headerPaths, + const WorkingCopy &workingCopy) { - const QSet<QString> &files = params.sourceFiles; - if (files.isEmpty()) { - CppModelManager::finishedRefreshingSourceFiles(files); - return; - } - - promise.setProgressRange(0, files.size()); + ParseParams params{headerPaths, workingCopy, sourceFiles()}; + promise.setProgressRange(0, params.sourceFiles.size()); if (CppIndexingSupport::isFindErrorsIndexingActive()) indexFindErrors(promise, params); else index(promise, params); - promise.setProgressValue(files.size()); - CppModelManager::finishedRefreshingSourceFiles(files); + promise.setProgressValue(params.sourceFiles.size()); + CppModelManager::finishedRefreshingSourceFiles(params.sourceFiles); } } // anonymous namespace @@ -302,18 +301,19 @@ bool CppIndexingSupport::isFindErrorsIndexingActive() return Utils::qtcEnvironmentVariable("QTC_FIND_ERRORS_INDEXING") == "1"; } -QFuture<void> CppIndexingSupport::refreshSourceFiles(const QSet<QString> &sourceFiles, - CppModelManager::ProgressNotificationMode mode) +QFuture<void> CppIndexingSupport::refreshSourceFiles( + const std::function<QSet<QString>()> &sourceFiles, + CppModelManager::ProgressNotificationMode mode) { - ParseParams params; - params.headerPaths = CppModelManager::headerPaths(); - params.workingCopy = CppModelManager::workingCopy(); - params.sourceFiles = sourceFiles; - - QFuture<void> result = Utils::asyncRun(CppModelManager::sharedThreadPool(), parse, params); + QFuture<void> result = Utils::asyncRun( + CppModelManager::sharedThreadPool(), + parse, + sourceFiles, + CppModelManager::headerPaths(), + CppModelManager::workingCopy()); m_synchronizer.addFuture(result); - if (mode == CppModelManager::ForcedProgressNotification || sourceFiles.count() > 1) { + if (mode == CppModelManager::ForcedProgressNotification) { Core::ProgressManager::addTask(result, Tr::tr("Parsing C/C++ Files"), CppEditor::Constants::TASK_INDEX); } diff --git a/src/plugins/cppeditor/cppindexingsupport.h b/src/plugins/cppeditor/cppindexingsupport.h index c04eb8ba76..f32498fa5e 100644 --- a/src/plugins/cppeditor/cppindexingsupport.h +++ b/src/plugins/cppeditor/cppindexingsupport.h @@ -11,6 +11,8 @@ #include <QFuture> +#include <functional> + namespace Utils { class SearchResultItem; } namespace CppEditor { @@ -59,8 +61,10 @@ class CPPEDITOR_EXPORT CppIndexingSupport public: static bool isFindErrorsIndexingActive(); - QFuture<void> refreshSourceFiles(const QSet<QString> &sourceFiles, - CppModelManager::ProgressNotificationMode mode); + QFuture<void> refreshSourceFiles( + const std::function<QSet<QString>()> &sourceFiles, + CppModelManager::ProgressNotificationMode mode); + private: Utils::FutureSynchronizer m_synchronizer; }; diff --git a/src/plugins/cppeditor/cppmodelmanager.cpp b/src/plugins/cppeditor/cppmodelmanager.cpp index 725d5632d5..fbb727eb72 100644 --- a/src/plugins/cppeditor/cppmodelmanager.cpp +++ b/src/plugins/cppeditor/cppmodelmanager.cpp @@ -90,6 +90,7 @@ #include <QWriteLocker> #include <memory> +#include <unordered_map> #if defined(QTCREATOR_WITH_DUMP_AST) && defined(Q_CC_GNU) #define WITH_AST_DUMP @@ -1353,15 +1354,25 @@ QFuture<void> CppModelManager::updateSourceFiles(const QSet<FilePath> &sourceFil if (sourceFiles.isEmpty() || !d->m_indexerEnabled) return QFuture<void>(); - QHash<Project *, QSet<QString>> sourcesPerProject; // TODO: Work with QList from here on? + std::unordered_map<Project *, QSet<QString>> sourcesPerProject; for (const FilePath &fp : sourceFiles) sourcesPerProject[ProjectManager::projectForFile(fp)] << fp.toString(); - QSet<QString> filteredFiles; - for (auto it = sourcesPerProject.cbegin(); it != sourcesPerProject.cend(); ++it) { - filteredFiles.unite( - filteredFilesRemoved(it.value(), CppCodeModelSettings::settingsForProject(it.key()))); + std::vector<std::pair<QSet<QString>, CppCodeModelSettings>> sourcesAndSettings; + for (const auto &it : sourcesPerProject) { + sourcesAndSettings + .emplace_back(it.second, CppCodeModelSettings::settingsForProject(it.first)); } + const auto filteredFiles = [sourcesAndSettings = std::move(sourcesAndSettings)] { + QSet<QString> result; + for (const auto &it : sourcesAndSettings) + result.unite(filteredFilesRemoved(it.first, it.second)); + return result; + }; + + // "ReservedProgressNotification" should be shown if there is more than one source file. + if (sourceFiles.size() > 1) + mode = ForcedProgressNotification; return d->m_internalIndexingSupport->refreshSourceFiles(filteredFiles, mode); } |