forked from OSchip/llvm-project
105 lines
3.9 KiB
C++
105 lines
3.9 KiB
C++
//===--- BackgroundIndexRebuild.h - when to rebuild the bg index--*- C++-*-===//
|
|
//
|
|
// 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
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This file contains an implementation detail of the background indexer
|
|
// (Background.h), which is exposed for testing.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_BACKGROUND_INDEX_REBUILD_H
|
|
#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_BACKGROUND_INDEX_REBUILD_H
|
|
|
|
#include "index/FileIndex.h"
|
|
#include "index/Index.h"
|
|
#include "llvm/Support/Threading.h"
|
|
#include <cstddef>
|
|
|
|
namespace clang {
|
|
namespace clangd {
|
|
|
|
// The BackgroundIndexRebuilder builds the serving data structures periodically
|
|
// in response to events in the background indexer. The goal is to ensure the
|
|
// served data stays fairly fresh, without wasting lots of CPU rebuilding it
|
|
// often.
|
|
//
|
|
// The index is always built after a set of shards are loaded from disk.
|
|
// This happens when clangd discovers a compilation database that we've
|
|
// previously built an index for. It's a fairly fast process that yields lots
|
|
// of data, so we wait to get all of it.
|
|
//
|
|
// The index is built after indexing a few translation units, if it wasn't built
|
|
// already. This ensures quick startup if there's no existing index.
|
|
// Waiting for a few random TUs yields coverage of the most common headers.
|
|
//
|
|
// The index is rebuilt every N TUs, to keep if fresh as files are indexed.
|
|
//
|
|
// The index is rebuilt every time the queue goes idle, if it's stale.
|
|
//
|
|
// All methods are threadsafe. They're called after FileSymbols is updated
|
|
// etc. Without external locking, the rebuilt index may include more updates
|
|
// than intended, which is fine.
|
|
//
|
|
// This class is exposed in the header so it can be tested.
|
|
class BackgroundIndexRebuilder {
|
|
public:
|
|
BackgroundIndexRebuilder(SwapIndex *Target, FileSymbols *Source,
|
|
unsigned Threads)
|
|
: TUsBeforeFirstBuild(llvm::heavyweight_hardware_concurrency(Threads)
|
|
.compute_thread_count()),
|
|
Target(Target), Source(Source) {}
|
|
|
|
// Called to indicate a TU has been indexed.
|
|
// May rebuild, if enough TUs have been indexed.
|
|
void indexedTU();
|
|
// Called to indicate that all worker threads are idle.
|
|
// May reindex, if the index is not up to date.
|
|
void idle();
|
|
// Called to indicate we're going to load a batch of shards from disk.
|
|
// startLoading() and doneLoading() must be paired, but multiple loading
|
|
// sessions may happen concurrently.
|
|
void startLoading();
|
|
// Called to indicate some shards were actually loaded from disk.
|
|
void loadedShard(size_t ShardCount);
|
|
// Called to indicate we're finished loading shards from disk.
|
|
// May rebuild (if any were loaded).
|
|
void doneLoading();
|
|
|
|
// Ensures we won't start any more rebuilds.
|
|
void shutdown();
|
|
|
|
// Thresholds for rebuilding as TUs get indexed.
|
|
const unsigned TUsBeforeFirstBuild; // Typically one per worker thread.
|
|
const unsigned TUsBeforeRebuild = 100;
|
|
|
|
private:
|
|
// Run Check under the lock, and rebuild if it returns true.
|
|
void maybeRebuild(const char *Reason, std::function<bool()> Check);
|
|
bool enoughTUsToRebuild() const;
|
|
|
|
// All transient state is guarded by the mutex.
|
|
std::mutex Mu;
|
|
bool ShouldStop = false;
|
|
// Index builds are versioned. ActiveVersion chases StartedVersion.
|
|
unsigned StartedVersion = 0;
|
|
unsigned ActiveVersion = 0;
|
|
// How many TUs have we indexed so far since startup?
|
|
unsigned IndexedTUs = 0;
|
|
unsigned IndexedTUsAtLastRebuild = 0;
|
|
// Are we loading shards? May be multiple concurrent sessions.
|
|
unsigned Loading = 0;
|
|
unsigned LoadedShards; // In the current loading session.
|
|
|
|
SwapIndex *Target;
|
|
FileSymbols *Source;
|
|
};
|
|
|
|
} // namespace clangd
|
|
} // namespace clang
|
|
|
|
#endif
|