//===------- string_pool.h - Thread-safe pool for strings -------*- 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
//
//===----------------------------------------------------------------------===//
//
// Contains a thread-safe string pool. Strings are ref-counted, but not
// automatically deallocated. Unused entries can be cleared by calling
// StringPool::clearDeadEntries.
//
//===----------------------------------------------------------------------===//

#ifndef ORC_RT_STRING_POOL_H
#define ORC_RT_STRING_POOL_H

#include <atomic>
#include <cassert>
#include <functional>
#include <mutex>
#include <string>
#include <unordered_map>

namespace orc_rt {

class PooledStringPtr;

/// String pool for strings names used by the ORC runtime.
class StringPool {
  friend class PooledStringPtr;

public:
  /// Destroy a StringPool.
  ~StringPool();

  /// Create a string pointer from the given string.
  PooledStringPtr intern(std::string S);

  /// Remove from the pool any entries that are no longer referenced.
  void clearDeadEntries();

  /// Returns true if the pool is empty.
  bool empty() const;

private:
  using RefCountType = std::atomic<size_t>;
  using PoolMap = std::unordered_map<std::string, RefCountType>;
  using PoolMapEntry = PoolMap::value_type;
  mutable std::mutex PoolMutex;
  PoolMap Pool;
};

/// Pointer to a pooled string.
class PooledStringPtr {
  friend class StringPool;
  friend struct std::hash<PooledStringPtr>;

public:
  PooledStringPtr() = default;
  PooledStringPtr(std::nullptr_t) {}
  PooledStringPtr(const PooledStringPtr &Other) : S(Other.S) {
    if (S)
      ++S->second;
  }

  PooledStringPtr &operator=(const PooledStringPtr &Other) {
    if (S) {
      assert(S->second && "Releasing PooledStringPtr with zero ref count");
      --S->second;
    }
    S = Other.S;
    if (S)
      ++S->second;
    return *this;
  }

  PooledStringPtr(PooledStringPtr &&Other) : S(nullptr) {
    std::swap(S, Other.S);
  }

  PooledStringPtr &operator=(PooledStringPtr &&Other) {
    if (S) {
      assert(S->second && "Releasing PooledStringPtr with zero ref count");
      --S->second;
    }
    S = nullptr;
    std::swap(S, Other.S);
    return *this;
  }

  ~PooledStringPtr() {
    if (S) {
      assert(S->second && "Releasing PooledStringPtr with zero ref count");
      --S->second;
    }
  }

  explicit operator bool() const { return S; }

  const std::string &operator*() const { return S->first; }

  friend bool operator==(const PooledStringPtr &LHS,
                         const PooledStringPtr &RHS) {
    return LHS.S == RHS.S;
  }

  friend bool operator!=(const PooledStringPtr &LHS,
                         const PooledStringPtr &RHS) {
    return !(LHS == RHS);
  }

  friend bool operator<(const PooledStringPtr &LHS,
                        const PooledStringPtr &RHS) {
    return LHS.S < RHS.S;
  }

private:
  using PoolEntry = StringPool::PoolMapEntry;
  using PoolEntryPtr = PoolEntry *;

  PooledStringPtr(StringPool::PoolMapEntry *S) : S(S) {
    if (S)
      ++S->second;
  }

  PoolEntryPtr S = nullptr;
};

inline StringPool::~StringPool() {
#ifndef NDEBUG
  clearDeadEntries();
  assert(Pool.empty() && "Dangling references at pool destruction time");
#endif // NDEBUG
}

inline PooledStringPtr StringPool::intern(std::string S) {
  std::lock_guard<std::mutex> Lock(PoolMutex);
  PoolMap::iterator I;
  bool Added;
  std::tie(I, Added) = Pool.try_emplace(std::move(S), 0);
  return PooledStringPtr(&*I);
}

inline void StringPool::clearDeadEntries() {
  std::lock_guard<std::mutex> Lock(PoolMutex);
  for (auto I = Pool.begin(), E = Pool.end(); I != E;) {
    auto Tmp = I++;
    if (Tmp->second == 0)
      Pool.erase(Tmp);
  }
}

inline bool StringPool::empty() const {
  std::lock_guard<std::mutex> Lock(PoolMutex);
  return Pool.empty();
}

} // namespace orc_rt

namespace std {

// Make PooledStringPtrs hashable.
template <> struct hash<orc_rt::PooledStringPtr> {
  size_t operator()(const orc_rt::PooledStringPtr &A) const {
    return hash<orc_rt::PooledStringPtr::PoolEntryPtr>()(A.S);
  }
};

} // namespace std

#endif // ORC_RT_REF_COUNTED_STRING_POOL_H
