Skip to content

Commit 349cdc4

Browse files
committed
didOpen: Sort index requests by approximity to working files
For a large project, it is preferable to prioritize indexing files neighboring working files.
1 parent ddbe413 commit 349cdc4

File tree

6 files changed

+40
-8
lines changed

6 files changed

+40
-8
lines changed

src/messages/ccls_info.cc

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,14 @@ struct Out_cclsInfo {
1717
int files, funcs, types, vars;
1818
} db;
1919
struct Pipeline {
20-
int64_t lastIdle, completed, enqueued;
20+
int64_t lastIdle, completed, enqueued, opened;
2121
} pipeline;
2222
struct Project {
2323
int entries;
2424
} project;
2525
};
2626
REFLECT_STRUCT(Out_cclsInfo::DB, files, funcs, types, vars);
27-
REFLECT_STRUCT(Out_cclsInfo::Pipeline, lastIdle, completed, enqueued);
27+
REFLECT_STRUCT(Out_cclsInfo::Pipeline, lastIdle, completed, enqueued, opened);
2828
REFLECT_STRUCT(Out_cclsInfo::Project, entries);
2929
REFLECT_STRUCT(Out_cclsInfo, db, pipeline, project);
3030
} // namespace
@@ -38,6 +38,7 @@ void MessageHandler::ccls_info(EmptyParam &, ReplyOnce &reply) {
3838
result.pipeline.lastIdle = pipeline::stats.last_idle;
3939
result.pipeline.completed = pipeline::stats.completed;
4040
result.pipeline.enqueued = pipeline::stats.enqueued;
41+
result.pipeline.opened = pipeline::stats.opened;
4142
result.project.entries = 0;
4243
for (auto &[_, folder] : project->root2folder)
4344
result.project.entries += folder.entries.size();

src/messages/textDocument_did.cc

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,20 @@ void MessageHandler::textDocument_didOpen(DidOpenTextDocumentParam &param) {
5050
project->indexRelated(path);
5151

5252
manager->onView(path);
53+
54+
// For the first few didOpen, sort indexer requests based on path similarity.
55+
if (++pipeline::stats.opened >= 5)
56+
return;
57+
std::unordered_map<std::string, int> dir2prio;
58+
{
59+
std::lock_guard lock(wfiles->mutex);
60+
for (auto &[f, wf] : wfiles->files) {
61+
std::string cur = lowerPathIfInsensitive(f);
62+
for (int pri = 1 << 20; !(cur = llvm::sys::path::parent_path(cur)).empty(); pri /= 2)
63+
dir2prio[cur] += pri;
64+
}
65+
}
66+
pipeline::indexerSort(dir2prio);
5367
}
5468

5569
void MessageHandler::textDocument_didSave(TextDocumentParam &param) {

src/pipeline.cc

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ struct IndexRequest {
8787
bool must_exist = false;
8888
RequestId id;
8989
int64_t ts = tick++;
90+
int prio = 0; // For didOpen sorting
9091
};
9192

9293
std::mutex thread_mtx;
@@ -488,6 +489,23 @@ void indexer_Main(SemaManager *manager, VFS *vfs, Project *project,
488489
break;
489490
}
490491

492+
void indexerSort(const std::unordered_map<std::string, int> &dir2prio) {
493+
index_request->apply([&](std::deque<IndexRequest> &q) {
494+
for (IndexRequest &request : q) {
495+
std::string cur = lowerPathIfInsensitive(request.path);
496+
while (!(cur = llvm::sys::path::parent_path(cur)).empty()) {
497+
auto it = dir2prio.find(cur);
498+
if (it != dir2prio.end()) {
499+
request.prio = it->second;
500+
LOG_V(3) << "set priority " << request.prio << " to " << request.path;
501+
break;
502+
}
503+
}
504+
}
505+
std::stable_sort(q.begin(), q.end(), [](auto &l, auto &r) { return l.prio > r.prio; });
506+
});
507+
}
508+
491509
void main_OnIndexed(DB *db, WorkingFiles *wfiles, IndexUpdate *update) {
492510
if (update->refresh) {
493511
LOG_S(INFO)

src/pipeline.hh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ enum class IndexMode {
4040
};
4141

4242
struct IndexStats {
43-
std::atomic<int64_t> last_idle, completed, enqueued;
43+
std::atomic<int64_t> last_idle, completed, enqueued, opened;
4444
};
4545

4646
namespace pipeline {
@@ -56,6 +56,7 @@ void launchStdin();
5656
void launchStdout();
5757
void indexer_Main(SemaManager *manager, VFS *vfs, Project *project,
5858
WorkingFiles *wfiles);
59+
void indexerSort(const std::unordered_map<std::string, int> &dir2prio);
5960
void mainLoop();
6061
void standalone(const std::string &root);
6162

src/project.hh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ struct Project {
2828
// 0 unless coming from a compile_commands.json entry.
2929
int compdb_size = 0;
3030
int id = -1;
31+
int prio = 0;
3132
};
3233

3334
struct Folder {

src/threaded_queue.hh

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -161,12 +161,9 @@ public:
161161
return std::nullopt;
162162
}
163163

164-
template <typename Fn> void iterate(Fn fn) {
164+
template <typename Fn> void apply(Fn fn) {
165165
std::lock_guard<std::mutex> lock(mutex_);
166-
for (auto &entry : priority_)
167-
fn(entry);
168-
for (auto &entry : queue_)
169-
fn(entry);
166+
fn(queue_);
170167
}
171168

172169
mutable std::mutex mutex_;

0 commit comments

Comments
 (0)