6#ifndef METALL_CONTAINER_CONCURRENT_STRING_KEY_STORE_HPP
7#define METALL_CONTAINER_CONCURRENT_STRING_KEY_STORE_HPP
31 typename allocator_type = metall::manager::allocator_type<std::byte>>
35 using other_allocator =
36 typename std::allocator_traits<allocator_type>::template
rebind_alloc<T>;
39 using other_scoped_allocator =
43 using internal_string_type =
45 using internal_value_type = std::tuple<internal_string_type, _value_type>;
48 internal_id_type, internal_value_type, std::hash<internal_id_type>,
49 std::equal_to<internal_id_type>,
50 other_scoped_allocator<
51 std::pair<const internal_id_type, internal_value_type>>>;
54 static constexpr internal_id_type k_max_internal_id =
55 std::numeric_limits<internal_id_type>::max();
73 const allocator_type &
allocator = allocator_type())
81 : m_unique(other.m_unique),
82 m_hash_seed(other.m_hash_seed),
83 m_map(other.m_map,
alloc) {}
91 : m_unique(other.m_unique),
92 m_hash_seed(other.m_hash_seed),
117 internal_value_type{std::allocator_arg, m_map.get_allocator()};
138 m_map.emplace(
internal_id, internal_value_type{std::allocator_arg,
139 m_map.get_allocator(),
157 std::allocator_arg, m_map.get_allocator(),
166 m_max_id_probe_distance = 0;
179 std::size_t
size()
const {
return m_map.size(); }
185 const auto &
key = std::get<0>(
position.m_iterator->second);
203 return std::get<1>(
position.m_iterator->second);
262 insert(std::get<0>(
elem.second), std::move(std::get<1>(
elem.second)));
281 internal_id_type priv_generate_internal_id(
const key_type &
key) {
289 m_max_id_probe_distance = std::max(
distance, m_max_id_probe_distance);
297 internal_id_type priv_find_internal_id(
const key_type &
key)
const {
300 for (std::size_t
d = 0;
d <= m_max_id_probe_distance; ++
d) {
302 if (
itr == m_map.end()) {
306 if (std::get<0>(
itr->second) ==
key) {
312 return k_max_internal_id;
318 internal_id_type priv_find_or_generate_internal_id(
const key_type &
key) {
327 static internal_id_type priv_hash_key(
const key_type &
key,
329#ifdef METALL_CONTAINER_STRING_KEY_STORE_USE_SIMPLE_HASH
332 auto hash = (internal_id_type)metall::mtlldetail::murmur_hash_64a(
335 if (hash == k_max_internal_id) {
336 hash = priv_increment_internal_id(hash);
338 assert(hash != k_max_internal_id);
342 static internal_id_type priv_increment_internal_id(
343 const internal_id_type
id) {
344 const auto new_id = (
id + 1) % k_max_internal_id;
349 bool m_unique{
false};
351 map_type m_map{allocator_type{}};
352 std::size_t m_max_id_probe_distance{0};