mirror of
https://github.com/MaskRay/ccls.git
synced 2024-11-21 15:15:07 +00:00
didOpen: Sort index requests by approximity to working files
For a large project, it is preferable to prioritize indexing files neighboring working files.
This commit is contained in:
parent
ddbe41300f
commit
349cdc471b
@ -17,14 +17,14 @@ struct Out_cclsInfo {
|
|||||||
int files, funcs, types, vars;
|
int files, funcs, types, vars;
|
||||||
} db;
|
} db;
|
||||||
struct Pipeline {
|
struct Pipeline {
|
||||||
int64_t lastIdle, completed, enqueued;
|
int64_t lastIdle, completed, enqueued, opened;
|
||||||
} pipeline;
|
} pipeline;
|
||||||
struct Project {
|
struct Project {
|
||||||
int entries;
|
int entries;
|
||||||
} project;
|
} project;
|
||||||
};
|
};
|
||||||
REFLECT_STRUCT(Out_cclsInfo::DB, files, funcs, types, vars);
|
REFLECT_STRUCT(Out_cclsInfo::DB, files, funcs, types, vars);
|
||||||
REFLECT_STRUCT(Out_cclsInfo::Pipeline, lastIdle, completed, enqueued);
|
REFLECT_STRUCT(Out_cclsInfo::Pipeline, lastIdle, completed, enqueued, opened);
|
||||||
REFLECT_STRUCT(Out_cclsInfo::Project, entries);
|
REFLECT_STRUCT(Out_cclsInfo::Project, entries);
|
||||||
REFLECT_STRUCT(Out_cclsInfo, db, pipeline, project);
|
REFLECT_STRUCT(Out_cclsInfo, db, pipeline, project);
|
||||||
} // namespace
|
} // namespace
|
||||||
@ -38,6 +38,7 @@ void MessageHandler::ccls_info(EmptyParam &, ReplyOnce &reply) {
|
|||||||
result.pipeline.lastIdle = pipeline::stats.last_idle;
|
result.pipeline.lastIdle = pipeline::stats.last_idle;
|
||||||
result.pipeline.completed = pipeline::stats.completed;
|
result.pipeline.completed = pipeline::stats.completed;
|
||||||
result.pipeline.enqueued = pipeline::stats.enqueued;
|
result.pipeline.enqueued = pipeline::stats.enqueued;
|
||||||
|
result.pipeline.opened = pipeline::stats.opened;
|
||||||
result.project.entries = 0;
|
result.project.entries = 0;
|
||||||
for (auto &[_, folder] : project->root2folder)
|
for (auto &[_, folder] : project->root2folder)
|
||||||
result.project.entries += folder.entries.size();
|
result.project.entries += folder.entries.size();
|
||||||
|
@ -50,6 +50,20 @@ void MessageHandler::textDocument_didOpen(DidOpenTextDocumentParam ¶m) {
|
|||||||
project->indexRelated(path);
|
project->indexRelated(path);
|
||||||
|
|
||||||
manager->onView(path);
|
manager->onView(path);
|
||||||
|
|
||||||
|
// For the first few didOpen, sort indexer requests based on path similarity.
|
||||||
|
if (++pipeline::stats.opened >= 5)
|
||||||
|
return;
|
||||||
|
std::unordered_map<std::string, int> dir2prio;
|
||||||
|
{
|
||||||
|
std::lock_guard lock(wfiles->mutex);
|
||||||
|
for (auto &[f, wf] : wfiles->files) {
|
||||||
|
std::string cur = lowerPathIfInsensitive(f);
|
||||||
|
for (int pri = 1 << 20; !(cur = llvm::sys::path::parent_path(cur)).empty(); pri /= 2)
|
||||||
|
dir2prio[cur] += pri;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pipeline::indexerSort(dir2prio);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessageHandler::textDocument_didSave(TextDocumentParam ¶m) {
|
void MessageHandler::textDocument_didSave(TextDocumentParam ¶m) {
|
||||||
|
@ -87,6 +87,7 @@ struct IndexRequest {
|
|||||||
bool must_exist = false;
|
bool must_exist = false;
|
||||||
RequestId id;
|
RequestId id;
|
||||||
int64_t ts = tick++;
|
int64_t ts = tick++;
|
||||||
|
int prio = 0; // For didOpen sorting
|
||||||
};
|
};
|
||||||
|
|
||||||
std::mutex thread_mtx;
|
std::mutex thread_mtx;
|
||||||
@ -488,6 +489,23 @@ void indexer_Main(SemaManager *manager, VFS *vfs, Project *project,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void indexerSort(const std::unordered_map<std::string, int> &dir2prio) {
|
||||||
|
index_request->apply([&](std::deque<IndexRequest> &q) {
|
||||||
|
for (IndexRequest &request : q) {
|
||||||
|
std::string cur = lowerPathIfInsensitive(request.path);
|
||||||
|
while (!(cur = llvm::sys::path::parent_path(cur)).empty()) {
|
||||||
|
auto it = dir2prio.find(cur);
|
||||||
|
if (it != dir2prio.end()) {
|
||||||
|
request.prio = it->second;
|
||||||
|
LOG_V(3) << "set priority " << request.prio << " to " << request.path;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::stable_sort(q.begin(), q.end(), [](auto &l, auto &r) { return l.prio > r.prio; });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
void main_OnIndexed(DB *db, WorkingFiles *wfiles, IndexUpdate *update) {
|
void main_OnIndexed(DB *db, WorkingFiles *wfiles, IndexUpdate *update) {
|
||||||
if (update->refresh) {
|
if (update->refresh) {
|
||||||
LOG_S(INFO)
|
LOG_S(INFO)
|
||||||
|
@ -40,7 +40,7 @@ enum class IndexMode {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct IndexStats {
|
struct IndexStats {
|
||||||
std::atomic<int64_t> last_idle, completed, enqueued;
|
std::atomic<int64_t> last_idle, completed, enqueued, opened;
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace pipeline {
|
namespace pipeline {
|
||||||
@ -56,6 +56,7 @@ void launchStdin();
|
|||||||
void launchStdout();
|
void launchStdout();
|
||||||
void indexer_Main(SemaManager *manager, VFS *vfs, Project *project,
|
void indexer_Main(SemaManager *manager, VFS *vfs, Project *project,
|
||||||
WorkingFiles *wfiles);
|
WorkingFiles *wfiles);
|
||||||
|
void indexerSort(const std::unordered_map<std::string, int> &dir2prio);
|
||||||
void mainLoop();
|
void mainLoop();
|
||||||
void standalone(const std::string &root);
|
void standalone(const std::string &root);
|
||||||
|
|
||||||
|
@ -28,6 +28,7 @@ struct Project {
|
|||||||
// 0 unless coming from a compile_commands.json entry.
|
// 0 unless coming from a compile_commands.json entry.
|
||||||
int compdb_size = 0;
|
int compdb_size = 0;
|
||||||
int id = -1;
|
int id = -1;
|
||||||
|
int prio = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Folder {
|
struct Folder {
|
||||||
|
@ -161,12 +161,9 @@ public:
|
|||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Fn> void iterate(Fn fn) {
|
template <typename Fn> void apply(Fn fn) {
|
||||||
std::lock_guard<std::mutex> lock(mutex_);
|
std::lock_guard<std::mutex> lock(mutex_);
|
||||||
for (auto &entry : priority_)
|
fn(queue_);
|
||||||
fn(entry);
|
|
||||||
for (auto &entry : queue_)
|
|
||||||
fn(entry);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mutable std::mutex mutex_;
|
mutable std::mutex mutex_;
|
||||||
|
Loading…
Reference in New Issue
Block a user