//===- subzero/src/IceStringPool.h - String pooling -------------*- C++ -*-===//
//
//                        The Subzero Code Generator
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// \file
/// \brief Defines unique pooled strings with short unique IDs.  This makes
/// hashing, equality testing, and ordered comparison faster, and avoids a lot
/// of memory allocation compared to directly using std::string.
///
//===----------------------------------------------------------------------===//

#ifndef SUBZERO_SRC_ICESTRINGPOOL_H
#define SUBZERO_SRC_ICESTRINGPOOL_H

#include <cstdint> // uintptr_t
#include <string>

namespace Ice {

class StringPool {
  StringPool(const StringPool &) = delete;
  StringPool &operator=(const StringPool &) = delete;

public:
  using IDType = uintptr_t;

  StringPool() = default;
  ~StringPool() = default;
  IDType getNewID() {
    // TODO(stichnot): Make it so that the GlobalString ctor doesn't have to
    // grab the lock, and instead does an atomic increment of NextID.
    auto NewID = NextID;
    NextID += IDIncrement;
    return NewID;
  }
  IDType getOrAddString(const std::string &Value) {
    auto Iter = StringToId.find(Value);
    if (Iter == StringToId.end()) {
      auto *NewStr = new std::string(Value);
      auto ID = reinterpret_cast<IDType>(NewStr);
      StringToId[Value].reset(NewStr);
      return ID;
    }
    return reinterpret_cast<IDType>(Iter->second.get());
  }
  void dump(Ostream &Str) const {
    if (StringToId.empty())
      return;
    Str << "String pool (NumStrings=" << StringToId.size()
        << " NumIDs=" << ((NextID - FirstID) / IDIncrement) << "):";
    for (const auto &Tuple : StringToId) {
      Str << " " << Tuple.first;
    }
    Str << "\n";
  }

private:
  static constexpr IDType FirstID = 1;
  static constexpr IDType IDIncrement = 2;
  IDType NextID = FirstID;
  std::unordered_map<std::string, std::unique_ptr<std::string>> StringToId;
};

template <typename Traits> class StringID {
public:
  using IDType = StringPool::IDType;

  StringID() = default; // Create a default, invalid StringID.
  StringID(const StringID &) = default;
  StringID &operator=(const StringID &) = default;

  /// Create a unique StringID without an actual string, by grabbing the next
  /// unique integral ID from the Owner.
  static StringID createWithoutString(const typename Traits::OwnerType *Owner) {
    return StringID(Owner);
  }
  /// Create a unique StringID that holds an actual string, by fetching or
  /// adding the string from the Owner's pool.
  static StringID createWithString(const typename Traits::OwnerType *Owner,
                                   const std::string &Value) {
    return StringID(Owner, Value);
  }

  /// Tests whether the StringID was initialized with respect to an actual
  /// std::string value, i.e. via StringID::createWithString().
  bool hasStdString() const { return isValid() && ((ID & 0x1) == 0); }

  IDType getID() const {
    assert(isValid());
    return ID;
  }
  const std::string &toString() const {
    if (!hasStdString())
      llvm::report_fatal_error(
          "toString() called when hasStdString() is false");
    return *reinterpret_cast<std::string *>(ID);
  }
  std::string toStringOrEmpty() const {
    if (hasStdString())
      return toString();
    return "";
  }

  bool operator==(const StringID &Other) const { return ID == Other.ID; }
  bool operator!=(const StringID &Other) const { return !(*this == Other); }
  bool operator<(const StringID &Other) const {
    const bool ThisHasString = hasStdString();
    const bool OtherHasString = Other.hasStdString();
    // Do a normal string comparison if both have strings.
    if (ThisHasString && OtherHasString)
      return this->toString() < Other.toString();
    // Use the ID as a tiebreaker if neither has a string.
    if (!ThisHasString && !OtherHasString)
      return ID < Other.ID;
    // If exactly one has a string, then that one comes first.
    assert(!OtherHasString);
    return ThisHasString;
  }

private:
  static constexpr IDType InvalidID = 0;
  IDType ID = InvalidID;

  explicit StringID(const typename Traits::OwnerType *Owner)
      : ID(Traits::getStrings(Owner)->getNewID()) {}
  StringID(const typename Traits::OwnerType *Owner, const std::string &Value)
      : ID(Traits::getStrings(Owner)->getOrAddString(Value)) {
    assert(hasStdString());
  }
  bool isValid() const { return ID != InvalidID; }
};

// TODO(stichnot, jpp): Move GlobalStringPoolTraits definition into
// IceGlobalContext.h, once the include order issues are solved.
struct GlobalStringPoolTraits {
  using OwnerType = GlobalContext;
  static LockedPtr<StringPool> getStrings(const OwnerType *Owner);
};

using GlobalString = StringID<struct GlobalStringPoolTraits>;

template <typename T>
Ostream &operator<<(Ostream &Str, const StringID<T> &Name) {
  return Str << Name.toString();
}

template <typename T>
std::string operator+(const std::string &A, const StringID<T> &B) {
  return A + B.toString();
}

template <typename T>
std::string operator+(const StringID<T> &A, const std::string &B) {
  return A.toString() + B;
}

} // end of namespace Ice

namespace std {
template <typename T> struct hash<Ice::StringID<T>> {
  size_t operator()(const Ice::StringID<T> &Key) const {
    if (Key.hasStdString())
      return hash<std::string>()(Key.toString());
    return hash<Ice::StringPool::IDType>()(Key.getID());
  }
};
} // end of namespace std

#endif // SUBZERO_SRC_ICESTRINGPOOL_H
