//===- PDBStringTableBuilder.cpp - PDB String Table -------------*- 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 "llvm/DebugInfo/PDB/Native/PDBStringTableBuilder.h"

#include "llvm/ADT/ArrayRef.h"
#include "llvm/DebugInfo/PDB/Native/Hash.h"
#include "llvm/DebugInfo/PDB/Native/RawTypes.h"
#include "llvm/Support/BinaryStreamWriter.h"
#include "llvm/Support/Endian.h"

#include <map>

using namespace llvm;
using namespace llvm::msf;
using namespace llvm::support;
using namespace llvm::support::endian;
using namespace llvm::pdb;

StringTableHashTraits::StringTableHashTraits(PDBStringTableBuilder &Table)
    : Table(&Table) {}

uint32_t StringTableHashTraits::hashLookupKey(StringRef S) const {
  // The reference implementation doesn't include code for /src/headerblock
  // handling, but it can only read natvis entries lld's PDB files if
  // this hash function truncates the hash to 16 bit.
  // PDB/include/misc.h in the reference implementation has a hashSz() function
  // that returns an unsigned short, that seems what's being used for
  // /src/headerblock.
  return static_cast<uint16_t>(Table->getIdForString(S));
}

StringRef StringTableHashTraits::storageKeyToLookupKey(uint32_t Offset) const {
  return Table->getStringForId(Offset);
}

uint32_t StringTableHashTraits::lookupKeyToStorageKey(StringRef S) {
  return Table->insert(S);
}

uint32_t PDBStringTableBuilder::insert(StringRef S) {
  return Strings.insert(S);
}

uint32_t PDBStringTableBuilder::getIdForString(StringRef S) const {
  return Strings.getIdForString(S);
}

StringRef PDBStringTableBuilder::getStringForId(uint32_t Id) const {
  return Strings.getStringForId(Id);
}

static uint32_t computeBucketCount(uint32_t NumStrings) {
  // This is a precomputed list of Buckets given the specified number of
  // strings.  Matching the reference algorithm exactly is not strictly
  // necessary for correctness, but it helps when comparing LLD's PDBs with
  // Microsoft's PDBs so as to eliminate superfluous differences.
  // The reference implementation does (in nmt.h, NMT::grow()):
  //   unsigned StringCount = 0;
  //   unsigned BucketCount = 1;
  //   fn insert() {
  //     ++StringCount;
  //     if (BucketCount * 3 / 4 < StringCount)
  //       BucketCount = BucketCount * 3 / 2 + 1;
  //   }
  // This list contains all StringCount, BucketCount pairs where BucketCount was
  // just incremented.  It ends before the first BucketCount entry where
  // BucketCount * 3 would overflow a 32-bit unsigned int.
  static const std::pair<uint32_t, uint32_t> StringsToBuckets[] = {
      {0, 1},
      {1, 2},
      {2, 4},
      {4, 7},
      {6, 11},
      {9, 17},
      {13, 26},
      {20, 40},
      {31, 61},
      {46, 92},
      {70, 139},
      {105, 209},
      {157, 314},
      {236, 472},
      {355, 709},
      {532, 1064},
      {799, 1597},
      {1198, 2396},
      {1798, 3595},
      {2697, 5393},
      {4045, 8090},
      {6068, 12136},
      {9103, 18205},
      {13654, 27308},
      {20482, 40963},
      {30723, 61445},
      {46084, 92168},
      {69127, 138253},
      {103690, 207380},
      {155536, 311071},
      {233304, 466607},
      {349956, 699911},
      {524934, 1049867},
      {787401, 1574801},
      {1181101, 2362202},
      {1771652, 3543304},
      {2657479, 5314957},
      {3986218, 7972436},
      {5979328, 11958655},
      {8968992, 17937983},
      {13453488, 26906975},
      {20180232, 40360463},
      {30270348, 60540695},
      {45405522, 90811043},
      {68108283, 136216565},
      {102162424, 204324848},
      {153243637, 306487273},
      {229865455, 459730910},
      {344798183, 689596366},
      {517197275, 1034394550},
      {775795913, 1551591826},
      {1163693870, 2327387740}};
  const auto *Entry = llvm::lower_bound(
      StringsToBuckets, std::make_pair(NumStrings, 0U), llvm::less_first());
  assert(Entry != std::end(StringsToBuckets));
  return Entry->second;
}

