forked from qt-creator/qt-creator
Clang: Reduce database accesses
If we prefetch data from the database to the caches we reduce the database transaction calls which are quite expensive. Change-Id: I617a0d886807402e0a94291a913a77f989970b55 Reviewed-by: Tim Jenssen <tim.jenssen@qt.io>
This commit is contained in:
@@ -46,8 +46,11 @@
|
||||
#include <utils/algorithm.h>
|
||||
#include <utils/namevalueitem.h>
|
||||
|
||||
#include <QDirIterator>
|
||||
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <iostream>
|
||||
|
||||
namespace ClangPchManager {
|
||||
|
||||
@@ -68,6 +71,7 @@ void ProjectUpdater::updateProjectParts(const std::vector<CppTools::ProjectPart
|
||||
Utils::SmallStringVector &&toolChainArguments)
|
||||
{
|
||||
addProjectFilesToFilePathCache(projectParts);
|
||||
fetchProjectPartIds(projectParts);
|
||||
|
||||
m_server.updateProjectParts(
|
||||
ClangBackEnd::UpdateProjectPartsMessage{toProjectPartContainers(projectParts),
|
||||
@@ -237,7 +241,7 @@ void updateWithSettings(ClangBackEnd::CompilerMacros ¯os,
|
||||
} // namespace
|
||||
|
||||
ClangBackEnd::CompilerMacros ProjectUpdater::createCompilerMacros(
|
||||
const ProjectExplorer::Macros &projectMacros, Utils::NameValueItems &&settingsMacros) const
|
||||
const ProjectExplorer::Macros &projectMacros, Utils::NameValueItems &&settingsMacros)
|
||||
{
|
||||
int index = 0;
|
||||
auto macros = Utils::transform<ClangBackEnd::CompilerMacros>(
|
||||
@@ -347,10 +351,10 @@ ClangBackEnd::ProjectPartContainer ProjectUpdater::toProjectPartContainer(
|
||||
|
||||
auto includeSearchPaths = createIncludeSearchPaths(*projectPart);
|
||||
|
||||
const QByteArray projectPartName = projectPart->id().toUtf8();
|
||||
|
||||
ClangBackEnd::ProjectPartId projectPartId = m_projectPartsStorage.fetchProjectPartId(
|
||||
projectPartName);
|
||||
ClangBackEnd::ProjectPartId projectPartId = m_projectPartIdCache.stringId(
|
||||
Utils::PathString{projectPart->id()}, [&](Utils::SmallStringView projectPartName) {
|
||||
return m_projectPartsStorage.fetchProjectPartId(projectPartName);
|
||||
});
|
||||
|
||||
ClangIndexingProjectSettings *settings = m_settingsManager.settings(projectPart->project);
|
||||
|
||||
@@ -415,36 +419,31 @@ ClangBackEnd::FilePaths ProjectUpdater::createExcludedPaths(
|
||||
|
||||
QString ProjectUpdater::fetchProjectPartName(ClangBackEnd::ProjectPartId projectPartId) const
|
||||
{
|
||||
return m_projectPartsStorage.fetchProjectPartName(projectPartId).toQString();
|
||||
return QString(m_projectPartIdCache.string(projectPartId.projectPathId,
|
||||
[&](ClangBackEnd::ProjectPartId projectPartId) {
|
||||
return m_projectPartsStorage.fetchProjectPartName(
|
||||
projectPartId);
|
||||
}));
|
||||
}
|
||||
|
||||
ClangBackEnd::ProjectPartIds ProjectUpdater::toProjectPartIds(
|
||||
const QStringList &projectPartNames) const
|
||||
const QStringList &projectPartNamesAsQString) const
|
||||
{
|
||||
ClangBackEnd::ProjectPartIds projectPartIds;
|
||||
projectPartIds.reserve(projectPartIds.size());
|
||||
|
||||
std::transform(projectPartNames.begin(),
|
||||
projectPartNames.end(),
|
||||
std::back_inserter(projectPartIds),
|
||||
[&](const QString &projectPartName) {
|
||||
return m_projectPartsStorage.fetchProjectPartId(
|
||||
Utils::SmallString{projectPartName});
|
||||
});
|
||||
auto projectPartNames = Utils::transform<std::vector<Utils::PathString>>(
|
||||
projectPartNamesAsQString, [&](const QString &projectPartName) { return projectPartName; });
|
||||
|
||||
return projectPartIds;
|
||||
return m_projectPartIdCache.stringIds(projectPartNames, [&](Utils::SmallStringView projectPartName) {
|
||||
return m_projectPartsStorage.fetchProjectPartId(projectPartName);
|
||||
});
|
||||
}
|
||||
|
||||
void ProjectUpdater::addProjectFilesToFilePathCache(const std::vector<CppTools::ProjectPart *> &projectParts)
|
||||
{
|
||||
std::size_t fileCount = std::accumulate(projectParts.begin(),
|
||||
projectParts.end(),
|
||||
std::size_t(0),
|
||||
[](std::size_t value, CppTools::ProjectPart *projectPart) {
|
||||
return value + std::size_t(projectPart->files.size());
|
||||
});
|
||||
ClangBackEnd::FilePaths filePaths;
|
||||
filePaths.reserve(fileCount);
|
||||
filePaths.reserve(10000);
|
||||
|
||||
for (CppTools::ProjectPart *projectPart : projectParts) {
|
||||
for (const CppTools::ProjectFile &file : projectPart->files)
|
||||
@@ -455,4 +454,28 @@ void ProjectUpdater::addProjectFilesToFilePathCache(const std::vector<CppTools::
|
||||
m_filePathCache.addFilePaths(filePaths);
|
||||
}
|
||||
|
||||
void ProjectUpdater::fetchProjectPartIds(const std::vector<CppTools::ProjectPart *> &projectParts)
|
||||
{
|
||||
std::unique_ptr<Sqlite::DeferredTransaction> transaction;
|
||||
|
||||
auto projectPartNames = Utils::transform<std::vector<Utils::PathString>>(
|
||||
projectParts, [](CppTools::ProjectPart *projectPart) { return projectPart->id(); });
|
||||
|
||||
auto projectPartNameViews = Utils::transform<std::vector<Utils::SmallStringView>>(
|
||||
projectPartNames,
|
||||
[](const Utils::PathString &projectPartName) { return projectPartName.toStringView(); });
|
||||
|
||||
m_projectPartIdCache
|
||||
.addStrings(std::move(projectPartNameViews), [&](Utils::SmallStringView projectPartName) {
|
||||
if (!transaction)
|
||||
transaction = std::make_unique<Sqlite::DeferredTransaction>(
|
||||
m_projectPartsStorage.transactionBackend());
|
||||
return m_projectPartsStorage.fetchProjectPartIdUnguarded(projectPartName);
|
||||
});
|
||||
|
||||
if (transaction)
|
||||
transaction->commit();
|
||||
|
||||
} // namespace ClangPchManager
|
||||
|
||||
} // namespace ClangPchManager
|
||||
|
||||
@@ -34,6 +34,8 @@
|
||||
#include <includesearchpath.h>
|
||||
#include <projectpartcontainer.h>
|
||||
#include <projectpartsstorageinterface.h>
|
||||
#include <projectpartstoragestructs.h>
|
||||
#include <stringcache.h>
|
||||
|
||||
#include <projectexplorer/headerpath.h>
|
||||
|
||||
@@ -66,6 +68,14 @@ class ClangIndexingProjectSettings;
|
||||
|
||||
class CLANGPCHMANAGER_EXPORT ProjectUpdater
|
||||
{
|
||||
using StringCache = ClangBackEnd::StringCache<Utils::PathString,
|
||||
Utils::SmallStringView,
|
||||
ClangBackEnd::ProjectPartId,
|
||||
ClangBackEnd::NonLockingMutex,
|
||||
decltype(&Utils::reverseCompare),
|
||||
Utils::reverseCompare,
|
||||
ClangBackEnd::Internal::ProjectPartNameId>;
|
||||
|
||||
public:
|
||||
struct SystemAndProjectIncludeSearchPaths
|
||||
{
|
||||
@@ -77,11 +87,13 @@ public:
|
||||
ClangBackEnd::FilePathCachingInterface &filePathCache,
|
||||
ClangBackEnd::ProjectPartsStorageInterface &projectPartsStorage,
|
||||
ClangIndexingSettingsManager &settingsManager)
|
||||
: m_server(server)
|
||||
, m_filePathCache(filePathCache)
|
||||
: m_filePathCache(filePathCache)
|
||||
, m_server(server)
|
||||
, m_projectPartsStorage(projectPartsStorage)
|
||||
, m_settingsManager(settingsManager)
|
||||
{}
|
||||
{
|
||||
m_projectPartIdCache.populate(m_projectPartsStorage.fetchAllProjectPartNamesAndIds());
|
||||
}
|
||||
|
||||
void updateProjectParts(const std::vector<CppTools::ProjectPart *> &projectParts,
|
||||
Utils::SmallStringVector &&toolChainArguments);
|
||||
@@ -104,8 +116,8 @@ public:
|
||||
void addToHeaderAndSources(HeaderAndSources &headerAndSources,
|
||||
const CppTools::ProjectFile &projectFile) const;
|
||||
static QStringList toolChainArguments(CppTools::ProjectPart *projectPart);
|
||||
ClangBackEnd::CompilerMacros createCompilerMacros(const ProjectExplorer::Macros &projectMacros,
|
||||
Utils::NameValueItems &&settingsMacros) const;
|
||||
static ClangBackEnd::CompilerMacros createCompilerMacros(const ProjectExplorer::Macros &projectMacros,
|
||||
Utils::NameValueItems &&settingsMacros);
|
||||
static SystemAndProjectIncludeSearchPaths createIncludeSearchPaths(
|
||||
const CppTools::ProjectPart &projectPart);
|
||||
static ClangBackEnd::FilePaths createExcludedPaths(
|
||||
@@ -115,16 +127,19 @@ public:
|
||||
|
||||
ClangBackEnd::ProjectPartIds toProjectPartIds(const QStringList &projectPartNames) const;
|
||||
|
||||
private:
|
||||
void addProjectFilesToFilePathCache(const std::vector<CppTools::ProjectPart *> &projectParts);
|
||||
void fetchProjectPartIds(const std::vector<CppTools::ProjectPart *> &projectParts);
|
||||
|
||||
protected:
|
||||
ClangBackEnd::FilePathCachingInterface &m_filePathCache;
|
||||
|
||||
private:
|
||||
ClangBackEnd::GeneratedFiles m_generatedFiles;
|
||||
ClangBackEnd::FilePaths m_excludedPaths;
|
||||
ClangBackEnd::ProjectManagementServerInterface &m_server;
|
||||
ClangBackEnd::FilePathCachingInterface &m_filePathCache;
|
||||
ClangBackEnd::ProjectPartsStorageInterface &m_projectPartsStorage;
|
||||
ClangIndexingSettingsManager &m_settingsManager;
|
||||
mutable StringCache m_projectPartIdCache;
|
||||
};
|
||||
|
||||
} // namespace ClangPchManager
|
||||
|
||||
@@ -29,6 +29,8 @@
|
||||
|
||||
#include <projectexplorer/project.h>
|
||||
|
||||
#include <filepathcachinginterface.h>
|
||||
|
||||
namespace ClangPchManager {
|
||||
|
||||
namespace Internal {
|
||||
@@ -38,16 +40,21 @@ CppTools::CppModelManager *cppModelManager()
|
||||
return CppTools::CppModelManager::instance();
|
||||
}
|
||||
|
||||
std::vector<ClangBackEnd::V2::FileContainer> createGeneratedFiles()
|
||||
std::vector<ClangBackEnd::V2::FileContainer> createGeneratedFiles(
|
||||
ClangBackEnd::FilePathCachingInterface &filePathCache)
|
||||
{
|
||||
auto abstractEditors = CppTools::CppModelManager::instance()->abstractEditorSupports();
|
||||
std::vector<ClangBackEnd::V2::FileContainer> generatedFiles;
|
||||
generatedFiles.reserve(std::size_t(abstractEditors.size()));
|
||||
|
||||
auto toFileContainer = [] (const CppTools::AbstractEditorSupport *abstractEditor) {
|
||||
return ClangBackEnd::V2::FileContainer(ClangBackEnd::FilePath(abstractEditor->fileName()),
|
||||
Utils::SmallString::fromQByteArray(abstractEditor->contents()),
|
||||
{});
|
||||
auto toFileContainer = [&](const CppTools::AbstractEditorSupport *abstractEditor) {
|
||||
ClangBackEnd::FilePath filePath(abstractEditor->fileName());
|
||||
ClangBackEnd::FilePathId filePathId = filePathCache.filePathId(filePath);
|
||||
return ClangBackEnd::V2::FileContainer(std::move(filePath),
|
||||
filePathId,
|
||||
Utils::SmallString::fromQByteArray(
|
||||
abstractEditor->contents()),
|
||||
{});
|
||||
};
|
||||
|
||||
std::transform(abstractEditors.begin(),
|
||||
|
||||
@@ -32,6 +32,8 @@
|
||||
|
||||
#include <filecontainerv2.h>
|
||||
|
||||
#include <utils/algorithm.h>
|
||||
|
||||
#include <QObject>
|
||||
|
||||
namespace ProjectExplorer {
|
||||
@@ -46,7 +48,8 @@ namespace ClangPchManager {
|
||||
|
||||
namespace Internal {
|
||||
CLANGPCHMANAGER_EXPORT CppTools::CppModelManager *cppModelManager();
|
||||
CLANGPCHMANAGER_EXPORT std::vector<ClangBackEnd::V2::FileContainer> createGeneratedFiles();
|
||||
CLANGPCHMANAGER_EXPORT std::vector<ClangBackEnd::V2::FileContainer> createGeneratedFiles(
|
||||
ClangBackEnd::FilePathCachingInterface &filePathCache);
|
||||
CLANGPCHMANAGER_EXPORT std::vector<CppTools::ProjectPart*> createProjectParts(ProjectExplorer::Project *project);
|
||||
}
|
||||
|
||||
@@ -83,9 +86,13 @@ public:
|
||||
ProjectUpdaterType::removeProjectParts(projectPartIds);
|
||||
}
|
||||
|
||||
void abstractEditorUpdated(const QString &filePath, const QByteArray &contents)
|
||||
void abstractEditorUpdated(const QString &qFilePath, const QByteArray &contents)
|
||||
{
|
||||
ProjectUpdaterType::updateGeneratedFiles({{ClangBackEnd::FilePath{filePath}, contents}});
|
||||
ClangBackEnd::FilePath filePath{qFilePath};
|
||||
ClangBackEnd::FilePathId filePathId = ProjectUpdaterType::m_filePathCache.filePathId(
|
||||
filePath);
|
||||
|
||||
ProjectUpdaterType::updateGeneratedFiles({{std::move(filePath), filePathId, contents}});
|
||||
}
|
||||
|
||||
void abstractEditorRemoved(const QString &filePath)
|
||||
@@ -98,6 +105,14 @@ protected:
|
||||
const Utils::FilePath &,
|
||||
const Utils::FilePathList &targets) override
|
||||
{
|
||||
auto filePaths = Utils::transform<ClangBackEnd::FilePaths>(targets,
|
||||
[](const Utils::FilePath &filePath) {
|
||||
return ClangBackEnd::FilePath{
|
||||
filePath.toString()};
|
||||
});
|
||||
|
||||
ProjectUpdater::m_filePathCache.addFilePaths(filePaths);
|
||||
|
||||
for (const Utils::FilePath &target : targets)
|
||||
abstractEditorUpdated(target.toString(), {});
|
||||
}
|
||||
@@ -105,7 +120,8 @@ protected:
|
||||
private:
|
||||
void connectToCppModelManager()
|
||||
{
|
||||
ProjectUpdaterType::updateGeneratedFiles(Internal::createGeneratedFiles());
|
||||
ProjectUpdaterType::updateGeneratedFiles(
|
||||
Internal::createGeneratedFiles(ProjectUpdaterType::m_filePathCache));
|
||||
|
||||
QObject::connect(Internal::cppModelManager(),
|
||||
&CppTools::CppModelManager::projectPartsUpdated,
|
||||
|
||||
Reference in New Issue
Block a user