From 45656335fcd5143ae64c03beed910d623dfed921 Mon Sep 17 00:00:00 2001 From: Erik Verbruggen Date: Tue, 26 Feb 2013 11:14:02 +0100 Subject: [PATCH] C++: Change the locator filter to queue changed documents. The changed documents get searched for symbols when either a limit of 10 pending documents is reached, or when the filter is asked to return all matches. Change-Id: Ic18fc66b0a802165fdd8a028bd13d0ce11524510 Reviewed-by: Nikolai Kosjar Reviewed-by: Eike Ziller --- src/plugins/cpptools/cpplocatorfilter.cpp | 56 ++++++++++++++++++++--- src/plugins/cpptools/cpplocatorfilter.h | 9 ++-- src/plugins/cpptools/searchsymbols.cpp | 3 +- src/plugins/cpptools/searchsymbols.h | 8 ++-- 4 files changed, 62 insertions(+), 14 deletions(-) diff --git a/src/plugins/cpptools/cpplocatorfilter.cpp b/src/plugins/cpptools/cpplocatorfilter.cpp index b9631bc680e..03b55718d9e 100644 --- a/src/plugins/cpptools/cpplocatorfilter.cpp +++ b/src/plugins/cpptools/cpplocatorfilter.cpp @@ -39,15 +39,19 @@ using namespace CppTools::Internal; using namespace Utils; +static const int MaxPendingDocuments = 10; + CppLocatorFilter::CppLocatorFilter(CppModelManager *manager) - : m_manager(manager), - m_forceNewSearchList(true) + : m_manager(manager) + , m_pendingDocumentsMutex(QMutex::Recursive) { setId("Classes and Methods"); setDisplayName(tr("C++ Classes and Methods")); setShortcutString(QString(QLatin1Char(':'))); setIncludedByDefault(false); + m_pendingDocuments.reserve(MaxPendingDocuments); + connect(manager, SIGNAL(documentUpdated(CPlusPlus::Document::Ptr)), this, SLOT(onDocumentUpdated(CPlusPlus::Document::Ptr))); @@ -58,13 +62,53 @@ CppLocatorFilter::CppLocatorFilter(CppModelManager *manager) CppLocatorFilter::~CppLocatorFilter() { } -void CppLocatorFilter::onDocumentUpdated(CPlusPlus::Document::Ptr doc) + +void CppLocatorFilter::flushPendingDocument(bool force) { - m_searchList[doc->fileName()] = search(doc); + QMutexLocker locker(&m_pendingDocumentsMutex); + if (!force && m_pendingDocuments.size() < MaxPendingDocuments) + return; + + foreach (CPlusPlus::Document::Ptr doc, m_pendingDocuments) { + QList &results = m_searchList[doc->fileName()]; + results = search(doc, results.size() + 10); + } + + m_pendingDocuments.clear(); + m_pendingDocuments.reserve(MaxPendingDocuments); +} + +void CppLocatorFilter::onDocumentUpdated(CPlusPlus::Document::Ptr updatedDoc) +{ + QMutexLocker locker(&m_pendingDocumentsMutex); + + int i = 0, ei = m_pendingDocuments.size(); + for (; i < ei; ++i) { + const CPlusPlus::Document::Ptr &doc = m_pendingDocuments.at(i); + if (doc->fileName() == updatedDoc->fileName() + && doc->revision() < updatedDoc->revision()) { + m_pendingDocuments[i] = updatedDoc; + break; + } + } + + if (i == ei) + m_pendingDocuments.append(updatedDoc); + + flushPendingDocument(false); } void CppLocatorFilter::onAboutToRemoveFiles(const QStringList &files) { + QMutexLocker locker(&m_pendingDocumentsMutex); + + for (int i = 0; i < m_pendingDocuments.size(); ) { + if (files.contains(m_pendingDocuments.at(i)->fileName())) + m_pendingDocuments.remove(i); + else + ++i; + } + foreach (const QString &file, files) m_searchList.remove(file); } @@ -82,6 +126,8 @@ static bool compareLexigraphically(const Locator::FilterEntry &a, QList CppLocatorFilter::matchesFor(QFutureInterface &future, const QString &origEntry) { + flushPendingDocument(true); + QString entry = trimWildcards(origEntry); QList goodEntries; QList betterEntries; @@ -140,7 +186,5 @@ void CppLocatorFilter::accept(Locator::FilterEntry selection) const void CppLocatorFilter::reset() { m_searchList.clear(); - m_previousResults.clear(); m_previousEntry.clear(); - m_forceNewSearchList = true; } diff --git a/src/plugins/cpptools/cpplocatorfilter.h b/src/plugins/cpptools/cpplocatorfilter.h index 82ec1458714..92eda5dbdb6 100644 --- a/src/plugins/cpptools/cpplocatorfilter.h +++ b/src/plugins/cpptools/cpplocatorfilter.h @@ -55,17 +55,20 @@ public: protected: SearchSymbols search; + void flushPendingDocument(bool force); + private slots: - void onDocumentUpdated(CPlusPlus::Document::Ptr doc); + void onDocumentUpdated(CPlusPlus::Document::Ptr updatedDoc); void onAboutToRemoveFiles(const QStringList &files); private: CppModelManager *m_manager; QHash > m_searchList; - QList m_previousResults; QString m_previousEntry; - bool m_forceNewSearchList; + + mutable QMutex m_pendingDocumentsMutex; + QVector m_pendingDocuments; }; } // namespace Internal diff --git a/src/plugins/cpptools/searchsymbols.cpp b/src/plugins/cpptools/searchsymbols.cpp index 9641d70b064..fe2851c3701 100644 --- a/src/plugins/cpptools/searchsymbols.cpp +++ b/src/plugins/cpptools/searchsymbols.cpp @@ -60,10 +60,11 @@ void SearchSymbols::setSeparateScope(bool separateScope) this->separateScope = separateScope; } -QList SearchSymbols::operator()(Document::Ptr doc, const QString &scope) +QList SearchSymbols::operator()(Document::Ptr doc, int sizeHint, const QString &scope) { QString previousScope = switchScope(scope); items.clear(); + items.reserve(sizeHint); for (unsigned i = 0; i < doc->globalSymbolCount(); ++i) { accept(doc->globalSymbolAt(i)); } diff --git a/src/plugins/cpptools/searchsymbols.h b/src/plugins/cpptools/searchsymbols.h index b29c0c00fb6..fe019b8dbca 100644 --- a/src/plugins/cpptools/searchsymbols.h +++ b/src/plugins/cpptools/searchsymbols.h @@ -99,7 +99,7 @@ struct CPPTOOLS_EXPORT ModelItemInfo int column; }; -class SearchSymbols: public std::unary_function >, +class SearchSymbols: public std::binary_function >, protected CPlusPlus::SymbolVisitor { public: @@ -112,10 +112,10 @@ public: void setSymbolsToSearchFor(SymbolTypes types); void setSeparateScope(bool separateScope); - QList operator()(CPlusPlus::Document::Ptr doc) - { return operator()(doc, QString()); } + QList operator()(CPlusPlus::Document::Ptr doc, int sizeHint = 500) + { return operator()(doc, sizeHint, QString()); } - QList operator()(CPlusPlus::Document::Ptr doc, const QString &scope); + QList operator()(CPlusPlus::Document::Ptr doc, int sizeHint, const QString &scope); protected: using SymbolVisitor::visit;