1 //===-- BackgroundRebuild.cpp - when to rebuild thei background index -----===//
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
7 //===----------------------------------------------------------------------===//
9 #include "index/BackgroundRebuild.h"
10 #include "index/FileIndex.h"
11 #include "support/Logger.h"
12 #include "support/Trace.h"
16 #include <condition_variable>
28 bool BackgroundIndexRebuilder::enoughTUsToRebuild() const {
29 if (!ActiveVersion
) // never built
30 return IndexedTUs
== TUsBeforeFirstBuild
; // use low threshold
31 // rebuild if we've reached the (higher) threshold
32 return IndexedTUs
>= IndexedTUsAtLastRebuild
+ TUsBeforeRebuild
;
35 void BackgroundIndexRebuilder::indexedTU() {
36 maybeRebuild("after indexing enough files", [this] {
39 return false; // rebuild once loading finishes
40 if (ActiveVersion
!= StartedVersion
) // currently building
41 return false; // no urgency, avoid overlapping builds
42 return enoughTUsToRebuild();
46 void BackgroundIndexRebuilder::idle() {
47 maybeRebuild("when background indexer is idle", [this] {
48 // rebuild if there's anything new in the index.
49 // (even if currently rebuilding! this ensures eventual completeness)
50 return IndexedTUs
> IndexedTUsAtLastRebuild
;
54 void BackgroundIndexRebuilder::startLoading() {
55 std::lock_guard
<std::mutex
> Lock(Mu
);
60 void BackgroundIndexRebuilder::loadedShard(size_t ShardCount
) {
61 std::lock_guard
<std::mutex
> Lock(Mu
);
63 LoadedShards
+= ShardCount
;
65 void BackgroundIndexRebuilder::doneLoading() {
66 maybeRebuild("after loading index from disk", [this] {
69 if (Loading
) // was loading multiple batches concurrently
70 return false; // rebuild once the last batch is done.
71 // Rebuild if we loaded any shards, or if we stopped an indexedTU rebuild.
72 return LoadedShards
> 0 || enoughTUsToRebuild();
76 void BackgroundIndexRebuilder::shutdown() {
77 std::lock_guard
<std::mutex
> Lock(Mu
);
81 void BackgroundIndexRebuilder::maybeRebuild(const char *Reason
,
82 std::function
<bool()> Check
) {
83 unsigned BuildVersion
= 0;
85 std::lock_guard
<std::mutex
> Lock(Mu
);
86 if (!ShouldStop
&& Check()) {
87 BuildVersion
= ++StartedVersion
;
88 IndexedTUsAtLastRebuild
= IndexedTUs
;
92 std::unique_ptr
<SymbolIndex
> NewIndex
;
94 vlog("BackgroundIndex: building version {0} {1}", BuildVersion
, Reason
);
95 trace::Span
Tracer("RebuildBackgroundIndex");
96 SPAN_ATTACH(Tracer
, "reason", Reason
);
97 NewIndex
= Source
->buildIndex(IndexType::Heavy
, DuplicateHandling::Merge
);
100 std::lock_guard
<std::mutex
> Lock(Mu
);
101 // Guard against rebuild finishing in the wrong order.
102 if (BuildVersion
> ActiveVersion
) {
103 ActiveVersion
= BuildVersion
;
104 vlog("BackgroundIndex: serving version {0} ({1} bytes)", BuildVersion
,
105 NewIndex
->estimateMemoryUsage());
106 Target
->reset(std::move(NewIndex
));
112 } // namespace clangd