From 7ffcbe541b87bc9977ba2cb14d6b48df717e7e11 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Wed, 19 Jun 2024 13:17:11 +0200 Subject: [PATCH] TreeScanner: Inline scanForFiles() method Make scanForFiles() a non-template method and hide it in treescanner.cpp. Inline scanForFilesRecursively(). Change-Id: I10e07f190e1a4a65cd7045c625a364350964afb9 Reviewed-by: David Schulz --- src/plugins/projectexplorer/CMakeLists.txt | 1 - .../projectexplorer/projectexplorer.qbs | 1 - .../projectexplorer/projectnodeshelper.h | 141 ------------------ src/plugins/projectexplorer/treescanner.cpp | 111 +++++++++++++- src/plugins/projectexplorer/treescanner.h | 2 +- 5 files changed, 107 insertions(+), 149 deletions(-) delete mode 100644 src/plugins/projectexplorer/projectnodeshelper.h diff --git a/src/plugins/projectexplorer/CMakeLists.txt b/src/plugins/projectexplorer/CMakeLists.txt index ea7a079d908..0c62d2177a1 100644 --- a/src/plugins/projectexplorer/CMakeLists.txt +++ b/src/plugins/projectexplorer/CMakeLists.txt @@ -140,7 +140,6 @@ add_qtc_plugin(ProjectExplorer projectmanager.cpp projectmanager.h projectmodels.cpp projectmodels.h projectnodes.cpp projectnodes.h - projectnodeshelper.h projectpanelfactory.cpp projectpanelfactory.h projectsettingswidget.cpp projectsettingswidget.h projecttree.cpp projecttree.h diff --git a/src/plugins/projectexplorer/projectexplorer.qbs b/src/plugins/projectexplorer/projectexplorer.qbs index 19b9221de2b..bce24dc1361 100644 --- a/src/plugins/projectexplorer/projectexplorer.qbs +++ b/src/plugins/projectexplorer/projectexplorer.qbs @@ -115,7 +115,6 @@ QtcPlugin { "projectmanager.cpp", "projectmanager.h", "projectmodels.cpp", "projectmodels.h", "projectnodes.cpp", "projectnodes.h", - "projectnodeshelper.h", "projectpanelfactory.cpp", "projectpanelfactory.h", "projectsettingswidget.cpp", "projectsettingswidget.h", "projecttree.cpp", diff --git a/src/plugins/projectexplorer/projectnodeshelper.h b/src/plugins/projectexplorer/projectnodeshelper.h deleted file mode 100644 index 37b015ec321..00000000000 --- a/src/plugins/projectexplorer/projectnodeshelper.h +++ /dev/null @@ -1,141 +0,0 @@ -// Copyright (C) 2021 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 - -#pragma once - -#include "projectnodes.h" - -#include -#include - -#include - -#include -#include -#include -#include - -#include - -namespace ProjectExplorer { -namespace Internal { - -struct DirectoryScanResult -{ - QList nodes; - Utils::FilePaths subDirectories; -}; - -static DirectoryScanResult scanForFiles( - const QFuture &future, - const Utils::FilePath &directory, - QDir::Filters filter, - const std::function &factory, - const QList &versionControls) -{ - DirectoryScanResult result; - - const Utils::FilePaths entries = directory.dirEntries(filter); - for (const Utils::FilePath &entry : entries) { - if (future.isCanceled()) - return result; - - if (Utils::anyOf(versionControls, [entry](const Core::IVersionControl *vc) { - return vc->isVcsFileOrDirectory(entry); - })) { - continue; - } - - if (entry.isDir()) - result.subDirectories.append(entry); - else if (FileNode *node = factory(entry)) - result.nodes.append(node); - } - return result; -} - -template -QList scanForFilesRecursively( - QPromise &promise, - int progressRange, - const Utils::FilePath &directory, - QDir::Filters filter, - const std::function &factory, - const QList &versionControls) -{ - const QFuture future(promise.future()); - - QSet visited; - const DirectoryScanResult result - = scanForFiles(future, directory, filter, factory, versionControls); - QList fileNodes = result.nodes; - const int progressIncrement = int( - progressRange / static_cast(fileNodes.count() + result.subDirectories.count())); - promise.setProgressValue(int(fileNodes.count() * progressIncrement)); - QList> subDirectories; - auto addSubDirectories = [&](const Utils::FilePaths &subdirs, int progressIncrement) { - for (const Utils::FilePath &subdir : subdirs) { - if (Utils::insert(visited, subdir.canonicalPath())) - subDirectories.append(qMakePair(subdir, progressIncrement)); - else - promise.setProgressValue(promise.future().progressValue() + progressIncrement); - } - }; - addSubDirectories(result.subDirectories, progressIncrement); - - while (!subDirectories.isEmpty()) { - using namespace Tasking; - const LoopList iterator(subDirectories); - subDirectories.clear(); - - auto onSetup = [&, iterator](Utils::Async &task) { - task.setConcurrentCallData( - scanForFiles, future, iterator->first, filter, factory, versionControls); - }; - - auto onDone = [&, iterator](const Utils::Async &task) { - const int progressRange = iterator->second; - const DirectoryScanResult result = task.result(); - fileNodes.append(result.nodes); - const qsizetype subDirCount = result.subDirectories.count(); - if (subDirCount == 0) { - promise.setProgressValue(promise.future().progressValue() + progressRange); - } else { - const qsizetype fileCount = result.nodes.count(); - const int increment = int( - progressRange / static_cast(fileCount + subDirCount)); - promise.setProgressValue( - promise.future().progressValue() + increment * fileCount); - addSubDirectories(result.subDirectories, increment); - } - }; - - const Group group{ - Utils::HostOsInfo::isLinuxHost() ? parallelLimit(2) : parallelIdealThreadCountLimit, - iterator, - Utils::AsyncTask(onSetup, onDone) - }; - TaskTree::runBlocking(group); - } - return fileNodes; -} - -} // namespace Internal - -template -QList scanForFiles( - QPromise &promise, - const Utils::FilePath &directory, - QDir::Filters filter, - const std::function &factory) -{ - promise.setProgressRange(0, 1000000); - return Internal::scanForFilesRecursively(promise, - 1000000, - directory, - filter, - factory, - Core::VcsManager::versionControls()); -} - -} // namespace ProjectExplorer diff --git a/src/plugins/projectexplorer/treescanner.cpp b/src/plugins/projectexplorer/treescanner.cpp index 49680621ec2..4411184c923 100644 --- a/src/plugins/projectexplorer/treescanner.cpp +++ b/src/plugins/projectexplorer/treescanner.cpp @@ -3,15 +3,17 @@ #include "treescanner.h" -#include "projectnodeshelper.h" #include "projecttree.h" #include #include -#include -#include +#include + #include +#include +#include +#include #include @@ -146,14 +148,113 @@ static std::unique_ptr createFolderNode(const Utils::FilePath &direc return fileSystemNode; } +struct DirectoryScanResult +{ + QList nodes; + Utils::FilePaths subDirectories; +}; + +static DirectoryScanResult scanForFilesImpl( + const QFuture &future, + const Utils::FilePath &directory, + QDir::Filters filter, + const std::function &factory, + const QList &versionControls) +{ + DirectoryScanResult result; + + const Utils::FilePaths entries = directory.dirEntries(filter); + for (const Utils::FilePath &entry : entries) { + if (future.isCanceled()) + return result; + + if (Utils::anyOf(versionControls, [entry](const Core::IVersionControl *vc) { + return vc->isVcsFileOrDirectory(entry); + })) { + continue; + } + + if (entry.isDir()) + result.subDirectories.append(entry); + else if (FileNode *node = factory(entry)) + result.nodes.append(node); + } + return result; +} + +static QList scanForFilesHelper( + TreeScanner::Promise &promise, + const Utils::FilePath &directory, + QDir::Filters filter, + const std::function &factory) +{ + const QFuture future(promise.future()); + + const int progressRange = 1000000; + const QList &versionControls = Core::VcsManager::versionControls(); + promise.setProgressRange(0, progressRange); + + QSet visited; + const DirectoryScanResult result = scanForFilesImpl(future, directory, filter, factory, versionControls); + QList fileNodes = result.nodes; + const int progressIncrement = int( + progressRange / static_cast(fileNodes.count() + result.subDirectories.count())); + promise.setProgressValue(int(fileNodes.count() * progressIncrement)); + QList> subDirectories; + auto addSubDirectories = [&](const Utils::FilePaths &subdirs, int progressIncrement) { + for (const Utils::FilePath &subdir : subdirs) { + if (Utils::insert(visited, subdir.canonicalPath())) + subDirectories.append(qMakePair(subdir, progressIncrement)); + else + promise.setProgressValue(future.progressValue() + progressIncrement); + } + }; + addSubDirectories(result.subDirectories, progressIncrement); + + while (!subDirectories.isEmpty()) { + using namespace Tasking; + const LoopList iterator(subDirectories); + subDirectories.clear(); + + auto onSetup = [&, iterator](Utils::Async &task) { + task.setConcurrentCallData( + scanForFilesImpl, future, iterator->first, filter, factory, versionControls); + }; + + auto onDone = [&, iterator](const Utils::Async &task) { + const int progressRange = iterator->second; + const DirectoryScanResult result = task.result(); + fileNodes.append(result.nodes); + const qsizetype subDirCount = result.subDirectories.count(); + if (subDirCount == 0) { + promise.setProgressValue(future.progressValue() + progressRange); + } else { + const qsizetype fileCount = result.nodes.count(); + const int increment = int( + progressRange / static_cast(fileCount + subDirCount)); + promise.setProgressValue(future.progressValue() + increment * fileCount); + addSubDirectories(result.subDirectories, increment); + } + }; + + const Group group{ + Utils::HostOsInfo::isLinuxHost() ? parallelLimit(2) : parallelIdealThreadCountLimit, + iterator, + Utils::AsyncTask(onSetup, onDone) + }; + TaskTree::runBlocking(group); + } + return fileNodes; +} + void TreeScanner::scanForFiles( Promise &promise, const Utils::FilePath &directory, const FileFilter &filter, - const QDir::Filters &dirFilter, + QDir::Filters dirFilter, const FileTypeFactory &factory) { - QList nodes = ProjectExplorer::scanForFiles( + QList nodes = scanForFilesHelper( promise, directory, dirFilter, [&filter, &factory](const Utils::FilePath &fn) -> FileNode * { const Utils::MimeType mimeType = Utils::mimeTypesForFileName(fn.path()).value(0); diff --git a/src/plugins/projectexplorer/treescanner.h b/src/plugins/projectexplorer/treescanner.h index 6de26e399ad..bc4dbe0b069 100644 --- a/src/plugins/projectexplorer/treescanner.h +++ b/src/plugins/projectexplorer/treescanner.h @@ -75,7 +75,7 @@ private: static void scanForFiles(Promise &fi, const Utils::FilePath &directory, const FileFilter &filter, - const QDir::Filters &dirFilter, + QDir::Filters dirFilter, const FileTypeFactory &factory); private: