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

Reply via email to