diff options
Diffstat (limited to 'clang-tools-extra/clangd/index/Background.cpp')
-rw-r--r-- | clang-tools-extra/clangd/index/Background.cpp | 65 |
1 files changed, 45 insertions, 20 deletions
diff --git a/clang-tools-extra/clangd/index/Background.cpp b/clang-tools-extra/clangd/index/Background.cpp index 9be2257a964..da96f8cad31 100644 --- a/clang-tools-extra/clangd/index/Background.cpp +++ b/clang-tools-extra/clangd/index/Background.cpp @@ -24,6 +24,9 @@ #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/SHA1.h" + +#include <memory> +#include <queue> #include <random> #include <string> @@ -31,21 +34,22 @@ using namespace llvm; namespace clang { namespace clangd { -BackgroundIndex::BackgroundIndex(Context BackgroundContext, - StringRef ResourceDir, - const FileSystemProvider &FSProvider, - ArrayRef<std::string> URISchemes, - size_t ThreadPoolSize) +BackgroundIndex::BackgroundIndex( + Context BackgroundContext, StringRef ResourceDir, + const FileSystemProvider &FSProvider, ArrayRef<std::string> URISchemes, + BackgroundIndexStorage::Factory IndexStorageFactory, size_t ThreadPoolSize) : SwapIndex(make_unique<MemIndex>()), ResourceDir(ResourceDir), FSProvider(FSProvider), BackgroundContext(std::move(BackgroundContext)), - URISchemes(URISchemes) { + URISchemes(URISchemes), + IndexStorageFactory(std::move(IndexStorageFactory)) { assert(ThreadPoolSize > 0 && "Thread pool size can't be zero."); + assert(IndexStorageFactory && "Storage factory can not be null!"); while (ThreadPoolSize--) { ThreadPool.emplace_back([this] { run(); }); // Set priority to low, since background indexing is a long running task we // do not want to eat up cpu when there are any other high priority threads. // FIXME: In the future we might want a more general way of handling this to - // support a tasks with various priorities. + // support tasks with various priorities. setThreadPriority(ThreadPool.back(), ThreadPriority::Low); } } @@ -97,9 +101,10 @@ void BackgroundIndex::blockUntilIdleForTest() { void BackgroundIndex::enqueue(StringRef Directory, tooling::CompileCommand Cmd) { + BackgroundIndexStorage *IndexStorage = IndexStorageFactory(Directory); { std::lock_guard<std::mutex> Lock(QueueMu); - enqueueLocked(std::move(Cmd)); + enqueueLocked(std::move(Cmd), IndexStorage); } QueueCV.notify_all(); } @@ -110,6 +115,7 @@ void BackgroundIndex::enqueueAll(StringRef Directory, // FIXME: this function may be slow. Perhaps enqueue a task to re-read the CDB // from disk and enqueue the commands asynchronously? auto Cmds = CDB.getAllCompileCommands(); + BackgroundIndexStorage *IndexStorage = IndexStorageFactory(Directory); SPAN_ATTACH(Tracer, "commands", int64_t(Cmds.size())); std::mt19937 Generator(std::random_device{}()); std::shuffle(Cmds.begin(), Cmds.end(), Generator); @@ -117,17 +123,18 @@ void BackgroundIndex::enqueueAll(StringRef Directory, { std::lock_guard<std::mutex> Lock(QueueMu); for (auto &Cmd : Cmds) - enqueueLocked(std::move(Cmd)); + enqueueLocked(std::move(Cmd), IndexStorage); } QueueCV.notify_all(); } -void BackgroundIndex::enqueueLocked(tooling::CompileCommand Cmd) { +void BackgroundIndex::enqueueLocked(tooling::CompileCommand Cmd, + BackgroundIndexStorage *IndexStorage) { Queue.push_back(Bind( - [this](tooling::CompileCommand Cmd) { + [this, IndexStorage](tooling::CompileCommand Cmd) { std::string Filename = Cmd.Filename; Cmd.CommandLine.push_back("-resource-dir=" + ResourceDir); - if (auto Error = index(std::move(Cmd))) + if (auto Error = index(std::move(Cmd), IndexStorage)) log("Indexing {0} failed: {1}", Filename, std::move(Error)); }, std::move(Cmd))); @@ -179,7 +186,8 @@ private: /// Given index results from a TU, only update files in \p FilesToUpdate. void BackgroundIndex::update(StringRef MainFile, SymbolSlab Symbols, RefSlab Refs, - const StringMap<FileDigest> &FilesToUpdate) { + const StringMap<FileDigest> &FilesToUpdate, + BackgroundIndexStorage *IndexStorage) { // Partition symbols/references into files. struct File { DenseSet<const Symbol *> Symbols; @@ -227,20 +235,35 @@ void BackgroundIndex::update(StringRef MainFile, SymbolSlab Symbols, for (const auto *R : F.second.Refs) Refs.insert(RefToIDs[R], *R); + auto SS = llvm::make_unique<SymbolSlab>(std::move(Syms).build()); + auto RS = llvm::make_unique<RefSlab>(std::move(Refs).build()); + + auto Hash = FilesToUpdate.lookup(Path); + // We need to store shards before updating the index, since the latter + // consumes slabs. + // FIXME: Store Hash in the Shard. + if (IndexStorage) { + IndexFileOut Shard; + Shard.Symbols = SS.get(); + Shard.Refs = RS.get(); + if (auto Error = IndexStorage->storeShard(Path, Shard)) + elog("Failed to write background-index shard for file {0}: {1}", Path, + std::move(Error)); + } + std::lock_guard<std::mutex> Lock(DigestsMu); // This can override a newer version that is added in another thread, // if this thread sees the older version but finishes later. This should be // rare in practice. - IndexedFileDigests[Path] = FilesToUpdate.lookup(Path); - IndexedSymbols.update(Path, - make_unique<SymbolSlab>(std::move(Syms).build()), - make_unique<RefSlab>(std::move(Refs).build())); + IndexedFileDigests[Path] = Hash; + IndexedSymbols.update(Path, std::move(SS), std::move(RS)); } } // Creates a filter to not collect index results from files with unchanged // digests. -// \p FileDigests contains file digests for the current indexed files, and all changed files will be added to \p FilesToUpdate. +// \p FileDigests contains file digests for the current indexed files, and all +// changed files will be added to \p FilesToUpdate. decltype(SymbolCollector::Options::FileFilter) createFileFilter( const llvm::StringMap<BackgroundIndex::FileDigest> &FileDigests, llvm::StringMap<BackgroundIndex::FileDigest> &FilesToUpdate) { @@ -269,7 +292,8 @@ decltype(SymbolCollector::Options::FileFilter) createFileFilter( }; } -Error BackgroundIndex::index(tooling::CompileCommand Cmd) { +Error BackgroundIndex::index(tooling::CompileCommand Cmd, + BackgroundIndexStorage *IndexStorage) { trace::Span Tracer("BackgroundIndex"); SPAN_ATTACH(Tracer, "file", Cmd.Filename); SmallString<128> AbsolutePath; @@ -342,7 +366,8 @@ Error BackgroundIndex::index(tooling::CompileCommand Cmd) { Symbols.size(), Refs.numRefs()); SPAN_ATTACH(Tracer, "symbols", int(Symbols.size())); SPAN_ATTACH(Tracer, "refs", int(Refs.numRefs())); - update(AbsolutePath, std::move(Symbols), std::move(Refs), FilesToUpdate); + update(AbsolutePath, std::move(Symbols), std::move(Refs), FilesToUpdate, + IndexStorage); { // Make sure hash for the main file is always updated even if there is no // index data in it. |