//===--- MemIndex.cpp - Dynamic in-memory symbol index. ----------*- C++-*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===-------------------------------------------------------------------===//

#include "MemIndex.h"
#include "FuzzyMatch.h"
#include "Logger.h"
#include "Quality.h"
#include "Trace.h"

using namespace llvm;
namespace clang {
namespace clangd {

std::unique_ptr<SymbolIndex> MemIndex::build(SymbolSlab Slab, RefSlab Refs) {
  // Store Slab size before it is moved.
  const auto BackingDataSize = Slab.bytes() + Refs.bytes();
  auto Data = std::make_pair(std::move(Slab), std::move(Refs));
  return llvm::make_unique<MemIndex>(Data.first, Data.second, std::move(Data),
                                     BackingDataSize);
}

bool MemIndex::fuzzyFind(const FuzzyFindRequest &Req,
                         function_ref<void(const Symbol &)> Callback) const {
  assert(!StringRef(Req.Query).contains("::") &&
         "There must be no :: in query.");
  trace::Span Tracer("MemIndex fuzzyFind");

  TopN<std::pair<float, const Symbol *>> Top(
      Req.Limit ? *Req.Limit : std::numeric_limits<size_t>::max());
  FuzzyMatcher Filter(Req.Query);
  bool More = false;
  for (const auto Pair : Index) {
    const Symbol *Sym = Pair.second;

    // Exact match against all possible scopes.
    if (!Req.AnyScope && !is_contained(Req.Scopes, Sym->Scope))
      continue;
    if (Req.RestrictForCodeCompletion &&
        !(Sym->Flags & Symbol::IndexedForCodeCompletion))
      continue;

    if (auto Score = Filter.match(Sym->Name))
      if (Top.push({*Score * quality(*Sym), Sym}))
        More = true; // An element with smallest score was discarded.
  }
  auto Results = std::move(Top).items();
  SPAN_ATTACH(Tracer, "results", static_cast<int>(Results.size()));
  for (const auto &Item : Results)
    Callback(*Item.second);
  return More;
}

void MemIndex::lookup(const LookupRequest &Req,
                      function_ref<void(const Symbol &)> Callback) const {
  trace::Span Tracer("MemIndex lookup");
  for (const auto &ID : Req.IDs) {
    auto I = Index.find(ID);
    if (I != Index.end())
      Callback(*I->second);
  }
}

void MemIndex::refs(const RefsRequest &Req,
                    function_ref<void(const Ref &)> Callback) const {
  trace::Span Tracer("MemIndex refs");
  for (const auto &ReqID : Req.IDs) {
    auto SymRefs = Refs.find(ReqID);
    if (SymRefs == Refs.end())
      continue;
    for (const auto &O : SymRefs->second)
      if (static_cast<int>(Req.Filter & O.Kind))
        Callback(O);
  }
}

size_t MemIndex::estimateMemoryUsage() const {
  return Index.getMemorySize() + Refs.getMemorySize() + BackingDataSize;
}

} // namespace clangd
} // namespace clang
