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 <nikolai.kosjar@digia.com>
Reviewed-by: Eike Ziller <eike.ziller@digia.com>
This commit is contained in:
Erik Verbruggen
2013-02-26 11:14:02 +01:00
committed by Erik Verbruggen
parent e0ba5d955c
commit 45656335fc
4 changed files with 62 additions and 14 deletions

View File

@@ -39,15 +39,19 @@
using namespace CppTools::Internal; using namespace CppTools::Internal;
using namespace Utils; using namespace Utils;
static const int MaxPendingDocuments = 10;
CppLocatorFilter::CppLocatorFilter(CppModelManager *manager) CppLocatorFilter::CppLocatorFilter(CppModelManager *manager)
: m_manager(manager), : m_manager(manager)
m_forceNewSearchList(true) , m_pendingDocumentsMutex(QMutex::Recursive)
{ {
setId("Classes and Methods"); setId("Classes and Methods");
setDisplayName(tr("C++ Classes and Methods")); setDisplayName(tr("C++ Classes and Methods"));
setShortcutString(QString(QLatin1Char(':'))); setShortcutString(QString(QLatin1Char(':')));
setIncludedByDefault(false); setIncludedByDefault(false);
m_pendingDocuments.reserve(MaxPendingDocuments);
connect(manager, SIGNAL(documentUpdated(CPlusPlus::Document::Ptr)), connect(manager, SIGNAL(documentUpdated(CPlusPlus::Document::Ptr)),
this, SLOT(onDocumentUpdated(CPlusPlus::Document::Ptr))); this, SLOT(onDocumentUpdated(CPlusPlus::Document::Ptr)));
@@ -58,13 +62,53 @@ CppLocatorFilter::CppLocatorFilter(CppModelManager *manager)
CppLocatorFilter::~CppLocatorFilter() 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<ModelItemInfo> &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) 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) foreach (const QString &file, files)
m_searchList.remove(file); m_searchList.remove(file);
} }
@@ -82,6 +126,8 @@ static bool compareLexigraphically(const Locator::FilterEntry &a,
QList<Locator::FilterEntry> CppLocatorFilter::matchesFor(QFutureInterface<Locator::FilterEntry> &future, const QString &origEntry) QList<Locator::FilterEntry> CppLocatorFilter::matchesFor(QFutureInterface<Locator::FilterEntry> &future, const QString &origEntry)
{ {
flushPendingDocument(true);
QString entry = trimWildcards(origEntry); QString entry = trimWildcards(origEntry);
QList<Locator::FilterEntry> goodEntries; QList<Locator::FilterEntry> goodEntries;
QList<Locator::FilterEntry> betterEntries; QList<Locator::FilterEntry> betterEntries;
@@ -140,7 +186,5 @@ void CppLocatorFilter::accept(Locator::FilterEntry selection) const
void CppLocatorFilter::reset() void CppLocatorFilter::reset()
{ {
m_searchList.clear(); m_searchList.clear();
m_previousResults.clear();
m_previousEntry.clear(); m_previousEntry.clear();
m_forceNewSearchList = true;
} }

View File

@@ -55,17 +55,20 @@ public:
protected: protected:
SearchSymbols search; SearchSymbols search;
void flushPendingDocument(bool force);
private slots: private slots:
void onDocumentUpdated(CPlusPlus::Document::Ptr doc); void onDocumentUpdated(CPlusPlus::Document::Ptr updatedDoc);
void onAboutToRemoveFiles(const QStringList &files); void onAboutToRemoveFiles(const QStringList &files);
private: private:
CppModelManager *m_manager; CppModelManager *m_manager;
QHash<QString, QList<ModelItemInfo> > m_searchList; QHash<QString, QList<ModelItemInfo> > m_searchList;
QList<ModelItemInfo> m_previousResults;
QString m_previousEntry; QString m_previousEntry;
bool m_forceNewSearchList;
mutable QMutex m_pendingDocumentsMutex;
QVector<CPlusPlus::Document::Ptr> m_pendingDocuments;
}; };
} // namespace Internal } // namespace Internal

View File

@@ -60,10 +60,11 @@ void SearchSymbols::setSeparateScope(bool separateScope)
this->separateScope = separateScope; this->separateScope = separateScope;
} }
QList<ModelItemInfo> SearchSymbols::operator()(Document::Ptr doc, const QString &scope) QList<ModelItemInfo> SearchSymbols::operator()(Document::Ptr doc, int sizeHint, const QString &scope)
{ {
QString previousScope = switchScope(scope); QString previousScope = switchScope(scope);
items.clear(); items.clear();
items.reserve(sizeHint);
for (unsigned i = 0; i < doc->globalSymbolCount(); ++i) { for (unsigned i = 0; i < doc->globalSymbolCount(); ++i) {
accept(doc->globalSymbolAt(i)); accept(doc->globalSymbolAt(i));
} }

View File

@@ -99,7 +99,7 @@ struct CPPTOOLS_EXPORT ModelItemInfo
int column; int column;
}; };
class SearchSymbols: public std::unary_function<CPlusPlus::Document::Ptr, QList<ModelItemInfo> >, class SearchSymbols: public std::binary_function<CPlusPlus::Document::Ptr, int, QList<ModelItemInfo> >,
protected CPlusPlus::SymbolVisitor protected CPlusPlus::SymbolVisitor
{ {
public: public:
@@ -112,10 +112,10 @@ public:
void setSymbolsToSearchFor(SymbolTypes types); void setSymbolsToSearchFor(SymbolTypes types);
void setSeparateScope(bool separateScope); void setSeparateScope(bool separateScope);
QList<ModelItemInfo> operator()(CPlusPlus::Document::Ptr doc) QList<ModelItemInfo> operator()(CPlusPlus::Document::Ptr doc, int sizeHint = 500)
{ return operator()(doc, QString()); } { return operator()(doc, sizeHint, QString()); }
QList<ModelItemInfo> operator()(CPlusPlus::Document::Ptr doc, const QString &scope); QList<ModelItemInfo> operator()(CPlusPlus::Document::Ptr doc, int sizeHint, const QString &scope);
protected: protected:
using SymbolVisitor::visit; using SymbolVisitor::visit;