mirror of
https://github.com/MaskRay/ccls.git
synced 2024-11-27 10:02:03 +00:00
Add index.trackDependency and improve pipeline
This commit is contained in:
parent
eb644bb78e
commit
0eb9428a32
10
src/config.h
10
src/config.h
@ -222,13 +222,13 @@ struct Config {
|
|||||||
// May be too slow for big projects, so it is off by default.
|
// May be too slow for big projects, so it is off by default.
|
||||||
bool onChange = false;
|
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
|
// 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.
|
// changed. The file will always be reparsed if its own write time changes.
|
||||||
// 0: no, 1: only after initial load of project, 2: yes
|
// 0: no, 1: only after initial load of project, 2: yes
|
||||||
int reparseForDependency = 2;
|
int trackDependency = 2;
|
||||||
|
|
||||||
// Number of indexer threads. If 0, 80% of cores are used.
|
|
||||||
int threads = 0;
|
|
||||||
|
|
||||||
std::vector<std::string> whitelist;
|
std::vector<std::string> whitelist;
|
||||||
} index;
|
} index;
|
||||||
@ -268,7 +268,7 @@ MAKE_REFLECT_STRUCT(Config::Highlight, lsRanges, blacklist, whitelist)
|
|||||||
MAKE_REFLECT_STRUCT(Config::Index, blacklist, comments, enabled,
|
MAKE_REFLECT_STRUCT(Config::Index, blacklist, comments, enabled,
|
||||||
initialBlacklist, initialWhitelist, multiVersion,
|
initialBlacklist, initialWhitelist, multiVersion,
|
||||||
multiVersionBlacklist, multiVersionWhitelist, onChange,
|
multiVersionBlacklist, multiVersionWhitelist, onChange,
|
||||||
reparseForDependency, threads, whitelist);
|
threads, trackDependency, whitelist);
|
||||||
MAKE_REFLECT_STRUCT(Config::WorkspaceSymbol, caseSensitivity, maxNum, sort);
|
MAKE_REFLECT_STRUCT(Config::WorkspaceSymbol, caseSensitivity, maxNum, sort);
|
||||||
MAKE_REFLECT_STRUCT(Config::Xref, container, maxNum);
|
MAKE_REFLECT_STRUCT(Config::Xref, container, maxNum);
|
||||||
MAKE_REFLECT_STRUCT(Config, compilationDatabaseCommand,
|
MAKE_REFLECT_STRUCT(Config, compilationDatabaseCommand,
|
||||||
|
@ -62,7 +62,8 @@ bool VFS::Stamp(const std::string &path, int64_t ts, int step) {
|
|||||||
|
|
||||||
namespace ccls::pipeline {
|
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 {
|
namespace {
|
||||||
|
|
||||||
@ -199,7 +200,7 @@ bool Indexer_Parse(CompletionManager *completion, WorkingFiles *wfiles,
|
|||||||
if (!mtime1)
|
if (!mtime1)
|
||||||
return true;
|
return true;
|
||||||
if (vfs->Stamp(request.path, *mtime1, 0))
|
if (vfs->Stamp(request.path, *mtime1, 0))
|
||||||
reparse = 1;
|
reparse = 2;
|
||||||
}
|
}
|
||||||
if (g_config->index.onChange) {
|
if (g_config->index.onChange) {
|
||||||
reparse = 2;
|
reparse = 2;
|
||||||
@ -208,45 +209,55 @@ bool Indexer_Parse(CompletionManager *completion, WorkingFiles *wfiles,
|
|||||||
if (request.path != path_to_index)
|
if (request.path != path_to_index)
|
||||||
vfs->state[request.path].step = 0;
|
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;
|
return true;
|
||||||
|
|
||||||
if (reparse < 2) do {
|
if (reparse < 2)
|
||||||
std::unique_lock lock(
|
do {
|
||||||
|
std::unique_lock lock(
|
||||||
mutexes[std::hash<std::string>()(path_to_index) % N_MUTEXES]);
|
mutexes[std::hash<std::string>()(path_to_index) % N_MUTEXES]);
|
||||||
prev = RawCacheLoad(path_to_index);
|
prev = RawCacheLoad(path_to_index);
|
||||||
if (!prev || CacheInvalid(vfs, prev.get(), path_to_index, entry.args,
|
if (!prev || CacheInvalid(vfs, prev.get(), path_to_index, entry.args,
|
||||||
std::nullopt))
|
std::nullopt))
|
||||||
break;
|
break;
|
||||||
bool update = false;
|
if (track)
|
||||||
for (const auto &dep : prev->dependencies)
|
for (const auto &dep : prev->dependencies) {
|
||||||
if (auto mtime1 = LastWriteTime(dep.first.val().str())) {
|
if (auto mtime1 = LastWriteTime(dep.first.val().str())) {
|
||||||
if (dep.second < *mtime1)
|
if (dep.second < *mtime1) {
|
||||||
update = true;
|
reparse = 2;
|
||||||
} else {
|
break;
|
||||||
update = true;
|
}
|
||||||
}
|
} else {
|
||||||
int forDep = g_config->index.reparseForDependency;
|
reparse = 2;
|
||||||
if (update && (forDep > 1 || (forDep == 1 && request.ts < loaded_ts)))
|
break;
|
||||||
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;
|
LOG_S(INFO) << "load cache for " << path_to_index;
|
||||||
auto dependencies = prev->dependencies;
|
auto dependencies = prev->dependencies;
|
||||||
if (reparse) {
|
IndexUpdate update = IndexUpdate::CreateDelta(nullptr, prev.get());
|
||||||
if (vfs->Loaded(path_to_index))
|
on_indexed->PushBack(std::move(update),
|
||||||
return true;
|
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);
|
std::lock_guard lock1(vfs->mutex);
|
||||||
vfs->state[path_to_index].loaded = true;
|
vfs->state[path_to_index].loaded = true;
|
||||||
}
|
}
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
|
|
||||||
for (const auto &dep : dependencies) {
|
for (const auto &dep : dependencies) {
|
||||||
std::string path = dep.first.val().str();
|
std::string path = dep.first.val().str();
|
||||||
|
if (!vfs->Stamp(path, dep.second, 1))
|
||||||
|
continue;
|
||||||
std::lock_guard lock1(
|
std::lock_guard lock1(
|
||||||
mutexes[std::hash<std::string>()(path) % N_MUTEXES]);
|
mutexes[std::hash<std::string>()(path) % N_MUTEXES]);
|
||||||
prev = RawCacheLoad(path);
|
prev = RawCacheLoad(path);
|
||||||
if (!prev)
|
if (!prev)
|
||||||
continue;
|
continue;
|
||||||
@ -260,15 +271,14 @@ bool Indexer_Parse(CompletionManager *completion, WorkingFiles *wfiles,
|
|||||||
}
|
}
|
||||||
IndexUpdate update = IndexUpdate::CreateDelta(nullptr, prev.get());
|
IndexUpdate update = IndexUpdate::CreateDelta(nullptr, prev.get());
|
||||||
on_indexed->PushBack(std::move(update),
|
on_indexed->PushBack(std::move(update),
|
||||||
request.mode != IndexMode::NonInteractive);
|
request.mode != IndexMode::NonInteractive);
|
||||||
if (entry.id >= 0) {
|
if (entry.id >= 0) {
|
||||||
std::lock_guard lock2(project->mutex_);
|
std::lock_guard lock2(project->mutex_);
|
||||||
project->path_to_entry_index[path] = entry.id;
|
project->path_to_entry_index[path] = entry.id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
} while (0);
|
||||||
} while (0);
|
|
||||||
|
|
||||||
LOG_IF_S(INFO, loud) << "parse " << path_to_index;
|
LOG_IF_S(INFO, loud) << "parse " << path_to_index;
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include "method.h"
|
#include "method.h"
|
||||||
#include "query.h"
|
#include "query.h"
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
@ -38,7 +39,8 @@ enum class IndexMode {
|
|||||||
};
|
};
|
||||||
|
|
||||||
namespace pipeline {
|
namespace pipeline {
|
||||||
extern int64_t loaded_ts, tick;
|
extern std::atomic<int64_t> loaded_ts;
|
||||||
|
extern int64_t tick;
|
||||||
void Init();
|
void Init();
|
||||||
void LaunchStdin();
|
void LaunchStdin();
|
||||||
void LaunchStdout();
|
void LaunchStdout();
|
||||||
|
Loading…
Reference in New Issue
Block a user