clang-tools 10.0.0

BackgroundRebuild.cpp
Go to the documentation of this file.
1 //===-- BackgroundRebuild.cpp - when to rebuild thei background index -----===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "index/BackgroundRebuild.h"
10 #include "Compiler.h"
11 #include "Headers.h"
12 #include "Logger.h"
13 #include "ParsedAST.h"
14 #include "Path.h"
15 #include "SourceCode.h"
16 #include "Symbol.h"
17 #include "Threading.h"
18 #include "Trace.h"
19 #include "URI.h"
20 #include "index/FileIndex.h"
21 #include "index/IndexAction.h"
22 #include "index/MemIndex.h"
23 #include "index/Ref.h"
24 #include "index/Relation.h"
25 #include "index/Serialization.h"
26 #include "index/SymbolCollector.h"
27 #include "clang/Basic/SourceLocation.h"
28 #include "clang/Basic/SourceManager.h"
29 #include "llvm/ADT/Hashing.h"
30 #include "llvm/ADT/STLExtras.h"
31 #include "llvm/ADT/ScopeExit.h"
32 #include "llvm/ADT/StringMap.h"
33 #include "llvm/ADT/StringRef.h"
34 #include "llvm/ADT/StringSet.h"
35 #include "llvm/Support/Error.h"
36 #include "llvm/Support/Threading.h"
37
38 #include <atomic>
39 #include <chrono>
40 #include <condition_variable>
41 #include <memory>
42 #include <mutex>
43 #include <numeric>
44 #include <queue>
45 #include <random>
46 #include <string>
47 #include <thread>
48
49 namespace clang {
50 namespace clangd {
51
52 bool BackgroundIndexRebuilder::enoughTUsToRebuild() const {
53 if (!ActiveVersion) // never built
54 return IndexedTUs == TUsBeforeFirstBuild; // use low threshold
55 // rebuild if we've reached the (higher) threshold
56 return IndexedTUs >= IndexedTUsAtLastRebuild + TUsBeforeRebuild;
57 }
58
59 void BackgroundIndexRebuilder::indexedTU() {
60 maybeRebuild("after indexing enough files", [this] {
61 ++IndexedTUs;
62 if (Loading)
63 return false; // rebuild once loading finishes
64 if (ActiveVersion != StartedVersion) // currently building
65 return false; // no urgency, avoid overlapping builds
66 return enoughTUsToRebuild();
67 });
68 }
69
70 void BackgroundIndexRebuilder::idle() {
71 maybeRebuild("when background indexer is idle", [this] {
72 // rebuild if there's anything new in the index.
73 // (even if currently rebuilding! this ensures eventual completeness)
74 return IndexedTUs > IndexedTUsAtLastRebuild;
75 });
76 }
77
78 void BackgroundIndexRebuilder::startLoading() {
79 std::lock_guard<std::mutex> Lock(Mu);
80 if (!Loading)
81 LoadedShards = 0;
82 ++Loading;
83 }
84 void BackgroundIndexRebuilder::loadedShard(size_t ShardCount) {
85 std::lock_guard<std::mutex> Lock(Mu);
86 assert(Loading);
87 LoadedShards += ShardCount;
88 }
89 void BackgroundIndexRebuilder::doneLoading() {
90 maybeRebuild("after loading index from disk", [this] {
91 assert(Loading);
92 --Loading;
93 if (Loading) // was loading multiple batches concurrently
94 return false; // rebuild once the last batch is done.
95 // Rebuild if we loaded any shards, or if we stopped an indexedTU rebuild.
96 return LoadedShards > 0 || enoughTUsToRebuild();
97 });
98 }
99
100 void BackgroundIndexRebuilder::shutdown() {
101 std::lock_guard<std::mutex> Lock(Mu);
102 ShouldStop = true;
103 }
104
105 void BackgroundIndexRebuilder::maybeRebuild(const char *Reason,
106 std::function<bool()> Check) {
107 unsigned BuildVersion = 0;
108 {
109 std::lock_guard<std::mutex> Lock(Mu);
110 if (!ShouldStop && Check()) {
111 BuildVersion = ++StartedVersion;
112 IndexedTUsAtLastRebuild = IndexedTUs;
113 }
114 }
115 if (BuildVersion) {
116 std::unique_ptr<SymbolIndex> NewIndex;
117 {
118 vlog("BackgroundIndex: building version {0} {1}", BuildVersion, Reason);
119 trace::Span Tracer("RebuildBackgroundIndex");
120 SPAN_ATTACH(Tracer, "reason", Reason);
121 NewIndex = Source->buildIndex(IndexType::Heavy, DuplicateHandling::Merge);
122 }
123 {
124 std::lock_guard<std::mutex> Lock(Mu);
125 // Guard against rebuild finishing in the wrong order.
126 if (BuildVersion > ActiveVersion) {
127 ActiveVersion = BuildVersion;
128 vlog("BackgroundIndex: serving version {0} ({1} bytes)", BuildVersion,
129 NewIndex->estimateMemoryUsage());
130 Target->reset(std::move(NewIndex));
131 }
132 }
133 }
134 }
135
136 } // namespace clangd
137 } // namespace clang
Trace.h
BackgroundRebuild.h
Symbol.h
SourceCode.h
clang::clangd::BackgroundIndexRebuilder::doneLoading
void doneLoading()
Definition: BackgroundRebuild.cpp:89
clang::clangd::DuplicateHandling::Merge
MemIndex.h
clang::clangd::vlog
void vlog(const char *Fmt, Ts &&... Vals)
Definition: Logger.h:67
Serialization.h
clang::clangd::BackgroundIndexRebuilder::loadedShard
void loadedShard(size_t ShardCount)
Definition: BackgroundRebuild.cpp:84
Headers.h
clang::clangd::BackgroundIndexRebuilder::TUsBeforeRebuild
const unsigned TUsBeforeRebuild
Definition: BackgroundRebuild.h:75
clang::clangd::BackgroundIndexRebuilder::idle
void idle()
Definition: BackgroundRebuild.cpp:70
Compiler.h
clang::clangd::BackgroundIndexRebuilder::TUsBeforeFirstBuild
const unsigned TUsBeforeFirstBuild
Definition: BackgroundRebuild.h:74
Relation.h
clang::clangd::FileSymbols::buildIndex
std::unique_ptr< SymbolIndex > buildIndex(IndexType, DuplicateHandling DuplicateHandle=DuplicateHandling::PickOne)
The index keeps the symbols alive.
Definition: FileIndex.cpp:127
Ref.h
Logger.h
clang::clangd::IndexType::Heavy
clang
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
Definition: ApplyReplacements.h:27
SymbolCollector.h
ParsedAST.h
Path.h
clang::clangd::BackgroundIndexRebuilder::startLoading
void startLoading()
Definition: BackgroundRebuild.cpp:78
URI.h
clang::clangd::BackgroundIndexRebuilder::shutdown
void shutdown()
Definition: BackgroundRebuild.cpp:100
FileIndex.h
clang::clangd::BackgroundIndexRebuilder::indexedTU
void indexedTU()
Definition: BackgroundRebuild.cpp:59
IndexAction.h
clang::clangd::trace::Span
Records an event whose duration is the lifetime of the Span object.
Definition: Trace.h:81
SPAN_ATTACH
#define SPAN_ATTACH(S, Name, Expr)
Attach a key-value pair to a Span event.
Definition: Trace.h:97
clang::clangd::SwapIndex::reset
void reset(std::unique_ptr< SymbolIndex >)
Definition: Index.cpp:20
Threading.h