Path: blob/main/contrib/llvm-project/compiler-rt/lib/orc/string_pool.h
39566 views
//===------- string_pool.h - Thread-safe pool for strings -------*- C++ -*-===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// Contains a thread-safe string pool. Strings are ref-counted, but not9// automatically deallocated. Unused entries can be cleared by calling10// StringPool::clearDeadEntries.11//12//===----------------------------------------------------------------------===//1314#ifndef ORC_RT_STRING_POOL_H15#define ORC_RT_STRING_POOL_H1617#include <atomic>18#include <cassert>19#include <functional>20#include <mutex>21#include <string>22#include <unordered_map>2324namespace __orc_rt {2526class PooledStringPtr;2728/// String pool for strings names used by the ORC runtime.29class StringPool {30friend class PooledStringPtr;3132public:33/// Destroy a StringPool.34~StringPool();3536/// Create a string pointer from the given string.37PooledStringPtr intern(std::string S);3839/// Remove from the pool any entries that are no longer referenced.40void clearDeadEntries();4142/// Returns true if the pool is empty.43bool empty() const;4445private:46using RefCountType = std::atomic<size_t>;47using PoolMap = std::unordered_map<std::string, RefCountType>;48using PoolMapEntry = PoolMap::value_type;49mutable std::mutex PoolMutex;50PoolMap Pool;51};5253/// Pointer to a pooled string.54class PooledStringPtr {55friend class StringPool;56friend struct std::hash<PooledStringPtr>;5758public:59PooledStringPtr() = default;60PooledStringPtr(std::nullptr_t) {}61PooledStringPtr(const PooledStringPtr &Other) : S(Other.S) {62if (S)63++S->second;64}6566PooledStringPtr &operator=(const PooledStringPtr &Other) {67if (S) {68assert(S->second && "Releasing PooledStringPtr with zero ref count");69--S->second;70}71S = Other.S;72if (S)73++S->second;74return *this;75}7677PooledStringPtr(PooledStringPtr &&Other) : S(nullptr) {78std::swap(S, Other.S);79}8081PooledStringPtr &operator=(PooledStringPtr &&Other) {82if (S) {83assert(S->second && "Releasing PooledStringPtr with zero ref count");84--S->second;85}86S = nullptr;87std::swap(S, Other.S);88return *this;89}9091~PooledStringPtr() {92if (S) {93assert(S->second && "Releasing PooledStringPtr with zero ref count");94--S->second;95}96}9798explicit operator bool() const { return S; }99100const std::string &operator*() const { return S->first; }101102friend bool operator==(const PooledStringPtr &LHS,103const PooledStringPtr &RHS) {104return LHS.S == RHS.S;105}106107friend bool operator!=(const PooledStringPtr &LHS,108const PooledStringPtr &RHS) {109return !(LHS == RHS);110}111112friend bool operator<(const PooledStringPtr &LHS,113const PooledStringPtr &RHS) {114return LHS.S < RHS.S;115}116117private:118using PoolEntry = StringPool::PoolMapEntry;119using PoolEntryPtr = PoolEntry *;120121PooledStringPtr(StringPool::PoolMapEntry *S) : S(S) {122if (S)123++S->second;124}125126PoolEntryPtr S = nullptr;127};128129inline StringPool::~StringPool() {130#ifndef NDEBUG131clearDeadEntries();132assert(Pool.empty() && "Dangling references at pool destruction time");133#endif // NDEBUG134}135136inline PooledStringPtr StringPool::intern(std::string S) {137std::lock_guard<std::mutex> Lock(PoolMutex);138PoolMap::iterator I;139bool Added;140std::tie(I, Added) = Pool.try_emplace(std::move(S), 0);141return PooledStringPtr(&*I);142}143144inline void StringPool::clearDeadEntries() {145std::lock_guard<std::mutex> Lock(PoolMutex);146for (auto I = Pool.begin(), E = Pool.end(); I != E;) {147auto Tmp = I++;148if (Tmp->second == 0)149Pool.erase(Tmp);150}151}152153inline bool StringPool::empty() const {154std::lock_guard<std::mutex> Lock(PoolMutex);155return Pool.empty();156}157158} // end namespace __orc_rt159160namespace std {161162// Make PooledStringPtrs hashable.163template <> struct hash<__orc_rt::PooledStringPtr> {164size_t operator()(const __orc_rt::PooledStringPtr &A) const {165return hash<__orc_rt::PooledStringPtr::PoolEntryPtr>()(A.S);166}167};168169} // namespace std170171#endif // ORC_RT_REF_COUNTED_STRING_POOL_H172173174