kadircet created this revision.
kadircet added a reviewer: sammccall.
Herald added subscribers: cfe-commits, usaxena95, arphaman, mgorny.
Herald added a project: clang.
kadircet requested review of this revision.
Herald added subscribers: MaskRay, ilya-biryukov.

An index implementation that can dispatch to a variety of indexes
depending on the file path. Enables clangd to work with multiple indexes in the
same instance, configured via config files.

Depends on D90749 <https://reviews.llvm.org/D90749>, D90746 
<https://reviews.llvm.org/D90746>


Repository:
  rG LLVM Github Monorepo

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,59 @@
+//===--- 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 <list>
+#include <memory>
+#include <mutex>
+#include <string>
+namespace clang {
+namespace clangd {
+
+class ProjectAwareIndex : public SymbolIndex {
+public:
+  size_t estimateMemoryUsage() const override;
+
+  void lookup(const LookupRequest &Req,
+              llvm::function_ref<void(const Symbol &)> Callback) const override;
+
+  bool refs(const RefsRequest &Req,
+            llvm::function_ref<void(const Ref &)> Callback) const override;
+
+  bool
+  fuzzyFind(const FuzzyFindRequest &Req,
+            llvm::function_ref<void(const Symbol &)> Callback) const override;
+
+  void relations(const RelationsRequest &Req,
+                 llvm::function_ref<void(const SymbolID &, const Symbol &)>
+                     Callback) const override;
+
+private:
+  SymbolIndex *getIndex() const;
+
+  Memoize<llvm::StringMap<SymbolIndex *>> IndexForProject;
+  mutable std::mutex Mu;
+  mutable std::list<std::unique_ptr<SymbolIndex>> IndexStorage;
+  AsyncTaskRunner Tasks;
+};
+} // 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,88 @@
+//===--- 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 "support/Logger.h"
+#include "llvm/ADT/StringRef.h"
+
+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 {
+  if (auto *Idx = getIndex())
+    return Idx->refs(Req, Callback);
+  return false;
+}
+
+bool ProjectAwareIndex::fuzzyFind(
+    const FuzzyFindRequest &Req,
+    llvm::function_ref<void(const Symbol &)> Callback) const {
+  if (auto *Idx = getIndex())
+    return Idx->fuzzyFind(Req, Callback);
+  return false;
+}
+
+void ProjectAwareIndex::relations(
+    const RelationsRequest &Req,
+    llvm::function_ref<void(const SymbolID &, const Symbol &)> Callback) const {
+  if (auto *Idx = getIndex())
+    Idx->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));
+          });
+          std::lock_guard<std::mutex> Lock(Mu);
+          IndexStorage.emplace_back(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);
+        std::lock_guard<std::mutex> Lock(Mu);
+        IndexStorage.emplace_back(std::move(NewIndex));
+        return IndexStorage.back().get();
+      });
+}
+
+} // 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