brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.5 KiB · 4dc2d3b Raw
114 lines · cpp
1//===-- BackgroundRebuild.cpp - when to rebuild the 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-exception6//7//===----------------------------------------------------------------------===//8 9#include "index/BackgroundRebuild.h"10#include "index/FileIndex.h"11#include "support/Logger.h"12#include "support/Trace.h"13 14#include <atomic>15#include <chrono>16#include <condition_variable>17#include <memory>18#include <mutex>19#include <numeric>20#include <queue>21#include <random>22#include <string>23#include <thread>24 25namespace clang {26namespace clangd {27 28bool BackgroundIndexRebuilder::enoughTUsToRebuild() const {29  if (!ActiveVersion)                         // never built30    return IndexedTUs == TUsBeforeFirstBuild; // use low threshold31  // rebuild if we've reached the (higher) threshold32  return IndexedTUs >= IndexedTUsAtLastRebuild + TUsBeforeRebuild;33}34 35void BackgroundIndexRebuilder::indexedTU() {36  maybeRebuild("after indexing enough files", [this] {37    ++IndexedTUs;38    if (Loading)39      return false;                      // rebuild once loading finishes40    if (ActiveVersion != StartedVersion) // currently building41      return false;                      // no urgency, avoid overlapping builds42    return enoughTUsToRebuild();43  });44}45 46void 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;51  });52}53 54void BackgroundIndexRebuilder::startLoading() {55  std::lock_guard<std::mutex> Lock(Mu);56  if (!Loading)57    LoadedShards = 0;58  ++Loading;59}60void BackgroundIndexRebuilder::loadedShard(size_t ShardCount) {61  std::lock_guard<std::mutex> Lock(Mu);62  assert(Loading);63  LoadedShards += ShardCount;64}65void BackgroundIndexRebuilder::doneLoading() {66  maybeRebuild("after loading index from disk", [this] {67    assert(Loading);68    --Loading;69    if (Loading)    // was loading multiple batches concurrently70      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();73  });74}75 76void BackgroundIndexRebuilder::shutdown() {77  std::lock_guard<std::mutex> Lock(Mu);78  ShouldStop = true;79}80 81void BackgroundIndexRebuilder::maybeRebuild(const char *Reason,82                                            std::function<bool()> Check) {83  unsigned BuildVersion = 0;84  {85    std::lock_guard<std::mutex> Lock(Mu);86    if (!ShouldStop && Check()) {87      BuildVersion = ++StartedVersion;88      IndexedTUsAtLastRebuild = IndexedTUs;89    }90  }91  if (BuildVersion) {92    std::unique_ptr<SymbolIndex> NewIndex;93    {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);98    }99    {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));107      }108    }109  }110}111 112} // namespace clangd113} // namespace clang114