kadircet updated this revision to Diff 303442. kadircet added a comment. The index has the following query semantics:
- Lookup: it only queries the associated index. This is to not regress latency for operations like Hover and Go-To. - FuzzyFind only queries the associated index when RestrictForCodeCompletion is set, it queries all otherwise. Again this is to prevent latency regression for code completion, but make sure we provide complete results for search operations like WorkspaceSymbol. - Refs, queries all. As incomplete results for such operations might result in bad UX for opeartions like rename. Also having an incomplete set of references might result in bad impressions. - Relations, queries all. Again this is used by operations like type and call hierarchy and having incomplete results are useless for such operations. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D90750/new/ https://reviews.llvm.org/D90750 Files: clang-tools-extra/clangd/CMakeLists.txt clang-tools-extra/clangd/index/ProjectAware.cpp clang-tools-extra/clangd/index/ProjectAware.h clang-tools-extra/clangd/unittests/CMakeLists.txt clang-tools-extra/clangd/unittests/ProjectAwareIndexTests.cpp
Index: clang-tools-extra/clangd/unittests/ProjectAwareIndexTests.cpp =================================================================== --- /dev/null +++ clang-tools-extra/clangd/unittests/ProjectAwareIndexTests.cpp @@ -0,0 +1,7 @@ +//===-- ProjectAwareIndexTests.cpp -------------------*- 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 +// +//===----------------------------------------------------------------------===// Index: clang-tools-extra/clangd/unittests/CMakeLists.txt =================================================================== --- clang-tools-extra/clangd/unittests/CMakeLists.txt +++ clang-tools-extra/clangd/unittests/CMakeLists.txt @@ -73,6 +73,7 @@ PathMappingTests.cpp PreambleTests.cpp PrintASTTests.cpp + ProjectAwareIndexTests.cpp QualityTests.cpp RenameTests.cpp RIFFTests.cpp Index: clang-tools-extra/clangd/index/ProjectAware.h =================================================================== --- /dev/null +++ clang-tools-extra/clangd/index/ProjectAware.h @@ -0,0 +1,76 @@ +//===--- ProjectAware.h ------------------------------------------*- 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_PROJECT_AWARE_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_PROJECT_AWARE_H + +#include "Config.h" +#include "index/Index.h" +#include "index/MemIndex.h" +#include "index/Merge.h" +#include "index/Serialization.h" +#include "index/remote/Client.h" +#include "support/Threading.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/StringMap.h" +#include "llvm/ADT/StringRef.h" +#include <cstddef> +#include <memory> +#include <mutex> +#include <string> +#include <vector> +namespace clang { +namespace clangd { + +class ProjectAwareIndex : public SymbolIndex { +public: + size_t estimateMemoryUsage() const override; + + /// Only queries the associated index with the current context. + void lookup(const LookupRequest &Req, + llvm::function_ref<void(const Symbol &)> Callback) const override; + + /// Query all indexes while prioritizing the associated one (if any). + bool refs(const RefsRequest &Req, + llvm::function_ref<void(const Ref &)> Callback) const override; + + /// Queries only the associates index when Req.RestrictForCodeCompletion is + /// set, otherwise queries all. + bool + fuzzyFind(const FuzzyFindRequest &Req, + llvm::function_ref<void(const Symbol &)> Callback) const override; + + /// Query all indexes while prioritizing the associated one (if any). + void relations(const RelationsRequest &Req, + llvm::function_ref<void(const SymbolID &, const Symbol &)> + Callback) const override; + +private: + // Returns the index associated with current context, if any. + SymbolIndex *getIndex() const; + // Adds the Idx into IndexStorage and adjusts the MergedIdx view. Returns a + // pointer to the Idx. + SymbolIndex *addIndex(std::unique_ptr<SymbolIndex> Idx) const; + + // Storage for all the external indexes. + Memoize<llvm::StringMap<SymbolIndex *>> IndexForProject; + mutable std::mutex Mu; + mutable std::vector<std::unique_ptr<SymbolIndex>> IndexStorage; + AsyncTaskRunner Tasks; + + // Used for creating a merged view over all the indexes seen so far to ease + // querying them all at once. + mutable std::mutex MergedIdxMu; + mutable std::vector<std::unique_ptr<SymbolIndex>> MergedIdxStorage; + // Points at root of merged view of all smybols. + mutable SymbolIndex *MergedIdx = nullptr; +}; +} // namespace clangd +} // namespace clang + +#endif Index: clang-tools-extra/clangd/index/ProjectAware.cpp =================================================================== --- /dev/null +++ clang-tools-extra/clangd/index/ProjectAware.cpp @@ -0,0 +1,125 @@ +//===--- ProjectAware.h ------------------------------------------*- 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 +// +//===----------------------------------------------------------------------===// + +#include "ProjectAware.h" +#include "index/Index.h" +#include "index/Merge.h" +#include "index/Ref.h" +#include "index/Symbol.h" +#include "index/SymbolID.h" +#include "support/Logger.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/StringRef.h" +#include <memory> +#include <mutex> + +namespace clang { +namespace clangd { +size_t ProjectAwareIndex::estimateMemoryUsage() const { + size_t Total = 0; + std::lock_guard<std::mutex> Lock(Mu); + for (auto &Idx : IndexStorage) + Total += Idx->estimateMemoryUsage(); + return Total; +} + +void ProjectAwareIndex::lookup( + const LookupRequest &Req, + llvm::function_ref<void(const Symbol &)> Callback) const { + if (auto *Idx = getIndex()) + Idx->lookup(Req, Callback); +} + +bool ProjectAwareIndex::refs( + const RefsRequest &Req, + llvm::function_ref<void(const Ref &)> Callback) const { + auto *AssocIdx = getIndex(); + std::lock_guard<std::mutex> Lock(MergedIdxMu); + if (AssocIdx) + return MergedIndex(AssocIdx, MergedIdx).refs(Req, Callback); + return MergedIdx->refs(Req, Callback); +} + +bool ProjectAwareIndex::fuzzyFind( + const FuzzyFindRequest &Req, + llvm::function_ref<void(const Symbol &)> Callback) const { + auto *AssocIdx = getIndex(); + if (Req.RestrictForCodeCompletion) { + if (AssocIdx) + return AssocIdx->fuzzyFind(Req, Callback); + return false; + } + std::lock_guard<std::mutex> Lock(MergedIdxMu); + if (AssocIdx) + return MergedIndex(AssocIdx, MergedIdx).fuzzyFind(Req, Callback); + return MergedIdx->fuzzyFind(Req, Callback); +} + +void ProjectAwareIndex::relations( + const RelationsRequest &Req, + llvm::function_ref<void(const SymbolID &, const Symbol &)> Callback) const { + auto *AssocIdx = getIndex(); + std::lock_guard<std::mutex> Lock(MergedIdxMu); + if (AssocIdx) + return MergedIndex(AssocIdx, MergedIdx).relations(Req, Callback); + return MergedIdx->relations(Req, Callback); +} + +SymbolIndex *ProjectAwareIndex::getIndex() const { + const auto &C = Config::current(); + if (C.Index.External.MountPoint.empty()) + return nullptr; + if (auto File = C.Index.External.File) { + return IndexForProject.get( + *File, [File = std::move(*File), + MP = llvm::StringRef(C.Index.External.MountPoint), this] { + log("Associating {0} with monolithic index at {1}.", MP, File); + auto NewIndex = + std::make_unique<SwapIndex>(std::make_unique<MemIndex>()); + SwapIndex *PlaceHolder = NewIndex.get(); + Tasks.runAsync("Load-index:" + File, [File, PlaceHolder] { + if (auto Idx = loadIndex(File, /*UseDex=*/true)) + PlaceHolder->reset(std::move(Idx)); + }); + addIndex(std::move(NewIndex)); + return PlaceHolder; + }); + } + assert(C.Index.External.Server); + auto Server = std::move(*C.Index.External.Server); + return IndexForProject.get( + Server, [Server = std::move(Server), + MP = llvm::StringRef(C.Index.External.MountPoint), this] { + log("Associating {0} with remote index at {1}.", MP, Server); + auto NewIndex = remote::getClient(Server, MP); + return addIndex(std::move(NewIndex)); + }); +} + +SymbolIndex * +ProjectAwareIndex::addIndex(std::unique_ptr<SymbolIndex> Idx) const { + SymbolIndex *NewIdx = Idx.get(); + { + std::lock_guard<std::mutex> Lock(Mu); + IndexStorage.emplace_back(std::move(Idx)); + } + { + std::lock_guard<std::mutex> Lock(MergedIdxMu); + if (!MergedIdx) + MergedIdx = NewIdx; + else { + MergedIdxStorage.emplace_back( + std::make_unique<MergedIndex>(NewIdx, MergedIdx)); + MergedIdx = MergedIdxStorage.back().get(); + } + } + return NewIdx; +} +} // namespace clangd +} // namespace clang Index: clang-tools-extra/clangd/CMakeLists.txt =================================================================== --- clang-tools-extra/clangd/CMakeLists.txt +++ clang-tools-extra/clangd/CMakeLists.txt @@ -93,6 +93,7 @@ index/IndexAction.cpp index/MemIndex.cpp index/Merge.cpp + index/ProjectAware.cpp index/Ref.cpp index/Relation.cpp index/Serialization.cpp
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits