ESBMC
Efficient SMT-based Context-Bounded Model Checker
Loading...
Searching...
No Matches
string_pool.h
Go to the documentation of this file.
1#ifndef STRING_POOL_H
2#define STRING_POOL_H
3
4#include <array>
5#include <atomic>
6#include <cassert>
7#include <cstddef>
8#include <memory>
9#include <shared_mutex>
10#include <string>
11#include <string_view>
12#include <unordered_map>
13
15{
16public:
17 using is_transparent = void;
18
19 size_t operator()(std::string_view sv) const
20 {
21 return std::hash<std::string_view>{}(sv);
22 }
23};
24
26{
27public:
28 using is_transparent = void;
29
30 bool operator()(std::string_view a, std::string_view b) const
31 {
32 return a == b;
33 }
34};
35
36// Append-only interning pool with lock-free reads.
37//
38// Storage is a segmented arena: a fixed-size table of chunk pointers, each
39// chunk a contiguous array of std::string. Chunks are heap-allocated lazily
40// under the writer mutex and published atomically. Once an index has been
41// returned from get(), the slot at that index is immutable; readers can
42// therefore look it up without any locking. The writer mutex only guards the
43// hash table and chunk allocation.
45{
46public:
47 template <typename T>
48 unsigned operator[](const T &s)
49 {
50 return get(std::string_view(s));
51 }
52
54 {
55 // allocate empty string -- this gets index 0
56 get(std::string_view(""));
57 }
58 ~string_pool() = default;
59
60 // the pointer is guaranteed to be stable
61 const char *c_str(size_t no) const
62 {
63 return get_string(no).c_str();
64 }
65
66 // the reference is guaranteed to be stable
67 const std::string &get_string(size_t no) const
68 {
69 assert(no < published_size.load(std::memory_order_acquire));
70 chunk_t *chunk = chunks[no >> CHUNK_SHIFT].load(std::memory_order_acquire);
71 return chunk->data[no & CHUNK_MASK];
72 }
73
74protected:
75 static constexpr size_t CHUNK_SHIFT = 12;
76 static constexpr size_t CHUNK_SIZE = size_t{1} << CHUNK_SHIFT; // 4096
77 static constexpr size_t CHUNK_MASK = CHUNK_SIZE - 1;
78 // 2048 chunks * 4096 strings = 8M unique strings ceiling.
79 static constexpr size_t MAX_CHUNKS = 2048;
80
81 struct chunk_t
82 {
83 std::string data[CHUNK_SIZE];
84 };
85
86 typedef std::unordered_map<
87 std::string_view,
88 unsigned,
92
93 // Writer-side state, guarded by pool_mutex.
95 std::array<std::unique_ptr<chunk_t>, MAX_CHUNKS> chunk_storage{};
96
97 // Reader-visible state. chunks[i] is published with release before
98 // published_size is incremented past any index belonging to that chunk.
99 std::array<std::atomic<chunk_t *>, MAX_CHUNKS> chunks{};
100 std::atomic<size_t> published_size{0};
101
102 mutable std::shared_mutex pool_mutex;
103
104 unsigned get(std::string_view s);
105};
106
108{
109 static string_pool ret;
110 return ret;
111}
112
113#endif
Definition string_pool.h:45
const char * c_str(size_t no) const
Definition string_pool.h:61
std::atomic< size_t > published_size
Definition string_pool.h:100
unsigned get(std::string_view s)
Definition string_pool.cpp:7
string_pool()
Definition string_pool.h:53
unsigned operator[](const T &s)
Definition string_pool.h:48
static constexpr size_t MAX_CHUNKS
Definition string_pool.h:79
std::unordered_map< std::string_view, unsigned, string_view_hash, string_view_equal > hash_tablet
Definition string_pool.h:91
const std::string & get_string(size_t no) const
Definition string_pool.h:67
std::array< std::unique_ptr< chunk_t >, MAX_CHUNKS > chunk_storage
Definition string_pool.h:95
std::array< std::atomic< chunk_t * >, MAX_CHUNKS > chunks
Definition string_pool.h:99
static constexpr size_t CHUNK_SIZE
Definition string_pool.h:76
hash_tablet hash_table
Definition string_pool.h:94
static constexpr size_t CHUNK_SHIFT
Definition string_pool.h:75
static constexpr size_t CHUNK_MASK
Definition string_pool.h:77
std::shared_mutex pool_mutex
Definition string_pool.h:102
~string_pool()=default
Definition string_pool.h:26
bool operator()(std::string_view a, std::string_view b) const
Definition string_pool.h:30
void is_transparent
Definition string_pool.h:28
Definition string_pool.h:15
void is_transparent
Definition string_pool.h:17
size_t operator()(std::string_view sv) const
Definition string_pool.h:19
#define T
Definition exp2f.c:24
string_pool & get_string_pool()
Definition string_pool.h:107
Definition string_pool.h:82
std::string data[CHUNK_SIZE]
Definition string_pool.h:83