9#include <rapidfuzz/details/GrowingHashmap.hpp>
10#include <rapidfuzz/details/Matrix.hpp>
11#include <rapidfuzz/details/Range.hpp>
12#include <rapidfuzz/details/intrinsics.hpp>
17struct BitvectorHashmap {
18 BitvectorHashmap() : m_map()
21 template <
typename CharT>
22 uint64_t get(CharT key)
const noexcept
24 return m_map[lookup(
static_cast<uint64_t
>(key))].value;
27 template <
typename CharT>
28 uint64_t& operator[](CharT key)
noexcept
30 uint32_t i = lookup(
static_cast<uint64_t
>(key));
31 m_map[i].key =
static_cast<uint64_t
>(key);
32 return m_map[i].value;
40 uint32_t lookup(uint64_t key)
const noexcept
42 uint32_t i = key % 128;
44 if (!m_map[i].value || m_map[i].key == key)
return i;
46 uint64_t perturb = key;
48 i = (
static_cast<uint64_t
>(i) * 5 + perturb + 1) % 128;
49 if (!m_map[i].value || m_map[i].key == key)
return i;
59 std::array<MapElem, 128> m_map;
62struct PatternMatchVector {
63 PatternMatchVector() : m_extendedAscii()
66 template <
typename InputIt>
67 PatternMatchVector(
const Range<InputIt>& s) : m_extendedAscii()
72 size_t size() const noexcept
77 template <
typename InputIt>
78 void insert(
const Range<InputIt>& s)
noexcept
81 for (
const auto& ch : s) {
82 insert_mask(ch, mask);
87 template <
typename CharT>
88 void insert(CharT key, int64_t pos)
noexcept
90 insert_mask(key, UINT64_C(1) << pos);
93 uint64_t get(
char key)
const noexcept
96 return m_extendedAscii[
static_cast<uint8_t
>(key)];
99 template <
typename CharT>
100 uint64_t get(CharT key)
const noexcept
102 if (key >= 0 && key <= 255)
103 return m_extendedAscii[
static_cast<uint8_t
>(key)];
105 return m_map.get(key);
108 template <
typename CharT>
109 uint64_t get(
size_t block, CharT key)
const noexcept
116 void insert_mask(
char key, uint64_t mask)
noexcept
119 m_extendedAscii[
static_cast<uint8_t
>(key)] |= mask;
122 template <
typename CharT>
123 void insert_mask(CharT key, uint64_t mask)
noexcept
125 if (key >= 0 && key <= 255)
126 m_extendedAscii[
static_cast<uint8_t
>(key)] |= mask;
132 BitvectorHashmap m_map;
133 std::array<uint64_t, 256> m_extendedAscii;
136struct BlockPatternMatchVector {
137 BlockPatternMatchVector() =
delete;
139 BlockPatternMatchVector(
size_t str_len)
140 : m_block_count(ceil_div(str_len, 64)), m_map(nullptr), m_extendedAscii(256, m_block_count, 0)
143 template <
typename InputIt>
144 BlockPatternMatchVector(
const Range<InputIt>& s) : BlockPatternMatchVector(s.size())
149 ~BlockPatternMatchVector()
154 size_t size() const noexcept
156 return m_block_count;
159 template <
typename CharT>
160 void insert(
size_t block, CharT ch,
int pos)
noexcept
162 uint64_t mask = UINT64_C(1) << pos;
163 insert_mask(block, ch, mask);
172 template <
typename InputIt>
173 void insert(
const Range<InputIt>& s)
noexcept
177 for (
auto iter = s.begin(); iter != s.end(); ++iter, ++i) {
178 size_t block = i / 64;
179 insert_mask(block, *iter, mask);
180 mask = rotl(mask, 1);
184 template <
typename CharT>
185 void insert_mask(
size_t block, CharT key, uint64_t mask)
noexcept
187 assert(block < size());
188 if (key >= 0 && key <= 255)
189 m_extendedAscii[
static_cast<uint8_t
>(key)][block] |= mask;
191 if (!m_map) m_map =
new BitvectorHashmap[m_block_count];
192 m_map[block][key] |= mask;
196 void insert_mask(
size_t block,
char key, uint64_t mask)
noexcept
198 insert_mask(block,
static_cast<uint8_t
>(key), mask);
201 template <
typename CharT>
202 uint64_t get(
size_t block, CharT key)
const noexcept
204 if (key >= 0 && key <= 255)
205 return m_extendedAscii[
static_cast<uint8_t
>(key)][block];
207 return m_map[block].get(key);
212 uint64_t get(
size_t block,
char ch)
const noexcept
214 return get(block,
static_cast<uint8_t
>(ch));
218 size_t m_block_count;
219 BitvectorHashmap* m_map;
220 BitMatrix<uint64_t> m_extendedAscii;