mirror of
https://github.com/MaskRay/ccls.git
synced 2024-11-22 15:45:08 +00:00
Don't call NormalizePath in core indexing logic; syscall dominates indexing time
This commit is contained in:
parent
33c91de4c0
commit
12a0db7d10
@ -1,36 +1,66 @@
|
||||
#include "file_consumer.h"
|
||||
|
||||
#include "indexer.h"
|
||||
#include "platform.h"
|
||||
#include "utils.h"
|
||||
|
||||
namespace {
|
||||
|
||||
std::string FileName(CXFile file) {
|
||||
CXString cx_name = clang_getFileName(file);
|
||||
std::string name = clang::ToString(cx_name);
|
||||
return NormalizePath(name);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
bool operator==(const CXFileUniqueID& a, const CXFileUniqueID& b) {
|
||||
return a.data[0] == b.data[0] && a.data[1] == b.data[1] && a.data[2] == b.data[2];
|
||||
}
|
||||
|
||||
FileConsumer::FileConsumer(SharedState* shared_state) : shared_(shared_state) {}
|
||||
|
||||
IndexedFile* FileConsumer::TryConsumeFile(const std::string& file, bool* is_first_ownership) {
|
||||
IndexedFile* FileConsumer::TryConsumeFile(CXFile file, bool* is_first_ownership) {
|
||||
assert(is_first_ownership);
|
||||
|
||||
CXFileUniqueID file_id;
|
||||
if (clang_getFileUniqueID(file, &file_id) != 0) {
|
||||
std::cerr << "Could not get unique file id for " << FileName(file) << std::endl;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Try to find cached local result.
|
||||
auto it = local_.find(file);
|
||||
auto it = local_.find(file_id);
|
||||
if (it != local_.end()) {
|
||||
*is_first_ownership = false;
|
||||
return it->second.get();
|
||||
}
|
||||
|
||||
std::string file_name = FileName(file);
|
||||
|
||||
// No result in local; we need to query global.
|
||||
bool did_insert = false;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(shared_->mutex);
|
||||
did_insert = shared_->files.insert(file).second;
|
||||
did_insert = shared_->files.insert(file_name).second;
|
||||
}
|
||||
*is_first_ownership = did_insert;
|
||||
local_[file] = did_insert ? MakeUnique<IndexedFile>(file) : nullptr;
|
||||
return local_[file].get();
|
||||
local_[file_id] = did_insert ? MakeUnique<IndexedFile>(file_name) : nullptr;
|
||||
return local_[file_id].get();
|
||||
}
|
||||
|
||||
IndexedFile* FileConsumer::ForceLocal(const std::string& file) {
|
||||
auto it = local_.find(file);
|
||||
IndexedFile* FileConsumer::ForceLocal(CXFile file) {
|
||||
CXFileUniqueID file_id;
|
||||
if (clang_getFileUniqueID(file, &file_id) != 0) {
|
||||
std::cerr << "Could not get unique file id for " << FileName(file) << std::endl;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto it = local_.find(file_id);
|
||||
if (it == local_.end())
|
||||
local_[file] = MakeUnique<IndexedFile>(file);
|
||||
return local_[file].get();
|
||||
local_[file_id] = MakeUnique<IndexedFile>(FileName(file));
|
||||
assert(local_.find(file_id) != local_.end());
|
||||
return local_[file_id].get();
|
||||
}
|
||||
|
||||
std::vector<std::unique_ptr<IndexedFile>> FileConsumer::TakeLocalState() {
|
||||
|
@ -1,11 +1,20 @@
|
||||
#pragma once
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
#include <clang-c/Index.h>
|
||||
|
||||
#include <functional>
|
||||
#include <mutex>
|
||||
#include <unordered_set>
|
||||
#include <unordered_map>
|
||||
|
||||
struct IndexedFile;
|
||||
|
||||
// Needed for unordered_map usage below.
|
||||
MAKE_HASHABLE(CXFileUniqueID, t.data[0], t.data[1], t.data[2]);
|
||||
bool operator==(const CXFileUniqueID& a, const CXFileUniqueID& b);
|
||||
|
||||
// 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
|
||||
@ -27,15 +36,15 @@ struct FileConsumer {
|
||||
// Returns IndexedFile for the file or nullptr. |is_first_ownership| is set
|
||||
// to true iff the function just took ownership over the file. Otherwise it
|
||||
// is set to false.
|
||||
IndexedFile* TryConsumeFile(const std::string& file, bool* is_first_ownership);
|
||||
IndexedFile* TryConsumeFile(CXFile file, bool* is_first_ownership);
|
||||
|
||||
// Forcibly create a local file, even if it has already been parsed.
|
||||
IndexedFile* ForceLocal(const std::string& file);
|
||||
IndexedFile* ForceLocal(CXFile file);
|
||||
|
||||
// Returns and passes ownership of all local state.
|
||||
std::vector<std::unique_ptr<IndexedFile>> TakeLocalState();
|
||||
|
||||
private:
|
||||
std::unordered_map<std::string, std::unique_ptr<IndexedFile>> local_;
|
||||
std::unordered_map<CXFileUniqueID, std::unique_ptr<IndexedFile>> local_;
|
||||
SharedState* shared_;
|
||||
};
|
@ -711,10 +711,9 @@ void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
|
||||
// TODO: Use clang_getFileUniqueID
|
||||
CXFile file;
|
||||
clang_getSpellingLocation(clang_indexLoc_getCXSourceLocation(decl->loc), &file, nullptr, nullptr, nullptr);
|
||||
std::string filename = NormalizePath(clang::ToString(clang_getFileName(file)));
|
||||
IndexParam* param = static_cast<IndexParam*>(client_data);
|
||||
bool is_first_time_visiting_file = false;
|
||||
IndexedFile* db = param->file_consumer->TryConsumeFile(filename, &is_first_time_visiting_file);
|
||||
IndexedFile* db = param->file_consumer->TryConsumeFile(file, &is_first_time_visiting_file);
|
||||
if (!db)
|
||||
return;
|
||||
|
||||
@ -1170,10 +1169,9 @@ void indexEntityReference(CXClientData client_data,
|
||||
// TODO: Use clang_getFileUniqueID
|
||||
CXFile file;
|
||||
clang_getSpellingLocation(clang_indexLoc_getCXSourceLocation(ref->loc), &file, nullptr, nullptr, nullptr);
|
||||
std::string filename = NormalizePath(clang::ToString(clang_getFileName(file)));
|
||||
IndexParam* param = static_cast<IndexParam*>(client_data);
|
||||
bool is_first_time_visiting_file = false;
|
||||
IndexedFile* db = param->file_consumer->TryConsumeFile(filename, &is_first_time_visiting_file);
|
||||
IndexedFile* db = param->file_consumer->TryConsumeFile(file, &is_first_time_visiting_file);
|
||||
if (!db)
|
||||
return;
|
||||
|
||||
@ -1415,7 +1413,8 @@ std::vector<std::unique_ptr<IndexedFile>> Parse(FileConsumer* file_consumer, std
|
||||
|
||||
IndexParam param(file_consumer);
|
||||
|
||||
param.primary_file = file_consumer->ForceLocal(filename);
|
||||
CXFile file = clang_getFile(tu.cx_tu, filename.c_str());
|
||||
param.primary_file = file_consumer->ForceLocal(file);
|
||||
|
||||
std::cerr << "!! [START] Indexing " << filename << std::endl;
|
||||
CXIndexAction index_action = clang_IndexAction_create(index.cx_index);
|
||||
|
Loading…
Reference in New Issue
Block a user