ProjectTree: Improve performance of finding nodes

Using projectNode->forEachGenericNode(...) to find a node is much slower
than using project->nodeForFilePath(...), since the latter uses a binary
search.

Fixes: QTCREATORBUG-25845
Change-Id: I91be577a11b03915d1f21fe86a4cdd9ab0381f51
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
This commit is contained in:
Eike Ziller
2021-07-13 16:58:02 +02:00
parent 098e616512
commit 426f8185c2
3 changed files with 10 additions and 11 deletions

View File

@@ -851,7 +851,7 @@ bool Project::isKnownFile(const Utils::FilePath &filename) const
} }
const Node *Project::nodeForFilePath(const Utils::FilePath &filePath, const Node *Project::nodeForFilePath(const Utils::FilePath &filePath,
const Project::NodeMatcher &extraMatcher) const Project::NodeMatcher &extraMatcher) const
{ {
const FileNode dummy(filePath, FileType::Unknown); const FileNode dummy(filePath, FileType::Unknown);
const auto range = std::equal_range(d->m_sortedNodeList.cbegin(), d->m_sortedNodeList.cend(), const auto range = std::equal_range(d->m_sortedNodeList.cbegin(), d->m_sortedNodeList.cend(),

View File

@@ -128,7 +128,7 @@ public:
Utils::FilePaths files(const NodeMatcher &matcher) const; Utils::FilePaths files(const NodeMatcher &matcher) const;
bool isKnownFile(const Utils::FilePath &filename) const; bool isKnownFile(const Utils::FilePath &filename) const;
const Node *nodeForFilePath(const Utils::FilePath &filePath, const Node *nodeForFilePath(const Utils::FilePath &filePath,
const NodeMatcher &extraMatcher = {}); const NodeMatcher &extraMatcher = {}) const;
virtual QVariantMap toMap() const; virtual QVariantMap toMap() const;

View File

@@ -458,15 +458,14 @@ Node *ProjectTree::nodeForFile(const FilePath &fileName)
{ {
Node *node = nullptr; Node *node = nullptr;
for (const Project *project : SessionManager::projects()) { for (const Project *project : SessionManager::projects()) {
if (ProjectNode *projectNode = project->rootProjectNode()) { project->nodeForFilePath(fileName, [&](const Node *n) {
projectNode->forEachGenericNode([&](Node *n) { if (!node || (!node->asFileNode() && n->asFileNode()))
if (n->filePath() == fileName) { node = const_cast<Node *>(n);
// prefer file nodes return false;
if (!node || (!node->asFileNode() && n->asFileNode())) });
node = n; // early return:
} if (node && node->asFileNode())
}); return node;
}
} }
return node; return node;
} }