From ff1ce3a475a22e3a9787eda5f893591906ed1af0 Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Tue, 27 Mar 2018 14:23:42 +0200 Subject: [PATCH] Clang: Honor directories for the file name The file name id must be unique for very entry, so the directory id must be incorporated too. Now there is always one unique integer id for every file path. The directory id is there to access and compare the directory much faster but not provide any data to the uniqueness of the id. Change-Id: I0f9a2ca70bc9dda0ce32ebc45eb7b082821eb909 Reviewed-by: Ivan Donchevskii --- src/libs/clangsupport/clangpathwatcher.h | 1 + src/libs/clangsupport/filepathcache.h | 75 ++++++++++++++++++++-- src/libs/clangsupport/stringcache.h | 30 +++++---- src/libs/clangsupport/stringcachefwd.h | 1 + tests/unit/unittest/filepathcache-test.cpp | 22 +++++++ tests/unit/unittest/stringcache-test.cpp | 1 + 6 files changed, 111 insertions(+), 19 deletions(-) diff --git a/src/libs/clangsupport/clangpathwatcher.h b/src/libs/clangsupport/clangpathwatcher.h index 9339c56d51d..258c63e9383 100644 --- a/src/libs/clangsupport/clangpathwatcher.h +++ b/src/libs/clangsupport/clangpathwatcher.h @@ -70,6 +70,7 @@ public: using WatcherEntries = std::vector; using IdCache = StringCache class FilePathCache { + class FileNameView + { + public: + friend bool operator==(const FileNameView &first, const FileNameView &second) + { + return first.directoryId == second.directoryId + && first.fileName == second.fileName; + } + + static + int compare(FileNameView first, FileNameView second) noexcept + { + int directoryDifference = first.directoryId - second.directoryId; + + if (directoryDifference) + return directoryDifference; + + return Utils::compare(first.fileName, second.fileName); + } + + public: + Utils::SmallStringView fileName; + int directoryId; + }; + + class FileNameEntry + { + public: + FileNameEntry(Utils::SmallStringView fileName, int directoryId) + : fileName(fileName), + directoryId(directoryId) + {} + + FileNameEntry(FileNameView view) + : fileName(view.fileName), + directoryId(view.directoryId) + {} + + friend bool operator==(const FileNameEntry &first, const FileNameEntry &second) + { + return first.directoryId == second.directoryId + && first.fileName == second.fileName; + } + + operator FileNameView() const + { + return {fileName, directoryId}; + } + + operator Utils::SmallString() && + { + return std::move(fileName); + } + + public: + Utils::SmallString fileName; + int directoryId; + }; + using DirectoryPathCache = StringCache; - using FileNameCache = StringCache; + decltype(&FileNameView::compare), + FileNameView::compare>; public: FilePathCache(FilePathStorage &filePathStorage) : m_filePathStorage(filePathStorage) @@ -67,8 +128,8 @@ public: Utils::SmallStringView fileName = filePath.name(); - int fileNameId = m_fileNameCache.stringId(fileName, - [&] (const Utils::SmallStringView) { + int fileNameId = m_fileNameCache.stringId({fileName, directoryId}, + [&] (const FileNameView) { return m_filePathStorage.fetchSourceId(directoryId, fileName); }); @@ -86,7 +147,9 @@ public: fetchFilePath); - auto fetchSoureName = [&] (int id) { return m_filePathStorage.fetchSourceName(id); }; + auto fetchSoureName = [&] (int id) { + return FileNameEntry{m_filePathStorage.fetchSourceName(id), filePathId.directoryId}; + }; Utils::SmallString fileName = m_fileNameCache.string(filePathId.filePathId, fetchSoureName); diff --git a/src/libs/clangsupport/stringcache.h b/src/libs/clangsupport/stringcache.h index 2c9f0159330..9192b46aa52 100644 --- a/src/libs/clangsupport/stringcache.h +++ b/src/libs/clangsupport/stringcache.h @@ -29,7 +29,6 @@ #include "stringcachefwd.h" #include -#include #include #include @@ -91,7 +90,9 @@ private: QReadWriteLock m_mutex; }; -template +template class StringCacheEntry { public: @@ -100,19 +101,22 @@ public: id(id) {} - operator Utils::SmallStringView() const + operator StringViewType() const { - return {string.data(), string.size()}; + return string; } StringType string; IndexType id; }; -template -using StringCacheEntries = std::vector>; +template +using StringCacheEntries = std::vector>; template ; - using CacheEntries = StringCacheEntries; + using CacheEntry = StringCacheEntry; + using CacheEntries = StringCacheEntries; using const_iterator = typename CacheEntries::const_iterator; using Found = ClangBackEnd::Found; @@ -145,7 +149,7 @@ public: { std::sort(entries.begin(), entries.end(), - [] (Utils::SmallStringView first, Utils::SmallStringView second) { + [] (StringViewType first, StringViewType second) { return compare(first, second) < 0; }); @@ -158,7 +162,7 @@ public: } - IndexType stringId(Utils::SmallStringView stringView) + IndexType stringId(StringViewType stringView) { std::shared_lock sharedLock(m_mutex); Found found = find(stringView); @@ -244,7 +248,7 @@ public: } template - IndexType stringId(Utils::SmallStringView stringView, Function storageFunction) + IndexType stringId(StringViewType stringView, Function storageFunction) { std::shared_lock sharedLock(m_mutex); @@ -271,7 +275,7 @@ public: } private: - Found find(Utils::SmallStringView stringView) + Found find(StringViewType stringView) { return findInSorted(m_strings.cbegin(), m_strings.cend(), stringView, compare); } @@ -293,7 +297,7 @@ private: } IndexType insertString(const_iterator beforeIterator, - Utils::SmallStringView stringView, + StringViewType stringView, IndexType id) { auto inserted = m_strings.emplace(beforeIterator, StringType(stringView), id); diff --git a/src/libs/clangsupport/stringcachefwd.h b/src/libs/clangsupport/stringcachefwd.h index 75f03056b20..adc00ff1f5f 100644 --- a/src/libs/clangsupport/stringcachefwd.h +++ b/src/libs/clangsupport/stringcachefwd.h @@ -32,6 +32,7 @@ namespace ClangBackEnd { class NonLockingMutex; template ; using StorageStringFunction = std::function; using Cache = ClangBackEnd::StringCache, decltype(&Utils::reverseCompare),