32 static constexpr std::uint32_t
NPOS = 0xFFFFFFFFU;
40 [[nodiscard]]
auto size() const noexcept -> std::
size_t {
return m_count; }
44 [[nodiscard]]
auto empty() const noexcept ->
bool {
return m_count == 0; }
49 [[nodiscard]]
auto find(std::uint64_t key)
const noexcept -> std::uint32_t {
50 std::size_t slot = hash(key) & m_mask;
51 while (m_slots[slot].used) {
52 if (m_slots[slot].key == key) {
53 return m_slots[slot].value;
55 slot = (slot + 1) & m_mask;
63 [[nodiscard]]
auto contains(std::uint64_t key)
const noexcept ->
bool {
70 auto insert(std::uint64_t key, std::uint32_t value) ->
void {
71 if ((m_count + 1) * LOAD_FACTOR_DEN >= m_slots.size() * LOAD_FACTOR_NUM) {
72 rehash(m_slots.size() * 2);
74 std::size_t slot = hash(key) & m_mask;
75 while (m_slots[slot].used) {
76 if (m_slots[slot].key == key) {
77 m_slots[slot].value = value;
80 slot = (slot + 1) & m_mask;
82 m_slots[slot] = Slot {key, value,
true};
88 auto erase(std::uint64_t key) ->
void {
89 std::size_t slot = hash(key) & m_mask;
90 while (m_slots[slot].used) {
91 if (m_slots[slot].key == key) {
95 slot = (slot + 1) & m_mask;
101 for (
auto& slot : m_slots) {
109 std::uint64_t key {0};
110 std::uint32_t value {0};
114 static constexpr std::size_t INITIAL_CAPACITY = 1024;
115 static constexpr std::size_t LOAD_FACTOR_NUM = 7;
116 static constexpr std::size_t LOAD_FACTOR_DEN = 10;
123 [[nodiscard]]
static auto hash(std::uint64_t key)
noexcept -> std::size_t {
125 key *= 0xFF51AFD7ED558CCDULL;
127 key *= 0xC4CEB9FE1A85EC53ULL;
129 return static_cast<std::size_t
>(key);
136 auto remove_at(std::size_t hole) ->
void {
137 m_slots[hole].used =
false;
139 std::size_t next = (hole + 1) & m_mask;
140 while (m_slots[next].used) {
141 const std::size_t home = hash(m_slots[next].key) & m_mask;
146 (hole <= next) ? (home <= hole || home > next) : (home <= hole && home > next);
148 m_slots[hole] = m_slots[next];
149 m_slots[next].used =
false;
152 next = (next + 1) & m_mask;
159 auto rehash(std::size_t new_capacity) ->
void {
160 std::vector<Slot> old = std::move(m_slots);
161 m_slots.assign(new_capacity, Slot {});
162 m_mask = new_capacity - 1;
164 for (
const auto& slot : old) {
166 insert(slot.key, slot.value);
171 std::vector<Slot> m_slots;
172 std::size_t m_count {0};
173 std::size_t m_mask {0};