diff options
author | Marco Bubke <marco.bubke@qt.io> | 2018-08-22 17:20:08 +0200 |
---|---|---|
committer | Marco Bubke <marco.bubke@qt.io> | 2018-08-27 09:17:39 +0000 |
commit | 5bd7af7a9077ab447b9cd60cfd75492b0aa65424 (patch) | |
tree | a7352833de6be41ad380b83ec7590f79a9aee4d3 /src/tools/clangrefactoringbackend/source | |
parent | 8b397d6501e4c01b0a9b91a11cb32918217db748 (diff) | |
download | qt-creator-5bd7af7a9077ab447b9cd60cfd75492b0aa65424.tar.gz |
ClangRefactoring: Add SymbolIndexerTaskQueue
A first step for concurrent index task.
Change-Id: I9a0dba9f4a67ee605281516785697045b34e2694
Reviewed-by: Ivan Donchevskii <ivan.donchevskii@qt.io>
Diffstat (limited to 'src/tools/clangrefactoringbackend/source')
3 files changed, 234 insertions, 2 deletions
diff --git a/src/tools/clangrefactoringbackend/source/clangrefactoringbackend-source.pri b/src/tools/clangrefactoringbackend/source/clangrefactoringbackend-source.pri index 30a651a81c..9acad5b394 100644 --- a/src/tools/clangrefactoringbackend/source/clangrefactoringbackend-source.pri +++ b/src/tools/clangrefactoringbackend/source/clangrefactoringbackend-source.pri @@ -23,7 +23,8 @@ HEADERS += \ $$PWD/filestatuscache.h \ $$PWD/indexdataconsumer.h \ $$PWD/projectpartqueue.h \ - $$PWD/sourcesmanager.h + $$PWD/sourcesmanager.h \ + $$PWD/symbolindexertaskqueue.h !isEmpty(LIBTOOLING_LIBS) { SOURCES += \ @@ -69,4 +70,5 @@ SOURCES += \ $$PWD/symbolindexer.cpp \ $$PWD/projectpartartefact.cpp \ $$PWD/filestatuscache.cpp \ - $$PWD/projectpartqueue.cpp + $$PWD/projectpartqueue.cpp \ + $$PWD/symbolindexertaskqueue.cpp diff --git a/src/tools/clangrefactoringbackend/source/symbolindexertaskqueue.cpp b/src/tools/clangrefactoringbackend/source/symbolindexertaskqueue.cpp new file mode 100644 index 0000000000..7335a6ecdd --- /dev/null +++ b/src/tools/clangrefactoringbackend/source/symbolindexertaskqueue.cpp @@ -0,0 +1,134 @@ +/**************************************************************************** +** +** 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" + +namespace ClangBackEnd { + +namespace { + +template<class InputIt1, + class InputIt2, + class OutputIt, + class Merge> +OutputIt set_union_merge(InputIt1 first1, + InputIt1 last1, + InputIt2 first2, + InputIt2 last2, + OutputIt d_first, + Merge merge) +{ + for (; first1 != last1; ++d_first) { + if (first2 == last2) + return std::copy(first1, last1, d_first); + if (*first2 < *first1) { + *d_first = *first2++; + } else { + if (*first1 < *first2) { + *d_first = *first1; + } else { + *d_first = merge(*first1, *first2); + ++first2; + } + ++first1; + } + } + return std::copy(first2, last2, d_first); +} + +} + +SymbolIndexerTaskQueue::SymbolIndexerTaskQueue() +{ + +} + +void SymbolIndexerTaskQueue::addOrUpdateTasks(std::vector<SymbolIndexerTask> &&tasks) +{ + std::vector<SymbolIndexerTask> mergedTasks; + mergedTasks.reserve(m_tasks.size() + tasks.size()); + + auto merge = [] (SymbolIndexerTask &&first, SymbolIndexerTask &&second) { + first.callable = std::move(second.callable); + + return std::move(first); + }; + + set_union_merge(std::make_move_iterator(tasks.begin()), + std::make_move_iterator(tasks.end()), + std::make_move_iterator(m_tasks.begin()), + std::make_move_iterator(m_tasks.end()), + std::back_inserter(mergedTasks), + merge); + + m_tasks = std::move(mergedTasks); +} + +void SymbolIndexerTaskQueue::removeTasks(const Utils::SmallStringVector &projectPartIds) +{ + std::vector<std::size_t> ids = projectPartNumberIds(projectPartIds); + + auto shouldBeRemoved = [&] (const SymbolIndexerTask& task) { + return std::binary_search(ids.begin(), ids.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; +} + +std::size_t SymbolIndexerTaskQueue::projectPartNumberId(Utils::SmallStringView projectPartId) +{ + auto found = std::find(m_projectPartIds.begin(), m_projectPartIds.end(), projectPartId); + + if (found != m_projectPartIds.end()) + return std::size_t(std::distance(m_projectPartIds.begin(), found)); + + m_projectPartIds.emplace_back(projectPartId); + + return m_projectPartIds.size() - 1; +} + +std::vector<std::size_t> SymbolIndexerTaskQueue::projectPartNumberIds(const Utils::SmallStringVector &projectPartIds) +{ + std::vector<std::size_t> ids; + std::transform(projectPartIds.begin(), + projectPartIds.end(), + std::back_inserter(ids), + [&] (Utils::SmallStringView projectPartId) { + return projectPartNumberId(projectPartId); + }); + + std::sort(ids.begin(), ids.end()); + + return ids; +} + +} // namespace ClangBackEnd diff --git a/src/tools/clangrefactoringbackend/source/symbolindexertaskqueue.h b/src/tools/clangrefactoringbackend/source/symbolindexertaskqueue.h new file mode 100644 index 0000000000..0f5fee1c74 --- /dev/null +++ b/src/tools/clangrefactoringbackend/source/symbolindexertaskqueue.h @@ -0,0 +1,96 @@ +/**************************************************************************** +** +** 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 <filepathid.h> + +#include <utils/smallstringvector.h> + +#include <functional> +#include <vector> + +namespace ClangBackEnd { + +class SymbolIndexerTask +{ +public: + using CallableType = std::function<void()>; + + SymbolIndexerTask(FilePathId filePathId, + std::size_t projectPartId, + CallableType &&callable) + : callable(std::move(callable)), + filePathId(filePathId), + projectPartId(projectPartId) + { + } + + SymbolIndexerTask clone() const + { + return *this; + } + + friend + bool operator==(const SymbolIndexerTask &first, const SymbolIndexerTask &second) + { + return first.filePathId == second.filePathId && first.projectPartId == second.projectPartId; + } + + friend + bool operator<(const SymbolIndexerTask &first, const SymbolIndexerTask &second) + { + return std::tie(first.filePathId, first.projectPartId) + < std::tie(second.filePathId, second.projectPartId); + } + +public: + CallableType callable; + FilePathId filePathId; + std::size_t projectPartId; +}; + +class SymbolIndexerTaskQueue +{ +public: + SymbolIndexerTaskQueue(); + + void addOrUpdateTasks(std::vector<SymbolIndexerTask> &&tasks) + /* [[expects: std::is_sorted(tasks)]] */; + void removeTasks(const Utils::SmallStringVector &projectPartIds) + /* [[expects: std::is_sorted(projectPartIds)]] */; + + const std::vector<SymbolIndexerTask> &tasks() const; + + std::size_t projectPartNumberId(Utils::SmallStringView projectPartId); + std::vector<std::size_t> projectPartNumberIds(const Utils::SmallStringVector &projectPartIds) + /* [[ensures result: std::is_sorted(result)]] */; + +private: + std::vector<Utils::SmallString> m_projectPartIds; + std::vector<SymbolIndexerTask> m_tasks; +}; + +} // namespace ClangBackEnd |