CppEditor: Reuse document for search results

Instead of open a document for every entry we do open it only once per
search. For that we sort the entries by file path, so that they are clustered
together and reuse the last document if the path hasn't changed. This can
improve the calculations of the search results drastically.

Change-Id: I9c9c1e387624297d84c6a2ca6edb6130f739d295
Reviewed-by: Nikolai Kosjar <nikolai.kosjar@qt.io>
This commit is contained in:
Marco Bubke
2019-08-21 14:33:13 +02:00
committed by Tim Jenssen
parent 246277c570
commit 20a304c8e0
2 changed files with 54 additions and 19 deletions

View File

@@ -346,18 +346,16 @@ void CppEditorWidget::onShowInfoBarAction(const Id &id, bool show)
action->setVisible(show); action->setVisible(show);
} }
static QString getDocumentLine(const QTextDocument &document, int line) static QString getDocumentLine(QTextDocument *document, int line)
{ {
return document.findBlockByNumber(line - 1).text(); if (document)
return document->findBlockByNumber(line - 1).text();
return {};
} }
static QString getFileLine(const QString &path, int line) static std::unique_ptr<QTextDocument> getCurrentDocument(const QString &path)
{ {
const IDocument *document = DocumentModel::documentForFilePath(path);
const auto textDocument = qobject_cast<const TextDocument *>(document);
if (textDocument)
return getDocumentLine(*textDocument->document(), line);
const QTextCodec *defaultCodec = Core::EditorManager::defaultTextCodec(); const QTextCodec *defaultCodec = Core::EditorManager::defaultTextCodec();
QString contents; QString contents;
Utils::TextFileFormat format; Utils::TextFileFormat format;
@@ -365,11 +363,10 @@ static QString getFileLine(const QString &path, int line)
if (Utils::TextFileFormat::readFile(path, defaultCodec, &contents, &format, &error) if (Utils::TextFileFormat::readFile(path, defaultCodec, &contents, &format, &error)
!= Utils::TextFileFormat::ReadSuccess) { != Utils::TextFileFormat::ReadSuccess) {
qWarning() << "Error reading file " << path << " : " << error; qWarning() << "Error reading file " << path << " : " << error;
return QString(); return {};
} }
const QTextDocument tmpDocument{contents}; return std::make_unique<QTextDocument>(contents);
return getDocumentLine(tmpDocument, line);
} }
static void onReplaceUsagesClicked(const QString &text, static void onReplaceUsagesClicked(const QString &text,
@@ -387,6 +384,43 @@ static void onReplaceUsagesClicked(const QString &text,
} }
} }
static QTextDocument *getOpenDocument(const QString &path)
{
const IDocument *document = DocumentModel::documentForFilePath(path);
if (document)
return qobject_cast<const TextDocument *>(document)->document();
return {};
}
static void addSearchResults(CppTools::Usages usages, SearchResult &search, const QString &text)
{
std::sort(usages.begin(), usages.end());
std::unique_ptr<QTextDocument> currentDocument;
QString lastPath;
for (const CppTools::Usage &usage : usages) {
QTextDocument *document = getOpenDocument(usage.path);
if (!document) {
if (usage.path != lastPath) {
currentDocument = getCurrentDocument(usage.path);
lastPath = usage.path;
}
document = currentDocument.get();
}
const QString lineContent = getDocumentLine(document, usage.line);
if (lineContent.size()) {
Search::TextRange range{Search::TextPosition(usage.line, usage.column - 1),
Search::TextPosition(usage.line, usage.column + text.length() - 1)};
search.addResult(usage.path, lineContent, range);
}
}
}
static void findRenameCallback(CppEditorWidget *widget, static void findRenameCallback(CppEditorWidget *widget,
const QTextCursor &baseCursor, const QTextCursor &baseCursor,
const CppTools::Usages &usages, const CppTools::Usages &usages,
@@ -413,14 +447,9 @@ static void findRenameCallback(CppEditorWidget *widget,
[widget, rename, replacement, baseCursor]() { [widget, rename, replacement, baseCursor]() {
rename ? widget->renameUsages(replacement, baseCursor) : widget->findUsages(baseCursor); rename ? widget->renameUsages(replacement, baseCursor) : widget->findUsages(baseCursor);
}); });
for (const CppTools::Usage &usage : usages) {
const QString lineStr = getFileLine(usage.path, usage.line); addSearchResults(usages, *search, text);
if (lineStr.isEmpty())
continue;
Search::TextRange range{Search::TextPosition(usage.line, usage.column - 1),
Search::TextPosition(usage.line, usage.column + text.length() - 1)};
search->addResult(usage.path, lineStr, range);
}
search->finishSearch(false); search->finishSearch(false);
QObject::connect(search, &SearchResult::activated, QObject::connect(search, &SearchResult::activated,
[](const Core::SearchResultItem& item) { [](const Core::SearchResultItem& item) {

View File

@@ -51,6 +51,12 @@ public:
&& first.path == second.path; && first.path == second.path;
} }
friend bool operator<(const Usage &first, const Usage &second)
{
return std::tie(first.path, first.line, first.column)
< std::tie(second.path, second.line, second.column);
}
public: public:
QString path; QString path;
int line = 0; int line = 0;