forked from qt-creator/qt-creator
Session: Get rid of cache of all project file names
Make the project responsible to provide information on which files belong to it instead. Change-Id: I80accf9104af33eaffc6b8f3e6024e9725697d37 Reviewed-by: Eike Ziller <eike.ziller@qt.io>
This commit is contained in:
@@ -57,10 +57,8 @@ void CurrentProjectFilter::prepareSearch(const QString &entry)
|
|||||||
Q_UNUSED(entry)
|
Q_UNUSED(entry)
|
||||||
if (!fileIterator()) {
|
if (!fileIterator()) {
|
||||||
QStringList paths;
|
QStringList paths;
|
||||||
if (m_project) {
|
if (m_project)
|
||||||
paths = Utils::transform(m_project->files(Project::AllFiles), &Utils::FileName::toString);
|
paths = Utils::transform(m_project->files(Project::AllFiles), &Utils::FileName::toString);
|
||||||
Utils::sort(paths);
|
|
||||||
}
|
|
||||||
setFileIterator(new BaseFileFilter::ListIterator(paths));
|
setFileIterator(new BaseFileFilter::ListIterator(paths));
|
||||||
}
|
}
|
||||||
BaseFileFilter::prepareSearch(entry);
|
BaseFileFilter::prepareSearch(entry);
|
||||||
|
@@ -48,6 +48,7 @@
|
|||||||
#include <projectexplorer/projecttree.h>
|
#include <projectexplorer/projecttree.h>
|
||||||
|
|
||||||
#include <utils/algorithm.h>
|
#include <utils/algorithm.h>
|
||||||
|
#include <utils/asconst.h>
|
||||||
#include <utils/macroexpander.h>
|
#include <utils/macroexpander.h>
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
|
|
||||||
@@ -91,6 +92,11 @@ static bool isListedFileNode(const Node *node)
|
|||||||
return node->nodeType() == NodeType::File && node->listInProject();
|
return node->nodeType() == NodeType::File && node->listInProject();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool nodeLessThan(const Node *n1, const Node *n2)
|
||||||
|
{
|
||||||
|
return n1->filePath() < n2->filePath();
|
||||||
|
}
|
||||||
|
|
||||||
const Project::NodeMatcher Project::AllFiles = [](const Node *node) {
|
const Project::NodeMatcher Project::AllFiles = [](const Node *node) {
|
||||||
return isListedFileNode(node);
|
return isListedFileNode(node);
|
||||||
};
|
};
|
||||||
@@ -172,6 +178,7 @@ public:
|
|||||||
Kit::Predicate m_preferredKitPredicate;
|
Kit::Predicate m_preferredKitPredicate;
|
||||||
|
|
||||||
Utils::MacroExpander m_macroExpander;
|
Utils::MacroExpander m_macroExpander;
|
||||||
|
mutable QVector<const Node *> m_sortedNodeList;
|
||||||
};
|
};
|
||||||
|
|
||||||
ProjectPrivate::~ProjectPrivate()
|
ProjectPrivate::~ProjectPrivate()
|
||||||
@@ -520,11 +527,21 @@ void Project::setRootProjectNode(ProjectNode *root)
|
|||||||
ProjectNode *oldNode = d->m_rootProjectNode;
|
ProjectNode *oldNode = d->m_rootProjectNode;
|
||||||
d->m_rootProjectNode = root;
|
d->m_rootProjectNode = root;
|
||||||
if (root) {
|
if (root) {
|
||||||
|
QVector<const Node *> nodeList;
|
||||||
|
root->forEachGenericNode([&nodeList](const Node *n) {
|
||||||
|
nodeList.append(n);
|
||||||
|
});
|
||||||
|
Utils::sort(nodeList, &nodeLessThan);
|
||||||
|
d->m_sortedNodeList = nodeList;
|
||||||
root->setParentFolderNode(d->m_containerNode.get());
|
root->setParentFolderNode(d->m_containerNode.get());
|
||||||
// Only announce non-null root, null is only used when project is destroyed.
|
// Only announce non-null root, null is only used when project is destroyed.
|
||||||
// In that case SessionManager::projectRemoved() triggers the update.
|
// In that case SessionManager::projectRemoved() triggers the update.
|
||||||
ProjectTree::emitSubtreeChanged(root);
|
ProjectTree::emitSubtreeChanged(root);
|
||||||
emit fileListChanged();
|
emit fileListChanged();
|
||||||
|
} else {
|
||||||
|
d->m_sortedNodeList.clear();
|
||||||
|
if (oldNode != nullptr)
|
||||||
|
emit fileListChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
delete oldNode;
|
delete oldNode;
|
||||||
@@ -574,6 +591,9 @@ Project::RestoreResult Project::restoreSettings(QString *errorMessage)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Returns a sorted list of all files matching the predicate \a filter.
|
||||||
|
*/
|
||||||
Utils::FileNameList Project::files(const Project::NodeMatcher &filter) const
|
Utils::FileNameList Project::files(const Project::NodeMatcher &filter) const
|
||||||
{
|
{
|
||||||
Utils::FileNameList result;
|
Utils::FileNameList result;
|
||||||
@@ -581,19 +601,19 @@ Utils::FileNameList Project::files(const Project::NodeMatcher &filter) const
|
|||||||
if (!rootProjectNode())
|
if (!rootProjectNode())
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
QSet<Utils::FileName> alreadySeen;
|
Utils::FileName lastAdded;
|
||||||
rootProjectNode()->forEachGenericNode([&](const Node *n) {
|
for (const Node *n : Utils::asConst(d->m_sortedNodeList)) {
|
||||||
if (filter && !filter(n))
|
if (filter && !filter(n))
|
||||||
return;
|
continue;
|
||||||
|
|
||||||
|
// Remove duplicates:
|
||||||
const Utils::FileName path = n->filePath();
|
const Utils::FileName path = n->filePath();
|
||||||
const int count = alreadySeen.count();
|
if (path == lastAdded)
|
||||||
alreadySeen.insert(path);
|
continue; // skip duplicates
|
||||||
if (count == alreadySeen.count())
|
lastAdded = path;
|
||||||
return; // skip duplicates
|
|
||||||
|
|
||||||
result.append(path);
|
result.append(path);
|
||||||
});
|
};
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -715,6 +735,14 @@ QStringList Project::filesGeneratedFrom(const QString &file) const
|
|||||||
return QStringList();
|
return QStringList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Project::isKnownFile(const Utils::FileName &filename) const
|
||||||
|
{
|
||||||
|
const auto end = std::end(d->m_sortedNodeList);
|
||||||
|
const FileNode element(filename, FileType::Unknown, false);
|
||||||
|
const auto it = std::lower_bound(std::begin(d->m_sortedNodeList), end, &element, &nodeLessThan);
|
||||||
|
return (it == end) ? false : (*it)->filePath() != filename;
|
||||||
|
}
|
||||||
|
|
||||||
void Project::setProjectContext(Core::Context context)
|
void Project::setProjectContext(Core::Context context)
|
||||||
{
|
{
|
||||||
if (d->m_projectContext == context)
|
if (d->m_projectContext == context)
|
||||||
|
@@ -137,6 +137,7 @@ public:
|
|||||||
|
|
||||||
Utils::FileNameList files(const NodeMatcher &matcher) const;
|
Utils::FileNameList files(const NodeMatcher &matcher) const;
|
||||||
virtual QStringList filesGeneratedFrom(const QString &sourceFile) const;
|
virtual QStringList filesGeneratedFrom(const QString &sourceFile) const;
|
||||||
|
bool isKnownFile(const Utils::FileName &filename) const;
|
||||||
|
|
||||||
static QString makeUnique(const QString &preferredName, const QStringList &usedNames);
|
static QString makeUnique(const QString &preferredName, const QStringList &usedNames);
|
||||||
|
|
||||||
|
@@ -101,8 +101,6 @@ public:
|
|||||||
mutable QStringList m_sessions;
|
mutable QStringList m_sessions;
|
||||||
mutable QHash<QString, QDateTime> m_sessionDateTimes;
|
mutable QHash<QString, QDateTime> m_sessionDateTimes;
|
||||||
|
|
||||||
mutable QHash<Project *, QStringList> m_projectFileCache;
|
|
||||||
|
|
||||||
Project *m_startupProject = nullptr;
|
Project *m_startupProject = nullptr;
|
||||||
QList<Project *> m_projects;
|
QList<Project *> m_projects;
|
||||||
QStringList m_failedProjects;
|
QStringList m_failedProjects;
|
||||||
@@ -178,17 +176,6 @@ void SessionManager::saveActiveMode(Id mode)
|
|||||||
setValue(QLatin1String("ActiveMode"), mode.toString());
|
setValue(QLatin1String("ActiveMode"), mode.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
void SessionManager::clearProjectFileCache()
|
|
||||||
{
|
|
||||||
// If triggered by the fileListChanged signal of one project
|
|
||||||
// only invalidate cache for this project
|
|
||||||
auto pro = qobject_cast<Project*>(m_instance->sender());
|
|
||||||
if (pro)
|
|
||||||
d->m_projectFileCache.remove(pro);
|
|
||||||
else
|
|
||||||
d->m_projectFileCache.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SessionManagerPrivate::recursiveDependencyCheck(const QString &newDep, const QString &checkDep) const
|
bool SessionManagerPrivate::recursiveDependencyCheck(const QString &newDep, const QString &checkDep) const
|
||||||
{
|
{
|
||||||
if (newDep == checkDep)
|
if (newDep == checkDep)
|
||||||
@@ -388,7 +375,6 @@ void SessionManager::addProject(Project *pro)
|
|||||||
|
|
||||||
d->m_projects.append(pro);
|
d->m_projects.append(pro);
|
||||||
|
|
||||||
connect(pro, &Project::fileListChanged, m_instance, &SessionManager::clearProjectFileCache);
|
|
||||||
connect(pro, &Project::displayNameChanged,
|
connect(pro, &Project::displayNameChanged,
|
||||||
m_instance, [pro]() { m_instance->projectDisplayNameChanged(pro); });
|
m_instance, [pro]() { m_instance->projectDisplayNameChanged(pro); });
|
||||||
|
|
||||||
@@ -689,10 +675,7 @@ Project *SessionManager::projectForFile(const Utils::FileName &fileName)
|
|||||||
|
|
||||||
bool SessionManager::projectContainsFile(Project *p, const Utils::FileName &fileName)
|
bool SessionManager::projectContainsFile(Project *p, const Utils::FileName &fileName)
|
||||||
{
|
{
|
||||||
if (!d->m_projectFileCache.contains(p))
|
return p && p->isKnownFile(fileName);
|
||||||
d->m_projectFileCache.insert(p, Utils::transform(p->files(Project::AllFiles), &Utils::FileName::toString));
|
|
||||||
|
|
||||||
return d->m_projectFileCache.value(p).contains(fileName.toString());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SessionManager::configureEditor(IEditor *editor, const QString &fileName)
|
void SessionManager::configureEditor(IEditor *editor, const QString &fileName)
|
||||||
@@ -757,9 +740,6 @@ void SessionManager::removeProjects(const QList<Project *> &remove)
|
|||||||
if (pro == d->m_startupProject)
|
if (pro == d->m_startupProject)
|
||||||
changeStartupProject = true;
|
changeStartupProject = true;
|
||||||
|
|
||||||
disconnect(pro, &Project::fileListChanged,
|
|
||||||
m_instance, &SessionManager::clearProjectFileCache);
|
|
||||||
d->m_projectFileCache.remove(pro);
|
|
||||||
emit m_instance->projectRemoved(pro);
|
emit m_instance->projectRemoved(pro);
|
||||||
FolderNavigationWidgetFactory::removeRootDirectory(projectFolderId(pro));
|
FolderNavigationWidgetFactory::removeRootDirectory(projectFolderId(pro));
|
||||||
}
|
}
|
||||||
|
@@ -140,7 +140,6 @@ signals: // for tests only
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
static void saveActiveMode(Core::Id mode);
|
static void saveActiveMode(Core::Id mode);
|
||||||
void clearProjectFileCache();
|
|
||||||
static void configureEditor(Core::IEditor *editor, const QString &fileName);
|
static void configureEditor(Core::IEditor *editor, const QString &fileName);
|
||||||
static void markSessionFileDirty(bool makeDefaultVirginDirty = true);
|
static void markSessionFileDirty(bool makeDefaultVirginDirty = true);
|
||||||
static void configureEditors(Project *project);
|
static void configureEditors(Project *project);
|
||||||
|
Reference in New Issue
Block a user