uint32_t PDBStringTableBuilder::calculateHashTableSize() const {
  uint32_t Size = sizeof(uint32_t); // Hash table begins with 4-byte size field.
  Size += sizeof(uint32_t) * computeBucketCount(Strings.size());

  return Size;
}

uint32_t PDBStringTableBuilder::calculateSerializedSize() const {
  uint32_t Size = 0;
  Size += sizeof(PDBStringTableHeader);
  Size += Strings.calculateSerializedSize();
  Size += calculateHashTableSize();
  Size += sizeof(uint32_t); // The /names stream ends with the string count.
  return Size;
}

void PDBStringTableBuilder::setStrings(
    const codeview::DebugStringTableSubsection &Strings) {
  this->Strings = Strings;
}

Error PDBStringTableBuilder::writeHeader(BinaryStreamWriter &Writer) const {
  // Write a header
  PDBStringTableHeader H;
  H.Signature = PDBStringTableSignature;
  H.HashVersion = 1;
  H.ByteSize = Strings.calculateSerializedSize();
  if (auto EC = Writer.writeObject(H))
    return EC;
  assert(Writer.bytesRemaining() == 0);
  return Error::success();
}

Error PDBStringTableBuilder::writeStrings(BinaryStreamWriter &Writer) const {
  if (auto EC = Strings.commit(Writer))
    return EC;

  assert(Writer.bytesRemaining() == 0);
  return Error::success();
}

Error PDBStringTableBuilder::writeHashTable(BinaryStreamWriter &Writer) const {
  // Write a hash table.
  uint32_t BucketCount = computeBucketCount(Strings.size());
  if (auto EC = Writer.writeInteger(BucketCount))
    return EC;
  std::vector<ulittle32_t> Buckets(BucketCount);

  for (const auto &Pair : Strings) {
    StringRef S = Pair.getKey();
    uint32_t Offset = Pair.getValue();
    uint32_t Hash = hashStringV1(S);

    for (uint32_t I = 0; I != BucketCount; ++I) {
      uint32_t Slot = (Hash + I) % BucketCount;
      if (Buckets[Slot] != 0)
        continue;
      Buckets[Slot] = Offset;
      break;
    }
  }

  if (auto EC = Writer.writeArray(ArrayRef<ulittle32_t>(Buckets)))
    return EC;

  assert(Writer.bytesRemaining() == 0);
  return Error::success();
}

Error PDBStringTableBuilder::writeEpilogue(BinaryStreamWriter &Writer) const {
  if (auto EC = Writer.writeInteger<uint32_t>(Strings.size()))
    return EC;
  assert(Writer.bytesRemaining() == 0);
  return Error::success();
}

Error PDBStringTableBuilder::commit(BinaryStreamWriter &Writer) const {
  BinaryStreamWriter SectionWriter;

  std::tie(SectionWriter, Writer) = Writer.split(sizeof(PDBStringTableHeader));
  if (auto EC = writeHeader(SectionWriter))
    return EC;

  std::tie(SectionWriter, Writer) =
      Writer.split(Strings.calculateSerializedSize());
  if (auto EC = writeStrings(SectionWriter))
    return EC;

  std::tie(SectionWriter, Writer) = Writer.split(calculateHashTableSize());
  if (auto EC = writeHashTable(SectionWriter))
    return EC;

  std::tie(SectionWriter, Writer) = Writer.split(sizeof(uint32_t));
  if (auto EC = writeEpilogue(SectionWriter))
    return EC;

  return Error::success();
}
