From d821ac34d811975224394b8b62d1886bcd1de3c4 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sun, 22 Apr 2018 10:01:44 -0700 Subject: [PATCH] Merge {timestamp_manager,iindexer}.{cc,h}; remove standard_includes.*; use last_write_time --- CMakeLists.txt | 10 +- src/cache_manager.cc | 7 -- src/cache_manager.h | 8 +- src/clang_indexer.cc | 59 +++++++++- src/clang_utils.cc | 3 + src/command_line.cc | 1 - src/file_consumer.cc | 2 - src/file_consumer.h | 2 +- src/iindexer.cc | 83 ------------- src/iindexer.h | 42 ------- src/import_pipeline.cc | 42 +++++-- src/import_pipeline.h | 19 ++- src/include_complete.cc | 10 -- src/include_complete.h | 1 - src/indexer.h | 37 ++++++ src/lsp_code_action.h | 27 +---- src/messages/ccls_freshen_index.cc | 4 +- src/platform_posix.cc | 22 ---- src/platform_win.cc | 22 ---- src/query.h | 1 - src/standard_includes.cc | 182 ----------------------------- src/standard_includes.h | 4 - src/symbol.h | 2 - src/timestamp_manager.cc | 27 ----- src/timestamp_manager.h | 22 ---- src/utils.cc | 11 ++ src/utils.h | 12 +- 27 files changed, 171 insertions(+), 491 deletions(-) delete mode 100644 src/iindexer.h delete mode 100644 src/standard_includes.cc delete mode 100644 src/standard_includes.h delete mode 100644 src/timestamp_manager.cc delete mode 100644 src/timestamp_manager.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 9ecb4680..97694a29 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -96,11 +96,12 @@ set(THREADS_PREFER_PTHREAD_FLAG ON) find_package(Threads REQUIRED) target_link_libraries(ccls PRIVATE Threads::Threads) -if(${CMAKE_SYSTEM_NAME} STREQUAL Darwin) - target_link_libraries(ccls PRIVATE -lc++experimental) +if(${CMAKE_SYSTEM_NAME} STREQUAL Linux) + target_link_libraries(ccls PRIVATE -lstdc++fs) elseif(MSVC) else() - target_link_libraries(ccls PRIVATE -lstdc++fs) + # e.g. Darwin, FreeBSD + target_link_libraries(ccls PRIVATE -lc++experimental) endif() if(${CMAKE_SYSTEM_NAME} STREQUAL Linux) @@ -212,7 +213,6 @@ target_sources(ccls PRIVATE src/file_consumer.cc src/filesystem.cc src/fuzzy_match.cc - src/iindexer.cc src/import_pipeline.cc src/include_complete.cc src/method.cc @@ -229,11 +229,9 @@ target_sources(ccls PRIVATE src/query.cc src/queue_manager.cc src/serializer.cc - src/standard_includes.cc src/test.cc src/third_party_impl.cc src/timer.cc - src/timestamp_manager.cc src/type_printer.cc src/utils.cc src/working_files.cc) diff --git a/src/cache_manager.cc b/src/cache_manager.cc index beb9186b..d33f66fe 100644 --- a/src/cache_manager.cc +++ b/src/cache_manager.cc @@ -143,10 +143,3 @@ std::unique_ptr ICacheManager::TakeOrLoad(const std::string& path) { assert(result); return result; } - -void ICacheManager::IterateLoadedCaches(std::function fn) { - for (const auto& cache : caches_) { - assert(cache.second); - fn(cache.second.get()); - } -} diff --git a/src/cache_manager.h b/src/cache_manager.h index 0904f098..920e3719 100644 --- a/src/cache_manager.h +++ b/src/cache_manager.h @@ -2,7 +2,6 @@ #include -#include #include #include #include @@ -41,8 +40,11 @@ struct ICacheManager { virtual std::optional LoadCachedFileContents( const std::string& path) = 0; - // Iterate over all loaded caches. - void IterateLoadedCaches(std::function fn); + template + void IterateLoadedCaches(Fn fn) { + for (const auto& cache : caches_) + fn(cache.second.get()); + } protected: virtual std::unique_ptr RawCacheLoad(const std::string& path) = 0; diff --git a/src/clang_indexer.cc b/src/clang_indexer.cc index 6c6426b0..8c4d25cd 100644 --- a/src/clang_indexer.cc +++ b/src/clang_indexer.cc @@ -371,7 +371,7 @@ IndexFile* ConsumeFile(IndexParam* param, CXFile file) { param->seen_files.push_back(file_name); // Set modification time. - std::optional modification_time = GetLastModificationTime(file_name); + std::optional modification_time = LastWriteTime(file_name); LOG_IF_S(ERROR, !modification_time) << "Failed fetching modification time for " << file_name; if (modification_time) @@ -2358,3 +2358,60 @@ void Reflect(Writer& visitor, Reference& value) { Reflect(visitor, value.role); } } + +namespace { + +struct TestIndexer : IIndexer { + static std::unique_ptr FromEntries( + const std::vector& entries) { + auto result = std::make_unique(); + + for (const TestEntry& entry : entries) { + std::vector> indexes; + + if (entry.num_indexes > 0) + indexes.push_back(std::make_unique(entry.path, "")); + for (int i = 1; i < entry.num_indexes; ++i) { + indexes.push_back(std::make_unique( + entry.path + "_extra_" + std::to_string(i) + ".h", "")); + } + + result->indexes.insert(std::make_pair(entry.path, std::move(indexes))); + } + + return result; + } + + ~TestIndexer() override = default; + + std::vector> Index( + FileConsumerSharedState* file_consumer_shared, + std::string file, + const std::vector& args, + const std::vector& file_contents, + PerformanceImportFile* perf) override { + auto it = indexes.find(file); + if (it == indexes.end()) { + // Don't return any indexes for unexpected data. + assert(false && "no indexes"); + return {}; + } + + // FIXME: allow user to control how many times we return the index for a + // specific file (atm it is always 1) + auto result = std::move(it->second); + indexes.erase(it); + return result; + } + + std::unordered_map>> + indexes; +}; + +} // namespace + +// static +std::unique_ptr IIndexer::MakeTestIndexer( + std::initializer_list entries) { + return TestIndexer::FromEntries(entries); +} diff --git a/src/clang_utils.cc b/src/clang_utils.cc index b9da4daf..07685050 100644 --- a/src/clang_utils.cc +++ b/src/clang_utils.cc @@ -138,6 +138,8 @@ const char* ClangBuiltinTypeName(CXTypeKind kind) { case CXType_Bool: return "bool"; case CXType_Char_U: return "char"; case CXType_UChar: return "unsigned char"; + case CXType_Char16: return "char16_t"; + case CXType_Char32: return "char32_t"; case CXType_UShort: return "unsigned short"; case CXType_UInt: return "unsigned int"; case CXType_ULong: return "unsigned long"; @@ -146,6 +148,7 @@ const char* ClangBuiltinTypeName(CXTypeKind kind) { case CXType_Char_S: return "char"; case CXType_SChar: return "signed char"; case CXType_WChar: return "wchar_t"; + case CXType_Short: return "short"; case CXType_Int: return "int"; case CXType_Long: return "long"; case CXType_LongLong: return "long long"; diff --git a/src/command_line.cc b/src/command_line.cc index cea67191..c244811f 100644 --- a/src/command_line.cc +++ b/src/command_line.cc @@ -21,7 +21,6 @@ #include "serializers/json.h" #include "test.h" #include "timer.h" -#include "timestamp_manager.h" #include "working_files.h" #include diff --git a/src/file_consumer.cc b/src/file_consumer.cc index 796bb9f0..6ba69cfb 100644 --- a/src/file_consumer.cc +++ b/src/file_consumer.cc @@ -29,8 +29,6 @@ bool operator==(const CXFileUniqueID& a, const CXFileUniqueID& b) { a.data[2] == b.data[2]; } -FileContents::FileContents() : line_offsets_{0} {} - FileContents::FileContents(const std::string& path, const std::string& content) : path(path), content(content) { line_offsets_.push_back(0); diff --git a/src/file_consumer.h b/src/file_consumer.h index 520aa5ed..4f8216a4 100644 --- a/src/file_consumer.h +++ b/src/file_consumer.h @@ -18,7 +18,7 @@ MAKE_HASHABLE(CXFileUniqueID, t.data[0], t.data[1], t.data[2]); bool operator==(const CXFileUniqueID& a, const CXFileUniqueID& b); struct FileContents { - FileContents(); + FileContents() = default; FileContents(const std::string& path, const std::string& content); std::optional ToOffset(Position p) const; diff --git a/src/iindexer.cc b/src/iindexer.cc index 7578fa22..e69de29b 100644 --- a/src/iindexer.cc +++ b/src/iindexer.cc @@ -1,83 +0,0 @@ -#include "iindexer.h" - -#include "indexer.h" - -namespace { -struct ClangIndexer : IIndexer { - ~ClangIndexer() override = default; - - std::vector> Index( - FileConsumerSharedState* file_consumer_shared, - std::string file, - const std::vector& args, - const std::vector& file_contents, - PerformanceImportFile* perf) override { - return Parse(file_consumer_shared, file, args, file_contents, perf, &index); - } - - // Note: constructing this acquires a global lock - ClangIndex index; -}; - -struct TestIndexer : IIndexer { - static std::unique_ptr FromEntries( - const std::vector& entries) { - auto result = std::make_unique(); - - for (const TestEntry& entry : entries) { - std::vector> indexes; - - if (entry.num_indexes > 0) - indexes.push_back(std::make_unique(entry.path, "")); - for (int i = 1; i < entry.num_indexes; ++i) { - indexes.push_back(std::make_unique( - entry.path + "_extra_" + std::to_string(i) + ".h", "")); - } - - result->indexes.insert(std::make_pair(entry.path, std::move(indexes))); - } - - return result; - } - - ~TestIndexer() override = default; - - std::vector> Index( - FileConsumerSharedState* file_consumer_shared, - std::string file, - const std::vector& args, - const std::vector& file_contents, - PerformanceImportFile* perf) override { - auto it = indexes.find(file); - if (it == indexes.end()) { - // Don't return any indexes for unexpected data. - assert(false && "no indexes"); - return {}; - } - - // FIXME: allow user to control how many times we return the index for a - // specific file (atm it is always 1) - auto result = std::move(it->second); - indexes.erase(it); - return result; - } - - std::unordered_map>> - indexes; -}; - -} // namespace - -IIndexer::TestEntry::TestEntry(const std::string& path, int num_indexes) - : path(path), num_indexes(num_indexes) {} - -// static -std::unique_ptr IIndexer::MakeClangIndexer() { - return std::make_unique(); -} - -// static -std::unique_ptr IIndexer::MakeTestIndexer( - std::initializer_list entries) { - return TestIndexer::FromEntries(entries); -} diff --git a/src/iindexer.h b/src/iindexer.h deleted file mode 100644 index 84b73a84..00000000 --- a/src/iindexer.h +++ /dev/null @@ -1,42 +0,0 @@ -#pragma once - -#include - -#include -#include -#include -#include - -// TODO: -// - rename indexer.h to clang_indexer.h and pull out non-clang specific code -// like IndexFile -// - rename this file to indexer.h - -struct IndexFile; -struct FileContents; -struct FileConsumerSharedState; -struct PerformanceImportFile; - -// Abstracts away the actual indexing process. Each IIndexer instance is -// per-thread and constructing an instance may be extremely expensive (ie, -// acquire a lock) and should be done as rarely as possible. -struct IIndexer { - struct TestEntry { - std::string path; - int num_indexes = 0; - - TestEntry(const std::string& path, int num_indexes); - }; - - static std::unique_ptr MakeClangIndexer(); - static std::unique_ptr MakeTestIndexer( - std::initializer_list entries); - - virtual ~IIndexer() = default; - virtual std::vector> Index( - FileConsumerSharedState* file_consumer_shared, - std::string file, - const std::vector& args, - const std::vector& file_contents, - PerformanceImportFile* perf) = 0; -}; diff --git a/src/import_pipeline.cc b/src/import_pipeline.cc index cea5ad6e..f970e92b 100644 --- a/src/import_pipeline.cc +++ b/src/import_pipeline.cc @@ -3,7 +3,6 @@ #include "cache_manager.h" #include "config.h" #include "diagnostics_engine.h" -#include "iindexer.h" #include "import_manager.h" #include "lsp.h" #include "message_handler.h" @@ -12,15 +11,11 @@ #include "query_utils.h" #include "queue_manager.h" #include "timer.h" -#include "timestamp_manager.h" #include #include -#include #include -#include -#include namespace { @@ -63,14 +58,14 @@ struct IterationLoop { struct IModificationTimestampFetcher { virtual ~IModificationTimestampFetcher() = default; - virtual std::optional GetModificationTime(const std::string& path) = 0; + virtual std::optional LastWriteTime(const std::string& path) = 0; }; struct RealModificationTimestampFetcher : IModificationTimestampFetcher { ~RealModificationTimestampFetcher() override = default; // IModificationTimestamp: - std::optional GetModificationTime(const std::string& path) override { - return GetLastModificationTime(path); + std::optional LastWriteTime(const std::string& path) override { + return ::LastWriteTime(path); } }; struct FakeModificationTimestampFetcher : IModificationTimestampFetcher { @@ -79,7 +74,7 @@ struct FakeModificationTimestampFetcher : IModificationTimestampFetcher { ~FakeModificationTimestampFetcher() override = default; // IModificationTimestamp: - std::optional GetModificationTime(const std::string& path) override { + std::optional LastWriteTime(const std::string& path) override { auto it = entries.find(path); assert(it != entries.end()); return it->second; @@ -174,7 +169,7 @@ ShouldParse FileNeedsParse( } std::optional modification_timestamp = - modification_timestamp_fetcher->GetModificationTime(path); + modification_timestamp_fetcher->LastWriteTime(path); // Cannot find file. if (!modification_timestamp) @@ -327,7 +322,7 @@ std::vector PreloadFileContents( // still valid. if so, we can use it, otherwise we need to load from disk. auto get_latest_content = [](const std::string& path, int64_t cached_time, const std::string& cached) -> std::string { - std::optional mod_time = GetLastModificationTime(path); + std::optional mod_time = LastWriteTime(path); if (!mod_time) return ""; @@ -533,6 +528,29 @@ bool IndexMergeIndexUpdates() { } // namespace +std::optional TimestampManager::GetLastCachedModificationTime( + ICacheManager* cache_manager, + const std::string& path) { + { + std::lock_guard guard(mutex_); + auto it = timestamps_.find(path); + if (it != timestamps_.end()) + return it->second; + } + IndexFile* file = cache_manager->TryLoad(path); + if (!file) + return std::nullopt; + + UpdateCachedModificationTime(path, file->last_modification_time); + return file->last_modification_time; +} + +void TimestampManager::UpdateCachedModificationTime(const std::string& path, + int64_t timestamp) { + std::lock_guard guard(mutex_); + timestamps_[path] = timestamp; +} + ImportPipelineStatus::ImportPipelineStatus() : num_active_threads(0), next_progress_output(0) {} @@ -586,7 +604,7 @@ void Indexer_Main(DiagnosticsEngine* diag_engine, RealModificationTimestampFetcher modification_timestamp_fetcher; auto* queue = QueueManager::instance(); // Build one index per-indexer, as building the index acquires a global lock. - auto indexer = IIndexer::MakeClangIndexer(); + auto indexer = std::make_unique(); while (true) { bool did_work = false; diff --git a/src/import_pipeline.h b/src/import_pipeline.h index f7e750f9..5a0fbc4e 100644 --- a/src/import_pipeline.h +++ b/src/import_pipeline.h @@ -5,20 +5,37 @@ #include #include +#include #include +#include +#include #include struct ClangTranslationUnit; class DiagnosticsEngine; struct FileConsumerSharedState; +struct ICacheManager; struct ImportManager; struct MultiQueueWaiter; struct Project; struct QueryDatabase; struct SemanticHighlightSymbolCache; -struct TimestampManager; struct WorkingFiles; +// Caches timestamps of cc files so we can avoid a filesystem reads. This is +// important for import perf, as during dependency checking the same files are +// checked over and over again if they are common headers. +struct TimestampManager { + std::optional GetLastCachedModificationTime(ICacheManager* cache_manager, + const std::string& path); + + void UpdateCachedModificationTime(const std::string& path, int64_t timestamp); + + // TODO: use std::shared_mutex so we can have multiple readers. + std::mutex mutex_; + std::unordered_map timestamps_; +}; + struct ImportPipelineStatus { std::atomic num_active_threads; std::atomic next_progress_output; diff --git a/src/include_complete.cc b/src/include_complete.cc index 4bedad39..f5ea1fc3 100644 --- a/src/include_complete.cc +++ b/src/include_complete.cc @@ -4,7 +4,6 @@ #include "match.h" #include "platform.h" #include "project.h" -#include "standard_includes.h" #include "timer.h" #include @@ -107,7 +106,6 @@ void IncludeComplete::Rescan() { SetThreadName("scan_includes"); Timer timer; - InsertStlIncludes(); InsertIncludesFromDirectory(g_config->projectRoot, false /*use_angle_brackets*/); for (const std::string& dir : project_->quote_include_directories) @@ -189,14 +187,6 @@ void IncludeComplete::InsertIncludesFromDirectory(std::string directory, std::move(result.completion_item)); } -void IncludeComplete::InsertStlIncludes() { - std::lock_guard lock(completion_items_mutex); - for (const char* stl_header : kStandardLibraryIncludes) { - completion_items.push_back(BuildCompletionItem( - stl_header, true /*use_angle_brackets*/, true /*is_stl*/)); - } -} - std::optional IncludeComplete::FindCompletionItemForAbsolutePath( const std::string& absolute_path) { std::lock_guard lock(completion_items_mutex); diff --git a/src/include_complete.h b/src/include_complete.h index 9cbee1ab..c45c2562 100644 --- a/src/include_complete.h +++ b/src/include_complete.h @@ -22,7 +22,6 @@ struct IncludeComplete { // blocking function and should be run off the querydb thread. void InsertIncludesFromDirectory(std::string directory, bool use_angle_brackets); - void InsertStlIncludes(); std::optional FindCompletionItemForAbsolutePath( const std::string& absolute_path); diff --git a/src/indexer.h b/src/indexer.h index 43035a6b..7b46b4e8 100644 --- a/src/indexer.h +++ b/src/indexer.h @@ -488,3 +488,40 @@ std::vector> ParseWithTu( bool ConcatTypeAndName(std::string& type, const std::string& name); void IndexInit(); + +// Abstracts away the actual indexing process. Each IIndexer instance is +// per-thread and constructing an instance may be extremely expensive (ie, +// acquire a lock) and should be done as rarely as possible. +struct IIndexer { + struct TestEntry { + std::string path; + int num_indexes = 0; + }; + + static std::unique_ptr MakeTestIndexer( + std::initializer_list entries); + + virtual ~IIndexer() = default; + virtual std::vector> Index( + FileConsumerSharedState* file_consumer_shared, + std::string file, + const std::vector& args, + const std::vector& file_contents, + PerformanceImportFile* perf) = 0; +}; + +struct ClangIndexer : IIndexer { + ~ClangIndexer() override = default; + + std::vector> Index( + FileConsumerSharedState* file_consumer_shared, + std::string file, + const std::vector& args, + const std::vector& file_contents, + PerformanceImportFile* perf) override { + return Parse(file_consumer_shared, file, args, file_contents, perf, &index); + } + + // Note: constructing this acquires a global lock + ClangIndex index; +}; diff --git a/src/lsp_code_action.h b/src/lsp_code_action.h index 44aa1381..2fbc5f4a 100644 --- a/src/lsp_code_action.h +++ b/src/lsp_code_action.h @@ -18,29 +18,4 @@ struct lsCodeLensCommandArguments { lsPosition position; std::vector locations; }; - -// FIXME Don't use array in vscode-ccls -inline void Reflect(Writer& visitor, lsCodeLensCommandArguments& value) { - visitor.StartArray(3); - Reflect(visitor, value.uri); - Reflect(visitor, value.position); - Reflect(visitor, value.locations); - visitor.EndArray(); -} - -inline void Reflect(Reader& visitor, lsCodeLensCommandArguments& value) { - int i = 0; - visitor.IterArray([&](Reader& visitor) { - switch (i++) { - case 0: - Reflect(visitor, value.uri); - break; - case 1: - Reflect(visitor, value.position); - break; - case 2: - Reflect(visitor, value.locations); - break; - } - }); -} +MAKE_REFLECT_STRUCT(lsCodeLensCommandArguments, uri, position, locations) diff --git a/src/messages/ccls_freshen_index.cc b/src/messages/ccls_freshen_index.cc index 91d0bc00..1989578d 100644 --- a/src/messages/ccls_freshen_index.cc +++ b/src/messages/ccls_freshen_index.cc @@ -1,11 +1,11 @@ #include "cache_manager.h" +#include "import_pipeline.h" #include "match.h" #include "message_handler.h" #include "platform.h" #include "project.h" #include "queue_manager.h" #include "timer.h" -#include "timestamp_manager.h" #include "working_files.h" #include @@ -66,7 +66,7 @@ struct Handler_CclsFreshenIndex : BaseMessageHandler { need_index.insert(file->def->path); std::optional modification_timestamp = - GetLastModificationTime(file->def->path); + LastWriteTime(file->def->path); if (!modification_timestamp) continue; std::optional cached_modification = diff --git a/src/platform_posix.cc b/src/platform_posix.cc index 4e9b952f..aba1b7f0 100644 --- a/src/platform_posix.cc +++ b/src/platform_posix.cc @@ -166,28 +166,6 @@ void SetThreadName(const std::string& thread_name) { #endif } -std::optional GetLastModificationTime(const std::string& absolute_path) { - struct stat buf; - if (stat(absolute_path.c_str(), &buf) != 0) { - switch (errno) { - case ENOENT: - // std::cerr << "GetLastModificationTime: unable to find file " << - // absolute_path << std::endl; - return std::nullopt; - case EINVAL: - // std::cerr << "GetLastModificationTime: invalid param to _stat for - // file file " << absolute_path << std::endl; - return std::nullopt; - default: - // std::cerr << "GetLastModificationTime: unhandled for " << - // absolute_path << std::endl; exit(1); - return std::nullopt; - } - } - - return buf.st_mtime; -} - void FreeUnusedMemory() { #if defined(__GLIBC__) malloc_trim(0); diff --git a/src/platform_win.cc b/src/platform_win.cc index f4c71a95..471c73be 100644 --- a/src/platform_win.cc +++ b/src/platform_win.cc @@ -79,28 +79,6 @@ void SetThreadName(const std::string& thread_name) { } } -std::optional GetLastModificationTime(const std::string& absolute_path) { - struct _stat buf; - if (_stat(absolute_path.c_str(), &buf) != 0) { - switch (errno) { - case ENOENT: - // std::cerr << "GetLastModificationTime: unable to find file " << - // absolute_path << std::endl; - return std::nullopt; - case EINVAL: - // std::cerr << "GetLastModificationTime: invalid param to _stat for - // file file " << absolute_path << std::endl; - return std::nullopt; - default: - // std::cerr << "GetLastModificationTime: unhandled for " << - // absolute_path << std::endl; exit(1); - return std::nullopt; - } - } - - return buf.st_mtime; -} - void FreeUnusedMemory() {} // TODO Wait for debugger to attach diff --git a/src/query.h b/src/query.h index e5cdd719..f75ad551 100644 --- a/src/query.h +++ b/src/query.h @@ -6,7 +6,6 @@ #include #include -#include struct QueryFile; struct QueryType; diff --git a/src/standard_includes.cc b/src/standard_includes.cc deleted file mode 100644 index 43a67c30..00000000 --- a/src/standard_includes.cc +++ /dev/null @@ -1,182 +0,0 @@ -#include "standard_includes.h" - -// See http://stackoverflow.com/a/2029106. -const char* kStandardLibraryIncludes[177] = { - "aio.h", - "algorithm", - "any", - "arpa/inet.h", - "array", - "assert.h", - "atomic", - "bitset", - "cassert", - "ccomplex", - "cctype", - "cerrno", - "cfenv", - "cfloat", - "chrono", - "cinttypes", - "ciso646", - "climits", - "clocale", - "cmath", - "codecvt", - "complex", - "complex.h", - "condition_variable", - "cpio.h", - "csetjmp", - "csignal", - "cstdalign", - "cstdarg", - "cstdbool", - "cstddef", - "cstdint", - "cstdio", - "cstdlib", - "cstring", - "ctgmath", - "ctime", - "ctype.h", - "cuchar", - "curses.h", - "cwchar", - "cwctype", - "deque", - "dirent.h", - "dlfcn.h", - "errno.h", - "exception", - "execution", - "fcntl.h", - "fenv.h", - "filesystem", - "float.h", - "fmtmsg.h", - "fnmatch.h", - "forward_list", - "fstream", - "ftw.h", - "functional", - "future", - "glob.h", - "grp.h", - "iconv.h", - "initializer_list", - "inttypes.h", - "iomanip", - "ios", - "iosfwd", - "iostream", - "iso646.h", - "istream", - "iterator", - "langinfo.h", - "libgen.h", - "limits", - "limits.h", - "list", - "locale", - "locale.h", - "map", - "math.h", - "memory", - "memory_resource", - "monetary.h", - "mqueue.h", - "mutex", - "ndbm.h", - "net/if.h", - "netdb.h", - "netinet/in.h", - "netinet/tcp.h", - "new", - "nl_types.h", - "numeric", - "std::optional", - "ostream", - "poll.h", - "pthread.h", - "pwd.h", - "queue", - "random", - "ratio", - "regex", - "regex.h", - "sched.h", - "scoped_allocator", - "search.h", - "semaphore.h", - "set", - "setjmp.h", - "shared_mutex", - "signal.h", - "spawn.h", - "sstream", - "stack", - "stdalign.h", - "stdarg.h", - "stdatomic.h", - "stdbool.h", - "stddef.h", - "stdexcept", - "stdint.h", - "stdio.h", - "stdlib.h", - "stdnoreturn.h", - "streambuf", - "string", - "string.h", - "string_view", - "strings.h", - "stropts.h", - "strstream", - "sys/ipc.h", - "sys/mman.h", - "sys/msg.h", - "sys/resource.h", - "sys/select.h", - "sys/sem.h", - "sys/shm.h", - "sys/socket.h", - "sys/stat.h", - "sys/statvfs.h", - "sys/time.h", - "sys/times.h", - "sys/types.h", - "sys/uio.h", - "sys/un.h", - "sys/utsname.h", - "sys/wait.h", - "syslog.h", - "system_error", - "tar.h", - "term.h", - "termios.h", - "tgmath.h", - "thread", - "threads.h", - "time.h", - "trace.h", - "tuple", - "type_traits", - "typeindex", - "typeinfo", - "uchar.h", - "ulimit.h", - "uncntrl.h", - "unistd.h", - "unordered_map", - "unordered_set", - "utility", - "utime.h", - "utmpx.h", - "valarray", - "variant", - "vector", - "wchar.h", - "wctype.h", - "wordexp.h", -}; \ No newline at end of file diff --git a/src/standard_includes.h b/src/standard_includes.h deleted file mode 100644 index 6c50227d..00000000 --- a/src/standard_includes.h +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once - -// A set of standard libary header names, ie, "vector". -extern const char* kStandardLibraryIncludes[177]; \ No newline at end of file diff --git a/src/symbol.h b/src/symbol.h index 54a09272..13b9f39a 100644 --- a/src/symbol.h +++ b/src/symbol.h @@ -7,7 +7,6 @@ // front of others. enum class SymbolKind : uint8_t { Invalid, File, Type, Func, Var }; MAKE_REFLECT_TYPE_PROXY(SymbolKind); -MAKE_ENUM_HASHABLE(SymbolKind); // clang/Basic/Specifiers.h clang::StorageClass enum class StorageClass : uint8_t { @@ -44,7 +43,6 @@ enum class Role : uint16_t { All = (1 << 9) - 1, }; MAKE_REFLECT_TYPE_PROXY(Role); -MAKE_ENUM_HASHABLE(Role); inline uint16_t operator&(Role lhs, Role rhs) { return uint16_t(lhs) & uint16_t(rhs); diff --git a/src/timestamp_manager.cc b/src/timestamp_manager.cc deleted file mode 100644 index 77f69acc..00000000 --- a/src/timestamp_manager.cc +++ /dev/null @@ -1,27 +0,0 @@ -#include "timestamp_manager.h" - -#include "cache_manager.h" -#include "indexer.h" - -std::optional TimestampManager::GetLastCachedModificationTime( - ICacheManager* cache_manager, - const std::string& path) { - { - std::lock_guard guard(mutex_); - auto it = timestamps_.find(path); - if (it != timestamps_.end()) - return it->second; - } - IndexFile* file = cache_manager->TryLoad(path); - if (!file) - return std::nullopt; - - UpdateCachedModificationTime(path, file->last_modification_time); - return file->last_modification_time; -} - -void TimestampManager::UpdateCachedModificationTime(const std::string& path, - int64_t timestamp) { - std::lock_guard guard(mutex_); - timestamps_[path] = timestamp; -} diff --git a/src/timestamp_manager.h b/src/timestamp_manager.h deleted file mode 100644 index ac02b10f..00000000 --- a/src/timestamp_manager.h +++ /dev/null @@ -1,22 +0,0 @@ -#pragma once - -#include - -#include -#include - -struct ICacheManager; - -// Caches timestamps of cc files so we can avoid a filesystem reads. This is -// important for import perf, as during dependency checking the same files are -// checked over and over again if they are common headers. -struct TimestampManager { - std::optional GetLastCachedModificationTime(ICacheManager* cache_manager, - const std::string& path); - - void UpdateCachedModificationTime(const std::string& path, int64_t timestamp); - - // TODO: use std::shared_mutex so we can have multiple readers. - std::mutex mutex_; - std::unordered_map timestamps_; -}; \ No newline at end of file diff --git a/src/utils.cc b/src/utils.cc index eb8fb6a3..c9d05a8d 100644 --- a/src/utils.cc +++ b/src/utils.cc @@ -1,5 +1,6 @@ #include "utils.h" +#include "filesystem.hh" #include "platform.h" #include @@ -130,6 +131,7 @@ std::optional ReadContent(const std::string& filename) { size_t n; while ((n = fread(buf, 1, sizeof buf, f)) > 0) ret.append(buf, n); + fclose(f); return ret; } @@ -142,6 +144,15 @@ void WriteToFile(const std::string& filename, const std::string& content) { fclose(f); } +std::optional LastWriteTime(const std::string& filename) { + std::error_code ec; + auto ftime = fs::last_write_time(filename, ec); + if (ec) return std::nullopt; + return std::chrono::time_point_cast(ftime) + .time_since_epoch() + .count(); +} + std::string GetDefaultResourceDirectory() { std::string result; diff --git a/src/utils.h b/src/utils.h index 6b117d05..3c49bab8 100644 --- a/src/utils.h +++ b/src/utils.h @@ -62,8 +62,8 @@ void EnsureEndsInSlash(std::string& path); std::string EscapeFileName(std::string path); std::optional ReadContent(const std::string& filename); - void WriteToFile(const std::string& filename, const std::string& content); +std::optional LastWriteTime(const std::string& filename); // http://stackoverflow.com/a/38140932 // @@ -95,14 +95,4 @@ inline void hash_combine(std::size_t& seed, const T& v, Rest... rest) { }; \ } -#define MAKE_ENUM_HASHABLE(type) \ - namespace std { \ - template <> \ - struct hash { \ - std::size_t operator()(const type& t) const { \ - return hash()(static_cast(t)); \ - } \ - }; \ - } - std::string GetDefaultResourceDirectory();