From f0400fdcf27ac2280b90a7993286e7f3646d9c3a Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Thu, 20 Sep 2018 18:04:55 -0700 Subject: [PATCH] Delete file_consumer.* --- CMakeLists.txt | 1 - src/file_consumer.cc | 63 --------------------------------- src/file_consumer.h | 70 ------------------------------------- src/indexer.cc | 33 ++++++++++++----- src/indexer.h | 12 ++++++- src/messages/ccls_reload.cc | 5 +-- src/pipeline.cc | 21 +++++++++++ src/pipeline.hh | 15 ++++++++ src/test.cc | 1 + 9 files changed, 73 insertions(+), 148 deletions(-) delete mode 100644 src/file_consumer.cc delete mode 100644 src/file_consumer.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 20a4bd91..3985e129 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -183,7 +183,6 @@ target_sources(ccls PRIVATE src/clang_tu.cc src/clang_utils.cc src/config.cc - src/file_consumer.cc src/filesystem.cc src/fuzzy_match.cc src/main.cc diff --git a/src/file_consumer.cc b/src/file_consumer.cc deleted file mode 100644 index 40ad2dc3..00000000 --- a/src/file_consumer.cc +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright 2017-2018 ccls Authors -// SPDX-License-Identifier: Apache-2.0 - -#include "file_consumer.h" - -#include "clang_utils.h" -#include "indexer.h" -#include "log.hh" -#include "platform.h" -#include "utils.h" - -bool VFS::Loaded(const std::string &path) { - std::lock_guard lock(mutex); - return state[path].loaded; -} - -bool VFS::Stamp(const std::string &path, int64_t ts, int step) { - std::lock_guard lock(mutex); - State &st = state[path]; - if (st.timestamp < ts || (st.timestamp == ts && st.step < step)) { - st.timestamp = ts; - st.step = step; - return true; - } else - return false; -} - -FileConsumer::FileConsumer(VFS *vfs, const std::string &parse_file) - : vfs_(vfs), parse_file_(parse_file) {} - -IndexFile *FileConsumer::TryConsumeFile( - const clang::FileEntry &File, - const std::unordered_map - &UID2File) { - auto UniqueID = File.getUniqueID(); - { - auto it = local_.find(UniqueID); - if (it != local_.end()) - return it->second.get(); - } - - auto it = UID2File.find(UniqueID); - assert(it != UID2File.end()); - assert(it->second.mtime); - if (!vfs_->Stamp(it->second.path, it->second.mtime, 1)) { - local_[UniqueID] = nullptr; - return nullptr; - } - - // Build IndexFile instance. - local_[UniqueID] = - std::make_unique(UniqueID, it->second.path, it->second.content); - return local_[UniqueID].get(); -} - -std::vector> FileConsumer::TakeLocalState() { - std::vector> result; - for (auto &entry : local_) { - if (entry.second) - result.push_back(std::move(entry.second)); - } - return result; -} diff --git a/src/file_consumer.h b/src/file_consumer.h deleted file mode 100644 index a2f27298..00000000 --- a/src/file_consumer.h +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright 2017-2018 ccls Authors -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include "position.h" -#include "serializer.h" -#include "utils.h" - -#include - -#include -#include -#include - -struct IndexFile; - -struct VFS { - struct State { - int64_t timestamp; - int step; - bool loaded; - }; - mutable std::unordered_map state; - mutable std::mutex mutex; - - bool Loaded(const std::string &path); - bool Stamp(const std::string &path, int64_t ts, int step); -}; - -namespace std { -template <> struct hash { - std::size_t operator()(llvm::sys::fs::UniqueID ID) const { - size_t ret = ID.getDevice(); - hash_combine(ret, ID.getFile()); - return ret; - } -}; -} // namespace std - -// FileConsumer is used by the indexer. When it encouters a file, it tries to -// take ownership over it. If the indexer has ownership over a file, it will -// produce an index, otherwise, it will emit nothing for that declarations -// and references coming from that file. -// -// The indexer does this because header files do not have their own translation -// units but we still want to index them. -struct FileConsumer { - struct File { - std::string path; - int64_t mtime; - std::string content; - }; - - FileConsumer(VFS *vfs, const std::string &parse_file); - - // Returns IndexFile or nullptr for the file or nullptr. - IndexFile *TryConsumeFile( - const clang::FileEntry &file, - const std::unordered_map &); - - // Returns and passes ownership of all local state. - std::vector> TakeLocalState(); - -private: - std::unordered_map> - local_; - VFS *vfs_; - std::string parse_file_; -}; diff --git a/src/indexer.cc b/src/indexer.cc index f1a0ea89..e10f7dcd 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -7,6 +7,7 @@ #include "clang_tu.h" #include "log.hh" #include "match.h" +#include "pipeline.hh" #include "platform.h" #include "serializer.h" using namespace ccls; @@ -36,8 +37,15 @@ constexpr int kInitializerMaxLines = 3; GroupMatch *multiVersionMatcher; +struct File { + std::string path; + int64_t mtime; + std::string content; + std::unique_ptr db; +}; + struct IndexParam { - std::unordered_map UID2File; + std::unordered_map UID2File; std::unordered_map UID2multi; struct DeclInfo { Usr usr; @@ -46,10 +54,9 @@ struct IndexParam { }; std::unordered_map Decl2Info; + VFS &vfs; ASTContext *Ctx; - FileConsumer *file_consumer = nullptr; - - IndexParam(FileConsumer *file_consumer) : file_consumer(file_consumer) {} + IndexParam(VFS &vfs) : vfs(vfs) {} void SeenFile(const FileEntry &File) { // If this is the first time we have seen the file (ignoring if we are @@ -64,12 +71,17 @@ struct IndexParam { it->second.mtime = *tim; if (std::optional content = ReadContent(path)) it->second.content = *content; + + if (!vfs.Stamp(path, it->second.mtime, 1)) + return; + it->second.db = std::make_unique(File.getUniqueID(), path, + it->second.content); } } IndexFile *ConsumeFile(const FileEntry &FE) { SeenFile(FE); - return file_consumer->TryConsumeFile(FE, UID2File); + return UID2File[FE.getUniqueID()].db.get(); } bool UseMultiVersion(const FileEntry &FE) { @@ -1262,8 +1274,7 @@ Index(CompletionManager *completion, WorkingFiles *wfiles, VFS *vfs, if (!Clang->hasTarget()) return {}; - FileConsumer file_consumer(vfs, file); - IndexParam param(&file_consumer); + IndexParam param(*vfs); auto DataConsumer = std::make_shared(param); index::IndexingOptions IndexOpts; @@ -1300,8 +1311,11 @@ Index(CompletionManager *completion, WorkingFiles *wfiles, VFS *vfs, for (auto &Buf : Bufs) Buf.release(); - auto result = param.file_consumer->TakeLocalState(); - for (std::unique_ptr &entry : result) { + std::vector> result; + for (auto &it : param.UID2File) { + if (!it.second.db) + continue; + std::unique_ptr &entry = it.second.db; entry->import_file = file; entry->args = args; for (auto &[_, it] : entry->uid2lid_and_path) @@ -1331,6 +1345,7 @@ Index(CompletionManager *completion, WorkingFiles *wfiles, VFS *vfs, entry->dependencies[llvm::CachedHashStringRef(Intern(path))] = file.mtime; } + result.push_back(std::move(entry)); } return result; diff --git a/src/indexer.h b/src/indexer.h index f2f74070..11c2b58b 100644 --- a/src/indexer.h +++ b/src/indexer.h @@ -4,7 +4,6 @@ #pragma once #include "clang_utils.h" -#include "file_consumer.h" #include "language.h" #include "lsp.h" #include "lsp_diagnostic.h" @@ -224,6 +223,16 @@ struct IndexInclude { const char *resolved_path; }; +namespace std { +template <> struct hash { + std::size_t operator()(llvm::sys::fs::UniqueID ID) const { + size_t ret = ID.getDevice(); + hash_combine(ret, ID.getFile()); + return ret; + } +}; +} // namespace std + struct IndexFile { // For both JSON and MessagePack cache files. static const int kMajorVersion; @@ -275,6 +284,7 @@ struct IndexFile { struct CompletionManager; struct WorkingFiles; +struct VFS; namespace ccls::idx { void Init(); diff --git a/src/messages/ccls_reload.cc b/src/messages/ccls_reload.cc index cea27bee..55963e81 100644 --- a/src/messages/ccls_reload.cc +++ b/src/messages/ccls_reload.cc @@ -35,10 +35,7 @@ struct Handler_CclsReload : BaseMessageHandler { const auto ¶ms = request->params; // Send index requests for every file. if (params.whitelist.empty() && params.blacklist.empty()) { - { - std::lock_guard lock(vfs->mutex); - vfs->state.clear(); - } + vfs->Clear(); db->clear(); project->Index(working_files, lsRequestId()); return; diff --git a/src/pipeline.cc b/src/pipeline.cc index bfc6368e..4a885520 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -62,6 +62,27 @@ void DiagnosticsPublisher::Publish(WorkingFiles *working_files, } } +void VFS::Clear() { + std::lock_guard lock(mutex); + state.clear(); +} + +bool VFS::Loaded(const std::string &path) { + std::lock_guard lock(mutex); + return state[path].loaded; +} + +bool VFS::Stamp(const std::string &path, int64_t ts, int step) { + std::lock_guard lock(mutex); + State &st = state[path]; + if (st.timestamp < ts || (st.timestamp == ts && st.step < step)) { + st.timestamp = ts; + st.step = step; + return true; + } else + return false; +} + namespace ccls::pipeline { int64_t loaded_ts = 0, tick = 0; diff --git a/src/pipeline.hh b/src/pipeline.hh index c1ffbd75..610fde24 100644 --- a/src/pipeline.hh +++ b/src/pipeline.hh @@ -7,6 +7,7 @@ #include "method.h" #include "query.h" +#include #include #include #include @@ -30,6 +31,20 @@ class DiagnosticsPublisher { std::vector diagnostics); }; +struct VFS { + struct State { + int64_t timestamp; + int step; + bool loaded; + }; + std::unordered_map state; + std::mutex mutex; + + void Clear(); + bool Loaded(const std::string &path); + bool Stamp(const std::string &path, int64_t ts, int step); +}; + namespace ccls { enum class IndexMode { NonInteractive, diff --git a/src/test.cc b/src/test.cc index d1d82715..d60a3bb5 100644 --- a/src/test.cc +++ b/src/test.cc @@ -6,6 +6,7 @@ #include "clang_complete.hh" #include "filesystem.hh" #include "indexer.h" +#include "pipeline.hh" #include "platform.h" #include "serializer.h" #include "utils.h"