This commit is contained in:
Fangrui Song 2018-09-09 23:46:13 -07:00
parent bfe5693983
commit 7149851ea2
7 changed files with 38 additions and 19 deletions

View File

@ -1236,7 +1236,7 @@ Index(CompletionManager *completion, WorkingFiles *wfiles, VFS *vfs,
CI->getLangOpts()->RetainCommentsFromSystemHeaders = true; CI->getLangOpts()->RetainCommentsFromSystemHeaders = true;
std::string buf = wfiles->GetContent(file); std::string buf = wfiles->GetContent(file);
std::vector<std::unique_ptr<llvm::MemoryBuffer>> Bufs; std::vector<std::unique_ptr<llvm::MemoryBuffer>> Bufs;
if (buf.size()) { if (g_config->index.onChange && buf.size()) {
// If there is a completion session, reuse its preamble if exists. // If there is a completion session, reuse its preamble if exists.
bool done_remap = false; bool done_remap = false;
std::shared_ptr<CompletionSession> session = std::shared_ptr<CompletionSession> session =

View File

@ -148,8 +148,8 @@ bool FindFileOrFail(DB *db, Project *project, std::optional<lsRequestId> id,
bool indexing; bool indexing;
{ {
std::lock_guard<std::mutex> lock(project->mutex_); std::lock_guard<std::mutex> lock(project->mutex_);
indexing = project->absolute_path_to_entry_index_.find(absolute_path) != indexing = project->path_to_entry_index.find(absolute_path) !=
project->absolute_path_to_entry_index_.end(); project->path_to_entry_index.end();
} }
if (indexing) if (indexing)
LOG_S(INFO) << "\"" << absolute_path << "\" is being indexed."; LOG_S(INFO) << "\"" << absolute_path << "\" is being indexed.";

View File

@ -45,8 +45,8 @@ struct Handler_WorkspaceDidChangeWatchedFiles
Project::Entry entry; Project::Entry entry;
{ {
std::lock_guard<std::mutex> lock(project->mutex_); std::lock_guard<std::mutex> lock(project->mutex_);
auto it = project->absolute_path_to_entry_index_.find(path); auto it = project->path_to_entry_index.find(path);
if (it == project->absolute_path_to_entry_index_.end()) if (it == project->path_to_entry_index.end())
continue; continue;
entry = project->entries[it->second]; entry = project->entries[it->second];
} }

View File

@ -20,6 +20,8 @@
using namespace llvm; using namespace llvm;
#include <chrono> #include <chrono>
#include <mutex>
#include <shared_mutex>
#include <thread> #include <thread>
#ifndef _WIN32 #ifndef _WIN32
#include <unistd.h> #include <unistd.h>
@ -87,6 +89,7 @@ struct InMemoryIndexFile {
std::string content; std::string content;
IndexFile index; IndexFile index;
}; };
std::shared_mutex g_index_mutex;
std::unordered_map<std::string, InMemoryIndexFile> g_index; std::unordered_map<std::string, InMemoryIndexFile> g_index;
bool CacheInvalid(VFS *vfs, IndexFile *prev, const std::string &path, bool CacheInvalid(VFS *vfs, IndexFile *prev, const std::string &path,
@ -135,6 +138,7 @@ std::string GetCachePath(const std::string &source_file) {
std::unique_ptr<IndexFile> RawCacheLoad(const std::string &path) { std::unique_ptr<IndexFile> RawCacheLoad(const std::string &path) {
if (g_config->cacheDirectory.empty()) { if (g_config->cacheDirectory.empty()) {
std::shared_lock lock(g_index_mutex);
auto it = g_index.find(path); auto it = g_index.find(path);
if (it == g_index.end()) if (it == g_index.end())
return nullptr; return nullptr;
@ -177,8 +181,8 @@ bool Indexer_Parse(CompletionManager *completion, WorkingFiles *wfiles,
Project::Entry entry; Project::Entry entry;
{ {
std::lock_guard<std::mutex> lock(project->mutex_); std::lock_guard<std::mutex> lock(project->mutex_);
auto it = project->absolute_path_to_entry_index_.find(request.path); auto it = project->path_to_entry_index.find(request.path);
if (it != project->absolute_path_to_entry_index_.end()) if (it != project->path_to_entry_index.end())
entry = project->entries[it->second]; entry = project->entries[it->second];
else { else {
entry.filename = request.path; entry.filename = request.path;
@ -295,6 +299,7 @@ bool Indexer_Parse(CompletionManager *completion, WorkingFiles *wfiles,
LOG_IF_S(INFO, loud) << "store index for " << path << " (delta: " << !!prev LOG_IF_S(INFO, loud) << "store index for " << path << " (delta: " << !!prev
<< ")"; << ")";
if (g_config->cacheDirectory.empty()) { if (g_config->cacheDirectory.empty()) {
std::lock_guard lock(g_index_mutex);
auto it = g_index.insert_or_assign( auto it = g_index.insert_or_assign(
path, InMemoryIndexFile{curr->file_contents, *curr}); path, InMemoryIndexFile{curr->file_contents, *curr});
std::string().swap(it.first->second.index.file_contents); std::string().swap(it.first->second.index.file_contents);
@ -309,7 +314,7 @@ bool Indexer_Parse(CompletionManager *completion, WorkingFiles *wfiles,
if (entry.id >= 0) { if (entry.id >= 0) {
std::lock_guard<std::mutex> lock(project->mutex_); std::lock_guard<std::mutex> lock(project->mutex_);
for (auto &dep : curr->dependencies) for (auto &dep : curr->dependencies)
project->absolute_path_to_entry_index_[dep.first()] = entry.id; project->path_to_entry_index[dep.first()] = entry.id;
} }
// Build delta update. // Build delta update.
@ -536,6 +541,7 @@ std::optional<int64_t> LastWriteTime(const std::string &path) {
std::optional<std::string> LoadIndexedContent(const std::string &path) { std::optional<std::string> LoadIndexedContent(const std::string &path) {
if (g_config->cacheDirectory.empty()) { if (g_config->cacheDirectory.empty()) {
std::shared_lock lock(g_index_mutex);
auto it = g_index.find(path); auto it = g_index.find(path);
if (it == g_index.end()) if (it == g_index.end())
return {}; return {};

View File

@ -365,13 +365,21 @@ void Project::Load(const std::string &root_directory) {
EnsureEndsInSlash(path); EnsureEndsInSlash(path);
LOG_S(INFO) << "angle_include_dir: " << path; LOG_S(INFO) << "angle_include_dir: " << path;
} }
// Setup project entries.
std::lock_guard lock(mutex_);
path_to_entry_index.reserve(entries.size());
for (size_t i = 0; i < entries.size(); ++i) {
entries[i].id = i;
path_to_entry_index[entries[i].filename] = i;
}
} }
void Project::SetFlagsForFile(const std::vector<std::string> &flags, void Project::SetFlagsForFile(const std::vector<std::string> &flags,
const std::string &path) { const std::string &path) {
std::lock_guard<std::mutex> lock(mutex_); std::lock_guard<std::mutex> lock(mutex_);
auto it = absolute_path_to_entry_index_.find(path); auto it = path_to_entry_index.find(path);
if (it != absolute_path_to_entry_index_.end()) { if (it != path_to_entry_index.end()) {
// The entry already exists in the project, just set the flags. // The entry already exists in the project, just set the flags.
this->entries[it->second].args = flags; this->entries[it->second].args = flags;
} else { } else {
@ -388,8 +396,8 @@ Project::Entry
Project::FindCompilationEntryForFile(const std::string &filename) { Project::FindCompilationEntryForFile(const std::string &filename) {
{ {
std::lock_guard<std::mutex> lock(mutex_); std::lock_guard<std::mutex> lock(mutex_);
auto it = absolute_path_to_entry_index_.find(filename); auto it = path_to_entry_index.find(filename);
if (it != absolute_path_to_entry_index_.end()) if (it != path_to_entry_index.end())
return entries[it->second]; return entries[it->second];
} }

View File

@ -31,7 +31,7 @@ struct Project {
std::vector<Entry> entries; std::vector<Entry> entries;
std::mutex mutex_; std::mutex mutex_;
std::unordered_map<std::string, int> absolute_path_to_entry_index_; std::unordered_map<std::string, int> path_to_entry_index;
// Loads a project for the given |directory|. // Loads a project for the given |directory|.
// //

View File

@ -215,16 +215,21 @@ void DB::ApplyIndexUpdate(IndexUpdate *u) {
SymbolKind kind, Use &use, int delta, int k = 1) { SymbolKind kind, Use &use, int delta, int k = 1) {
use.file_id = use.file_id =
use.file_id == -1 ? u->file_id : lid2fid.find(use.file_id)->second; use.file_id == -1 ? u->file_id : lid2fid.find(use.file_id)->second;
SymbolRef sym{{use.range, usr, kind, use.role}};
if (k & 1) { if (k & 1) {
int &v = int &v = files[use.file_id].symbol2refcnt[sym];
files[use.file_id]
.symbol2refcnt[SymbolRef{{use.range, usr, kind, use.role}}];
v += delta; v += delta;
assert(v >= 0); assert(v >= 0);
if (!v)
files[use.file_id].symbol2refcnt.erase(sym);
}
if (k & 2) {
int &v = files[use.file_id].outline2refcnt[sym];
v += delta;
assert(v >= 0);
if (!v)
files[use.file_id].outline2refcnt.erase(sym);
} }
if (k & 2)
files[use.file_id]
.outline2refcnt[SymbolRef{{use.range, usr, kind, use.role}}] += delta;
}; };
auto RefDecl = [&](std::unordered_map<int, int> &lid2fid, Usr usr, auto RefDecl = [&](std::unordered_map<int, int> &lid2fid, Usr usr,
SymbolKind kind, DeclRef &dr, int delta) { SymbolKind kind, DeclRef &dr, int delta) {