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

Reply via email to