[clangd] Minimal implementation of automatic static index (not enabled).
Summary:
See tinyurl.com/clangd-automatic-index for design and goals.
Lots of limitations to keep this patch smallish, TODOs everywhere:
- no serialization to disk
- no changes to dynamic index, which now has a much simpler job
- no partitioning of symbols by file to avoid duplication of header symbols
- no reindexing of edited files
- only a single worker thread
- compilation database is slurped synchronously (doesn't scale)
- uses memindex, rebuilds after every file (should be dex, periodically)
It's not hooked up to ClangdServer/ClangdLSPServer yet: the layering
isn't clear (it should really be in ClangdServer, but ClangdLSPServer
has all the CDB interactions).
Reviewers: ioeric
Subscribers: mgorny, ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, jfb, cfe-commits
Differential Revision: https://reviews.llvm.org/D53032
llvm-svn: 344513
2018-10-15 21:34:10 +08:00
|
|
|
//===-- Background.cpp - Build an index in a background thread ------------===//
|
|
|
|
//
|
2019-01-19 16:50:56 +08:00
|
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
[clangd] Minimal implementation of automatic static index (not enabled).
Summary:
See tinyurl.com/clangd-automatic-index for design and goals.
Lots of limitations to keep this patch smallish, TODOs everywhere:
- no serialization to disk
- no changes to dynamic index, which now has a much simpler job
- no partitioning of symbols by file to avoid duplication of header symbols
- no reindexing of edited files
- only a single worker thread
- compilation database is slurped synchronously (doesn't scale)
- uses memindex, rebuilds after every file (should be dex, periodically)
It's not hooked up to ClangdServer/ClangdLSPServer yet: the layering
isn't clear (it should really be in ClangdServer, but ClangdLSPServer
has all the CDB interactions).
Reviewers: ioeric
Subscribers: mgorny, ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, jfb, cfe-commits
Differential Revision: https://reviews.llvm.org/D53032
llvm-svn: 344513
2018-10-15 21:34:10 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#include "index/Background.h"
|
|
|
|
#include "ClangdUnit.h"
|
|
|
|
#include "Compiler.h"
|
2019-07-11 21:34:38 +08:00
|
|
|
#include "Context.h"
|
2019-07-19 00:25:36 +08:00
|
|
|
#include "FSProvider.h"
|
2019-07-04 17:51:43 +08:00
|
|
|
#include "Headers.h"
|
[clangd] Minimal implementation of automatic static index (not enabled).
Summary:
See tinyurl.com/clangd-automatic-index for design and goals.
Lots of limitations to keep this patch smallish, TODOs everywhere:
- no serialization to disk
- no changes to dynamic index, which now has a much simpler job
- no partitioning of symbols by file to avoid duplication of header symbols
- no reindexing of edited files
- only a single worker thread
- compilation database is slurped synchronously (doesn't scale)
- uses memindex, rebuilds after every file (should be dex, periodically)
It's not hooked up to ClangdServer/ClangdLSPServer yet: the layering
isn't clear (it should really be in ClangdServer, but ClangdLSPServer
has all the CDB interactions).
Reviewers: ioeric
Subscribers: mgorny, ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, jfb, cfe-commits
Differential Revision: https://reviews.llvm.org/D53032
llvm-svn: 344513
2018-10-15 21:34:10 +08:00
|
|
|
#include "Logger.h"
|
2019-07-04 17:51:43 +08:00
|
|
|
#include "Path.h"
|
2018-11-28 00:08:53 +08:00
|
|
|
#include "SourceCode.h"
|
2019-02-28 21:23:03 +08:00
|
|
|
#include "Symbol.h"
|
2018-10-30 20:13:27 +08:00
|
|
|
#include "Threading.h"
|
[clangd] Minimal implementation of automatic static index (not enabled).
Summary:
See tinyurl.com/clangd-automatic-index for design and goals.
Lots of limitations to keep this patch smallish, TODOs everywhere:
- no serialization to disk
- no changes to dynamic index, which now has a much simpler job
- no partitioning of symbols by file to avoid duplication of header symbols
- no reindexing of edited files
- only a single worker thread
- compilation database is slurped synchronously (doesn't scale)
- uses memindex, rebuilds after every file (should be dex, periodically)
It's not hooked up to ClangdServer/ClangdLSPServer yet: the layering
isn't clear (it should really be in ClangdServer, but ClangdLSPServer
has all the CDB interactions).
Reviewers: ioeric
Subscribers: mgorny, ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, jfb, cfe-commits
Differential Revision: https://reviews.llvm.org/D53032
llvm-svn: 344513
2018-10-15 21:34:10 +08:00
|
|
|
#include "Trace.h"
|
2018-11-06 18:55:21 +08:00
|
|
|
#include "URI.h"
|
2019-07-19 00:25:36 +08:00
|
|
|
#include "index/BackgroundIndexLoader.h"
|
[clangd] Rewrite of logic to rebuild the background index serving structures.
Summary:
Previously it was rebuilding every 5s by default, which was much too frequent
in the long run - the goal was to provide an early build. There were also some
bugs. There were also some bugs, and a dedicated thread was used in production
but not tested.
- rebuilds are triggered by #TUs built, rather than time. This should scale
more sensibly to fast vs slow machines.
- there are two separate indexed-TU thresholds to trigger index build: 5 TUs
for the first build, 100 for subsequent rebuilds.
- rebuild is always done on the regular indexing threads, and is affected by
blockUntilIdle. This means unit/lit tests run the production configuration.
- fixed a bug where we'd rebuild after attempting to load shards, even if there
were no shards.
- the BackgroundIndexTests don't really test the subtleties of the rebuild
policy (for determinism, we call blockUntilIdle, so rebuild-on-idle is enough
to pass the tests). Instead, we expose the rebuilder as a separate class and
have fine-grained tests for it.
Reviewers: kadircet
Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, jfb, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D64291
llvm-svn: 365531
2019-07-10 02:30:49 +08:00
|
|
|
#include "index/FileIndex.h"
|
[clangd] Minimal implementation of automatic static index (not enabled).
Summary:
See tinyurl.com/clangd-automatic-index for design and goals.
Lots of limitations to keep this patch smallish, TODOs everywhere:
- no serialization to disk
- no changes to dynamic index, which now has a much simpler job
- no partitioning of symbols by file to avoid duplication of header symbols
- no reindexing of edited files
- only a single worker thread
- compilation database is slurped synchronously (doesn't scale)
- uses memindex, rebuilds after every file (should be dex, periodically)
It's not hooked up to ClangdServer/ClangdLSPServer yet: the layering
isn't clear (it should really be in ClangdServer, but ClangdLSPServer
has all the CDB interactions).
Reviewers: ioeric
Subscribers: mgorny, ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, jfb, cfe-commits
Differential Revision: https://reviews.llvm.org/D53032
llvm-svn: 344513
2018-10-15 21:34:10 +08:00
|
|
|
#include "index/IndexAction.h"
|
|
|
|
#include "index/MemIndex.h"
|
2019-07-04 17:51:43 +08:00
|
|
|
#include "index/Ref.h"
|
|
|
|
#include "index/Relation.h"
|
[clangd] Minimal implementation of automatic static index (not enabled).
Summary:
See tinyurl.com/clangd-automatic-index for design and goals.
Lots of limitations to keep this patch smallish, TODOs everywhere:
- no serialization to disk
- no changes to dynamic index, which now has a much simpler job
- no partitioning of symbols by file to avoid duplication of header symbols
- no reindexing of edited files
- only a single worker thread
- compilation database is slurped synchronously (doesn't scale)
- uses memindex, rebuilds after every file (should be dex, periodically)
It's not hooked up to ClangdServer/ClangdLSPServer yet: the layering
isn't clear (it should really be in ClangdServer, but ClangdLSPServer
has all the CDB interactions).
Reviewers: ioeric
Subscribers: mgorny, ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, jfb, cfe-commits
Differential Revision: https://reviews.llvm.org/D53032
llvm-svn: 344513
2018-10-15 21:34:10 +08:00
|
|
|
#include "index/Serialization.h"
|
2018-11-06 18:55:21 +08:00
|
|
|
#include "index/SymbolCollector.h"
|
|
|
|
#include "clang/Basic/SourceLocation.h"
|
|
|
|
#include "clang/Basic/SourceManager.h"
|
2019-07-12 18:18:42 +08:00
|
|
|
#include "clang/Driver/Types.h"
|
2019-07-19 00:25:36 +08:00
|
|
|
#include "llvm/ADT/ArrayRef.h"
|
|
|
|
#include "llvm/ADT/DenseSet.h"
|
2019-07-04 17:51:53 +08:00
|
|
|
#include "llvm/ADT/Hashing.h"
|
2018-11-06 18:55:21 +08:00
|
|
|
#include "llvm/ADT/STLExtras.h"
|
2018-12-17 20:30:27 +08:00
|
|
|
#include "llvm/ADT/ScopeExit.h"
|
2018-11-06 18:55:21 +08:00
|
|
|
#include "llvm/ADT/StringMap.h"
|
|
|
|
#include "llvm/ADT/StringRef.h"
|
2019-07-04 17:51:43 +08:00
|
|
|
#include "llvm/ADT/StringSet.h"
|
|
|
|
#include "llvm/Support/Error.h"
|
2019-07-11 21:34:38 +08:00
|
|
|
#include "llvm/Support/Path.h"
|
2019-04-18 21:46:40 +08:00
|
|
|
#include "llvm/Support/Threading.h"
|
2018-11-16 17:03:56 +08:00
|
|
|
|
2019-07-11 21:34:38 +08:00
|
|
|
#include <algorithm>
|
2019-04-18 21:46:40 +08:00
|
|
|
#include <atomic>
|
2018-12-18 23:39:33 +08:00
|
|
|
#include <chrono>
|
[clangd] Rewrite of logic to rebuild the background index serving structures.
Summary:
Previously it was rebuilding every 5s by default, which was much too frequent
in the long run - the goal was to provide an early build. There were also some
bugs. There were also some bugs, and a dedicated thread was used in production
but not tested.
- rebuilds are triggered by #TUs built, rather than time. This should scale
more sensibly to fast vs slow machines.
- there are two separate indexed-TU thresholds to trigger index build: 5 TUs
for the first build, 100 for subsequent rebuilds.
- rebuild is always done on the regular indexing threads, and is affected by
blockUntilIdle. This means unit/lit tests run the production configuration.
- fixed a bug where we'd rebuild after attempting to load shards, even if there
were no shards.
- the BackgroundIndexTests don't really test the subtleties of the rebuild
policy (for determinism, we call blockUntilIdle, so rebuild-on-idle is enough
to pass the tests). Instead, we expose the rebuilder as a separate class and
have fine-grained tests for it.
Reviewers: kadircet
Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, jfb, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D64291
llvm-svn: 365531
2019-07-10 02:30:49 +08:00
|
|
|
#include <condition_variable>
|
2019-07-19 00:25:36 +08:00
|
|
|
#include <cstddef>
|
2018-11-16 17:03:56 +08:00
|
|
|
#include <memory>
|
[clangd] Rewrite of logic to rebuild the background index serving structures.
Summary:
Previously it was rebuilding every 5s by default, which was much too frequent
in the long run - the goal was to provide an early build. There were also some
bugs. There were also some bugs, and a dedicated thread was used in production
but not tested.
- rebuilds are triggered by #TUs built, rather than time. This should scale
more sensibly to fast vs slow machines.
- there are two separate indexed-TU thresholds to trigger index build: 5 TUs
for the first build, 100 for subsequent rebuilds.
- rebuild is always done on the regular indexing threads, and is affected by
blockUntilIdle. This means unit/lit tests run the production configuration.
- fixed a bug where we'd rebuild after attempting to load shards, even if there
were no shards.
- the BackgroundIndexTests don't really test the subtleties of the rebuild
policy (for determinism, we call blockUntilIdle, so rebuild-on-idle is enough
to pass the tests). Instead, we expose the rebuilder as a separate class and
have fine-grained tests for it.
Reviewers: kadircet
Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, jfb, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D64291
llvm-svn: 365531
2019-07-10 02:30:49 +08:00
|
|
|
#include <mutex>
|
2018-11-26 21:35:02 +08:00
|
|
|
#include <numeric>
|
2018-11-16 17:03:56 +08:00
|
|
|
#include <queue>
|
[clangd] Minimal implementation of automatic static index (not enabled).
Summary:
See tinyurl.com/clangd-automatic-index for design and goals.
Lots of limitations to keep this patch smallish, TODOs everywhere:
- no serialization to disk
- no changes to dynamic index, which now has a much simpler job
- no partitioning of symbols by file to avoid duplication of header symbols
- no reindexing of edited files
- only a single worker thread
- compilation database is slurped synchronously (doesn't scale)
- uses memindex, rebuilds after every file (should be dex, periodically)
It's not hooked up to ClangdServer/ClangdLSPServer yet: the layering
isn't clear (it should really be in ClangdServer, but ClangdLSPServer
has all the CDB interactions).
Reviewers: ioeric
Subscribers: mgorny, ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, jfb, cfe-commits
Differential Revision: https://reviews.llvm.org/D53032
llvm-svn: 344513
2018-10-15 21:34:10 +08:00
|
|
|
#include <random>
|
2018-11-06 18:55:21 +08:00
|
|
|
#include <string>
|
2018-12-18 23:39:33 +08:00
|
|
|
#include <thread>
|
2019-07-19 00:25:36 +08:00
|
|
|
#include <utility>
|
|
|
|
#include <vector>
|
[clangd] Minimal implementation of automatic static index (not enabled).
Summary:
See tinyurl.com/clangd-automatic-index for design and goals.
Lots of limitations to keep this patch smallish, TODOs everywhere:
- no serialization to disk
- no changes to dynamic index, which now has a much simpler job
- no partitioning of symbols by file to avoid duplication of header symbols
- no reindexing of edited files
- only a single worker thread
- compilation database is slurped synchronously (doesn't scale)
- uses memindex, rebuilds after every file (should be dex, periodically)
It's not hooked up to ClangdServer/ClangdLSPServer yet: the layering
isn't clear (it should really be in ClangdServer, but ClangdLSPServer
has all the CDB interactions).
Reviewers: ioeric
Subscribers: mgorny, ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, jfb, cfe-commits
Differential Revision: https://reviews.llvm.org/D53032
llvm-svn: 344513
2018-10-15 21:34:10 +08:00
|
|
|
|
|
|
|
namespace clang {
|
|
|
|
namespace clangd {
|
2018-12-04 19:31:57 +08:00
|
|
|
namespace {
|
2019-04-18 21:46:40 +08:00
|
|
|
|
2018-12-04 19:31:57 +08:00
|
|
|
// Resolves URI to file paths with cache.
|
|
|
|
class URIToFileCache {
|
|
|
|
public:
|
|
|
|
URIToFileCache(llvm::StringRef HintPath) : HintPath(HintPath) {}
|
|
|
|
|
|
|
|
llvm::StringRef resolve(llvm::StringRef FileURI) {
|
|
|
|
auto I = URIToPathCache.try_emplace(FileURI);
|
|
|
|
if (I.second) {
|
|
|
|
auto U = URI::parse(FileURI);
|
|
|
|
if (!U) {
|
|
|
|
elog("Failed to parse URI {0}: {1}", FileURI, U.takeError());
|
|
|
|
assert(false && "Failed to parse URI");
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
auto Path = URI::resolve(*U, HintPath);
|
|
|
|
if (!Path) {
|
|
|
|
elog("Failed to resolve URI {0}: {1}", FileURI, Path.takeError());
|
|
|
|
assert(false && "Failed to resolve URI");
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
I.first->second = *Path;
|
|
|
|
}
|
|
|
|
return I.first->second;
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
std::string HintPath;
|
|
|
|
llvm::StringMap<std::string> URIToPathCache;
|
|
|
|
};
|
|
|
|
|
|
|
|
// We keep only the node "U" and its edges. Any node other than "U" will be
|
|
|
|
// empty in the resultant graph.
|
|
|
|
IncludeGraph getSubGraph(const URI &U, const IncludeGraph &FullGraph) {
|
|
|
|
IncludeGraph IG;
|
|
|
|
|
|
|
|
std::string FileURI = U.toString();
|
|
|
|
auto Entry = IG.try_emplace(FileURI).first;
|
|
|
|
auto &Node = Entry->getValue();
|
|
|
|
Node = FullGraph.lookup(Entry->getKey());
|
|
|
|
Node.URI = Entry->getKey();
|
|
|
|
|
|
|
|
// URIs inside nodes must point into the keys of the same IncludeGraph.
|
|
|
|
for (auto &Include : Node.DirectIncludes) {
|
|
|
|
auto I = IG.try_emplace(Include).first;
|
|
|
|
I->getValue().URI = I->getKey();
|
|
|
|
Include = I->getKey();
|
|
|
|
}
|
|
|
|
|
|
|
|
return IG;
|
|
|
|
}
|
2018-12-13 21:07:29 +08:00
|
|
|
|
2019-01-11 01:03:04 +08:00
|
|
|
// We cannot use vfs->makeAbsolute because Cmd.FileName is either absolute or
|
|
|
|
// relative to Cmd.Directory, which might not be the same as current working
|
|
|
|
// directory.
|
|
|
|
llvm::SmallString<128> getAbsolutePath(const tooling::CompileCommand &Cmd) {
|
|
|
|
llvm::SmallString<128> AbsolutePath;
|
|
|
|
if (llvm::sys::path::is_absolute(Cmd.Filename)) {
|
|
|
|
AbsolutePath = Cmd.Filename;
|
|
|
|
} else {
|
|
|
|
AbsolutePath = Cmd.Directory;
|
|
|
|
llvm::sys::path::append(AbsolutePath, Cmd.Filename);
|
2019-03-08 17:57:33 +08:00
|
|
|
llvm::sys::path::remove_dots(AbsolutePath, true);
|
2019-01-11 01:03:04 +08:00
|
|
|
}
|
|
|
|
return AbsolutePath;
|
|
|
|
}
|
2019-07-19 00:25:36 +08:00
|
|
|
|
|
|
|
bool shardIsStale(const LoadedShard &LS, llvm::vfs::FileSystem *FS) {
|
|
|
|
auto Buf = FS->getBufferForFile(LS.AbsolutePath);
|
|
|
|
if (!Buf) {
|
|
|
|
elog("Background-index: Couldn't read {0} to validate stored index: {1}",
|
|
|
|
LS.AbsolutePath, Buf.getError().message());
|
|
|
|
// There is no point in indexing an unreadable file.
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return digest(Buf->get()->getBuffer()) != LS.Digest;
|
|
|
|
}
|
|
|
|
|
2018-12-04 19:31:57 +08:00
|
|
|
} // namespace
|
[clangd] Minimal implementation of automatic static index (not enabled).
Summary:
See tinyurl.com/clangd-automatic-index for design and goals.
Lots of limitations to keep this patch smallish, TODOs everywhere:
- no serialization to disk
- no changes to dynamic index, which now has a much simpler job
- no partitioning of symbols by file to avoid duplication of header symbols
- no reindexing of edited files
- only a single worker thread
- compilation database is slurped synchronously (doesn't scale)
- uses memindex, rebuilds after every file (should be dex, periodically)
It's not hooked up to ClangdServer/ClangdLSPServer yet: the layering
isn't clear (it should really be in ClangdServer, but ClangdLSPServer
has all the CDB interactions).
Reviewers: ioeric
Subscribers: mgorny, ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, jfb, cfe-commits
Differential Revision: https://reviews.llvm.org/D53032
llvm-svn: 344513
2018-10-15 21:34:10 +08:00
|
|
|
|
2018-11-16 17:03:56 +08:00
|
|
|
BackgroundIndex::BackgroundIndex(
|
2019-01-22 17:10:20 +08:00
|
|
|
Context BackgroundContext, const FileSystemProvider &FSProvider,
|
|
|
|
const GlobalCompilationDatabase &CDB,
|
[clangd] Rewrite of logic to rebuild the background index serving structures.
Summary:
Previously it was rebuilding every 5s by default, which was much too frequent
in the long run - the goal was to provide an early build. There were also some
bugs. There were also some bugs, and a dedicated thread was used in production
but not tested.
- rebuilds are triggered by #TUs built, rather than time. This should scale
more sensibly to fast vs slow machines.
- there are two separate indexed-TU thresholds to trigger index build: 5 TUs
for the first build, 100 for subsequent rebuilds.
- rebuild is always done on the regular indexing threads, and is affected by
blockUntilIdle. This means unit/lit tests run the production configuration.
- fixed a bug where we'd rebuild after attempting to load shards, even if there
were no shards.
- the BackgroundIndexTests don't really test the subtleties of the rebuild
policy (for determinism, we call blockUntilIdle, so rebuild-on-idle is enough
to pass the tests). Instead, we expose the rebuilder as a separate class and
have fine-grained tests for it.
Reviewers: kadircet
Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, jfb, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D64291
llvm-svn: 365531
2019-07-10 02:30:49 +08:00
|
|
|
BackgroundIndexStorage::Factory IndexStorageFactory, size_t ThreadPoolSize)
|
2019-01-22 17:10:20 +08:00
|
|
|
: SwapIndex(llvm::make_unique<MemIndex>()), FSProvider(FSProvider),
|
|
|
|
CDB(CDB), BackgroundContext(std::move(BackgroundContext)),
|
2019-07-16 18:17:06 +08:00
|
|
|
Rebuilder(this, &IndexedSymbols, ThreadPoolSize),
|
[clangd] Auto-index watches global CDB for changes.
Summary:
Instead of receiving compilation commands, auto-index is triggered by just
filenames to reindex, and gets commands from the global comp DB internally.
This has advantages:
- more of the work can be done asynchronously (fetching compilation commands
upfront can be slow for large CDBs)
- we get access to the CDB which can be used to retrieve interpolated commands
for headers (useful in some cases where the original TU goes away)
- fits nicely with the filename-only change observation from r347297
The interface to GlobalCompilationDatabase gets extended: when retrieving a
compile command, the GCDB can optionally report the project the file belongs to.
This naturally fits together with getCompileCommand: it's hard to implement one
without the other. But because most callers don't care, I've ended up with an
awkward optional-out-param-in-virtual method pattern - maybe there's a better
one.
This is the main missing integration point between ClangdServer and
BackgroundIndex, after this we should be able to add an auto-index flag.
Reviewers: ioeric, kadircet
Subscribers: MaskRay, jkorous, arphaman, cfe-commits, ilya-biryukov
Differential Revision: https://reviews.llvm.org/D54865
llvm-svn: 347538
2018-11-26 17:51:50 +08:00
|
|
|
IndexStorageFactory(std::move(IndexStorageFactory)),
|
|
|
|
CommandsChanged(
|
|
|
|
CDB.watch([&](const std::vector<std::string> &ChangedFiles) {
|
|
|
|
enqueue(ChangedFiles);
|
|
|
|
})) {
|
2018-10-30 20:13:27 +08:00
|
|
|
assert(ThreadPoolSize > 0 && "Thread pool size can't be zero.");
|
2018-11-16 17:41:14 +08:00
|
|
|
assert(this->IndexStorageFactory && "Storage factory can not be null!");
|
2019-05-09 20:04:07 +08:00
|
|
|
for (unsigned I = 0; I < ThreadPoolSize; ++I) {
|
2019-07-11 21:34:38 +08:00
|
|
|
ThreadPool.runAsync("background-worker-" + llvm::Twine(I + 1), [this] {
|
|
|
|
WithContext Ctx(this->BackgroundContext.clone());
|
|
|
|
Queue.work([&] { Rebuilder.idle(); });
|
|
|
|
});
|
2019-05-09 20:04:07 +08:00
|
|
|
}
|
2018-10-30 20:13:27 +08:00
|
|
|
}
|
[clangd] Minimal implementation of automatic static index (not enabled).
Summary:
See tinyurl.com/clangd-automatic-index for design and goals.
Lots of limitations to keep this patch smallish, TODOs everywhere:
- no serialization to disk
- no changes to dynamic index, which now has a much simpler job
- no partitioning of symbols by file to avoid duplication of header symbols
- no reindexing of edited files
- only a single worker thread
- compilation database is slurped synchronously (doesn't scale)
- uses memindex, rebuilds after every file (should be dex, periodically)
It's not hooked up to ClangdServer/ClangdLSPServer yet: the layering
isn't clear (it should really be in ClangdServer, but ClangdLSPServer
has all the CDB interactions).
Reviewers: ioeric
Subscribers: mgorny, ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, jfb, cfe-commits
Differential Revision: https://reviews.llvm.org/D53032
llvm-svn: 344513
2018-10-15 21:34:10 +08:00
|
|
|
|
|
|
|
BackgroundIndex::~BackgroundIndex() {
|
|
|
|
stop();
|
2019-05-09 20:04:07 +08:00
|
|
|
ThreadPool.wait();
|
[clangd] Minimal implementation of automatic static index (not enabled).
Summary:
See tinyurl.com/clangd-automatic-index for design and goals.
Lots of limitations to keep this patch smallish, TODOs everywhere:
- no serialization to disk
- no changes to dynamic index, which now has a much simpler job
- no partitioning of symbols by file to avoid duplication of header symbols
- no reindexing of edited files
- only a single worker thread
- compilation database is slurped synchronously (doesn't scale)
- uses memindex, rebuilds after every file (should be dex, periodically)
It's not hooked up to ClangdServer/ClangdLSPServer yet: the layering
isn't clear (it should really be in ClangdServer, but ClangdLSPServer
has all the CDB interactions).
Reviewers: ioeric
Subscribers: mgorny, ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, jfb, cfe-commits
Differential Revision: https://reviews.llvm.org/D53032
llvm-svn: 344513
2018-10-15 21:34:10 +08:00
|
|
|
}
|
|
|
|
|
2019-07-11 21:34:38 +08:00
|
|
|
BackgroundQueue::Task BackgroundIndex::changedFilesTask(
|
|
|
|
const std::vector<std::string> &ChangedFiles) {
|
|
|
|
BackgroundQueue::Task T([this, ChangedFiles] {
|
|
|
|
trace::Span Tracer("BackgroundIndexEnqueue");
|
|
|
|
// We're doing this asynchronously, because we'll read shards here too.
|
|
|
|
log("Enqueueing {0} commands for indexing", ChangedFiles.size());
|
|
|
|
SPAN_ATTACH(Tracer, "files", int64_t(ChangedFiles.size()));
|
|
|
|
|
2019-07-19 00:25:36 +08:00
|
|
|
auto NeedsReIndexing = loadProject(std::move(ChangedFiles));
|
2019-07-11 21:34:38 +08:00
|
|
|
// Run indexing for files that need to be updated.
|
|
|
|
std::shuffle(NeedsReIndexing.begin(), NeedsReIndexing.end(),
|
|
|
|
std::mt19937(std::random_device{}()));
|
|
|
|
std::vector<BackgroundQueue::Task> Tasks;
|
|
|
|
Tasks.reserve(NeedsReIndexing.size());
|
[clangd] BackgroundIndex stores shards to the closest project
Summary:
Changes persistance logic to store shards at the directory of closest
CDB. Previously we were storing all shards to directory of the CDB that
triggered indexing, it had its downsides.
For example, if you had two TUs coming from a different CDB but depending on the
same header foo.h, we will store the foo.h only for the first CDB, and it would
be missing for the second and we would never persist it since it was actually
present in the memory and persisted before.
This patch still stores only a single copy of a shard, but makes the directory a
function of the file name. So that the shard place will be unique even with
multiple CDBs accessing the file. This directory is determined as the first
directory containing a CDB in the file's parent directories, if no such
directory exists we make use of the home directory.
Reviewers: sammccall
Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D64745
llvm-svn: 366467
2019-07-19 01:20:41 +08:00
|
|
|
for (auto &Cmd : NeedsReIndexing)
|
|
|
|
Tasks.push_back(indexFileTask(std::move(Cmd)));
|
2019-07-11 21:34:38 +08:00
|
|
|
Queue.append(std::move(Tasks));
|
|
|
|
});
|
|
|
|
|
|
|
|
T.QueuePri = LoadShards;
|
|
|
|
T.ThreadPri = llvm::ThreadPriority::Default;
|
|
|
|
return T;
|
[clangd] Minimal implementation of automatic static index (not enabled).
Summary:
See tinyurl.com/clangd-automatic-index for design and goals.
Lots of limitations to keep this patch smallish, TODOs everywhere:
- no serialization to disk
- no changes to dynamic index, which now has a much simpler job
- no partitioning of symbols by file to avoid duplication of header symbols
- no reindexing of edited files
- only a single worker thread
- compilation database is slurped synchronously (doesn't scale)
- uses memindex, rebuilds after every file (should be dex, periodically)
It's not hooked up to ClangdServer/ClangdLSPServer yet: the layering
isn't clear (it should really be in ClangdServer, but ClangdLSPServer
has all the CDB interactions).
Reviewers: ioeric
Subscribers: mgorny, ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, jfb, cfe-commits
Differential Revision: https://reviews.llvm.org/D53032
llvm-svn: 344513
2018-10-15 21:34:10 +08:00
|
|
|
}
|
|
|
|
|
2019-07-12 18:18:42 +08:00
|
|
|
static llvm::StringRef filenameWithoutExtension(llvm::StringRef Path) {
|
|
|
|
Path = llvm::sys::path::filename(Path);
|
|
|
|
return Path.drop_back(llvm::sys::path::extension(Path).size());
|
|
|
|
}
|
|
|
|
|
2019-07-11 21:34:38 +08:00
|
|
|
BackgroundQueue::Task
|
[clangd] BackgroundIndex stores shards to the closest project
Summary:
Changes persistance logic to store shards at the directory of closest
CDB. Previously we were storing all shards to directory of the CDB that
triggered indexing, it had its downsides.
For example, if you had two TUs coming from a different CDB but depending on the
same header foo.h, we will store the foo.h only for the first CDB, and it would
be missing for the second and we would never persist it since it was actually
present in the memory and persisted before.
This patch still stores only a single copy of a shard, but makes the directory a
function of the file name. So that the shard place will be unique even with
multiple CDBs accessing the file. This directory is determined as the first
directory containing a CDB in the file's parent directories, if no such
directory exists we make use of the home directory.
Reviewers: sammccall
Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D64745
llvm-svn: 366467
2019-07-19 01:20:41 +08:00
|
|
|
BackgroundIndex::indexFileTask(tooling::CompileCommand Cmd) {
|
|
|
|
BackgroundQueue::Task T([this, Cmd] {
|
2019-07-11 21:34:38 +08:00
|
|
|
// We can't use llvm::StringRef here since we are going to
|
|
|
|
// move from Cmd during the call below.
|
|
|
|
const std::string FileName = Cmd.Filename;
|
[clangd] BackgroundIndex stores shards to the closest project
Summary:
Changes persistance logic to store shards at the directory of closest
CDB. Previously we were storing all shards to directory of the CDB that
triggered indexing, it had its downsides.
For example, if you had two TUs coming from a different CDB but depending on the
same header foo.h, we will store the foo.h only for the first CDB, and it would
be missing for the second and we would never persist it since it was actually
present in the memory and persisted before.
This patch still stores only a single copy of a shard, but makes the directory a
function of the file name. So that the shard place will be unique even with
multiple CDBs accessing the file. This directory is determined as the first
directory containing a CDB in the file's parent directories, if no such
directory exists we make use of the home directory.
Reviewers: sammccall
Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D64745
llvm-svn: 366467
2019-07-19 01:20:41 +08:00
|
|
|
if (auto Error = index(std::move(Cmd)))
|
2019-07-11 21:34:38 +08:00
|
|
|
elog("Indexing {0} failed: {1}", FileName, std::move(Error));
|
|
|
|
});
|
|
|
|
T.QueuePri = IndexFile;
|
2019-07-12 18:18:42 +08:00
|
|
|
T.Tag = filenameWithoutExtension(Cmd.Filename);
|
2019-07-11 21:34:38 +08:00
|
|
|
return T;
|
[clangd] Minimal implementation of automatic static index (not enabled).
Summary:
See tinyurl.com/clangd-automatic-index for design and goals.
Lots of limitations to keep this patch smallish, TODOs everywhere:
- no serialization to disk
- no changes to dynamic index, which now has a much simpler job
- no partitioning of symbols by file to avoid duplication of header symbols
- no reindexing of edited files
- only a single worker thread
- compilation database is slurped synchronously (doesn't scale)
- uses memindex, rebuilds after every file (should be dex, periodically)
It's not hooked up to ClangdServer/ClangdLSPServer yet: the layering
isn't clear (it should really be in ClangdServer, but ClangdLSPServer
has all the CDB interactions).
Reviewers: ioeric
Subscribers: mgorny, ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, jfb, cfe-commits
Differential Revision: https://reviews.llvm.org/D53032
llvm-svn: 344513
2018-10-15 21:34:10 +08:00
|
|
|
}
|
|
|
|
|
2019-07-12 18:18:42 +08:00
|
|
|
void BackgroundIndex::boostRelated(llvm::StringRef Path) {
|
|
|
|
namespace types = clang::driver::types;
|
|
|
|
auto Type =
|
|
|
|
types::lookupTypeForExtension(llvm::sys::path::extension(Path).substr(1));
|
|
|
|
// is this a header?
|
|
|
|
if (Type != types::TY_INVALID && types::onlyPrecompileType(Type))
|
|
|
|
Queue.boost(filenameWithoutExtension(Path), IndexBoostedFile);
|
|
|
|
}
|
|
|
|
|
2019-01-15 17:03:33 +08:00
|
|
|
/// Given index results from a TU, only update symbols coming from files that
|
2019-07-04 17:52:12 +08:00
|
|
|
/// are different or missing from than \p ShardVersionsSnapshot. Also stores new
|
|
|
|
/// index information on IndexStorage.
|
|
|
|
void BackgroundIndex::update(
|
|
|
|
llvm::StringRef MainFile, IndexFileIn Index,
|
|
|
|
const llvm::StringMap<ShardVersion> &ShardVersionsSnapshot,
|
[clangd] BackgroundIndex stores shards to the closest project
Summary:
Changes persistance logic to store shards at the directory of closest
CDB. Previously we were storing all shards to directory of the CDB that
triggered indexing, it had its downsides.
For example, if you had two TUs coming from a different CDB but depending on the
same header foo.h, we will store the foo.h only for the first CDB, and it would
be missing for the second and we would never persist it since it was actually
present in the memory and persisted before.
This patch still stores only a single copy of a shard, but makes the directory a
function of the file name. So that the shard place will be unique even with
multiple CDBs accessing the file. This directory is determined as the first
directory containing a CDB in the file's parent directories, if no such
directory exists we make use of the home directory.
Reviewers: sammccall
Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D64745
llvm-svn: 366467
2019-07-19 01:20:41 +08:00
|
|
|
bool HadErrors) {
|
2018-11-06 18:55:21 +08:00
|
|
|
// Partition symbols/references into files.
|
|
|
|
struct File {
|
2019-01-07 23:45:19 +08:00
|
|
|
llvm::DenseSet<const Symbol *> Symbols;
|
|
|
|
llvm::DenseSet<const Ref *> Refs;
|
2019-06-15 10:26:47 +08:00
|
|
|
llvm::DenseSet<const Relation *> Relations;
|
2019-01-15 17:03:33 +08:00
|
|
|
FileDigest Digest;
|
2018-11-06 18:55:21 +08:00
|
|
|
};
|
2019-01-07 23:45:19 +08:00
|
|
|
llvm::StringMap<File> Files;
|
2018-11-06 18:55:21 +08:00
|
|
|
URIToFileCache URICache(MainFile);
|
2019-01-15 17:03:33 +08:00
|
|
|
for (const auto &IndexIt : *Index.Sources) {
|
|
|
|
const auto &IGN = IndexIt.getValue();
|
2019-07-04 17:52:12 +08:00
|
|
|
// Note that sources do not contain any information regarding missing
|
|
|
|
// headers, since we don't even know what absolute path they should fall in.
|
2019-01-15 17:03:33 +08:00
|
|
|
const auto AbsPath = URICache.resolve(IGN.URI);
|
2019-07-04 17:52:12 +08:00
|
|
|
const auto DigestIt = ShardVersionsSnapshot.find(AbsPath);
|
|
|
|
// File has different contents, or indexing was successfull this time.
|
|
|
|
if (DigestIt == ShardVersionsSnapshot.end() ||
|
|
|
|
DigestIt->getValue().Digest != IGN.Digest ||
|
|
|
|
(DigestIt->getValue().HadErrors && !HadErrors))
|
2019-01-15 17:03:33 +08:00
|
|
|
Files.try_emplace(AbsPath).first->getValue().Digest = IGN.Digest;
|
|
|
|
}
|
2019-06-15 10:26:47 +08:00
|
|
|
// This map is used to figure out where to store relations.
|
|
|
|
llvm::DenseMap<SymbolID, File *> SymbolIDToFile;
|
2018-11-28 00:08:53 +08:00
|
|
|
for (const auto &Sym : *Index.Symbols) {
|
2018-11-06 18:55:21 +08:00
|
|
|
if (Sym.CanonicalDeclaration) {
|
|
|
|
auto DeclPath = URICache.resolve(Sym.CanonicalDeclaration.FileURI);
|
2019-01-15 17:03:33 +08:00
|
|
|
const auto FileIt = Files.find(DeclPath);
|
2019-06-15 10:26:47 +08:00
|
|
|
if (FileIt != Files.end()) {
|
2019-01-15 17:03:33 +08:00
|
|
|
FileIt->second.Symbols.insert(&Sym);
|
2019-06-15 10:26:47 +08:00
|
|
|
SymbolIDToFile[Sym.ID] = &FileIt->second;
|
|
|
|
}
|
2018-11-06 18:55:21 +08:00
|
|
|
}
|
|
|
|
// For symbols with different declaration and definition locations, we store
|
|
|
|
// the full symbol in both the header file and the implementation file, so
|
|
|
|
// that merging can tell the preferred symbols (from canonical headers) from
|
|
|
|
// other symbols (e.g. forward declarations).
|
|
|
|
if (Sym.Definition &&
|
|
|
|
Sym.Definition.FileURI != Sym.CanonicalDeclaration.FileURI) {
|
|
|
|
auto DefPath = URICache.resolve(Sym.Definition.FileURI);
|
2019-01-15 17:03:33 +08:00
|
|
|
const auto FileIt = Files.find(DefPath);
|
|
|
|
if (FileIt != Files.end())
|
|
|
|
FileIt->second.Symbols.insert(&Sym);
|
2018-11-06 18:55:21 +08:00
|
|
|
}
|
|
|
|
}
|
2019-01-07 23:45:19 +08:00
|
|
|
llvm::DenseMap<const Ref *, SymbolID> RefToIDs;
|
2018-11-28 00:08:53 +08:00
|
|
|
for (const auto &SymRefs : *Index.Refs) {
|
2018-11-06 18:55:21 +08:00
|
|
|
for (const auto &R : SymRefs.second) {
|
|
|
|
auto Path = URICache.resolve(R.Location.FileURI);
|
2019-01-15 17:03:33 +08:00
|
|
|
const auto FileIt = Files.find(Path);
|
|
|
|
if (FileIt != Files.end()) {
|
|
|
|
auto &F = FileIt->getValue();
|
2018-11-06 18:55:21 +08:00
|
|
|
RefToIDs[&R] = SymRefs.first;
|
|
|
|
F.Refs.insert(&R);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2019-06-15 10:26:47 +08:00
|
|
|
for (const auto &Rel : *Index.Relations) {
|
|
|
|
const auto FileIt = SymbolIDToFile.find(Rel.Subject);
|
|
|
|
if (FileIt != SymbolIDToFile.end())
|
|
|
|
FileIt->second->Relations.insert(&Rel);
|
|
|
|
}
|
2018-11-06 18:55:21 +08:00
|
|
|
|
|
|
|
// Build and store new slabs for each updated file.
|
2019-01-15 17:03:33 +08:00
|
|
|
for (const auto &FileIt : Files) {
|
|
|
|
llvm::StringRef Path = FileIt.getKey();
|
2018-11-06 18:55:21 +08:00
|
|
|
SymbolSlab::Builder Syms;
|
|
|
|
RefSlab::Builder Refs;
|
2019-06-15 10:26:47 +08:00
|
|
|
RelationSlab::Builder Relations;
|
2019-01-15 17:03:33 +08:00
|
|
|
for (const auto *S : FileIt.second.Symbols)
|
|
|
|
Syms.insert(*S);
|
|
|
|
for (const auto *R : FileIt.second.Refs)
|
|
|
|
Refs.insert(RefToIDs[R], *R);
|
2019-06-15 10:26:47 +08:00
|
|
|
for (const auto *Rel : FileIt.second.Relations)
|
|
|
|
Relations.insert(*Rel);
|
2018-11-16 17:03:56 +08:00
|
|
|
auto SS = llvm::make_unique<SymbolSlab>(std::move(Syms).build());
|
|
|
|
auto RS = llvm::make_unique<RefSlab>(std::move(Refs).build());
|
2019-06-15 10:26:47 +08:00
|
|
|
auto RelS = llvm::make_unique<RelationSlab>(std::move(Relations).build());
|
2018-12-04 19:31:57 +08:00
|
|
|
auto IG = llvm::make_unique<IncludeGraph>(
|
|
|
|
getSubGraph(URI::create(Path), Index.Sources.getValue()));
|
2019-07-04 17:51:43 +08:00
|
|
|
|
2018-11-16 17:03:56 +08:00
|
|
|
// We need to store shards before updating the index, since the latter
|
|
|
|
// consumes slabs.
|
2019-07-04 17:51:43 +08:00
|
|
|
// FIXME: Also skip serializing the shard if it is already up-to-date.
|
[clangd] BackgroundIndex stores shards to the closest project
Summary:
Changes persistance logic to store shards at the directory of closest
CDB. Previously we were storing all shards to directory of the CDB that
triggered indexing, it had its downsides.
For example, if you had two TUs coming from a different CDB but depending on the
same header foo.h, we will store the foo.h only for the first CDB, and it would
be missing for the second and we would never persist it since it was actually
present in the memory and persisted before.
This patch still stores only a single copy of a shard, but makes the directory a
function of the file name. So that the shard place will be unique even with
multiple CDBs accessing the file. This directory is determined as the first
directory containing a CDB in the file's parent directories, if no such
directory exists we make use of the home directory.
Reviewers: sammccall
Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D64745
llvm-svn: 366467
2019-07-19 01:20:41 +08:00
|
|
|
BackgroundIndexStorage *IndexStorage = IndexStorageFactory(Path);
|
|
|
|
IndexFileOut Shard;
|
|
|
|
Shard.Symbols = SS.get();
|
|
|
|
Shard.Refs = RS.get();
|
|
|
|
Shard.Relations = RelS.get();
|
|
|
|
Shard.Sources = IG.get();
|
|
|
|
|
|
|
|
// Only store command line hash for main files of the TU, since our
|
|
|
|
// current model keeps only one version of a header file.
|
|
|
|
if (Path == MainFile)
|
|
|
|
Shard.Cmd = Index.Cmd.getPointer();
|
|
|
|
|
|
|
|
if (auto Error = IndexStorage->storeShard(Path, Shard))
|
|
|
|
elog("Failed to write background-index shard for file {0}: {1}", Path,
|
|
|
|
std::move(Error));
|
2019-07-04 17:51:43 +08:00
|
|
|
|
2019-01-11 01:03:04 +08:00
|
|
|
{
|
2019-07-04 17:52:12 +08:00
|
|
|
std::lock_guard<std::mutex> Lock(ShardVersionsMu);
|
2019-01-15 17:03:33 +08:00
|
|
|
auto Hash = FileIt.second.Digest;
|
2019-07-04 17:52:12 +08:00
|
|
|
auto DigestIt = ShardVersions.try_emplace(Path);
|
|
|
|
ShardVersion &SV = DigestIt.first->second;
|
|
|
|
// Skip if file is already up to date, unless previous index was broken
|
|
|
|
// and this one is not.
|
|
|
|
if (!DigestIt.second && SV.Digest == Hash && SV.HadErrors && !HadErrors)
|
2019-01-11 01:03:04 +08:00
|
|
|
continue;
|
2019-07-04 17:52:12 +08:00
|
|
|
SV.Digest = Hash;
|
|
|
|
SV.HadErrors = HadErrors;
|
|
|
|
|
2019-01-11 01:03:04 +08:00
|
|
|
// 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.
|
2019-06-15 10:26:47 +08:00
|
|
|
IndexedSymbols.update(Path, std::move(SS), std::move(RS), std::move(RelS),
|
2019-05-09 22:22:07 +08:00
|
|
|
Path == MainFile);
|
2019-01-11 01:03:04 +08:00
|
|
|
}
|
2018-11-06 18:55:21 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
[clangd] BackgroundIndex stores shards to the closest project
Summary:
Changes persistance logic to store shards at the directory of closest
CDB. Previously we were storing all shards to directory of the CDB that
triggered indexing, it had its downsides.
For example, if you had two TUs coming from a different CDB but depending on the
same header foo.h, we will store the foo.h only for the first CDB, and it would
be missing for the second and we would never persist it since it was actually
present in the memory and persisted before.
This patch still stores only a single copy of a shard, but makes the directory a
function of the file name. So that the shard place will be unique even with
multiple CDBs accessing the file. This directory is determined as the first
directory containing a CDB in the file's parent directories, if no such
directory exists we make use of the home directory.
Reviewers: sammccall
Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D64745
llvm-svn: 366467
2019-07-19 01:20:41 +08:00
|
|
|
llvm::Error BackgroundIndex::index(tooling::CompileCommand Cmd) {
|
[clangd] Minimal implementation of automatic static index (not enabled).
Summary:
See tinyurl.com/clangd-automatic-index for design and goals.
Lots of limitations to keep this patch smallish, TODOs everywhere:
- no serialization to disk
- no changes to dynamic index, which now has a much simpler job
- no partitioning of symbols by file to avoid duplication of header symbols
- no reindexing of edited files
- only a single worker thread
- compilation database is slurped synchronously (doesn't scale)
- uses memindex, rebuilds after every file (should be dex, periodically)
It's not hooked up to ClangdServer/ClangdLSPServer yet: the layering
isn't clear (it should really be in ClangdServer, but ClangdLSPServer
has all the CDB interactions).
Reviewers: ioeric
Subscribers: mgorny, ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, jfb, cfe-commits
Differential Revision: https://reviews.llvm.org/D53032
llvm-svn: 344513
2018-10-15 21:34:10 +08:00
|
|
|
trace::Span Tracer("BackgroundIndex");
|
|
|
|
SPAN_ATTACH(Tracer, "file", Cmd.Filename);
|
2019-01-11 01:03:04 +08:00
|
|
|
auto AbsolutePath = getAbsolutePath(Cmd);
|
[clangd] Minimal implementation of automatic static index (not enabled).
Summary:
See tinyurl.com/clangd-automatic-index for design and goals.
Lots of limitations to keep this patch smallish, TODOs everywhere:
- no serialization to disk
- no changes to dynamic index, which now has a much simpler job
- no partitioning of symbols by file to avoid duplication of header symbols
- no reindexing of edited files
- only a single worker thread
- compilation database is slurped synchronously (doesn't scale)
- uses memindex, rebuilds after every file (should be dex, periodically)
It's not hooked up to ClangdServer/ClangdLSPServer yet: the layering
isn't clear (it should really be in ClangdServer, but ClangdLSPServer
has all the CDB interactions).
Reviewers: ioeric
Subscribers: mgorny, ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, jfb, cfe-commits
Differential Revision: https://reviews.llvm.org/D53032
llvm-svn: 344513
2018-10-15 21:34:10 +08:00
|
|
|
|
|
|
|
auto FS = FSProvider.getFileSystem();
|
|
|
|
auto Buf = FS->getBufferForFile(AbsolutePath);
|
|
|
|
if (!Buf)
|
2019-01-07 23:45:19 +08:00
|
|
|
return llvm::errorCodeToError(Buf.getError());
|
2018-11-06 18:55:21 +08:00
|
|
|
auto Hash = digest(Buf->get()->getBuffer());
|
|
|
|
|
2019-07-04 17:52:12 +08:00
|
|
|
// Take a snapshot of the versions to avoid locking for each file in the TU.
|
|
|
|
llvm::StringMap<ShardVersion> ShardVersionsSnapshot;
|
2018-11-06 18:55:21 +08:00
|
|
|
{
|
2019-07-04 17:52:12 +08:00
|
|
|
std::lock_guard<std::mutex> Lock(ShardVersionsMu);
|
|
|
|
ShardVersionsSnapshot = ShardVersions;
|
[clangd] Minimal implementation of automatic static index (not enabled).
Summary:
See tinyurl.com/clangd-automatic-index for design and goals.
Lots of limitations to keep this patch smallish, TODOs everywhere:
- no serialization to disk
- no changes to dynamic index, which now has a much simpler job
- no partitioning of symbols by file to avoid duplication of header symbols
- no reindexing of edited files
- only a single worker thread
- compilation database is slurped synchronously (doesn't scale)
- uses memindex, rebuilds after every file (should be dex, periodically)
It's not hooked up to ClangdServer/ClangdLSPServer yet: the layering
isn't clear (it should really be in ClangdServer, but ClangdLSPServer
has all the CDB interactions).
Reviewers: ioeric
Subscribers: mgorny, ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, jfb, cfe-commits
Differential Revision: https://reviews.llvm.org/D53032
llvm-svn: 344513
2018-10-15 21:34:10 +08:00
|
|
|
}
|
|
|
|
|
2019-01-19 01:04:26 +08:00
|
|
|
vlog("Indexing {0} (digest:={1})", Cmd.Filename, llvm::toHex(Hash));
|
[clangd] Minimal implementation of automatic static index (not enabled).
Summary:
See tinyurl.com/clangd-automatic-index for design and goals.
Lots of limitations to keep this patch smallish, TODOs everywhere:
- no serialization to disk
- no changes to dynamic index, which now has a much simpler job
- no partitioning of symbols by file to avoid duplication of header symbols
- no reindexing of edited files
- only a single worker thread
- compilation database is slurped synchronously (doesn't scale)
- uses memindex, rebuilds after every file (should be dex, periodically)
It's not hooked up to ClangdServer/ClangdLSPServer yet: the layering
isn't clear (it should really be in ClangdServer, but ClangdLSPServer
has all the CDB interactions).
Reviewers: ioeric
Subscribers: mgorny, ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, jfb, cfe-commits
Differential Revision: https://reviews.llvm.org/D53032
llvm-svn: 344513
2018-10-15 21:34:10 +08:00
|
|
|
ParseInputs Inputs;
|
|
|
|
Inputs.FS = std::move(FS);
|
|
|
|
Inputs.FS->setCurrentWorkingDirectory(Cmd.Directory);
|
|
|
|
Inputs.CompileCommand = std::move(Cmd);
|
|
|
|
auto CI = buildCompilerInvocation(Inputs);
|
|
|
|
if (!CI)
|
2019-01-07 23:45:19 +08:00
|
|
|
return llvm::createStringError(llvm::inconvertibleErrorCode(),
|
|
|
|
"Couldn't build compiler invocation");
|
[clangd] Minimal implementation of automatic static index (not enabled).
Summary:
See tinyurl.com/clangd-automatic-index for design and goals.
Lots of limitations to keep this patch smallish, TODOs everywhere:
- no serialization to disk
- no changes to dynamic index, which now has a much simpler job
- no partitioning of symbols by file to avoid duplication of header symbols
- no reindexing of edited files
- only a single worker thread
- compilation database is slurped synchronously (doesn't scale)
- uses memindex, rebuilds after every file (should be dex, periodically)
It's not hooked up to ClangdServer/ClangdLSPServer yet: the layering
isn't clear (it should really be in ClangdServer, but ClangdLSPServer
has all the CDB interactions).
Reviewers: ioeric
Subscribers: mgorny, ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, jfb, cfe-commits
Differential Revision: https://reviews.llvm.org/D53032
llvm-svn: 344513
2018-10-15 21:34:10 +08:00
|
|
|
IgnoreDiagnostics IgnoreDiags;
|
2019-04-04 20:56:03 +08:00
|
|
|
auto Clang = prepareCompilerInstance(std::move(CI), /*Preamble=*/nullptr,
|
|
|
|
std::move(*Buf), Inputs.FS, IgnoreDiags);
|
[clangd] Minimal implementation of automatic static index (not enabled).
Summary:
See tinyurl.com/clangd-automatic-index for design and goals.
Lots of limitations to keep this patch smallish, TODOs everywhere:
- no serialization to disk
- no changes to dynamic index, which now has a much simpler job
- no partitioning of symbols by file to avoid duplication of header symbols
- no reindexing of edited files
- only a single worker thread
- compilation database is slurped synchronously (doesn't scale)
- uses memindex, rebuilds after every file (should be dex, periodically)
It's not hooked up to ClangdServer/ClangdLSPServer yet: the layering
isn't clear (it should really be in ClangdServer, but ClangdLSPServer
has all the CDB interactions).
Reviewers: ioeric
Subscribers: mgorny, ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, jfb, cfe-commits
Differential Revision: https://reviews.llvm.org/D53032
llvm-svn: 344513
2018-10-15 21:34:10 +08:00
|
|
|
if (!Clang)
|
2019-01-07 23:45:19 +08:00
|
|
|
return llvm::createStringError(llvm::inconvertibleErrorCode(),
|
|
|
|
"Couldn't build compiler instance");
|
[clangd] Minimal implementation of automatic static index (not enabled).
Summary:
See tinyurl.com/clangd-automatic-index for design and goals.
Lots of limitations to keep this patch smallish, TODOs everywhere:
- no serialization to disk
- no changes to dynamic index, which now has a much simpler job
- no partitioning of symbols by file to avoid duplication of header symbols
- no reindexing of edited files
- only a single worker thread
- compilation database is slurped synchronously (doesn't scale)
- uses memindex, rebuilds after every file (should be dex, periodically)
It's not hooked up to ClangdServer/ClangdLSPServer yet: the layering
isn't clear (it should really be in ClangdServer, but ClangdLSPServer
has all the CDB interactions).
Reviewers: ioeric
Subscribers: mgorny, ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, jfb, cfe-commits
Differential Revision: https://reviews.llvm.org/D53032
llvm-svn: 344513
2018-10-15 21:34:10 +08:00
|
|
|
|
|
|
|
SymbolCollector::Options IndexOpts;
|
2019-07-04 17:52:12 +08:00
|
|
|
// Creates a filter to not collect index results from files with unchanged
|
|
|
|
// digests.
|
|
|
|
IndexOpts.FileFilter = [&ShardVersionsSnapshot](const SourceManager &SM,
|
|
|
|
FileID FID) {
|
|
|
|
const auto *F = SM.getFileEntryForID(FID);
|
|
|
|
if (!F)
|
|
|
|
return false; // Skip invalid files.
|
|
|
|
auto AbsPath = getCanonicalPath(F, SM);
|
|
|
|
if (!AbsPath)
|
|
|
|
return false; // Skip files without absolute path.
|
|
|
|
auto Digest = digestFile(SM, FID);
|
|
|
|
if (!Digest)
|
|
|
|
return false;
|
|
|
|
auto D = ShardVersionsSnapshot.find(*AbsPath);
|
|
|
|
if (D != ShardVersionsSnapshot.end() && D->second.Digest == Digest &&
|
|
|
|
!D->second.HadErrors)
|
|
|
|
return false; // Skip files that haven't changed, without errors.
|
|
|
|
return true;
|
|
|
|
};
|
|
|
|
|
2018-12-04 19:31:57 +08:00
|
|
|
IndexFileIn Index;
|
[clangd] Minimal implementation of automatic static index (not enabled).
Summary:
See tinyurl.com/clangd-automatic-index for design and goals.
Lots of limitations to keep this patch smallish, TODOs everywhere:
- no serialization to disk
- no changes to dynamic index, which now has a much simpler job
- no partitioning of symbols by file to avoid duplication of header symbols
- no reindexing of edited files
- only a single worker thread
- compilation database is slurped synchronously (doesn't scale)
- uses memindex, rebuilds after every file (should be dex, periodically)
It's not hooked up to ClangdServer/ClangdLSPServer yet: the layering
isn't clear (it should really be in ClangdServer, but ClangdLSPServer
has all the CDB interactions).
Reviewers: ioeric
Subscribers: mgorny, ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, jfb, cfe-commits
Differential Revision: https://reviews.llvm.org/D53032
llvm-svn: 344513
2018-10-15 21:34:10 +08:00
|
|
|
auto Action = createStaticIndexingAction(
|
2018-12-04 19:31:57 +08:00
|
|
|
IndexOpts, [&](SymbolSlab S) { Index.Symbols = std::move(S); },
|
|
|
|
[&](RefSlab R) { Index.Refs = std::move(R); },
|
2019-06-15 10:26:47 +08:00
|
|
|
[&](RelationSlab R) { Index.Relations = std::move(R); },
|
2018-12-04 19:31:57 +08:00
|
|
|
[&](IncludeGraph IG) { Index.Sources = std::move(IG); });
|
[clangd] Minimal implementation of automatic static index (not enabled).
Summary:
See tinyurl.com/clangd-automatic-index for design and goals.
Lots of limitations to keep this patch smallish, TODOs everywhere:
- no serialization to disk
- no changes to dynamic index, which now has a much simpler job
- no partitioning of symbols by file to avoid duplication of header symbols
- no reindexing of edited files
- only a single worker thread
- compilation database is slurped synchronously (doesn't scale)
- uses memindex, rebuilds after every file (should be dex, periodically)
It's not hooked up to ClangdServer/ClangdLSPServer yet: the layering
isn't clear (it should really be in ClangdServer, but ClangdLSPServer
has all the CDB interactions).
Reviewers: ioeric
Subscribers: mgorny, ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, jfb, cfe-commits
Differential Revision: https://reviews.llvm.org/D53032
llvm-svn: 344513
2018-10-15 21:34:10 +08:00
|
|
|
|
|
|
|
// We're going to run clang here, and it could potentially crash.
|
|
|
|
// We could use CrashRecoveryContext to try to make indexing crashes nonfatal,
|
|
|
|
// but the leaky "recovery" is pretty scary too in a long-running process.
|
|
|
|
// If crashes are a real problem, maybe we should fork a child process.
|
|
|
|
|
|
|
|
const FrontendInputFile &Input = Clang->getFrontendOpts().Inputs.front();
|
|
|
|
if (!Action->BeginSourceFile(*Clang, Input))
|
2019-01-07 23:45:19 +08:00
|
|
|
return llvm::createStringError(llvm::inconvertibleErrorCode(),
|
|
|
|
"BeginSourceFile() failed");
|
2019-06-27 03:50:12 +08:00
|
|
|
if (llvm::Error Err = Action->Execute())
|
|
|
|
return Err;
|
|
|
|
|
[clangd] Minimal implementation of automatic static index (not enabled).
Summary:
See tinyurl.com/clangd-automatic-index for design and goals.
Lots of limitations to keep this patch smallish, TODOs everywhere:
- no serialization to disk
- no changes to dynamic index, which now has a much simpler job
- no partitioning of symbols by file to avoid duplication of header symbols
- no reindexing of edited files
- only a single worker thread
- compilation database is slurped synchronously (doesn't scale)
- uses memindex, rebuilds after every file (should be dex, periodically)
It's not hooked up to ClangdServer/ClangdLSPServer yet: the layering
isn't clear (it should really be in ClangdServer, but ClangdLSPServer
has all the CDB interactions).
Reviewers: ioeric
Subscribers: mgorny, ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, jfb, cfe-commits
Differential Revision: https://reviews.llvm.org/D53032
llvm-svn: 344513
2018-10-15 21:34:10 +08:00
|
|
|
Action->EndSourceFile();
|
2018-12-14 20:39:08 +08:00
|
|
|
|
2019-07-04 17:51:53 +08:00
|
|
|
Index.Cmd = Inputs.CompileCommand;
|
2019-01-11 01:03:04 +08:00
|
|
|
assert(Index.Symbols && Index.Refs && Index.Sources &&
|
|
|
|
"Symbols, Refs and Sources must be set.");
|
[clangd] Minimal implementation of automatic static index (not enabled).
Summary:
See tinyurl.com/clangd-automatic-index for design and goals.
Lots of limitations to keep this patch smallish, TODOs everywhere:
- no serialization to disk
- no changes to dynamic index, which now has a much simpler job
- no partitioning of symbols by file to avoid duplication of header symbols
- no reindexing of edited files
- only a single worker thread
- compilation database is slurped synchronously (doesn't scale)
- uses memindex, rebuilds after every file (should be dex, periodically)
It's not hooked up to ClangdServer/ClangdLSPServer yet: the layering
isn't clear (it should really be in ClangdServer, but ClangdLSPServer
has all the CDB interactions).
Reviewers: ioeric
Subscribers: mgorny, ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, jfb, cfe-commits
Differential Revision: https://reviews.llvm.org/D53032
llvm-svn: 344513
2018-10-15 21:34:10 +08:00
|
|
|
|
2018-12-04 19:31:57 +08:00
|
|
|
log("Indexed {0} ({1} symbols, {2} refs, {3} files)",
|
|
|
|
Inputs.CompileCommand.Filename, Index.Symbols->size(),
|
|
|
|
Index.Refs->numRefs(), Index.Sources->size());
|
|
|
|
SPAN_ATTACH(Tracer, "symbols", int(Index.Symbols->size()));
|
|
|
|
SPAN_ATTACH(Tracer, "refs", int(Index.Refs->numRefs()));
|
|
|
|
SPAN_ATTACH(Tracer, "sources", int(Index.Sources->size()));
|
2018-11-28 00:08:53 +08:00
|
|
|
|
2019-07-04 17:51:43 +08:00
|
|
|
bool HadErrors = Clang->hasDiagnostics() &&
|
|
|
|
Clang->getDiagnostics().hasUncompilableErrorOccurred();
|
2019-07-04 17:52:04 +08:00
|
|
|
if (HadErrors) {
|
|
|
|
log("Failed to compile {0}, index may be incomplete", AbsolutePath);
|
|
|
|
for (auto &It : *Index.Sources)
|
|
|
|
It.second.Flags |= IncludeGraphNode::SourceFlag::HadErrors;
|
|
|
|
}
|
[clangd] BackgroundIndex stores shards to the closest project
Summary:
Changes persistance logic to store shards at the directory of closest
CDB. Previously we were storing all shards to directory of the CDB that
triggered indexing, it had its downsides.
For example, if you had two TUs coming from a different CDB but depending on the
same header foo.h, we will store the foo.h only for the first CDB, and it would
be missing for the second and we would never persist it since it was actually
present in the memory and persisted before.
This patch still stores only a single copy of a shard, but makes the directory a
function of the file name. So that the shard place will be unique even with
multiple CDBs accessing the file. This directory is determined as the first
directory containing a CDB in the file's parent directories, if no such
directory exists we make use of the home directory.
Reviewers: sammccall
Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D64745
llvm-svn: 366467
2019-07-19 01:20:41 +08:00
|
|
|
update(AbsolutePath, std::move(Index), ShardVersionsSnapshot, HadErrors);
|
[clangd] Minimal implementation of automatic static index (not enabled).
Summary:
See tinyurl.com/clangd-automatic-index for design and goals.
Lots of limitations to keep this patch smallish, TODOs everywhere:
- no serialization to disk
- no changes to dynamic index, which now has a much simpler job
- no partitioning of symbols by file to avoid duplication of header symbols
- no reindexing of edited files
- only a single worker thread
- compilation database is slurped synchronously (doesn't scale)
- uses memindex, rebuilds after every file (should be dex, periodically)
It's not hooked up to ClangdServer/ClangdLSPServer yet: the layering
isn't clear (it should really be in ClangdServer, but ClangdLSPServer
has all the CDB interactions).
Reviewers: ioeric
Subscribers: mgorny, ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, jfb, cfe-commits
Differential Revision: https://reviews.llvm.org/D53032
llvm-svn: 344513
2018-10-15 21:34:10 +08:00
|
|
|
|
[clangd] Rewrite of logic to rebuild the background index serving structures.
Summary:
Previously it was rebuilding every 5s by default, which was much too frequent
in the long run - the goal was to provide an early build. There were also some
bugs. There were also some bugs, and a dedicated thread was used in production
but not tested.
- rebuilds are triggered by #TUs built, rather than time. This should scale
more sensibly to fast vs slow machines.
- there are two separate indexed-TU thresholds to trigger index build: 5 TUs
for the first build, 100 for subsequent rebuilds.
- rebuild is always done on the regular indexing threads, and is affected by
blockUntilIdle. This means unit/lit tests run the production configuration.
- fixed a bug where we'd rebuild after attempting to load shards, even if there
were no shards.
- the BackgroundIndexTests don't really test the subtleties of the rebuild
policy (for determinism, we call blockUntilIdle, so rebuild-on-idle is enough
to pass the tests). Instead, we expose the rebuilder as a separate class and
have fine-grained tests for it.
Reviewers: kadircet
Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, jfb, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D64291
llvm-svn: 365531
2019-07-10 02:30:49 +08:00
|
|
|
Rebuilder.indexedTU();
|
2019-01-07 23:45:19 +08:00
|
|
|
return llvm::Error::success();
|
[clangd] Minimal implementation of automatic static index (not enabled).
Summary:
See tinyurl.com/clangd-automatic-index for design and goals.
Lots of limitations to keep this patch smallish, TODOs everywhere:
- no serialization to disk
- no changes to dynamic index, which now has a much simpler job
- no partitioning of symbols by file to avoid duplication of header symbols
- no reindexing of edited files
- only a single worker thread
- compilation database is slurped synchronously (doesn't scale)
- uses memindex, rebuilds after every file (should be dex, periodically)
It's not hooked up to ClangdServer/ClangdLSPServer yet: the layering
isn't clear (it should really be in ClangdServer, but ClangdLSPServer
has all the CDB interactions).
Reviewers: ioeric
Subscribers: mgorny, ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, jfb, cfe-commits
Differential Revision: https://reviews.llvm.org/D53032
llvm-svn: 344513
2018-10-15 21:34:10 +08:00
|
|
|
}
|
|
|
|
|
2019-07-19 00:25:36 +08:00
|
|
|
// Restores shards for \p MainFiles from index storage. Then checks staleness of
|
|
|
|
// those shards and returns a list of TUs that needs to be indexed to update
|
|
|
|
// staleness.
|
[clangd] BackgroundIndex stores shards to the closest project
Summary:
Changes persistance logic to store shards at the directory of closest
CDB. Previously we were storing all shards to directory of the CDB that
triggered indexing, it had its downsides.
For example, if you had two TUs coming from a different CDB but depending on the
same header foo.h, we will store the foo.h only for the first CDB, and it would
be missing for the second and we would never persist it since it was actually
present in the memory and persisted before.
This patch still stores only a single copy of a shard, but makes the directory a
function of the file name. So that the shard place will be unique even with
multiple CDBs accessing the file. This directory is determined as the first
directory containing a CDB in the file's parent directories, if no such
directory exists we make use of the home directory.
Reviewers: sammccall
Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D64745
llvm-svn: 366467
2019-07-19 01:20:41 +08:00
|
|
|
std::vector<tooling::CompileCommand>
|
2019-07-19 00:25:36 +08:00
|
|
|
BackgroundIndex::loadProject(std::vector<std::string> MainFiles) {
|
[clangd] BackgroundIndex stores shards to the closest project
Summary:
Changes persistance logic to store shards at the directory of closest
CDB. Previously we were storing all shards to directory of the CDB that
triggered indexing, it had its downsides.
For example, if you had two TUs coming from a different CDB but depending on the
same header foo.h, we will store the foo.h only for the first CDB, and it would
be missing for the second and we would never persist it since it was actually
present in the memory and persisted before.
This patch still stores only a single copy of a shard, but makes the directory a
function of the file name. So that the shard place will be unique even with
multiple CDBs accessing the file. This directory is determined as the first
directory containing a CDB in the file's parent directories, if no such
directory exists we make use of the home directory.
Reviewers: sammccall
Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D64745
llvm-svn: 366467
2019-07-19 01:20:41 +08:00
|
|
|
std::vector<tooling::CompileCommand> NeedsReIndexing;
|
2019-01-11 01:03:04 +08:00
|
|
|
|
2019-07-19 00:25:36 +08:00
|
|
|
Rebuilder.startLoading();
|
|
|
|
// Load shards for all of the mainfiles.
|
|
|
|
const std::vector<LoadedShard> Result =
|
|
|
|
loadIndexShards(MainFiles, IndexStorageFactory, CDB);
|
|
|
|
size_t LoadedShards = 0;
|
2019-01-11 01:03:04 +08:00
|
|
|
{
|
2019-07-19 00:25:36 +08:00
|
|
|
// Update in-memory state.
|
2019-07-04 17:52:12 +08:00
|
|
|
std::lock_guard<std::mutex> Lock(ShardVersionsMu);
|
2019-07-19 00:25:36 +08:00
|
|
|
for (auto &LS : Result) {
|
|
|
|
if (!LS.Shard)
|
|
|
|
continue;
|
2019-01-11 01:03:04 +08:00
|
|
|
auto SS =
|
2019-07-19 00:25:36 +08:00
|
|
|
LS.Shard->Symbols
|
|
|
|
? llvm::make_unique<SymbolSlab>(std::move(*LS.Shard->Symbols))
|
2019-01-11 01:03:04 +08:00
|
|
|
: nullptr;
|
2019-07-19 00:25:36 +08:00
|
|
|
auto RS = LS.Shard->Refs
|
|
|
|
? llvm::make_unique<RefSlab>(std::move(*LS.Shard->Refs))
|
2019-01-11 01:03:04 +08:00
|
|
|
: nullptr;
|
2019-06-15 10:26:47 +08:00
|
|
|
auto RelS =
|
2019-07-19 00:25:36 +08:00
|
|
|
LS.Shard->Relations
|
|
|
|
? llvm::make_unique<RelationSlab>(std::move(*LS.Shard->Relations))
|
2019-06-15 10:26:47 +08:00
|
|
|
: nullptr;
|
2019-07-19 00:25:36 +08:00
|
|
|
ShardVersion &SV = ShardVersions[LS.AbsolutePath];
|
|
|
|
SV.Digest = LS.Digest;
|
|
|
|
SV.HadErrors = LS.HadErrors;
|
|
|
|
++LoadedShards;
|
2019-07-04 17:52:12 +08:00
|
|
|
|
2019-07-19 00:25:36 +08:00
|
|
|
IndexedSymbols.update(LS.AbsolutePath, std::move(SS), std::move(RS),
|
|
|
|
std::move(RelS), LS.CountReferences);
|
2019-01-11 01:03:04 +08:00
|
|
|
}
|
|
|
|
}
|
2019-07-19 00:25:36 +08:00
|
|
|
Rebuilder.loadedShard(LoadedShards);
|
|
|
|
Rebuilder.doneLoading();
|
2019-01-11 01:03:04 +08:00
|
|
|
|
2019-07-19 00:25:36 +08:00
|
|
|
auto FS = FSProvider.getFileSystem();
|
|
|
|
llvm::DenseSet<PathRef> TUsToIndex;
|
|
|
|
// We'll accept data from stale shards, but ensure the files get reindexed
|
|
|
|
// soon.
|
|
|
|
for (auto &LS : Result) {
|
|
|
|
if (!shardIsStale(LS, FS.get()))
|
|
|
|
continue;
|
|
|
|
PathRef TUForFile = LS.DependentTU;
|
|
|
|
assert(!TUForFile.empty() && "File without a TU!");
|
|
|
|
|
|
|
|
// FIXME: Currently, we simply schedule indexing on a TU whenever any of
|
|
|
|
// its dependencies needs re-indexing. We might do it smarter by figuring
|
|
|
|
// out a minimal set of TUs that will cover all the stale dependencies.
|
|
|
|
// FIXME: Try looking at other TUs if no compile commands are available
|
|
|
|
// for this TU, i.e TU was deleted after we performed indexing.
|
|
|
|
TUsToIndex.insert(TUForFile);
|
|
|
|
}
|
2019-01-11 01:03:04 +08:00
|
|
|
|
2019-07-19 00:25:36 +08:00
|
|
|
for (PathRef TU : TUsToIndex) {
|
|
|
|
auto Cmd = CDB.getCompileCommand(TU);
|
2019-01-11 01:03:04 +08:00
|
|
|
if (!Cmd)
|
|
|
|
continue;
|
[clangd] BackgroundIndex stores shards to the closest project
Summary:
Changes persistance logic to store shards at the directory of closest
CDB. Previously we were storing all shards to directory of the CDB that
triggered indexing, it had its downsides.
For example, if you had two TUs coming from a different CDB but depending on the
same header foo.h, we will store the foo.h only for the first CDB, and it would
be missing for the second and we would never persist it since it was actually
present in the memory and persisted before.
This patch still stores only a single copy of a shard, but makes the directory a
function of the file name. So that the shard place will be unique even with
multiple CDBs accessing the file. This directory is determined as the first
directory containing a CDB in the file's parent directories, if no such
directory exists we make use of the home directory.
Reviewers: sammccall
Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D64745
llvm-svn: 366467
2019-07-19 01:20:41 +08:00
|
|
|
NeedsReIndexing.emplace_back(std::move(*Cmd));
|
2019-01-11 01:03:04 +08:00
|
|
|
}
|
2019-07-19 00:25:36 +08:00
|
|
|
|
2019-01-11 01:03:04 +08:00
|
|
|
return NeedsReIndexing;
|
|
|
|
}
|
|
|
|
|
[clangd] Minimal implementation of automatic static index (not enabled).
Summary:
See tinyurl.com/clangd-automatic-index for design and goals.
Lots of limitations to keep this patch smallish, TODOs everywhere:
- no serialization to disk
- no changes to dynamic index, which now has a much simpler job
- no partitioning of symbols by file to avoid duplication of header symbols
- no reindexing of edited files
- only a single worker thread
- compilation database is slurped synchronously (doesn't scale)
- uses memindex, rebuilds after every file (should be dex, periodically)
It's not hooked up to ClangdServer/ClangdLSPServer yet: the layering
isn't clear (it should really be in ClangdServer, but ClangdLSPServer
has all the CDB interactions).
Reviewers: ioeric
Subscribers: mgorny, ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, jfb, cfe-commits
Differential Revision: https://reviews.llvm.org/D53032
llvm-svn: 344513
2018-10-15 21:34:10 +08:00
|
|
|
} // namespace clangd
|
|
|
|
} // namespace clang
|