diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/libs/clangsupport/clangsupport-lib.pri | 1 | ||||
-rw-r--r-- | src/libs/clangsupport/filestatuscache.cpp | 54 | ||||
-rw-r--r-- | src/libs/clangsupport/modifiedtimechecker.h | 183 | ||||
-rw-r--r-- | src/libs/clangsupport/set_algorithm.h | 101 | ||||
-rw-r--r-- | src/libs/clangsupport/sourceentry.h | 4 | ||||
-rw-r--r-- | src/tools/clangpchmanagerbackend/clangpchmanagerbackendmain.cpp | 7 | ||||
-rw-r--r-- | src/tools/clangrefactoringbackend/source/symbolindexing.h | 7 |
7 files changed, 178 insertions, 179 deletions
diff --git a/src/libs/clangsupport/clangsupport-lib.pri b/src/libs/clangsupport/clangsupport-lib.pri index 9b6bbdf3ee..dc66408e58 100644 --- a/src/libs/clangsupport/clangsupport-lib.pri +++ b/src/libs/clangsupport/clangsupport-lib.pri @@ -157,6 +157,7 @@ HEADERS += \ $$PWD/refactoringserverinterface.h \ $$PWD/refactoringserverproxy.h \ $$PWD/referencesmessage.h \ + $$PWD/set_algorithm.h \ $$PWD/unsavedfilesupdatedmessage.h \ $$PWD/removeprojectpartsmessage.h \ $$PWD/requestannotationsmessage.h \ diff --git a/src/libs/clangsupport/filestatuscache.cpp b/src/libs/clangsupport/filestatuscache.cpp index 480b745525..e8ed50a833 100644 --- a/src/libs/clangsupport/filestatuscache.cpp +++ b/src/libs/clangsupport/filestatuscache.cpp @@ -26,6 +26,8 @@ #include "filestatuscache.h" #include "filesystem.h" +#include <set_algorithm.h> + #include <utils/algorithm.h> #include <QDateTime> @@ -51,49 +53,15 @@ void FileStatusCache::update(FilePathId filePathId) found->lastModified = m_fileSystem.lastModified(filePathId); } -namespace { -template<class InputIt1, class InputIt2, class Callable> -void set_intersection_call(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2, Callable callable) -{ - while (first1 != last1 && first2 != last2) { - if (*first1 < *first2) { - ++first1; - } else { - if (!(*first2 < *first1)) - callable(*first1++); - ++first2; - } - } -} - -template<class InputIt1, class InputIt2, class Callable> -void set_difference_call(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2, Callable callable) -{ - while (first1 != last1) { - if (first2 == last2) { - std::for_each(first1, last1, callable); - return; - } - if (*first1 < *first2) { - callable(*first1++); - } else { - if (!(*first2 < *first1)) - ++first1; - ++first2; - } - } -} -} // namespace - void FileStatusCache::update(FilePathIds filePathIds) { - set_intersection_call(m_cacheEntries.begin(), + std::set_intersection(m_cacheEntries.begin(), m_cacheEntries.end(), filePathIds.begin(), filePathIds.end(), - [&](auto &entry) { + make_iterator([&](auto &entry) { entry.lastModified = m_fileSystem.lastModified(entry.filePathId); - }); + })); } FilePathIds FileStatusCache::modified(FilePathIds filePathIds) const @@ -101,30 +69,30 @@ FilePathIds FileStatusCache::modified(FilePathIds filePathIds) const FilePathIds modifiedFilePathIds; modifiedFilePathIds.reserve(filePathIds.size()); - set_intersection_call(m_cacheEntries.begin(), + std::set_intersection(m_cacheEntries.begin(), m_cacheEntries.end(), filePathIds.begin(), filePathIds.end(), - [&](auto &entry) { + make_iterator([&](auto &entry) { auto newLastModified = m_fileSystem.lastModified(entry.filePathId); if (newLastModified > entry.lastModified) { modifiedFilePathIds.push_back(entry.filePathId); entry.lastModified = newLastModified; } - }); + })); Internal::FileStatusCacheEntries newEntries; newEntries.reserve(filePathIds.size()); - set_difference_call(filePathIds.begin(), + std::set_difference(filePathIds.begin(), filePathIds.end(), m_cacheEntries.begin(), m_cacheEntries.end(), - [&](FilePathId newFilePathId) { + make_iterator([&](FilePathId newFilePathId) { newEntries.emplace_back(newFilePathId, m_fileSystem.lastModified(newFilePathId)); modifiedFilePathIds.push_back(newFilePathId); - }); + })); if (newEntries.size()) { Internal::FileStatusCacheEntries mergedEntries; diff --git a/src/libs/clangsupport/modifiedtimechecker.h b/src/libs/clangsupport/modifiedtimechecker.h index 9247933b18..00e8e3ebac 100644 --- a/src/libs/clangsupport/modifiedtimechecker.h +++ b/src/libs/clangsupport/modifiedtimechecker.h @@ -25,24 +25,23 @@ #pragma once -#include "clangpathwatcher.h" -#include "filepathcachinginterface.h" +#include "filesysteminterface.h" #include "modifiedtimecheckerinterface.h" +#include "set_algorithm.h" #include <algorithm> #include <iterator> namespace ClangBackEnd { + template<typename SourceEntries = ::ClangBackEnd::SourceEntries> class ModifiedTimeChecker final : public ModifiedTimeCheckerInterface<SourceEntries> { using SourceEntry = typename SourceEntries::value_type; public: - using GetModifiedTime = std::function<ClangBackEnd::TimeStamp(ClangBackEnd::FilePathView filePath)>; - ModifiedTimeChecker(GetModifiedTime &getModifiedTime, FilePathCachingInterface &filePathCache) - : m_getModifiedTime(getModifiedTime) - , m_filePathCache(filePathCache) + ModifiedTimeChecker(FileSystemInterface &fileSystem) + : m_fileSystem(fileSystem) {} bool isUpToDate(const SourceEntries &sourceEntries) const @@ -52,165 +51,101 @@ public: updateCurrentSourceTimeStamps(sourceEntries); - return compareEntries(sourceEntries); + return compareEntries(sourceEntries) && notReseted(sourceEntries); } void pathsChanged(const FilePathIds &filePathIds) override { - using SourceTimeStampReferences = std::vector<std::reference_wrapper<SourceTimeStamp>>; - - SourceTimeStampReferences timeStampsToUpdate; - timeStampsToUpdate.reserve(filePathIds.size()); - std::set_intersection(m_currentSourceTimeStamps.begin(), m_currentSourceTimeStamps.end(), filePathIds.begin(), filePathIds.end(), - std::back_inserter(timeStampsToUpdate)); + make_iterator([&](SourceTimeStamp &sourceTimeStamp) { + sourceTimeStamp.timeStamp = m_fileSystem.lastModified( + sourceTimeStamp.sourceId); + })); + } + + void reset(const FilePathIds &filePathIds) + { + FilePathIds newResetFilePathIds; + newResetFilePathIds.reserve(newResetFilePathIds.size() + m_resetFilePathIds.size()); + + std::set_union(m_resetFilePathIds.begin(), + m_resetFilePathIds.end(), + filePathIds.begin(), + filePathIds.end(), + std::back_inserter(newResetFilePathIds)); - for (SourceTimeStamp &sourceTimeStamp : timeStampsToUpdate) { - sourceTimeStamp.timeStamp = m_getModifiedTime( - m_filePathCache.filePath(sourceTimeStamp.sourceId)); - } + m_resetFilePathIds = std::move(newResetFilePathIds); } private: bool compareEntries(const SourceEntries &sourceEntries) const { - class CompareSourceId - { - public: - bool operator()(SourceTimeStamp first, SourceTimeStamp second) - { - return first.sourceId < second.sourceId; - } - - bool operator()(::ClangBackEnd::SourceEntry first, ::ClangBackEnd::SourceEntry second) - { - return first.sourceId < second.sourceId; - } - - bool operator()(SourceTimeStamp first, ::ClangBackEnd::SourceEntry second) - { - return first.sourceId < second.sourceId; - } - - bool operator()(::ClangBackEnd::SourceEntry first, SourceTimeStamp second) - { - return first.sourceId < second.sourceId; - } - }; - - SourceTimeStamps currentSourceTimeStamp; - currentSourceTimeStamp.reserve(sourceEntries.size()); - std::set_intersection(m_currentSourceTimeStamps.begin(), - m_currentSourceTimeStamps.end(), - sourceEntries.begin(), - sourceEntries.end(), - std::back_inserter(currentSourceTimeStamp), - CompareSourceId{}); - - class CompareTime - { - public: - bool operator()(SourceTimeStamp first, SourceTimeStamp second) - { - return first.timeStamp <= second.timeStamp; - } - - bool operator()(::ClangBackEnd::SourceEntry first, ::ClangBackEnd::SourceEntry second) - { - return first.timeStamp <= second.timeStamp; - } - - bool operator()(SourceTimeStamp first, ::ClangBackEnd::SourceEntry second) - { - return first.timeStamp <= second.timeStamp; - } - - bool operator()(::ClangBackEnd::SourceEntry first, SourceTimeStamp second) - { - return first.timeStamp <= second.timeStamp; - } - }; - - return std::lexicographical_compare(currentSourceTimeStamp.begin(), - currentSourceTimeStamp.end(), - sourceEntries.begin(), - sourceEntries.end(), - CompareTime{}); + return set_intersection_compare( + m_currentSourceTimeStamps.begin(), + m_currentSourceTimeStamps.end(), + sourceEntries.begin(), + sourceEntries.end(), + [](auto first, auto second) { return second.timeStamp > first.timeStamp; }, + [](auto first, auto second) { return first.sourceId < second.sourceId; }); } void updateCurrentSourceTimeStamps(const SourceEntries &sourceEntries) const { SourceTimeStamps sourceTimeStamps = newSourceTimeStamps(sourceEntries); - for (SourceTimeStamp &newSourceTimeStamp : sourceTimeStamps) { - newSourceTimeStamp.timeStamp = m_getModifiedTime( - m_filePathCache.filePath(newSourceTimeStamp.sourceId)); - } - auto split = sourceTimeStamps.insert(sourceTimeStamps.end(), m_currentSourceTimeStamps.begin(), m_currentSourceTimeStamps.end()); std::inplace_merge(sourceTimeStamps.begin(), split, sourceTimeStamps.end()); - m_currentSourceTimeStamps = sourceTimeStamps; + m_currentSourceTimeStamps = std::move(sourceTimeStamps); } SourceTimeStamps newSourceTimeStamps(const SourceEntries &sourceEntries) const { - SourceEntries newSourceEntries; - newSourceEntries.reserve(sourceEntries.size()); - - class CompareSourceId - { - public: - bool operator()(SourceTimeStamp first, SourceTimeStamp second) - { - return first.sourceId < second.sourceId; - } - - bool operator()(::ClangBackEnd::SourceEntry first, ::ClangBackEnd::SourceEntry second) - { - return first.sourceId < second.sourceId; - } - - bool operator()(SourceTimeStamp first, ::ClangBackEnd::SourceEntry second) - { - return first.sourceId < second.sourceId; - } - - bool operator()(::ClangBackEnd::SourceEntry first, SourceTimeStamp second) - { - return first.sourceId < second.sourceId; - } - }; + SourceTimeStamps newTimeStamps; + newTimeStamps.reserve(sourceEntries.size()); std::set_difference(sourceEntries.begin(), sourceEntries.end(), m_currentSourceTimeStamps.begin(), m_currentSourceTimeStamps.end(), - std::back_inserter(newSourceEntries), - CompareSourceId{}); + make_iterator([&](const SourceEntry &sourceEntry) { + newTimeStamps.emplace_back(sourceEntry.sourceId, + m_fileSystem.lastModified( + sourceEntry.sourceId)); + }), + [](auto first, auto second) { + return first.sourceId < second.sourceId && first.timeStamp > 0; + }); - SourceTimeStamps newTimeStamps; - newTimeStamps.reserve(newSourceEntries.size()); + return newTimeStamps; + } - std::transform(newSourceEntries.begin(), - newSourceEntries.end(), - std::back_inserter(newTimeStamps), - [](SourceEntry entry) { - return SourceTimeStamp{entry.sourceId, {}}; - }); + bool notReseted(const SourceEntries &sourceEntries) const + { + auto oldSize = m_resetFilePathIds.size(); + FilePathIds newResetFilePathIds; + newResetFilePathIds.reserve(newResetFilePathIds.size()); - return newTimeStamps; + std::set_difference(m_resetFilePathIds.begin(), + m_resetFilePathIds.end(), + sourceEntries.begin(), + sourceEntries.end(), + std::back_inserter(newResetFilePathIds)); + + m_resetFilePathIds = std::move(newResetFilePathIds); + + return oldSize == m_resetFilePathIds.size(); } private: mutable SourceTimeStamps m_currentSourceTimeStamps; - GetModifiedTime &m_getModifiedTime; - FilePathCachingInterface &m_filePathCache; + mutable FilePathIds m_resetFilePathIds; + FileSystemInterface &m_fileSystem; }; } // namespace ClangBackEnd diff --git a/src/libs/clangsupport/set_algorithm.h b/src/libs/clangsupport/set_algorithm.h new file mode 100644 index 0000000000..39bd3a2055 --- /dev/null +++ b/src/libs/clangsupport/set_algorithm.h @@ -0,0 +1,101 @@ +/**************************************************************************** +** +** Copyright (C) 2019 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 <algorithm> + +namespace ClangBackEnd { + +template<class Callable> +class function_output_iterator +{ +public: + typedef std::output_iterator_tag iterator_category; + typedef void value_type; + typedef void difference_type; + typedef void pointer; + typedef void reference; + + explicit function_output_iterator() {} + + explicit function_output_iterator(const Callable &callable) + : m_callable(&callable) + {} + + function_output_iterator &operator=(const function_output_iterator &iterator) + { + m_callable = iterator.m_callable; + + return *this; + } + + struct helper + { + helper(const Callable *callable) + : m_callable(callable) + {} + template<class T> + helper &operator=(T &&value) + { + (*m_callable)(std::forward<T>(value)); + return *this; + } + const Callable *m_callable; + }; + + helper operator*() { return helper(m_callable); } + function_output_iterator &operator++() { return *this; } + function_output_iterator &operator++(int) { return *this; } + +private: + const Callable *m_callable; +}; + +template<typename Callable> +function_output_iterator<Callable> make_iterator(const Callable &callable) +{ + return function_output_iterator<Callable>(callable); +} + +template<class InputIt1, class InputIt2, class Callable, class Compare> +bool set_intersection_compare( + InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2, Callable call, Compare comp) +{ + while (first1 != last1 && first2 != last2) { + if (comp(*first1, *first2)) { + ++first1; + } else { + if (!comp(*first2, *first1)) { + if (call(*first2, *first1++)) + return false; + } + ++first2; + } + } + + return true; +} +} // namespace ClangBackEnd diff --git a/src/libs/clangsupport/sourceentry.h b/src/libs/clangsupport/sourceentry.h index c593f1fcd3..5e8769d14f 100644 --- a/src/libs/clangsupport/sourceentry.h +++ b/src/libs/clangsupport/sourceentry.h @@ -131,6 +131,10 @@ public: return first.sourceId < second.sourceId; } + friend bool operator<(SourceEntry first, FilePathId second) { return first.sourceId < second; } + + friend bool operator<(FilePathId first, SourceEntry second) { return first < second.sourceId; } + friend bool operator==(SourceEntry first, SourceEntry second) { return first.sourceId == second.sourceId && first.sourceType == second.sourceType diff --git a/src/tools/clangpchmanagerbackend/clangpchmanagerbackendmain.cpp b/src/tools/clangpchmanagerbackend/clangpchmanagerbackendmain.cpp index d9e7dd3175..bcf05e5d04 100644 --- a/src/tools/clangpchmanagerbackend/clangpchmanagerbackendmain.cpp +++ b/src/tools/clangpchmanagerbackend/clangpchmanagerbackendmain.cpp @@ -214,12 +214,7 @@ struct Data // because we have a cycle dependency ClangBackEnd::BuildDependencyCollector buildDependencyCollector{filePathCache, generatedFiles, environment}; - std::function<TimeStamp(FilePathView filePath)> getModifiedTime{ - [&](ClangBackEnd::FilePathView path) -> TimeStamp { - return QFileInfo(QString(path)).lastModified().toSecsSinceEpoch(); - }}; - ClangBackEnd::ModifiedTimeChecker<ClangBackEnd::SourceEntries> modifiedTimeChecker{getModifiedTime, - filePathCache}; + ClangBackEnd::ModifiedTimeChecker<ClangBackEnd::SourceEntries> modifiedTimeChecker{fileSystem}; ClangBackEnd::BuildDependenciesProvider buildDependencyProvider{buildDependencyStorage, modifiedTimeChecker, buildDependencyCollector, diff --git a/src/tools/clangrefactoringbackend/source/symbolindexing.h b/src/tools/clangrefactoringbackend/source/symbolindexing.h index bed279904d..936a34af00 100644 --- a/src/tools/clangrefactoringbackend/source/symbolindexing.h +++ b/src/tools/clangrefactoringbackend/source/symbolindexing.h @@ -148,12 +148,7 @@ private: FileStatusCache m_fileStatusCache{m_fileSytem}; SymbolsCollectorManager m_collectorManger; ProgressCounter m_progressCounter; - std::function<TimeStamp(FilePathView filePath)> getModifiedTime{ - [&](ClangBackEnd::FilePathView path) -> TimeStamp { - return QFileInfo(QString(path)).lastModified().toSecsSinceEpoch(); - }}; - ModifiedTimeChecker<ClangBackEnd::SourceTimeStamps> m_modifiedTimeChecker{getModifiedTime, - m_filePathCache}; + ModifiedTimeChecker<ClangBackEnd::SourceTimeStamps> m_modifiedTimeChecker{m_fileSytem}; SymbolIndexer m_indexer; SymbolIndexerTaskQueue m_indexerQueue; SymbolIndexerTaskScheduler m_indexerScheduler; |