Delete file_consumer.*

This commit is contained in:
Fangrui Song 2018-09-20 18:04:55 -07:00
parent 41756297ef
commit 4d76108d6b
9 changed files with 73 additions and 172 deletions

View File

@ -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

View File

@ -1,75 +0,0 @@
/* Copyright 2017-2018 ccls Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/
#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<std::mutex> 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<llvm::sys::fs::UniqueID, FileConsumer::File>
&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<IndexFile>(UniqueID, it->second.path, it->second.content);
return local_[UniqueID].get();
}
std::vector<std::unique_ptr<IndexFile>> FileConsumer::TakeLocalState() {
std::vector<std::unique_ptr<IndexFile>> result;
for (auto &entry : local_) {
if (entry.second)
result.push_back(std::move(entry.second));
}
return result;
}

View File

@ -1,82 +0,0 @@
/* Copyright 2017-2018 ccls Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/
#pragma once
#include "position.h"
#include "serializer.h"
#include "utils.h"
#include <clang/Basic/FileManager.h>
#include <mutex>
#include <unordered_map>
#include <vector>
struct IndexFile;
struct VFS {
struct State {
int64_t timestamp;
int step;
bool loaded;
};
mutable std::unordered_map<std::string, State> 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<llvm::sys::fs::UniqueID> {
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<llvm::sys::fs::UniqueID, File> &);
// Returns and passes ownership of all local state.
std::vector<std::unique_ptr<IndexFile>> TakeLocalState();
private:
std::unordered_map<llvm::sys::fs::UniqueID, std::unique_ptr<IndexFile>>
local_;
VFS *vfs_;
std::string parse_file_;
};

View File

@ -19,6 +19,7 @@ limitations under the License.
#include "clang_tu.h"
#include "log.hh"
#include "match.h"
#include "pipeline.hh"
#include "platform.h"
#include "serializer.h"
using namespace ccls;
@ -48,8 +49,15 @@ constexpr int kInitializerMaxLines = 3;
GroupMatch *multiVersionMatcher;
struct File {
std::string path;
int64_t mtime;
std::string content;
std::unique_ptr<IndexFile> db;
};
struct IndexParam {
std::unordered_map<llvm::sys::fs::UniqueID, FileConsumer::File> UID2File;
std::unordered_map<llvm::sys::fs::UniqueID, File> UID2File;
std::unordered_map<llvm::sys::fs::UniqueID, bool> UID2multi;
struct DeclInfo {
Usr usr;
@ -58,10 +66,9 @@ struct IndexParam {
};
std::unordered_map<const Decl *, DeclInfo> 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
@ -76,12 +83,17 @@ struct IndexParam {
it->second.mtime = *tim;
if (std::optional<std::string> content = ReadContent(path))
it->second.content = *content;
if (!vfs.Stamp(path, it->second.mtime, 1))
return;
it->second.db = std::make_unique<IndexFile>(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) {
@ -1287,8 +1299,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<IndexDataConsumer>(param);
index::IndexingOptions IndexOpts;
@ -1325,8 +1336,11 @@ Index(CompletionManager *completion, WorkingFiles *wfiles, VFS *vfs,
for (auto &Buf : Bufs)
Buf.release();
auto result = param.file_consumer->TakeLocalState();
for (std::unique_ptr<IndexFile> &entry : result) {
std::vector<std::unique_ptr<IndexFile>> result;
for (auto &it : param.UID2File) {
if (!it.second.db)
continue;
std::unique_ptr<IndexFile> &entry = it.second.db;
entry->import_file = file;
entry->args = args;
for (auto &[_, it] : entry->uid2lid_and_path)
@ -1356,6 +1370,7 @@ Index(CompletionManager *completion, WorkingFiles *wfiles, VFS *vfs,
entry->dependencies[llvm::CachedHashStringRef(Intern(path))] =
file.mtime;
}
result.push_back(std::move(entry));
}
return result;

View File

@ -16,7 +16,6 @@ limitations under the License.
#pragma once
#include "clang_utils.h"
#include "file_consumer.h"
#include "language.h"
#include "lsp.h"
#include "lsp_diagnostic.h"
@ -236,6 +235,16 @@ struct IndexInclude {
const char *resolved_path;
};
namespace std {
template <> struct hash<llvm::sys::fs::UniqueID> {
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;
@ -287,6 +296,7 @@ struct IndexFile {
struct CompletionManager;
struct WorkingFiles;
struct VFS;
namespace ccls::idx {
void Init();

View File

@ -47,10 +47,7 @@ struct Handler_CclsReload : BaseMessageHandler<In_CclsReload> {
const auto &params = 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;

View File

@ -74,6 +74,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<std::mutex> 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;

View File

@ -4,6 +4,7 @@
#include "method.h"
#include "query.h"
#include <mutex>
#include <string>
#include <unordered_map>
#include <vector>
@ -27,6 +28,20 @@ class DiagnosticsPublisher {
std::vector<lsDiagnostic> diagnostics);
};
struct VFS {
struct State {
int64_t timestamp;
int step;
bool loaded;
};
std::unordered_map<std::string, State> 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,

View File

@ -18,6 +18,7 @@ limitations under the License.
#include "clang_complete.hh"
#include "filesystem.hh"
#include "indexer.h"
#include "pipeline.hh"
#include "platform.h"
#include "serializer.h"
#include "utils.h"