Add index.trackDependency and improve pipeline

This commit is contained in:
Fangrui Song 2018-09-23 23:02:19 -07:00
parent 4420bcf76f
commit d425e15cdb
3 changed files with 49 additions and 37 deletions

View File

@ -210,13 +210,13 @@ struct Config {
// May be too slow for big projects, so it is off by default.
bool onChange = false;
// Number of indexer threads. If 0, 80% of cores are used.
int threads = 0;
// Whether to reparse a file if write times of its dependencies have
// changed. The file will always be reparsed if its own write time changes.
// 0: no, 1: only after initial load of project, 2: yes
int reparseForDependency = 2;
// Number of indexer threads. If 0, 80% of cores are used.
int threads = 0;
int trackDependency = 2;
std::vector<std::string> whitelist;
} index;
@ -256,7 +256,7 @@ MAKE_REFLECT_STRUCT(Config::Highlight, lsRanges, blacklist, whitelist)
MAKE_REFLECT_STRUCT(Config::Index, blacklist, comments, enabled,
initialBlacklist, initialWhitelist, multiVersion,
multiVersionBlacklist, multiVersionWhitelist, onChange,
reparseForDependency, threads, whitelist);
threads, trackDependency, whitelist);
MAKE_REFLECT_STRUCT(Config::WorkspaceSymbol, caseSensitivity, maxNum, sort);
MAKE_REFLECT_STRUCT(Config::Xref, container, maxNum);
MAKE_REFLECT_STRUCT(Config, compilationDatabaseCommand,

View File

@ -50,7 +50,8 @@ bool VFS::Stamp(const std::string &path, int64_t ts, int step) {
namespace ccls::pipeline {
int64_t loaded_ts = 0, tick = 0;
std::atomic<int64_t> loaded_ts = ATOMIC_VAR_INIT(0);
int64_t tick = 0;
namespace {
@ -187,7 +188,7 @@ bool Indexer_Parse(CompletionManager *completion, WorkingFiles *wfiles,
if (!mtime1)
return true;
if (vfs->Stamp(request.path, *mtime1, 0))
reparse = 1;
reparse = 2;
}
if (g_config->index.onChange) {
reparse = 2;
@ -196,45 +197,55 @@ bool Indexer_Parse(CompletionManager *completion, WorkingFiles *wfiles,
if (request.path != path_to_index)
vfs->state[request.path].step = 0;
}
if (!reparse)
bool track = g_config->index.trackDependency > 1 ||
(g_config->index.trackDependency == 1 && request.ts < loaded_ts);
if (!reparse && !track)
return true;
if (reparse < 2) do {
std::unique_lock lock(
if (reparse < 2)
do {
std::unique_lock lock(
mutexes[std::hash<std::string>()(path_to_index) % N_MUTEXES]);
prev = RawCacheLoad(path_to_index);
if (!prev || CacheInvalid(vfs, prev.get(), path_to_index, entry.args,
std::nullopt))
break;
bool update = false;
for (const auto &dep : prev->dependencies)
if (auto mtime1 = LastWriteTime(dep.first.val().str())) {
if (dep.second < *mtime1)
update = true;
} else {
update = true;
}
int forDep = g_config->index.reparseForDependency;
if (update && (forDep > 1 || (forDep == 1 && request.ts < loaded_ts)))
break;
prev = RawCacheLoad(path_to_index);
if (!prev || CacheInvalid(vfs, prev.get(), path_to_index, entry.args,
std::nullopt))
break;
if (track)
for (const auto &dep : prev->dependencies) {
if (auto mtime1 = LastWriteTime(dep.first.val().str())) {
if (dep.second < *mtime1) {
reparse = 2;
break;
}
} else {
reparse = 2;
break;
}
}
if (reparse == 0)
return true;
if (reparse == 2)
break;
if (reparse < 2) {
if (vfs->Loaded(path_to_index))
return true;
LOG_S(INFO) << "load cache for " << path_to_index;
auto dependencies = prev->dependencies;
if (reparse) {
if (vfs->Loaded(path_to_index))
return true;
IndexUpdate update = IndexUpdate::CreateDelta(nullptr, prev.get());
on_indexed->PushBack(std::move(update),
request.mode != IndexMode::NonInteractive);
IndexUpdate update = IndexUpdate::CreateDelta(nullptr, prev.get());
on_indexed->PushBack(std::move(update),
request.mode != IndexMode::NonInteractive);
{
std::lock_guard lock1(vfs->mutex);
vfs->state[path_to_index].loaded = true;
}
lock.unlock();
for (const auto &dep : dependencies) {
std::string path = dep.first.val().str();
if (!vfs->Stamp(path, dep.second, 1))
continue;
std::lock_guard lock1(
mutexes[std::hash<std::string>()(path) % N_MUTEXES]);
mutexes[std::hash<std::string>()(path) % N_MUTEXES]);
prev = RawCacheLoad(path);
if (!prev)
continue;
@ -248,15 +259,14 @@ bool Indexer_Parse(CompletionManager *completion, WorkingFiles *wfiles,
}
IndexUpdate update = IndexUpdate::CreateDelta(nullptr, prev.get());
on_indexed->PushBack(std::move(update),
request.mode != IndexMode::NonInteractive);
request.mode != IndexMode::NonInteractive);
if (entry.id >= 0) {
std::lock_guard lock2(project->mutex_);
project->path_to_entry_index[path] = entry.id;
}
}
return true;
}
} while (0);
} while (0);
LOG_IF_S(INFO, loud) << "parse " << path_to_index;

View File

@ -7,6 +7,7 @@
#include "method.h"
#include "query.h"
#include <atomic>
#include <mutex>
#include <string>
#include <unordered_map>
@ -41,7 +42,8 @@ enum class IndexMode {
};
namespace pipeline {
extern int64_t loaded_ts, tick;
extern std::atomic<int64_t> loaded_ts;
extern int64_t tick;
void Init();
void LaunchStdin();
void LaunchStdout();