Author: azhar Date: Fri Jul 19 02:26:33 2019 New Revision: 366551 URL: http://llvm.org/viewvc/llvm-project?rev=366551&view=rev Log: Revert r366458, r366467 and r366468
r366458 is causing test failures. r366467 and r366468 had to be reverted as they were casuing conflict while reverting r366458. r366468 [clangd] Remove dead code from BackgroundIndex r366467 [clangd] BackgroundIndex stores shards to the closest project r366458 [clangd] Refactor background-index shard loading Added: clang-tools-extra/trunk/clangd/test/Inputs/background-index/foo.h Removed: clang-tools-extra/trunk/clangd/index/BackgroundIndexLoader.cpp clang-tools-extra/trunk/clangd/index/BackgroundIndexLoader.h clang-tools-extra/trunk/clangd/test/Inputs/background-index/sub_dir/ Modified: clang-tools-extra/trunk/clangd/CMakeLists.txt clang-tools-extra/trunk/clangd/ClangdServer.cpp clang-tools-extra/trunk/clangd/index/Background.cpp clang-tools-extra/trunk/clangd/index/Background.h clang-tools-extra/trunk/clangd/index/BackgroundIndexStorage.cpp clang-tools-extra/trunk/clangd/index/BackgroundRebuild.cpp clang-tools-extra/trunk/clangd/index/BackgroundRebuild.h clang-tools-extra/trunk/clangd/test/Inputs/background-index/definition.jsonrpc clang-tools-extra/trunk/clangd/test/Inputs/background-index/foo.cpp clang-tools-extra/trunk/clangd/test/background-index.test clang-tools-extra/trunk/clangd/unittests/BackgroundIndexTests.cpp Modified: clang-tools-extra/trunk/clangd/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/CMakeLists.txt?rev=366551&r1=366550&r2=366551&view=diff ============================================================================== --- clang-tools-extra/trunk/clangd/CMakeLists.txt (original) +++ clang-tools-extra/trunk/clangd/CMakeLists.txt Fri Jul 19 02:26:33 2019 @@ -73,7 +73,6 @@ add_clang_library(clangDaemon XRefs.cpp index/Background.cpp - index/BackgroundIndexLoader.cpp index/BackgroundIndexStorage.cpp index/BackgroundQueue.cpp index/BackgroundRebuild.cpp Modified: clang-tools-extra/trunk/clangd/ClangdServer.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ClangdServer.cpp?rev=366551&r1=366550&r2=366551&view=diff ============================================================================== --- clang-tools-extra/trunk/clangd/ClangdServer.cpp (original) +++ clang-tools-extra/trunk/clangd/ClangdServer.cpp Fri Jul 19 02:26:33 2019 @@ -127,8 +127,7 @@ ClangdServer::ClangdServer(const GlobalC if (Opts.BackgroundIndex) { BackgroundIdx = llvm::make_unique<BackgroundIndex>( Context::current().clone(), FSProvider, CDB, - BackgroundIndexStorage::createDiskBackedStorageFactory( - [&CDB](llvm::StringRef File) { return CDB.getProjectInfo(File); })); + BackgroundIndexStorage::createDiskBackedStorageFactory()); AddIndex(BackgroundIdx.get()); } if (DynamicIdx) Modified: clang-tools-extra/trunk/clangd/index/Background.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/index/Background.cpp?rev=366551&r1=366550&r2=366551&view=diff ============================================================================== --- clang-tools-extra/trunk/clangd/index/Background.cpp (original) +++ clang-tools-extra/trunk/clangd/index/Background.cpp Fri Jul 19 02:26:33 2019 @@ -10,7 +10,6 @@ #include "ClangdUnit.h" #include "Compiler.h" #include "Context.h" -#include "FSProvider.h" #include "Headers.h" #include "Logger.h" #include "Path.h" @@ -19,7 +18,6 @@ #include "Threading.h" #include "Trace.h" #include "URI.h" -#include "index/BackgroundIndexLoader.h" #include "index/FileIndex.h" #include "index/IndexAction.h" #include "index/MemIndex.h" @@ -30,8 +28,6 @@ #include "clang/Basic/SourceLocation.h" #include "clang/Basic/SourceManager.h" #include "clang/Driver/Types.h" -#include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/DenseSet.h" #include "llvm/ADT/Hashing.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/ScopeExit.h" @@ -46,7 +42,6 @@ #include <atomic> #include <chrono> #include <condition_variable> -#include <cstddef> #include <memory> #include <mutex> #include <numeric> @@ -54,8 +49,6 @@ #include <random> #include <string> #include <thread> -#include <utility> -#include <vector> namespace clang { namespace clangd { @@ -126,18 +119,6 @@ llvm::SmallString<128> getAbsolutePath(c } return AbsolutePath; } - -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; -} - } // namespace BackgroundIndex::BackgroundIndex( @@ -175,14 +156,14 @@ BackgroundQueue::Task BackgroundIndex::c log("Enqueueing {0} commands for indexing", ChangedFiles.size()); SPAN_ATTACH(Tracer, "files", int64_t(ChangedFiles.size())); - auto NeedsReIndexing = loadProject(std::move(ChangedFiles)); + auto NeedsReIndexing = loadShards(std::move(ChangedFiles)); // 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()); - for (auto &Cmd : NeedsReIndexing) - Tasks.push_back(indexFileTask(std::move(Cmd))); + for (auto &Elem : NeedsReIndexing) + Tasks.push_back(indexFileTask(std::move(Elem.first), Elem.second)); Queue.append(std::move(Tasks)); }); @@ -197,12 +178,13 @@ static llvm::StringRef filenameWithoutEx } BackgroundQueue::Task -BackgroundIndex::indexFileTask(tooling::CompileCommand Cmd) { - BackgroundQueue::Task T([this, Cmd] { +BackgroundIndex::indexFileTask(tooling::CompileCommand Cmd, + BackgroundIndexStorage *Storage) { + BackgroundQueue::Task T([this, Storage, Cmd] { // 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; - if (auto Error = index(std::move(Cmd))) + if (auto Error = index(std::move(Cmd), Storage)) elog("Indexing {0} failed: {1}", FileName, std::move(Error)); }); T.QueuePri = IndexFile; @@ -225,7 +207,7 @@ void BackgroundIndex::boostRelated(llvm: void BackgroundIndex::update( llvm::StringRef MainFile, IndexFileIn Index, const llvm::StringMap<ShardVersion> &ShardVersionsSnapshot, - bool HadErrors) { + BackgroundIndexStorage *IndexStorage, bool HadErrors) { // Partition symbols/references into files. struct File { llvm::DenseSet<const Symbol *> Symbols; @@ -309,21 +291,22 @@ void BackgroundIndex::update( // We need to store shards before updating the index, since the latter // consumes slabs. // FIXME: Also skip serializing the shard if it is already up-to-date. - 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)); + if (IndexStorage) { + 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)); + } { std::lock_guard<std::mutex> Lock(ShardVersionsMu); @@ -346,7 +329,8 @@ void BackgroundIndex::update( } } -llvm::Error BackgroundIndex::index(tooling::CompileCommand Cmd) { +llvm::Error BackgroundIndex::index(tooling::CompileCommand Cmd, + BackgroundIndexStorage *IndexStorage) { trace::Span Tracer("BackgroundIndex"); SPAN_ATTACH(Tracer, "file", Cmd.Filename); auto AbsolutePath = getAbsolutePath(Cmd); @@ -440,78 +424,176 @@ llvm::Error BackgroundIndex::index(tooli for (auto &It : *Index.Sources) It.second.Flags |= IncludeGraphNode::SourceFlag::HadErrors; } - update(AbsolutePath, std::move(Index), ShardVersionsSnapshot, HadErrors); + update(AbsolutePath, std::move(Index), ShardVersionsSnapshot, IndexStorage, + HadErrors); Rebuilder.indexedTU(); return llvm::Error::success(); } -// 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. -std::vector<tooling::CompileCommand> -BackgroundIndex::loadProject(std::vector<std::string> MainFiles) { - std::vector<tooling::CompileCommand> NeedsReIndexing; +std::vector<BackgroundIndex::Source> +BackgroundIndex::loadShard(const tooling::CompileCommand &Cmd, + BackgroundIndexStorage *IndexStorage, + llvm::StringSet<> &LoadedShards) { + struct ShardInfo { + std::string AbsolutePath; + std::unique_ptr<IndexFileIn> Shard; + FileDigest Digest = {}; + bool CountReferences = false; + bool HadErrors = false; + }; + std::vector<ShardInfo> IntermediateSymbols; + // Make sure we don't have duplicate elements in the queue. Keys are absolute + // paths. + llvm::StringSet<> InQueue; + auto FS = FSProvider.getFileSystem(); + // Dependencies of this TU, paired with the information about whether they + // need to be re-indexed or not. + std::vector<Source> Dependencies; + std::queue<Source> ToVisit; + std::string AbsolutePath = getAbsolutePath(Cmd).str(); + // Up until we load the shard related to a dependency it needs to be + // re-indexed. + ToVisit.emplace(AbsolutePath, true); + InQueue.insert(AbsolutePath); + // Goes over each dependency. + while (!ToVisit.empty()) { + Dependencies.push_back(std::move(ToVisit.front())); + // Dependencies is not modified during the rest of the loop, so it is safe + // to keep the reference. + auto &CurDependency = Dependencies.back(); + ToVisit.pop(); + // If we have already seen this shard before(either loaded or failed) don't + // re-try again. Since the information in the shard won't change from one TU + // to another. + if (!LoadedShards.try_emplace(CurDependency.Path).second) { + // If the dependency needs to be re-indexed, first occurence would already + // have detected that, so we don't need to issue it again. + CurDependency.NeedsReIndexing = false; + continue; + } - Rebuilder.startLoading(); - // Load shards for all of the mainfiles. - const std::vector<LoadedShard> Result = - loadIndexShards(MainFiles, IndexStorageFactory, CDB); - size_t LoadedShards = 0; + auto Shard = IndexStorage->loadShard(CurDependency.Path); + if (!Shard || !Shard->Sources) { + // File will be returned as requiring re-indexing to caller. + vlog("Failed to load shard: {0}", CurDependency.Path); + continue; + } + // These are the edges in the include graph for current dependency. + for (const auto &I : *Shard->Sources) { + auto U = URI::parse(I.getKey()); + if (!U) + continue; + auto AbsolutePath = URI::resolve(*U, CurDependency.Path); + if (!AbsolutePath) + continue; + // Add file as dependency if haven't seen before. + if (InQueue.try_emplace(*AbsolutePath).second) + ToVisit.emplace(*AbsolutePath, true); + // The node contains symbol information only for current file, the rest is + // just edges. + if (*AbsolutePath != CurDependency.Path) + continue; + + // We found source file info for current dependency. + assert(I.getValue().Digest != FileDigest{{0}} && "Digest is empty?"); + ShardInfo SI; + SI.AbsolutePath = CurDependency.Path; + SI.Shard = std::move(Shard); + SI.Digest = I.getValue().Digest; + SI.CountReferences = + I.getValue().Flags & IncludeGraphNode::SourceFlag::IsTU; + SI.HadErrors = + I.getValue().Flags & IncludeGraphNode::SourceFlag::HadErrors; + IntermediateSymbols.push_back(std::move(SI)); + // Check if the source needs re-indexing. + // Get the digest, skip it if file doesn't exist. + auto Buf = FS->getBufferForFile(CurDependency.Path); + if (!Buf) { + elog("Couldn't get buffer for file: {0}: {1}", CurDependency.Path, + Buf.getError().message()); + continue; + } + // If digests match then dependency doesn't need re-indexing. + // FIXME: Also check for dependencies(sources) of this shard and compile + // commands for cache invalidation. + CurDependency.NeedsReIndexing = + digest(Buf->get()->getBuffer()) != I.getValue().Digest; + } + } + // Load shard information into background-index. { - // Update in-memory state. std::lock_guard<std::mutex> Lock(ShardVersionsMu); - for (auto &LS : Result) { - if (!LS.Shard) - continue; + // 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. + for (const ShardInfo &SI : IntermediateSymbols) { auto SS = - LS.Shard->Symbols - ? llvm::make_unique<SymbolSlab>(std::move(*LS.Shard->Symbols)) + SI.Shard->Symbols + ? llvm::make_unique<SymbolSlab>(std::move(*SI.Shard->Symbols)) : nullptr; - auto RS = LS.Shard->Refs - ? llvm::make_unique<RefSlab>(std::move(*LS.Shard->Refs)) + auto RS = SI.Shard->Refs + ? llvm::make_unique<RefSlab>(std::move(*SI.Shard->Refs)) : nullptr; auto RelS = - LS.Shard->Relations - ? llvm::make_unique<RelationSlab>(std::move(*LS.Shard->Relations)) + SI.Shard->Relations + ? llvm::make_unique<RelationSlab>(std::move(*SI.Shard->Relations)) : nullptr; - ShardVersion &SV = ShardVersions[LS.AbsolutePath]; - SV.Digest = LS.Digest; - SV.HadErrors = LS.HadErrors; - ++LoadedShards; + ShardVersion &SV = ShardVersions[SI.AbsolutePath]; + SV.Digest = SI.Digest; + SV.HadErrors = SI.HadErrors; - IndexedSymbols.update(LS.AbsolutePath, std::move(SS), std::move(RS), - std::move(RelS), LS.CountReferences); + IndexedSymbols.update(SI.AbsolutePath, std::move(SS), std::move(RS), + std::move(RelS), SI.CountReferences); } } - Rebuilder.loadedShard(LoadedShards); - Rebuilder.doneLoading(); - - 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!"); + if (!IntermediateSymbols.empty()) + Rebuilder.loadedTU(); - // 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); - } + return Dependencies; +} - for (PathRef TU : TUsToIndex) { - auto Cmd = CDB.getCompileCommand(TU); +// Goes over each changed file and loads them from index. Returns the list of +// TUs that had out-of-date/no shards. +std::vector<std::pair<tooling::CompileCommand, BackgroundIndexStorage *>> +BackgroundIndex::loadShards(std::vector<std::string> ChangedFiles) { + std::vector<std::pair<tooling::CompileCommand, BackgroundIndexStorage *>> + NeedsReIndexing; + // Keeps track of the files that will be reindexed, to make sure we won't + // re-index same dependencies more than once. Keys are AbsolutePaths. + llvm::StringSet<> FilesToIndex; + // Keeps track of the loaded shards to make sure we don't perform redundant + // disk IO. Keys are absolute paths. + llvm::StringSet<> LoadedShards; + Rebuilder.startLoading(); + for (const auto &File : ChangedFiles) { + auto Cmd = CDB.getCompileCommand(File); if (!Cmd) continue; - NeedsReIndexing.emplace_back(std::move(*Cmd)); - } + std::string ProjectRoot; + if (auto PI = CDB.getProjectInfo(File)) + ProjectRoot = std::move(PI->SourceRoot); + + BackgroundIndexStorage *IndexStorage = IndexStorageFactory(ProjectRoot); + auto Dependencies = loadShard(*Cmd, IndexStorage, LoadedShards); + for (const auto &Dependency : Dependencies) { + if (!Dependency.NeedsReIndexing || FilesToIndex.count(Dependency.Path)) + continue; + // 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. + vlog("Enqueueing TU {0} because its dependency {1} needs re-indexing.", + Cmd->Filename, Dependency.Path); + NeedsReIndexing.push_back({std::move(*Cmd), IndexStorage}); + // Mark all of this TU's dependencies as to-be-indexed so that we won't + // try to re-index those. + for (const auto &Dependency : Dependencies) + FilesToIndex.insert(Dependency.Path); + break; + } + } + Rebuilder.doneLoading(); return NeedsReIndexing; } Modified: clang-tools-extra/trunk/clangd/index/Background.h URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/index/Background.h?rev=366551&r1=366550&r2=366551&view=diff ============================================================================== --- clang-tools-extra/trunk/clangd/index/Background.h (original) +++ clang-tools-extra/trunk/clangd/index/Background.h Fri Jul 19 02:26:33 2019 @@ -12,7 +12,6 @@ #include "Context.h" #include "FSProvider.h" #include "GlobalCompilationDatabase.h" -#include "Path.h" #include "SourceCode.h" #include "Threading.h" #include "index/BackgroundRebuild.h" @@ -50,17 +49,15 @@ public: virtual std::unique_ptr<IndexFileIn> loadShard(llvm::StringRef ShardIdentifier) const = 0; - // The factory provides storage for each File. + // The factory provides storage for each CDB. // It keeps ownership of the storage instances, and should manage caching // itself. Factory must be threadsafe and never returns nullptr. - using Factory = llvm::unique_function<BackgroundIndexStorage *(PathRef)>; + using Factory = + llvm::unique_function<BackgroundIndexStorage *(llvm::StringRef)>; // Creates an Index Storage that saves shards into disk. Index storage uses - // CDBDirectory + ".clangd/index/" as the folder to save shards. CDBDirectory - // is the first directory containing a CDB in parent directories of a file, or - // user's home directory if none was found, e.g. standard library headers. - static Factory createDiskBackedStorageFactory( - std::function<llvm::Optional<ProjectInfo>(PathRef)> GetProjectInfo); + // CDBDirectory + ".clangd/index/" as the folder to save shards. + static Factory createDiskBackedStorageFactory(); }; // A priority queue of tasks which can be run on (external) worker threads. @@ -160,14 +157,15 @@ private: /// information on IndexStorage. void update(llvm::StringRef MainFile, IndexFileIn Index, const llvm::StringMap<ShardVersion> &ShardVersionsSnapshot, - bool HadErrors); + BackgroundIndexStorage *IndexStorage, bool HadErrors); // configuration const FileSystemProvider &FSProvider; const GlobalCompilationDatabase &CDB; Context BackgroundContext; - llvm::Error index(tooling::CompileCommand); + llvm::Error index(tooling::CompileCommand, + BackgroundIndexStorage *IndexStorage); FileSymbols IndexedSymbols; BackgroundIndexRebuilder Rebuilder; @@ -175,13 +173,25 @@ private: std::mutex ShardVersionsMu; BackgroundIndexStorage::Factory IndexStorageFactory; - // Tries to load shards for the MainFiles and their dependencies. - std::vector<tooling::CompileCommand> - loadProject(std::vector<std::string> MainFiles); + struct Source { + std::string Path; + bool NeedsReIndexing; + Source(llvm::StringRef Path, bool NeedsReIndexing) + : Path(Path), NeedsReIndexing(NeedsReIndexing) {} + }; + // Loads the shards for a single TU and all of its dependencies. Returns the + // list of sources and whether they need to be re-indexed. + std::vector<Source> loadShard(const tooling::CompileCommand &Cmd, + BackgroundIndexStorage *IndexStorage, + llvm::StringSet<> &LoadedShards); + // Tries to load shards for the ChangedFiles. + std::vector<std::pair<tooling::CompileCommand, BackgroundIndexStorage *>> + loadShards(std::vector<std::string> ChangedFiles); BackgroundQueue::Task changedFilesTask(const std::vector<std::string> &ChangedFiles); - BackgroundQueue::Task indexFileTask(tooling::CompileCommand Cmd); + BackgroundQueue::Task indexFileTask(tooling::CompileCommand Cmd, + BackgroundIndexStorage *Storage); // from lowest to highest priority enum QueuePriority { Removed: clang-tools-extra/trunk/clangd/index/BackgroundIndexLoader.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/index/BackgroundIndexLoader.cpp?rev=366550&view=auto ============================================================================== --- clang-tools-extra/trunk/clangd/index/BackgroundIndexLoader.cpp (original) +++ clang-tools-extra/trunk/clangd/index/BackgroundIndexLoader.cpp (removed) @@ -1,151 +0,0 @@ -//===-- BackgroundIndexLoader.cpp - ---------------------------------------===// -// -// 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 -// -//===----------------------------------------------------------------------===// - -#include "index/BackgroundIndexLoader.h" -#include "GlobalCompilationDatabase.h" -#include "Logger.h" -#include "Path.h" -#include "index/Background.h" -#include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/DenseSet.h" -#include "llvm/ADT/SmallString.h" -#include "llvm/ADT/StringMap.h" -#include "llvm/Support/Path.h" -#include <string> -#include <utility> -#include <vector> - -namespace clang { -namespace clangd { -namespace { - -llvm::Optional<Path> uriToAbsolutePath(llvm::StringRef URI, PathRef HintPath) { - auto U = URI::parse(URI); - if (!U) - return llvm::None; - auto AbsolutePath = URI::resolve(*U, HintPath); - if (!AbsolutePath) - return llvm::None; - return *AbsolutePath; -} - -/// A helper class to cache BackgroundIndexStorage operations and keep the -/// inverse dependency mapping. -class BackgroundIndexLoader { -public: - BackgroundIndexLoader(BackgroundIndexStorage::Factory &IndexStorageFactory) - : IndexStorageFactory(IndexStorageFactory) {} - /// Load the shards for \p MainFile and all of its dependencies. - void load(PathRef MainFile); - - /// Consumes the loader and returns all shards. - std::vector<LoadedShard> takeResult() &&; - -private: - /// Returns the Shard for \p StartSourceFile from cache or loads it from \p - /// Storage. Also returns paths for dependencies of \p StartSourceFile if it - /// wasn't cached yet. - std::pair<const LoadedShard &, std::vector<Path>> - loadShard(PathRef StartSourceFile); - - /// Cache for Storage lookups. - llvm::StringMap<LoadedShard> LoadedShards; - - /// References are into the AbsolutePaths in LoadedShards. - llvm::DenseMap<PathRef, PathRef> FileToTU; - - BackgroundIndexStorage::Factory &IndexStorageFactory; -}; - -std::pair<const LoadedShard &, std::vector<Path>> -BackgroundIndexLoader::loadShard(PathRef StartSourceFile) { - auto It = LoadedShards.try_emplace(StartSourceFile); - LoadedShard &LS = It.first->getValue(); - std::vector<Path> Edges = {}; - // Return the cached shard. - if (!It.second) - return {LS, Edges}; - - LS.AbsolutePath = StartSourceFile.str(); - BackgroundIndexStorage *Storage = IndexStorageFactory(LS.AbsolutePath); - auto Shard = Storage->loadShard(StartSourceFile); - if (!Shard || !Shard->Sources) { - vlog("Failed to load shard: {0}", StartSourceFile); - return {LS, Edges}; - } - - LS.Shard = std::move(Shard); - for (const auto &It : *LS.Shard->Sources) { - auto AbsPath = uriToAbsolutePath(It.getKey(), StartSourceFile); - if (!AbsPath) - continue; - // A shard contains only edges for non main-file sources. - if (*AbsPath != StartSourceFile) { - Edges.push_back(*AbsPath); - continue; - } - - // Fill in shard metadata. - const IncludeGraphNode &IGN = It.getValue(); - LS.Digest = IGN.Digest; - LS.CountReferences = IGN.Flags & IncludeGraphNode::SourceFlag::IsTU; - LS.HadErrors = IGN.Flags & IncludeGraphNode::SourceFlag::HadErrors; - } - assert(LS.Digest != FileDigest{{0}} && "Digest is empty?"); - return {LS, Edges}; -} - -void BackgroundIndexLoader::load(PathRef MainFile) { - llvm::StringSet<> InQueue; - // Following containers points to strings inside InQueue. - std::queue<PathRef> ToVisit; - InQueue.insert(MainFile); - ToVisit.push(MainFile); - - while (!ToVisit.empty()) { - PathRef SourceFile = ToVisit.front(); - ToVisit.pop(); - - auto ShardAndEdges = loadShard(SourceFile); - FileToTU[ShardAndEdges.first.AbsolutePath] = MainFile; - for (PathRef Edge : ShardAndEdges.second) { - auto It = InQueue.insert(Edge); - if (It.second) - ToVisit.push(It.first->getKey()); - } - } -} - -std::vector<LoadedShard> BackgroundIndexLoader::takeResult() && { - std::vector<LoadedShard> Result; - Result.reserve(LoadedShards.size()); - for (auto &It : LoadedShards) { - Result.push_back(std::move(It.getValue())); - LoadedShard &LS = Result.back(); - auto TUsIt = FileToTU.find(LS.AbsolutePath); - assert(TUsIt != FileToTU.end() && "No TU registered for the shard"); - Result.back().DependentTU = TUsIt->second; - } - return Result; -} -} // namespace - -std::vector<LoadedShard> -loadIndexShards(llvm::ArrayRef<Path> MainFiles, - BackgroundIndexStorage::Factory &IndexStorageFactory, - const GlobalCompilationDatabase &CDB) { - BackgroundIndexLoader Loader(IndexStorageFactory); - for (llvm::StringRef MainFile : MainFiles) { - assert(llvm::sys::path::is_absolute(MainFile)); - Loader.load(MainFile); - } - return std::move(Loader).takeResult(); -} - -} // namespace clangd -} // namespace clang Removed: clang-tools-extra/trunk/clangd/index/BackgroundIndexLoader.h URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/index/BackgroundIndexLoader.h?rev=366550&view=auto ============================================================================== --- clang-tools-extra/trunk/clangd/index/BackgroundIndexLoader.h (original) +++ clang-tools-extra/trunk/clangd/index/BackgroundIndexLoader.h (removed) @@ -1,54 +0,0 @@ -//===--- BackgroundIndexLoader.h - Load shards from index storage-*- 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 -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_BACKGROUND_INDEX_LOADER_H -#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_BACKGROUND_INDEX_LOADER_H - -#include "Path.h" -#include "index/Background.h" -#include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/Optional.h" -#include "llvm/ADT/StringMap.h" -#include "llvm/ADT/StringRef.h" -#include "llvm/Support/VirtualFileSystem.h" -#include <memory> -#include <vector> - -namespace clang { -namespace clangd { - -/// Represents a shard loaded from storage, stores contents in \p Shard and -/// metadata about the source file that generated this shard. -struct LoadedShard { - /// Path of the source file that produced this shard. - Path AbsolutePath; - /// Digest of the source file contents that produced this shard. - FileDigest Digest = {}; - /// Whether the RefSlab in Shard should be used for updating symbol reference - /// counts when building an index. - bool CountReferences = false; - /// Whether the indexing action producing that shard had errors. - bool HadErrors = false; - /// Path to a TU that is depending on this shard. - Path DependentTU; - /// Will be nullptr when index storage couldn't provide a valid shard for - /// AbsolutePath. - std::unique_ptr<IndexFileIn> Shard; -}; - -/// Loads all shards for the TU \p MainFile from \p Storage. -std::vector<LoadedShard> -loadIndexShards(llvm::ArrayRef<Path> MainFiles, - BackgroundIndexStorage::Factory &IndexStorageFactory, - const GlobalCompilationDatabase &CDB); - -} // namespace clangd -} // namespace clang - -#endif Modified: clang-tools-extra/trunk/clangd/index/BackgroundIndexStorage.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/index/BackgroundIndexStorage.cpp?rev=366551&r1=366550&r2=366551&view=diff ============================================================================== --- clang-tools-extra/trunk/clangd/index/BackgroundIndexStorage.cpp (original) +++ clang-tools-extra/trunk/clangd/index/BackgroundIndexStorage.cpp Fri Jul 19 02:26:33 2019 @@ -6,21 +6,13 @@ // //===----------------------------------------------------------------------===// -#include "GlobalCompilationDatabase.h" #include "Logger.h" -#include "Path.h" #include "index/Background.h" -#include "llvm/ADT/Optional.h" -#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/ScopeExit.h" -#include "llvm/ADT/SmallString.h" -#include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/StringRef.h" #include "llvm/Support/Error.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Path.h" -#include <functional> namespace clang { namespace clangd { @@ -126,21 +118,12 @@ public: // Creates and owns IndexStorages for multiple CDBs. class DiskBackedIndexStorageManager { public: - DiskBackedIndexStorageManager( - std::function<llvm::Optional<ProjectInfo>(PathRef)> GetProjectInfo) - : IndexStorageMapMu(llvm::make_unique<std::mutex>()), - GetProjectInfo(std::move(GetProjectInfo)) { - llvm::SmallString<128> HomeDir; - llvm::sys::path::home_directory(HomeDir); - this->HomeDir = HomeDir.str().str(); - } + DiskBackedIndexStorageManager() + : IndexStorageMapMu(llvm::make_unique<std::mutex>()) {} - // Creates or fetches to storage from cache for the specified project. - BackgroundIndexStorage *operator()(PathRef File) { + // Creates or fetches to storage from cache for the specified CDB. + BackgroundIndexStorage *operator()(llvm::StringRef CDBDirectory) { std::lock_guard<std::mutex> Lock(*IndexStorageMapMu); - Path CDBDirectory = HomeDir; - if (auto PI = GetProjectInfo(File)) - CDBDirectory = PI->SourceRoot; auto &IndexStorage = IndexStorageMap[CDBDirectory]; if (!IndexStorage) IndexStorage = create(CDBDirectory); @@ -148,28 +131,21 @@ public: } private: - std::unique_ptr<BackgroundIndexStorage> create(PathRef CDBDirectory) { - if (CDBDirectory.empty()) { - elog("Tried to create storage for empty directory!"); + std::unique_ptr<BackgroundIndexStorage> create(llvm::StringRef CDBDirectory) { + if (CDBDirectory.empty()) return llvm::make_unique<NullStorage>(); - } return llvm::make_unique<DiskBackedIndexStorage>(CDBDirectory); } - Path HomeDir; - llvm::StringMap<std::unique_ptr<BackgroundIndexStorage>> IndexStorageMap; std::unique_ptr<std::mutex> IndexStorageMapMu; - - std::function<llvm::Optional<ProjectInfo>(PathRef)> GetProjectInfo; }; } // namespace BackgroundIndexStorage::Factory -BackgroundIndexStorage::createDiskBackedStorageFactory( - std::function<llvm::Optional<ProjectInfo>(PathRef)> GetProjectInfo) { - return DiskBackedIndexStorageManager(std::move(GetProjectInfo)); +BackgroundIndexStorage::createDiskBackedStorageFactory() { + return DiskBackedIndexStorageManager(); } } // namespace clangd Modified: clang-tools-extra/trunk/clangd/index/BackgroundRebuild.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/index/BackgroundRebuild.cpp?rev=366551&r1=366550&r2=366551&view=diff ============================================================================== --- clang-tools-extra/trunk/clangd/index/BackgroundRebuild.cpp (original) +++ clang-tools-extra/trunk/clangd/index/BackgroundRebuild.cpp Fri Jul 19 02:26:33 2019 @@ -78,13 +78,13 @@ void BackgroundIndexRebuilder::idle() { void BackgroundIndexRebuilder::startLoading() { std::lock_guard<std::mutex> Lock(Mu); if (!Loading) - LoadedShards = 0; + LoadedTUs = 0; ++Loading; } -void BackgroundIndexRebuilder::loadedShard(size_t ShardCount) { +void BackgroundIndexRebuilder::loadedTU() { std::lock_guard<std::mutex> Lock(Mu); assert(Loading); - LoadedShards += ShardCount; + ++LoadedTUs; } void BackgroundIndexRebuilder::doneLoading() { maybeRebuild("after loading index from disk", [this] { @@ -93,7 +93,7 @@ void BackgroundIndexRebuilder::doneLoadi if (Loading) // was loading multiple batches concurrently return false; // rebuild once the last batch is done. // Rebuild if we loaded any shards, or if we stopped an indexedTU rebuild. - return LoadedShards > 0 || enoughTUsToRebuild(); + return LoadedTUs > 0 || enoughTUsToRebuild(); }); } Modified: clang-tools-extra/trunk/clangd/index/BackgroundRebuild.h URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/index/BackgroundRebuild.h?rev=366551&r1=366550&r2=366551&view=diff ============================================================================== --- clang-tools-extra/trunk/clangd/index/BackgroundRebuild.h (original) +++ clang-tools-extra/trunk/clangd/index/BackgroundRebuild.h Fri Jul 19 02:26:33 2019 @@ -17,7 +17,6 @@ #include "index/FileIndex.h" #include "index/Index.h" #include "llvm/Support/Threading.h" -#include <cstddef> namespace clang { namespace clangd { @@ -62,7 +61,7 @@ public: // sessions may happen concurrently. void startLoading(); // Called to indicate some shards were actually loaded from disk. - void loadedShard(size_t ShardCount); + void loadedTU(); // Called to indicate we're finished loading shards from disk. // May rebuild (if any were loaded). void doneLoading(); @@ -90,7 +89,7 @@ private: unsigned IndexedTUsAtLastRebuild = 0; // Are we loading shards? May be multiple concurrent sessions. unsigned Loading = 0; - unsigned LoadedShards; // In the current loading session. + unsigned LoadedTUs; // In the current loading session. SwapIndex *Target; FileSymbols *Source; Modified: clang-tools-extra/trunk/clangd/test/Inputs/background-index/definition.jsonrpc URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/test/Inputs/background-index/definition.jsonrpc?rev=366551&r1=366550&r2=366551&view=diff ============================================================================== --- clang-tools-extra/trunk/clangd/test/Inputs/background-index/definition.jsonrpc (original) +++ clang-tools-extra/trunk/clangd/test/Inputs/background-index/definition.jsonrpc Fri Jul 19 02:26:33 2019 @@ -18,7 +18,7 @@ "uri": "file://DIRECTORY/bar.cpp", "languageId": "cpp", "version": 1, - "text": "#include \"sub_dir/foo.h\"\nint main(){\nreturn foo();\n}" + "text": "#include \"foo.h\"\nint main(){\nreturn foo();\n}" } } } Modified: clang-tools-extra/trunk/clangd/test/Inputs/background-index/foo.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/test/Inputs/background-index/foo.cpp?rev=366551&r1=366550&r2=366551&view=diff ============================================================================== --- clang-tools-extra/trunk/clangd/test/Inputs/background-index/foo.cpp (original) +++ clang-tools-extra/trunk/clangd/test/Inputs/background-index/foo.cpp Fri Jul 19 02:26:33 2019 @@ -1,2 +1,2 @@ -#include "sub_dir/foo.h" +#include "foo.h" int foo() { return 42; } Added: clang-tools-extra/trunk/clangd/test/Inputs/background-index/foo.h URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/test/Inputs/background-index/foo.h?rev=366551&view=auto ============================================================================== --- clang-tools-extra/trunk/clangd/test/Inputs/background-index/foo.h (added) +++ clang-tools-extra/trunk/clangd/test/Inputs/background-index/foo.h Fri Jul 19 02:26:33 2019 @@ -0,0 +1,4 @@ +#ifndef FOO_H +#define FOO_H +int foo(); +#endif Modified: clang-tools-extra/trunk/clangd/test/background-index.test URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/test/background-index.test?rev=366551&r1=366550&r2=366551&view=diff ============================================================================== --- clang-tools-extra/trunk/clangd/test/background-index.test (original) +++ clang-tools-extra/trunk/clangd/test/background-index.test Fri Jul 19 02:26:33 2019 @@ -5,8 +5,7 @@ # RUN: rm -rf %t # RUN: cp -r %S/Inputs/background-index %t # Need to embed the correct temp path in the actual JSON-RPC requests. -# RUN: sed -i -e "s|DIRECTORY|%t|" %t/definition.jsonrpc -# RUN: sed -i -e "s|DIRECTORY|%t|" %t/compile_commands.json +# RUN: sed -i -e "s|DIRECTORY|%t|" %t/* # We're editing bar.cpp, which includes foo.h. # foo() is declared in foo.h and defined in foo.cpp. @@ -15,7 +14,6 @@ # Test that the index is writing files in the expected location. # RUN: ls %t/.clangd/index/foo.cpp.*.idx -# RUN: ls %t/sub_dir/.clangd/index/foo.h.*.idx # Test the index is read from disk: delete code and restart clangd. # RUN: rm %t/foo.cpp Modified: clang-tools-extra/trunk/clangd/unittests/BackgroundIndexTests.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/unittests/BackgroundIndexTests.cpp?rev=366551&r1=366550&r2=366551&view=diff ============================================================================== --- clang-tools-extra/trunk/clangd/unittests/BackgroundIndexTests.cpp (original) +++ clang-tools-extra/trunk/clangd/unittests/BackgroundIndexTests.cpp Fri Jul 19 02:26:33 2019 @@ -211,7 +211,7 @@ TEST_F(BackgroundIndexTest, ShardStorage OverlayCDB CDB(/*Base=*/nullptr); BackgroundIndex Idx(Context::empty(), FS, CDB, [&](llvm::StringRef) { return &MSS; }); - CDB.setCompileCommand(testPath("root/A.cc"), Cmd); + CDB.setCompileCommand(testPath("root"), Cmd); ASSERT_TRUE(Idx.blockUntilIdleForTest()); } EXPECT_EQ(CacheHits, 2U); // Check both A.cc and A.h loaded from cache. @@ -335,7 +335,7 @@ TEST_F(BackgroundIndexTest, ShardStorage OverlayCDB CDB(/*Base=*/nullptr); BackgroundIndex Idx(Context::empty(), FS, CDB, [&](llvm::StringRef) { return &MSS; }); - CDB.setCompileCommand(testPath("root/A.cc"), Cmd); + CDB.setCompileCommand(testPath("root"), Cmd); ASSERT_TRUE(Idx.blockUntilIdleForTest()); } EXPECT_EQ(CacheHits, 2U); // Check both A.cc and A.h loaded from cache. @@ -353,7 +353,7 @@ TEST_F(BackgroundIndexTest, ShardStorage OverlayCDB CDB(/*Base=*/nullptr); BackgroundIndex Idx(Context::empty(), FS, CDB, [&](llvm::StringRef) { return &MSS; }); - CDB.setCompileCommand(testPath("root/A.cc"), Cmd); + CDB.setCompileCommand(testPath("root"), Cmd); ASSERT_TRUE(Idx.blockUntilIdleForTest()); } EXPECT_EQ(CacheHits, 2U); // Check both A.cc and A.h loaded from cache. @@ -621,8 +621,8 @@ TEST_F(BackgroundIndexRebuilderTest, Ind TEST_F(BackgroundIndexRebuilderTest, LoadingShards) { Rebuilder.startLoading(); - Rebuilder.loadedShard(10); - Rebuilder.loadedShard(20); + Rebuilder.loadedTU(); + Rebuilder.loadedTU(); EXPECT_TRUE(checkRebuild([&] { Rebuilder.doneLoading(); })); // No rebuild for no shards. @@ -631,11 +631,11 @@ TEST_F(BackgroundIndexRebuilderTest, Loa // Loads can overlap. Rebuilder.startLoading(); - Rebuilder.loadedShard(1); + Rebuilder.loadedTU(); Rebuilder.startLoading(); - Rebuilder.loadedShard(1); + Rebuilder.loadedTU(); EXPECT_FALSE(checkRebuild([&] { Rebuilder.doneLoading(); })); - Rebuilder.loadedShard(1); + Rebuilder.loadedTU(); EXPECT_TRUE(checkRebuild([&] { Rebuilder.doneLoading(); })); // No rebuilding for indexed files while loading. _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits