ModelEditor: Do not query all files in the project for their mime type

Consulting the mime type database is much too expensive to do it for all
files in a project, so take a shortcut.
Example benchmark: When loading the Qt Creator super project (with all
the commercial plugins) on my Linux machine, with this patch the time
spent in ModelIndexer::scanProject() goes down from ~8 seconds to under
300 milliseconds. Note that the UI is frozen during that period.

Task-number: QTCREATORBUG-18533
Change-Id: Id75d6bbcf37b4f4e41383a089e9e0dc5262cfbae
Reviewed-by: hjk <hjk@qt.io>
Reviewed-by: Jochen Becher <jochen_becher@gmx.de>
This commit is contained in:
Christian Kandeler
2020-02-05 16:30:33 +01:00
parent a478359405
commit 3782eebfaf
2 changed files with 21 additions and 13 deletions

View File

@@ -399,17 +399,20 @@ void ModelIndexer::scanProject(ProjectExplorer::Project *project)
QQueue<QueuedFile> filesQueue; QQueue<QueuedFile> filesQueue;
QSet<QueuedFile> filesSet; QSet<QueuedFile> filesSet;
const Utils::MimeType modelMimeType = Utils::mimeTypeForName(Constants::MIME_TYPE_MODEL);
if (modelMimeType.isValid()) {
for (const Utils::FilePath &file : files) { for (const Utils::FilePath &file : files) {
QFileInfo fileInfo = file.toFileInfo(); const QFileInfo fileInfo = file.toFileInfo();
Utils::MimeType mimeType = Utils::mimeTypeForFile(fileInfo); if (modelMimeType.suffixes().contains(fileInfo.completeSuffix())) {
if (mimeType.name() == QLatin1String(Constants::MIME_TYPE_MODEL)) {
QueuedFile queuedFile(file.toString(), project, fileInfo.lastModified()); QueuedFile queuedFile(file.toString(), project, fileInfo.lastModified());
filesQueue.append(queuedFile); filesQueue.append(queuedFile);
filesSet.insert(queuedFile); filesSet.insert(queuedFile);
} }
} }
}
QString defaultModelFile = findFirstModel(project->rootProjectNode()); // FIXME: This potentially iterates over all files again.
QString defaultModelFile = findFirstModel(project->rootProjectNode(), modelMimeType);
bool filesAreQueued = false; bool filesAreQueued = false;
{ {
@@ -460,15 +463,17 @@ void ModelIndexer::scanProject(ProjectExplorer::Project *project)
emit filesQueued(); emit filesQueued();
} }
QString ModelIndexer::findFirstModel(ProjectExplorer::FolderNode *folderNode) QString ModelIndexer::findFirstModel(ProjectExplorer::FolderNode *folderNode,
const Utils::MimeType &mimeType)
{ {
if (!mimeType.isValid())
return QString();
foreach (ProjectExplorer::FileNode *fileNode, folderNode->fileNodes()) { foreach (ProjectExplorer::FileNode *fileNode, folderNode->fileNodes()) {
Utils::MimeType mimeType = Utils::mimeTypeForFile(fileNode->filePath().toFileInfo()); if (mimeType.suffixes().contains(fileNode->filePath().toFileInfo().completeSuffix()))
if (mimeType.name() == QLatin1String(Constants::MIME_TYPE_MODEL))
return fileNode->filePath().toString(); return fileNode->filePath().toString();
} }
foreach (ProjectExplorer::FolderNode *subFolderNode, folderNode->folderNodes()) { foreach (ProjectExplorer::FolderNode *subFolderNode, folderNode->folderNodes()) {
QString modelFileName = findFirstModel(subFolderNode); QString modelFileName = findFirstModel(subFolderNode, mimeType);
if (!modelFileName.isEmpty()) if (!modelFileName.isEmpty())
return modelFileName; return modelFileName;
} }

View File

@@ -34,6 +34,8 @@ class Project;
class FolderNode; class FolderNode;
} }
namespace Utils { class MimeType; }
namespace ModelEditor { namespace ModelEditor {
namespace Internal { namespace Internal {
@@ -72,7 +74,8 @@ private:
private: private:
void scanProject(ProjectExplorer::Project *project); void scanProject(ProjectExplorer::Project *project);
QString findFirstModel(ProjectExplorer::FolderNode *folderNode); QString findFirstModel(ProjectExplorer::FolderNode *folderNode,
const Utils::MimeType &mimeType);
void forgetProject(ProjectExplorer::Project *project); void forgetProject(ProjectExplorer::Project *project);
void removeModelFile(const QString &file, ProjectExplorer::Project *project); void removeModelFile(const QString &file, ProjectExplorer::Project *project);
void removeDiagramReferenceFile(const QString &file, ProjectExplorer::Project *project); void removeDiagramReferenceFile(const QString &file, ProjectExplorer::Project *project);