28 typename Hash = std::hash<Key>,
29 typename KeyEqual = std::equal_to<Key>
61 using map_type = std::conditional_t<Is_Const, const RefCountingHashMap, RefCountingHashMap>;
62 using bucket_type = std::conditional_t<Is_Const, const typename map_type::entry_type, typename map_type::entry_type>;
63 using pointer = std::conditional_t<Is_Const, const typename map_type::const_pointer, typename map_type::pointer>;
64 using reference = std::conditional_t<Is_Const, const typename map_type::const_reference, typename map_type::reference>;
100 using map_type = std::conditional_t<Is_Const, const RefCountingHashMap, RefCountingHashMap>;
101 using bucket_type = std::conditional_t<Is_Const, const typename map_type::entry_type, typename map_type::entry_type>;
102 using pointer = std::conditional_t<Is_Const, const typename map_type::const_pointer, typename map_type::pointer>;
103 using reference = std::conditional_t<Is_Const, const typename map_type::const_reference, typename map_type::reference>;
176 if (bucket_count == 0)
177 throw std::invalid_argument(
"bucket_count must not be zero");
189 if (p->probe_length != 0)
217 const auto hash =
h_(key);
230 M_insist(distance > 0,
"the distance must not be 0, otherwise we would have run into the likely case above");
234 M_insist(probe !=
bucket,
"the probed slot must not be the original bucket as the distance is not 0 and always "
235 "less than capacity");
254 const auto hash =
h_(key);
263 return std::make_pair(
iterator(*
this, probe),
false);
264 ++insertion_probe_length;
265 insertion_probe_distance += insertion_probe_length;
266 probe =
table_ +
masked(index + insertion_probe_distance);
273 return std::make_pair(
iterator(*
this, probe),
true);
277 const auto hash =
h_(key);
286 while (probe->
probe_length != 0
and lookup_probe_length < bucket->probe_length) {
289 ++lookup_probe_length;
290 lookup_probe_distance += lookup_probe_length;
296 size_type lookup_probe_distance = (lookup_probe_length * (lookup_probe_length - 1)) >> 1;
297 while (lookup_probe_length != 0) {
301 --lookup_probe_length;
302 lookup_probe_distance -= lookup_probe_length;
312 const auto hash =
h_(key);
322 if (
eq_(key, it->first))
328 if (
eq_(key, it->first))
335 for_all(key, [&cnt](
auto) { ++cnt; });
342 M_insist((new_capacity & (new_capacity - 1)) == 0,
"not a power of 2");
352 for (
auto runner = old_table,
end = old_table + old_capacity; runner !=
end; ++runner) {
353 if (runner->probe_length) {
354 auto &key_ref =
const_cast<key_type&
>(runner->value.first);
366 new_capacity = std::max<decltype(new_capacity)>(new_capacity, std::ceil(
size() /
max_load_factor()));
367 new_capacity = ceil_to_pow_2(new_capacity);
383 auto &entry = map.
table_[i];
384 out <<
'[' << std::setw(log10) << i <<
"]: probe length = " << std::setw(log10) << entry.
probe_length;
385 if (entry.probe_length) {
386 out <<
", value = (" << entry.value.first <<
", " << entry.value.second <<
')';
393 void dump(std::ostream &out)
const { out << *
this; out.flush(); }
401 throw std::runtime_error(
"allocation failed");
bool M_EXPORT equal(const T &first, const U &second)
Checks whether first and second are equal considering permutations.
uint32_t probe_length
Counts the length of the probe sequence.
value_type value
The value stored in this entry.
std::conditional_t< Is_Const, const typename map_type::entry_type, typename map_type::entry_type > bucket_type
the_bucket_iterator(map_type &map, size_type bucket_index)
size_type probe_length() const
typename map_type::size_type size_type
the_bucket_iterator & operator++(int)
std::conditional_t< Is_Const, const RefCountingHashMap, RefCountingHashMap > map_type
static constexpr bool Is_Const
the_bucket_iterator & operator++()
size_type current_index() const
size_type probe_distance() const
size_type bucket_index() const
reference operator*() const
bucket_type * bucket() const
std::conditional_t< Is_Const, const typename map_type::const_reference, typename map_type::reference > reference
pointer operator->() const
the_iterator operator++(int)
std::conditional_t< Is_Const, const RefCountingHashMap, RefCountingHashMap > map_type
std::conditional_t< Is_Const, const typename map_type::entry_type, typename map_type::entry_type > bucket_type
reference operator*() const
pointer operator->() const
the_iterator & operator++()
static constexpr bool Is_Const
std::conditional_t< Is_Const, const typename map_type::const_reference, typename map_type::reference > reference
bool operator==(the_iterator other) const
the_iterator(map_type &map, entry_type *bucket)
bool operator!=(the_iterator other) const
const_iterator begin() const
size_type masked(size_type index) const
const_iterator end() const
the_iterator< false > iterator
void rehash(std::size_t new_capacity)
Rehash all elements.
const_bucket_iterator bucket(const key_type &key) const
const_iterator cend() const
const value_type & const_reference
size_type watermark_high() const
the_bucket_iterator< false > bucket_iterator
M_LCOV_EXCL_START friend std::ostream & operator<<(std::ostream &out, const RefCountingHashMap &map)
void dump(std::ostream &out) const
size_type count(const key_type &key) const
size_type capacity() const
static entry_type * allocate(size_type n, entry_type *hint=nullptr)
std::pair< iterator, bool > insert_without_duplicates(key_type key, mapped_type value)
std::pair< const Key, Value > value_type
size_type capacity_
The total number of entries allocated in the table.
size_type size_
The number of occupied entries in the table.
std::ptrdiff_t difference_type
const_iterator find(const key_type &key) const
const_iterator cbegin() const
iterator insert_with_duplicates(key_type key, mapped_type value)
float max_load_factor() const
float max_load_factor_
The maximum load factor before resizing.
void max_load_factor(float ml)
bucket_iterator bucket(const key_type &key)
the_bucket_iterator< true > const_bucket_iterator
RefCountingHashMap(size_type bucket_count, const hasher &hash=hasher(), const key_equal &equal=key_equal())
the_iterator< true > const_iterator
void for_all(const key_type &key, std::function< void(const value_type &)> callback) const
iterator find(const key_type &key)
size_type watermark_high_
The maximum size before resizing.
entry_type * table_
A pointer to the beginning of the table.
void resize(std::size_t new_capacity)
const value_type * const_pointer
void for_all(const key_type &key, std::function< void(value_type &)> callback)
This class holds a SQL attribute value.