container: hmap fixups

This commit is contained in:
Merry 2022-07-10 10:00:57 +01:00
parent 5b5c0130da
commit fc8d745cc1
5 changed files with 29 additions and 22 deletions

View File

@ -134,7 +134,7 @@ struct meta_byte_group {
bool is_all_empty_or_tombstone() const bool is_all_empty_or_tombstone() const
{ {
return match_empty_or_tombstone() const == 0xffff; return match_empty_or_tombstone() == 0xffff;
} }
meta_byte get(size_t index) const meta_byte get(size_t index) const
@ -154,7 +154,7 @@ struct meta_byte_group {
# define MCL_HMAP_MATCH_META_BYTE_GROUP(MATCH, ...) \ # define MCL_HMAP_MATCH_META_BYTE_GROUP(MATCH, ...) \
{ \ { \
for (const u32 match_result{MATCH}; match_result != 0; match_result &= match_result - 1) { \ for (u16 match_result{MATCH}; match_result != 0; match_result &= match_result - 1) { \
const size_t match_index{static_cast<size_t>(std::countr_zero(match_result))}; \ const size_t match_index{static_cast<size_t>(std::countr_zero(match_result))}; \
__VA_ARGS__ \ __VA_ARGS__ \
} \ } \
@ -162,7 +162,7 @@ struct meta_byte_group {
# define MCL_HMAP_MATCH_META_BYTE_GROUP_EXCEPT_LAST(MATCH, ...) \ # define MCL_HMAP_MATCH_META_BYTE_GROUP_EXCEPT_LAST(MATCH, ...) \
{ \ { \
for (const u32 match_result{(MATCH) & (0x7fff)}; match_result != 0; match_result &= match_result - 1) { \ for (u16 match_result{static_cast<u16>((MATCH) & (0x7fff))}; match_result != 0; match_result &= match_result - 1) { \
const size_t match_index{static_cast<size_t>(std::countr_zero(match_result))}; \ const size_t match_index{static_cast<size_t>(std::countr_zero(match_result))}; \
__VA_ARGS__ \ __VA_ARGS__ \
} \ } \

View File

@ -9,6 +9,7 @@ namespace mcl::detail {
template<typename ValueType> template<typename ValueType>
union slot_union { union slot_union {
slot_union() {} slot_union() {}
~slot_union() {}
ValueType value; ValueType value;
}; };

View File

@ -16,8 +16,10 @@
#include "mcl/container/detail/slot_union.hpp" #include "mcl/container/detail/slot_union.hpp"
#include "mcl/hash/xmrx.hpp" #include "mcl/hash/xmrx.hpp"
#include "mcl/hint/assume.hpp" #include "mcl/hint/assume.hpp"
#include "mcl/memory/overaligned_unique_ptr.hpp"
namespace mcl { namespace mcl {
template<typename KeyType, typename MappedType, typename Hash, typename Pred> template<typename KeyType, typename MappedType, typename Hash, typename Pred>
class hmap; class hmap;
@ -127,13 +129,15 @@ public:
using const_iterator = hmap_iterator<true, key_type, mapped_type, hasher, key_equal>; using const_iterator = hmap_iterator<true, key_type, mapped_type, hasher, key_equal>;
private: private:
using slot_type = detail::slot_union<value_type>;
static_assert(!std::is_reference_v<key_type>);
static_assert(!std::is_reference_v<mapped_type>);
static constexpr size_t group_size{detail::meta_byte_group::max_group_size}; static constexpr size_t group_size{detail::meta_byte_group::max_group_size};
static constexpr size_t average_max_group_load{group_size - 2}; static constexpr size_t average_max_group_load{group_size - 2};
using slot_type = detail::slot_union<value_type>;
using slot_ptr = std::unique_ptr<slot_type[]>;
using meta_byte_ptr = overaligned_unique_ptr<group_size, detail::meta_byte[]>;
static_assert(!std::is_reference_v<key_type>);
static_assert(!std::is_reference_v<mapped_type>);
public: public:
hmap() hmap()
{ {
@ -501,8 +505,8 @@ private:
// DEBUG_ASSERT(group_count != 0 && std::ispow2(group_count)); // DEBUG_ASSERT(group_count != 0 && std::ispow2(group_count));
group_index_mask = group_count - 1; group_index_mask = group_count - 1;
mbs = std::unique_ptr<detail::meta_byte[]>{new (std::align_val_t(group_size)) detail::meta_byte[group_count * group_size + 1]}; mbs = make_overaligned_unique_ptr_array<group_size, detail::meta_byte>(group_count * group_size + 1);
slots = std::unique_ptr<slot_type[]>{new slot_type[group_count * group_size]}; slots = slot_ptr{new slot_type[group_count * group_size]};
clear_metadata(); clear_metadata();
} }
@ -521,8 +525,8 @@ private:
std::size_t group_index_mask; std::size_t group_index_mask;
std::size_t empty_slots; std::size_t empty_slots;
std::size_t full_slots; std::size_t full_slots;
std::unique_ptr<detail::meta_byte[]> mbs; meta_byte_ptr mbs;
std::unique_ptr<slot_type[]> slots; slot_ptr slots;
}; };
} // namespace mcl } // namespace mcl

View File

@ -470,7 +470,7 @@ private:
{ {
group_type& g{groups[pos.group_index]}; group_type& g{groups[pos.group_index]};
g.slots[pos.slot_index].value->~value_type(); g.slots[pos.slot_index].value.~value_type();
--full_slots; --full_slots;
if (g.meta.is_any_empty()) { if (g.meta.is_any_empty()) {

View File

@ -4,6 +4,8 @@
// Reference: http://jonkagstrom.com/bit-mixer-construction/ // Reference: http://jonkagstrom.com/bit-mixer-construction/
#pragma once
#include <functional> #include <functional>
#include "mcl/bit/rotate.hpp" #include "mcl/bit/rotate.hpp"