kadircet updated this revision to Diff 304795. kadircet added a comment. - Rebase
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,10 @@ +//===-- 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 +// +//===----------------------------------------------------------------------===// + +#include "gmock/gmock.h" +#include "gtest/gtest.h" 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,74 @@ +//===--- 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; + // Creates a view over all indexes, putting Primary at the top. + SymbolIndex *mergedView(SymbolIndex *Primary) const; + + // Storage for all the external indexes. + Memoize<llvm::StringMap<SymbolIndex *>> IndexForProject; + mutable std::mutex Mu; + mutable std::vector<std::unique_ptr<SymbolIndex>> IndexStorage; + mutable AsyncTaskRunner Tasks; + // Used for creating a merged view over all the indexes seen so far to ease + // querying them all at once. + mutable std::vector<std::unique_ptr<SymbolIndex>> MergedIdxStorage; +}; +} // 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,138 @@ +//===--- 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 "support/Trace.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/ErrorHandling.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 { + trace::Span Tracer("ProjectAwareIndex::lookup"); + if (auto *Idx = getIndex()) + Idx->lookup(Req, Callback); +} + +bool ProjectAwareIndex::refs( + const RefsRequest &Req, + llvm::function_ref<void(const Ref &)> Callback) const { + trace::Span Tracer("ProjectAwareIndex::refs"); + if (auto *Idx = mergedView(getIndex())) + return Idx->refs(Req, Callback); + return false; +} + +bool ProjectAwareIndex::fuzzyFind( + const FuzzyFindRequest &Req, + llvm::function_ref<void(const Symbol &)> Callback) const { + trace::Span Tracer("ProjectAwareIndex::fuzzyFind"); + auto *AssocIdx = getIndex(); + if (Req.RestrictForCodeCompletion) { + if (AssocIdx) + return AssocIdx->fuzzyFind(Req, Callback); + } else if (auto *Idx = mergedView(AssocIdx)) { + return Idx->fuzzyFind(Req, Callback); + } + return false; +} + +void ProjectAwareIndex::relations( + const RelationsRequest &Req, + llvm::function_ref<void(const SymbolID &, const Symbol &)> Callback) const { + trace::Span Tracer("ProjectAwareIndex::relations"); + if (auto *Idx = mergedView(getIndex())) + return Idx->relations(Req, Callback); +} + +SymbolIndex *ProjectAwareIndex::getIndex() const { + const auto &C = Config::current(); + if (!C.Index.External) + return nullptr; + const auto &External = *C.Index.External; + switch (External.Kind) { + case Config::ExternalIndexSpec::Server: + return IndexForProject.get( + External.Location, [Server = External.Location, + MP = llvm::StringRef(External.MountPoint), this] { + log("Associating {0} with remote index at {1}.", MP, Server); + auto NewIndex = remote::getClient(Server, MP); + return addIndex(std::move(NewIndex)); + }); + break; + case Config::ExternalIndexSpec::File: + return IndexForProject.get( + External.Location, [File = External.Location, + MP = llvm::StringRef(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; + }); + break; + } + llvm_unreachable("Invalid ExternalIndexKind."); +} + +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)); + return NewIdx; +} + +SymbolIndex *ProjectAwareIndex::mergedView(SymbolIndex *Primary) const { + trace::Span Tracer("ProjectAwareIndex::mergedView"); + SymbolIndex *Result = nullptr; + auto PushIndex = [this, &Result](SymbolIndex *Idx) { + if (!Result) { + Result = Idx; + } else { + MergedIdxStorage.emplace_back(std::make_unique<MergedIndex>(Idx, Result)); + Result = MergedIdxStorage.back().get(); + } + }; + std::lock_guard<std::mutex> Lock(Mu); + for (const auto &Idx : IndexStorage) { + if (Idx.get() == Primary) + continue; + PushIndex(Idx.get()); + } + if (Primary) + PushIndex(Primary); + return Result; +} +} // 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