forked from qt-creator/qt-creator
Clang: Reuse thread based pipeline for pch creation
The pch creation so far used signal and slots but there was no explicit pipeline. This patch is introducing the same architecture like the refactoring plugin. It is filtering out older project parts from the pipeline. Change-Id: Iaa6bd2ca1272231b97ebe1f5f7b2ce8e43bc590c Task-number: QTCREATORBUG-21111 Reviewed-by: Ivan Donchevskii <ivan.donchevskii@qt.io>
This commit is contained in:
@@ -24,11 +24,7 @@ HEADERS += \
|
||||
$$PWD/indexdataconsumer.h \
|
||||
$$PWD/sourcesmanager.h \
|
||||
$$PWD/symbolindexertaskqueue.h \
|
||||
$$PWD/symbolindexertaskscheduler.h \
|
||||
$$PWD/symbolscollectormanagerinterface.h \
|
||||
$$PWD/symbolindexertaskqueueinterface.h \
|
||||
$$PWD/symbolindexertaskschedulerinterface.h \
|
||||
$$PWD/symbolscollectormanager.h \
|
||||
$$PWD/symbolindexertask.h
|
||||
|
||||
!isEmpty(LIBTOOLING_LIBS) {
|
||||
@@ -74,6 +70,4 @@ SOURCES += \
|
||||
$$PWD/sourcerangefilter.cpp \
|
||||
$$PWD/symbolindexer.cpp \
|
||||
$$PWD/projectpartartefact.cpp \
|
||||
$$PWD/filestatuscache.cpp \
|
||||
$$PWD/symbolindexertaskqueue.cpp \
|
||||
$$PWD/symbolindexertaskscheduler.cpp
|
||||
$$PWD/filestatuscache.cpp
|
||||
|
||||
@@ -101,27 +101,25 @@ void SymbolIndexer::updateProjectPart(V2::ProjectPartContainer &&projectPart)
|
||||
std::vector<SymbolIndexerTask> symbolIndexerTask;
|
||||
symbolIndexerTask.reserve(projectPart.sourcePathIds.size());
|
||||
for (FilePathId sourcePathId : projectPart.sourcePathIds) {
|
||||
auto indexing = [projectPartId, arguments, sourcePathId]
|
||||
(SymbolsCollectorInterface &symbolsCollector,
|
||||
SymbolStorageInterface &symbolStorage,
|
||||
Sqlite::TransactionInterface &transactionInterface) {
|
||||
auto indexing = [projectPartId, arguments, sourcePathId, this]
|
||||
(SymbolsCollectorInterface &symbolsCollector) {
|
||||
symbolsCollector.setFile(sourcePathId, arguments);
|
||||
|
||||
symbolsCollector.collectSymbols();
|
||||
|
||||
Sqlite::ImmediateTransaction transaction{transactionInterface};
|
||||
Sqlite::ImmediateTransaction transaction{m_transactionInterface};
|
||||
|
||||
symbolStorage.addSymbolsAndSourceLocations(symbolsCollector.symbols(),
|
||||
symbolsCollector.sourceLocations());
|
||||
m_symbolStorage.addSymbolsAndSourceLocations(symbolsCollector.symbols(),
|
||||
symbolsCollector.sourceLocations());
|
||||
|
||||
symbolStorage.updateProjectPartSources(projectPartId,
|
||||
symbolsCollector.sourceFiles());
|
||||
m_symbolStorage.updateProjectPartSources(projectPartId,
|
||||
symbolsCollector.sourceFiles());
|
||||
|
||||
symbolStorage.insertOrUpdateUsedMacros(symbolsCollector.usedMacros());
|
||||
m_symbolStorage.insertOrUpdateUsedMacros(symbolsCollector.usedMacros());
|
||||
|
||||
symbolStorage.insertFileStatuses(symbolsCollector.fileStatuses());
|
||||
m_symbolStorage.insertFileStatuses(symbolsCollector.fileStatuses());
|
||||
|
||||
symbolStorage.insertOrUpdateSourceDependencies(symbolsCollector.sourceDependencies());
|
||||
m_symbolStorage.insertOrUpdateSourceDependencies(symbolsCollector.sourceDependencies());
|
||||
|
||||
transaction.commit();
|
||||
};
|
||||
@@ -130,7 +128,7 @@ void SymbolIndexer::updateProjectPart(V2::ProjectPartContainer &&projectPart)
|
||||
}
|
||||
|
||||
m_symbolIndexerTaskQueue.addOrUpdateTasks(std::move(symbolIndexerTask));
|
||||
m_symbolIndexerTaskQueue.processTasks();
|
||||
m_symbolIndexerTaskQueue.processEntries();
|
||||
}
|
||||
|
||||
void SymbolIndexer::pathsWithIdsChanged(const Utils::SmallStringVector &)
|
||||
@@ -146,7 +144,7 @@ void SymbolIndexer::pathsChanged(const FilePathIds &filePathIds)
|
||||
updateChangedPath(filePathId, symbolIndexerTask);
|
||||
|
||||
m_symbolIndexerTaskQueue.addOrUpdateTasks(std::move(symbolIndexerTask));
|
||||
m_symbolIndexerTaskQueue.processTasks();
|
||||
m_symbolIndexerTaskQueue.processEntries();
|
||||
}
|
||||
|
||||
void SymbolIndexer::updateChangedPath(FilePathId filePathId,
|
||||
@@ -169,26 +167,24 @@ void SymbolIndexer::updateChangedPath(FilePathId filePathId,
|
||||
const Utils::SmallStringVector arguments = compilerArguments(artefact.compilerArguments,
|
||||
optionalProjectPartPch);
|
||||
|
||||
auto indexing = [projectPartId=artefact.projectPartId, arguments, filePathId]
|
||||
(SymbolsCollectorInterface &symbolsCollector,
|
||||
SymbolStorageInterface &symbolStorage,
|
||||
Sqlite::TransactionInterface &transactionInterface) {
|
||||
auto indexing = [projectPartId=artefact.projectPartId, arguments, filePathId, this]
|
||||
(SymbolsCollectorInterface &symbolsCollector) {
|
||||
symbolsCollector.setFile(filePathId, arguments);
|
||||
|
||||
symbolsCollector.collectSymbols();
|
||||
|
||||
Sqlite::ImmediateTransaction transaction{transactionInterface};
|
||||
Sqlite::ImmediateTransaction transaction{m_transactionInterface};
|
||||
|
||||
symbolStorage.addSymbolsAndSourceLocations(symbolsCollector.symbols(),
|
||||
symbolsCollector.sourceLocations());
|
||||
m_symbolStorage.addSymbolsAndSourceLocations(symbolsCollector.symbols(),
|
||||
symbolsCollector.sourceLocations());
|
||||
|
||||
symbolStorage.updateProjectPartSources(projectPartId, symbolsCollector.sourceFiles());
|
||||
m_symbolStorage.updateProjectPartSources(projectPartId, symbolsCollector.sourceFiles());
|
||||
|
||||
symbolStorage.insertOrUpdateUsedMacros(symbolsCollector.usedMacros());
|
||||
m_symbolStorage.insertOrUpdateUsedMacros(symbolsCollector.usedMacros());
|
||||
|
||||
symbolStorage.insertFileStatuses(symbolsCollector.fileStatuses());
|
||||
m_symbolStorage.insertFileStatuses(symbolsCollector.fileStatuses());
|
||||
|
||||
symbolStorage.insertOrUpdateSourceDependencies(symbolsCollector.sourceDependencies());
|
||||
m_symbolStorage.insertOrUpdateSourceDependencies(symbolsCollector.sourceDependencies());
|
||||
|
||||
transaction.commit();
|
||||
};
|
||||
|
||||
@@ -35,16 +35,13 @@ class TransactionInterface;
|
||||
|
||||
namespace ClangBackEnd {
|
||||
|
||||
class SymbolIndexerTaskSchedulerInterface;
|
||||
class SymbolsCollectorInterface;
|
||||
class SymbolStorageInterface;
|
||||
|
||||
class SymbolIndexerTask
|
||||
{
|
||||
public:
|
||||
using Callable = std::function<void(SymbolsCollectorInterface &symbolsCollector,
|
||||
SymbolStorageInterface &symbolStorage,
|
||||
Sqlite::TransactionInterface &transaction)>;
|
||||
using Callable = std::function<void(SymbolsCollectorInterface &symbolsCollector)>;
|
||||
|
||||
SymbolIndexerTask(FilePathId filePathId,
|
||||
int projectPartId,
|
||||
|
||||
@@ -1,71 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2018 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "symbolindexertaskqueue.h"
|
||||
|
||||
#include <symbolindexertaskschedulerinterface.h>
|
||||
|
||||
#include <utils/algorithm.h>
|
||||
|
||||
namespace ClangBackEnd {
|
||||
|
||||
void SymbolIndexerTaskQueue::addOrUpdateTasks(std::vector<SymbolIndexerTask> &&tasks)
|
||||
{
|
||||
auto merge = [] (SymbolIndexerTask &&first, SymbolIndexerTask &&second) {
|
||||
first.callable = std::move(second.callable);
|
||||
|
||||
return std::move(first);
|
||||
};
|
||||
|
||||
m_tasks = Utils::setUnionMerge<std::vector<SymbolIndexerTask>>(tasks, m_tasks, merge);
|
||||
}
|
||||
|
||||
void SymbolIndexerTaskQueue::removeTasks(const std::vector<int> &projectPartIds)
|
||||
{
|
||||
auto shouldBeRemoved = [&] (const SymbolIndexerTask& task) {
|
||||
return std::binary_search(projectPartIds.begin(), projectPartIds.end(), task.projectPartId);
|
||||
};
|
||||
|
||||
auto newEnd = std::remove_if(m_tasks.begin(), m_tasks.end(), shouldBeRemoved);
|
||||
|
||||
m_tasks.erase(newEnd, m_tasks.end());
|
||||
}
|
||||
|
||||
const std::vector<SymbolIndexerTask> &SymbolIndexerTaskQueue::tasks() const
|
||||
{
|
||||
return m_tasks;
|
||||
}
|
||||
|
||||
void SymbolIndexerTaskQueue::processTasks()
|
||||
{
|
||||
int taskCount = m_symbolIndexerScheduler.freeSlots();
|
||||
|
||||
auto newEnd = std::prev(m_tasks.end(), std::min<int>(taskCount, int(m_tasks.size())));
|
||||
m_symbolIndexerScheduler.addTasks({std::make_move_iterator(newEnd),
|
||||
std::make_move_iterator(m_tasks.end())});
|
||||
m_tasks.erase(newEnd, m_tasks.end());
|
||||
}
|
||||
|
||||
} // namespace ClangBackEnd
|
||||
@@ -29,7 +29,9 @@
|
||||
#include "symbolindexertask.h"
|
||||
|
||||
#include <filepathid.h>
|
||||
#include <taskschedulerinterface.h>
|
||||
|
||||
#include <utils/algorithm.h>
|
||||
#include <utils/smallstringvector.h>
|
||||
|
||||
#include <functional>
|
||||
@@ -41,29 +43,59 @@ class TransactionInterface;
|
||||
|
||||
namespace ClangBackEnd {
|
||||
|
||||
class SymbolIndexerTaskSchedulerInterface;
|
||||
class SymbolsCollectorInterface;
|
||||
class SymbolStorageInterface;
|
||||
|
||||
class SymbolIndexerTaskQueue final : public SymbolIndexerTaskQueueInterface
|
||||
{
|
||||
public:
|
||||
SymbolIndexerTaskQueue(SymbolIndexerTaskSchedulerInterface &symbolIndexerTaskScheduler)
|
||||
using Task = SymbolIndexerTask::Callable;
|
||||
|
||||
SymbolIndexerTaskQueue(TaskSchedulerInterface<Task> &symbolIndexerTaskScheduler)
|
||||
: m_symbolIndexerScheduler(symbolIndexerTaskScheduler)
|
||||
{}
|
||||
|
||||
void addOrUpdateTasks(std::vector<SymbolIndexerTask> &&tasks);
|
||||
void removeTasks(const std::vector<int> &projectPartIds);
|
||||
void addOrUpdateTasks(std::vector<SymbolIndexerTask> &&tasks)
|
||||
{
|
||||
auto merge = [] (SymbolIndexerTask &&first, SymbolIndexerTask &&second) {
|
||||
first.callable = std::move(second.callable);
|
||||
|
||||
const std::vector<SymbolIndexerTask> &tasks() const;
|
||||
return std::move(first);
|
||||
};
|
||||
|
||||
void processTasks();
|
||||
m_tasks = Utils::setUnionMerge<std::vector<SymbolIndexerTask>>(tasks, m_tasks, merge);
|
||||
}
|
||||
void removeTasks(const std::vector<int> &projectPartIds)
|
||||
{
|
||||
auto shouldBeRemoved = [&] (const SymbolIndexerTask& task) {
|
||||
return std::binary_search(projectPartIds.begin(), projectPartIds.end(), task.projectPartId);
|
||||
};
|
||||
|
||||
auto newEnd = std::remove_if(m_tasks.begin(), m_tasks.end(), shouldBeRemoved);
|
||||
|
||||
m_tasks.erase(newEnd, m_tasks.end());
|
||||
}
|
||||
|
||||
const std::vector<SymbolIndexerTask> &tasks() const
|
||||
{
|
||||
return m_tasks;
|
||||
}
|
||||
|
||||
void processEntries()
|
||||
{
|
||||
uint taskCount = m_symbolIndexerScheduler.freeSlots();
|
||||
|
||||
auto newEnd = std::prev(m_tasks.end(), std::min<int>(int(taskCount), int(m_tasks.size())));
|
||||
m_symbolIndexerScheduler.addTasks({std::make_move_iterator(newEnd),
|
||||
std::make_move_iterator(m_tasks.end())});
|
||||
m_tasks.erase(newEnd, m_tasks.end());
|
||||
}
|
||||
void syncTasks();
|
||||
|
||||
private:
|
||||
std::vector<Utils::SmallString> m_projectPartIds;
|
||||
std::vector<SymbolIndexerTask> m_tasks;
|
||||
SymbolIndexerTaskSchedulerInterface &m_symbolIndexerScheduler;
|
||||
TaskSchedulerInterface<Task> &m_symbolIndexerScheduler;
|
||||
};
|
||||
|
||||
} // namespace ClangBackEnd
|
||||
|
||||
@@ -25,24 +25,21 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <queueinterface.h>
|
||||
|
||||
#include <utils/smallstringvector.h>
|
||||
|
||||
namespace ClangBackEnd {
|
||||
|
||||
class SymbolIndexerTask;
|
||||
|
||||
class SymbolIndexerTaskQueueInterface
|
||||
class SymbolIndexerTaskQueueInterface : public QueueInterface
|
||||
{
|
||||
public:
|
||||
SymbolIndexerTaskQueueInterface() = default;
|
||||
SymbolIndexerTaskQueueInterface(const SymbolIndexerTaskQueueInterface &) = delete;
|
||||
SymbolIndexerTaskQueueInterface &operator=(const SymbolIndexerTaskQueueInterface &) = delete;
|
||||
|
||||
virtual void addOrUpdateTasks(std::vector<SymbolIndexerTask> &&tasks) = 0
|
||||
/* [[expects: std::is_sorted(tasks)]] */;
|
||||
virtual void removeTasks(const std::vector<int> &projectPartIds) = 0
|
||||
/* [[expects: std::is_sorted(projectPartIds)]] */;
|
||||
virtual void processTasks() = 0;
|
||||
|
||||
protected:
|
||||
~SymbolIndexerTaskQueueInterface() = default;
|
||||
|
||||
@@ -1,146 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2018 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "symbolindexertaskscheduler.h"
|
||||
|
||||
#include <symbolindexertaskqueueinterface.h>
|
||||
#include <symbolscollectormanagerinterface.h>
|
||||
#include <symbolscollectorinterface.h>
|
||||
|
||||
#include <QAbstractEventDispatcher>
|
||||
#include <QCoreApplication>
|
||||
#include <QMetaObject>
|
||||
#include <QThread>
|
||||
|
||||
#include <algorithm>
|
||||
#include <thread>
|
||||
|
||||
namespace ClangBackEnd {
|
||||
namespace {
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 10, 0)
|
||||
template <typename CallableType>
|
||||
class CallableEvent : public QEvent {
|
||||
public:
|
||||
using Callable = std::decay_t<CallableType>;
|
||||
CallableEvent(Callable &&callable)
|
||||
: QEvent(QEvent::None),
|
||||
callable(std::move(callable))
|
||||
{}
|
||||
CallableEvent(const Callable &callable)
|
||||
: QEvent(QEvent::None),
|
||||
callable(callable)
|
||||
{}
|
||||
|
||||
~CallableEvent()
|
||||
{
|
||||
callable();
|
||||
}
|
||||
public:
|
||||
Callable callable;
|
||||
};
|
||||
|
||||
template <typename Callable>
|
||||
void executeInLoop(Callable &&callable, QObject *object = QCoreApplication::instance()) {
|
||||
if (QThread *thread = qobject_cast<QThread*>(object))
|
||||
object = QAbstractEventDispatcher::instance(thread);
|
||||
|
||||
QCoreApplication::postEvent(object,
|
||||
new CallableEvent<Callable>(std::forward<Callable>(callable)),
|
||||
Qt::HighEventPriority);
|
||||
}
|
||||
#else
|
||||
template <typename Callable>
|
||||
void executeInLoop(Callable &&callable, QObject *object = QCoreApplication::instance()) {
|
||||
if (QThread *thread = qobject_cast<QThread*>(object))
|
||||
object = QAbstractEventDispatcher::instance(thread);
|
||||
|
||||
QMetaObject::invokeMethod(object, std::forward<Callable>(callable));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void SymbolIndexerTaskScheduler::addTasks(std::vector<Task> &&tasks)
|
||||
{
|
||||
for (auto &task : tasks) {
|
||||
auto callWrapper = [&, task=std::move(task)] (
|
||||
std::reference_wrapper<SymbolsCollectorInterface> symbolsCollector)
|
||||
-> SymbolsCollectorInterface& {
|
||||
task(symbolsCollector.get(), m_symbolStorage, m_transactionInterface);
|
||||
executeInLoop([&] {
|
||||
m_symbolIndexerTaskQueue.processTasks();
|
||||
});
|
||||
|
||||
return symbolsCollector;
|
||||
};
|
||||
m_futures.emplace_back(std::async(m_launchPolicy,
|
||||
std::move(callWrapper),
|
||||
std::ref(m_symbolsCollectorManager.unusedSymbolsCollector())));
|
||||
}
|
||||
}
|
||||
|
||||
const std::vector<SymbolIndexerTaskScheduler::Future> &SymbolIndexerTaskScheduler::futures() const
|
||||
{
|
||||
return m_futures;
|
||||
}
|
||||
|
||||
uint SymbolIndexerTaskScheduler::freeSlots()
|
||||
{
|
||||
removeFinishedFutures();
|
||||
|
||||
if (m_isDisabled)
|
||||
return 0;
|
||||
|
||||
return uint(std::max(int(m_hardware_concurrency) - int(m_futures.size()), 0));
|
||||
}
|
||||
|
||||
void SymbolIndexerTaskScheduler::syncTasks()
|
||||
{
|
||||
for (auto &future : m_futures)
|
||||
future.wait();
|
||||
}
|
||||
|
||||
void SymbolIndexerTaskScheduler::disable()
|
||||
{
|
||||
m_isDisabled = true;
|
||||
}
|
||||
|
||||
void SymbolIndexerTaskScheduler::removeFinishedFutures()
|
||||
{
|
||||
auto notReady = [] (Future &future) {
|
||||
return future.wait_for(std::chrono::duration<int>::zero()) != std::future_status::ready;
|
||||
};
|
||||
|
||||
auto split = std::partition(m_futures.begin(), m_futures.end(), notReady);
|
||||
|
||||
std::for_each(split, m_futures.end(), [] (Future &future) {
|
||||
SymbolsCollectorInterface &symbolCollector = future.get();
|
||||
symbolCollector.setIsUsed(false);
|
||||
symbolCollector.clear();
|
||||
});
|
||||
|
||||
m_futures.erase(split, m_futures.end());
|
||||
}
|
||||
|
||||
} // namespace ClangBackEnd
|
||||
@@ -1,91 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2018 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "symbolindexertaskschedulerinterface.h"
|
||||
#include "symbolindexertask.h"
|
||||
|
||||
#include <functional>
|
||||
#include <future>
|
||||
#include <vector>
|
||||
|
||||
namespace Sqlite {
|
||||
class TransactionInterface;
|
||||
};
|
||||
|
||||
namespace ClangBackEnd {
|
||||
|
||||
class FilePathCachingInterface;
|
||||
class SymbolsCollectorInterface;
|
||||
class SymbolsCollectorManagerInterface;
|
||||
class SymbolIndexerTaskQueueInterface;
|
||||
class SymbolStorageInterface;
|
||||
|
||||
class SymbolIndexerTaskScheduler final : public SymbolIndexerTaskSchedulerInterface
|
||||
{
|
||||
public:
|
||||
using Task = SymbolIndexerTask::Callable;
|
||||
using Future = std::future<SymbolsCollectorInterface&>;
|
||||
|
||||
SymbolIndexerTaskScheduler(SymbolsCollectorManagerInterface &symbolsCollectorManager,
|
||||
SymbolStorageInterface &symbolStorage,
|
||||
Sqlite::TransactionInterface &transactionInterface,
|
||||
SymbolIndexerTaskQueueInterface &symbolIndexerTaskQueue,
|
||||
uint hardware_concurrency,
|
||||
std::launch launchPolicy = std::launch::async)
|
||||
: m_symbolsCollectorManager(symbolsCollectorManager),
|
||||
m_symbolStorage(symbolStorage),
|
||||
m_transactionInterface(transactionInterface),
|
||||
m_symbolIndexerTaskQueue(symbolIndexerTaskQueue),
|
||||
m_hardware_concurrency(hardware_concurrency),
|
||||
m_launchPolicy(launchPolicy)
|
||||
{}
|
||||
|
||||
void addTasks(std::vector<Task> &&tasks);
|
||||
|
||||
const std::vector<Future> &futures() const;
|
||||
|
||||
uint freeSlots();
|
||||
|
||||
void syncTasks();
|
||||
|
||||
void disable();
|
||||
|
||||
private:
|
||||
void removeFinishedFutures();
|
||||
|
||||
private:
|
||||
std::vector<Future> m_futures;
|
||||
SymbolsCollectorManagerInterface &m_symbolsCollectorManager;
|
||||
SymbolStorageInterface &m_symbolStorage;
|
||||
Sqlite::TransactionInterface &m_transactionInterface;
|
||||
SymbolIndexerTaskQueueInterface &m_symbolIndexerTaskQueue;
|
||||
uint m_hardware_concurrency;
|
||||
std::launch m_launchPolicy;
|
||||
bool m_isDisabled = false;
|
||||
};
|
||||
|
||||
} // namespace ClangBackEnd
|
||||
@@ -1,60 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2018 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
#include <vector>
|
||||
|
||||
namespace Sqlite {
|
||||
class TransactionInterface;
|
||||
}
|
||||
|
||||
namespace ClangBackEnd {
|
||||
|
||||
class SymbolsCollectorInterface;
|
||||
class SymbolStorageInterface;
|
||||
|
||||
using uint = unsigned int;
|
||||
|
||||
class SymbolIndexerTaskSchedulerInterface
|
||||
{
|
||||
public:
|
||||
using Task = std::function<void(SymbolsCollectorInterface &symbolsCollector,
|
||||
SymbolStorageInterface &symbolStorage,
|
||||
Sqlite::TransactionInterface &transaction)>;
|
||||
|
||||
SymbolIndexerTaskSchedulerInterface() = default;
|
||||
SymbolIndexerTaskSchedulerInterface(const SymbolIndexerTaskSchedulerInterface &) = delete;
|
||||
SymbolIndexerTaskSchedulerInterface &operator=(const SymbolIndexerTaskSchedulerInterface &) = delete;
|
||||
|
||||
virtual void addTasks(std::vector<Task> &&tasks) = 0;
|
||||
virtual uint freeSlots() = 0;
|
||||
|
||||
protected:
|
||||
~SymbolIndexerTaskSchedulerInterface() = default;
|
||||
};
|
||||
|
||||
} // namespace ClangBackEnd
|
||||
@@ -30,9 +30,9 @@
|
||||
#include "storagesqlitestatementfactory.h"
|
||||
#include "symbolindexer.h"
|
||||
#include "symbolscollector.h"
|
||||
#include "symbolscollectormanager.h"
|
||||
#include "processormanager.h"
|
||||
#include "symbolindexertaskqueue.h"
|
||||
#include "symbolindexertaskscheduler.h"
|
||||
#include "taskscheduler.h"
|
||||
#include "symbolstorage.h"
|
||||
|
||||
#include <refactoringdatabaseinitializer.h>
|
||||
@@ -48,19 +48,40 @@
|
||||
|
||||
namespace ClangBackEnd {
|
||||
|
||||
class SymbolsCollectorManager;
|
||||
|
||||
class SymbolsCollectorManager final : public ClangBackEnd::ProcessorManager<SymbolsCollector>
|
||||
{
|
||||
public:
|
||||
using Processor = SymbolsCollector;
|
||||
SymbolsCollectorManager(const ClangBackEnd::GeneratedFiles &generatedFiles,
|
||||
Sqlite::Database &database)
|
||||
: ProcessorManager(generatedFiles),
|
||||
m_database(database)
|
||||
{}
|
||||
|
||||
protected:
|
||||
std::unique_ptr<SymbolsCollector> createProcessor() const
|
||||
{
|
||||
return std::make_unique<SymbolsCollector>(m_database);
|
||||
}
|
||||
|
||||
private:
|
||||
Sqlite::Database &m_database;
|
||||
};
|
||||
|
||||
class SymbolIndexing final : public SymbolIndexingInterface
|
||||
{
|
||||
public:
|
||||
using StatementFactory = ClangBackEnd::StorageSqliteStatementFactory<Sqlite::Database>;
|
||||
using Storage = ClangBackEnd::SymbolStorage<StatementFactory>;
|
||||
|
||||
SymbolIndexing(Sqlite::Database &database,
|
||||
FilePathCachingInterface &filePathCache,
|
||||
const GeneratedFiles &generatedFiles)
|
||||
: m_filePathCache(filePathCache),
|
||||
m_statementFactory(database),
|
||||
m_collectorManger(database, generatedFiles),
|
||||
m_indexerScheduler(m_collectorManger, m_symbolStorage, database, m_indexerQueue, std::thread::hardware_concurrency())
|
||||
m_collectorManger(generatedFiles, database),
|
||||
m_indexerScheduler(m_collectorManger, m_indexerQueue, std::thread::hardware_concurrency())
|
||||
{
|
||||
}
|
||||
|
||||
@@ -86,12 +107,13 @@ public:
|
||||
void updateProjectParts(V2::ProjectPartContainers &&projectParts) override;
|
||||
|
||||
private:
|
||||
using SymbolIndexerTaskScheduler = TaskScheduler<SymbolsCollectorManager, SymbolIndexerTask::Callable>;
|
||||
FilePathCachingInterface &m_filePathCache;
|
||||
StatementFactory m_statementFactory;
|
||||
Storage m_symbolStorage{m_statementFactory};
|
||||
ClangPathWatcher<QFileSystemWatcher, QTimer> m_sourceWatcher{m_filePathCache};
|
||||
FileStatusCache m_fileStatusCache{m_filePathCache};
|
||||
SymbolsCollectorManager<SymbolsCollector> m_collectorManger;
|
||||
SymbolsCollectorManager m_collectorManger;
|
||||
SymbolIndexerTaskScheduler m_indexerScheduler;
|
||||
SymbolIndexerTaskQueue m_indexerQueue{m_indexerScheduler};
|
||||
SymbolIndexer m_indexer{m_indexerQueue,
|
||||
|
||||
@@ -129,6 +129,10 @@ void SymbolsCollector::collectSymbols()
|
||||
&m_collectMacrosSourceFileCallbacks).get());
|
||||
}
|
||||
|
||||
void SymbolsCollector::doInMainThreadAfterFinished()
|
||||
{
|
||||
}
|
||||
|
||||
const SymbolEntries &SymbolsCollector::symbols() const
|
||||
{
|
||||
return m_symbolEntries;
|
||||
|
||||
@@ -54,6 +54,8 @@ public:
|
||||
|
||||
void collectSymbols() override;
|
||||
|
||||
void doInMainThreadAfterFinished() override;
|
||||
|
||||
const SymbolEntries &symbols() const override;
|
||||
const SourceLocationEntries &sourceLocations() const override;
|
||||
const FilePathIds &sourceFiles() const override;
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
#include "sourcelocationentry.h"
|
||||
#include "usedmacro.h"
|
||||
|
||||
#include <filecontainerv2.h>
|
||||
#include <processorinterface.h>
|
||||
|
||||
#include <utils/smallstringvector.h>
|
||||
|
||||
@@ -40,20 +40,10 @@
|
||||
|
||||
namespace ClangBackEnd {
|
||||
|
||||
class SymbolsCollectorInterface
|
||||
class SymbolsCollectorInterface : public ProcessorInterface
|
||||
{
|
||||
public:
|
||||
SymbolsCollectorInterface() = default;
|
||||
virtual ~SymbolsCollectorInterface() = default;
|
||||
SymbolsCollectorInterface(const SymbolsCollectorInterface &) = delete;
|
||||
SymbolsCollectorInterface &operator=(const SymbolsCollectorInterface &) = delete;
|
||||
|
||||
virtual void setFile(FilePathId filePathId, const Utils::SmallStringVector &arguments) = 0;
|
||||
|
||||
virtual void setUnsavedFiles(const V2::FileContainers &unsavedFiles) = 0;
|
||||
|
||||
virtual void clear() = 0;
|
||||
|
||||
virtual void collectSymbols() = 0;
|
||||
|
||||
virtual const SymbolEntries &symbols() const = 0;
|
||||
@@ -62,9 +52,6 @@ public:
|
||||
virtual const UsedMacros &usedMacros() const = 0;
|
||||
virtual const FileStatuses &fileStatuses() const = 0;
|
||||
virtual const SourceDependencies &sourceDependencies() const = 0;
|
||||
|
||||
virtual bool isUsed() const = 0;
|
||||
virtual void setIsUsed(bool isUsed) = 0;
|
||||
};
|
||||
|
||||
} // namespace ClangBackEnd
|
||||
|
||||
@@ -1,89 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2018 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "symbolscollectormanagerinterface.h"
|
||||
#include "symbolscollectorinterface.h"
|
||||
#include "generatedfiles.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace Sqlite {
|
||||
class Database;
|
||||
}
|
||||
|
||||
namespace ClangBackEnd {
|
||||
|
||||
class GeneratedFiles;
|
||||
class SymbolsCollector;
|
||||
template<typename SymbolsCollector>
|
||||
class SymbolsCollectorManager final : public SymbolsCollectorManagerInterface
|
||||
{
|
||||
public:
|
||||
SymbolsCollectorManager(Sqlite::Database &database,
|
||||
const GeneratedFiles &generatedFiles)
|
||||
: m_database(database),
|
||||
m_generatedFiles(generatedFiles)
|
||||
{}
|
||||
|
||||
SymbolsCollector &unusedSymbolsCollector() override
|
||||
{
|
||||
auto split = std::partition(m_collectors.begin(),
|
||||
m_collectors.end(),
|
||||
[] (const auto &collector) {
|
||||
return collector->isUsed();
|
||||
});
|
||||
|
||||
auto freeCollectors = std::distance(split, m_collectors.end());
|
||||
|
||||
if (freeCollectors > 0)
|
||||
return initializedCollector(*split->get());
|
||||
|
||||
m_collectors.emplace_back(std::make_unique<SymbolsCollector>(m_database));
|
||||
|
||||
return initializedCollector(*m_collectors.back().get());
|
||||
}
|
||||
|
||||
const std::vector<std::unique_ptr<SymbolsCollector>> &collectors() const
|
||||
{
|
||||
return m_collectors;
|
||||
}
|
||||
|
||||
private:
|
||||
SymbolsCollector &initializedCollector(SymbolsCollector &collector)
|
||||
{
|
||||
collector.setIsUsed(true);
|
||||
collector.setUnsavedFiles(m_generatedFiles.fileContainers());
|
||||
return collector;
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<std::unique_ptr<SymbolsCollector>> m_collectors;
|
||||
Sqlite::Database &m_database;
|
||||
const GeneratedFiles &m_generatedFiles;
|
||||
};
|
||||
|
||||
} // namespace ClangBackEnd
|
||||
@@ -1,49 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2018 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <filecontainerv2.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace ClangBackEnd {
|
||||
|
||||
class SymbolsCollectorInterface;
|
||||
|
||||
class SymbolsCollectorManagerInterface
|
||||
{
|
||||
public:
|
||||
SymbolsCollectorManagerInterface() = default;
|
||||
SymbolsCollectorManagerInterface(const SymbolsCollectorManagerInterface &) = delete;
|
||||
SymbolsCollectorManagerInterface &operator=(const SymbolsCollectorManagerInterface &) = delete;
|
||||
|
||||
virtual SymbolsCollectorInterface &unusedSymbolsCollector() = 0;
|
||||
|
||||
protected:
|
||||
~SymbolsCollectorManagerInterface() = default;
|
||||
};
|
||||
|
||||
} // namespace ClangBackEnd
|
||||
Reference in New Issue
Block a user