@@ -1448,6 +1448,18 @@ namespace hud
14481448 {
14491449 // Move elements to new buffer if any
14501450 // Relocate slots to newly allocated buffer
1451+ // iterate_over_full_slots(old_control_ptr, old_slot_ptr, [this](control_type *control_ptr, slot_type *slot_ptr)
1452+ // {
1453+ // // Compute the hash
1454+ // u64 hash {hasher_type {}(slot_ptr->key())};
1455+ // // Find H1 slot index
1456+ // u64 h1 {H1(hash)};
1457+ // usize slot_index {find_first_empty_or_deleted(control_ptr_, max_slot_count_, h1)};
1458+ // // Save h2 in control h1 index
1459+ // control::set_h2(control_ptr_, slot_index, H2(hash), max_slot_count_);
1460+ // // Move old slot to new slot
1461+ // hud::memory::move_or_copy_construct_object_then_destroy(slot_ptr_ + slot_index, hud::move(*slot_ptr)); });
1462+
14511463 auto [control_full_or_sentinel, slot_full_or_sentinel] = skip_empty_or_deleted (old_control_ptr, old_slot_ptr);
14521464 while (control_full_or_sentinel != old_control_ptr + old_max_slot_count)
14531465 {
@@ -1681,6 +1693,54 @@ namespace hud
16811693 }
16821694 }
16831695
1696+ constexpr void iterate_over_full_slots (control_type *control_ptr, auto *slot_ptr, auto callback) noexcept
1697+ {
1698+ // When max slot count is less than the probing group
1699+ // We have cloned control in the group
1700+ // In this case, we start probing at the sentinel instead of 0
1701+ if (max_slot_count_ < group_type::SLOT_PER_GROUP - 1 )
1702+ {
1703+ group_type group {control_ptr_sentinel ()};
1704+
1705+ // In the case of constant expression
1706+ // If the hashmap is empty, slot_ptr is nullptr, we don't want to decrement the pointer in the case
1707+ // In a non constant expression slot_ptr is located after control in the same memory layout,
1708+ // we can safely decrement as soon as we don't read the value
1709+ if (hud::is_constant_evaluated ())
1710+ {
1711+ // Iterate over cloned control bytes
1712+ for (u32 full_index : group.mask_of_full_slot ())
1713+ {
1714+ callback (control_ptr + full_index, slot_ptr + full_index);
1715+ }
1716+ }
1717+ else
1718+ {
1719+ --slot_ptr;
1720+ // Iterate over cloned control bytes
1721+ for (u32 full_index : group.mask_of_full_slot ())
1722+ {
1723+ callback (control_ptr + full_index, slot_ptr + full_index);
1724+ }
1725+ }
1726+ }
1727+ else
1728+ {
1729+ size_t remaining_slots {count ()};
1730+ while (remaining_slots != 0 )
1731+ {
1732+ group_type group {control_ptr};
1733+ for (u32 full_index : group.mask_of_full_slot ())
1734+ {
1735+ callback (control_ptr + full_index, slot_ptr + full_index);
1736+ --remaining_slots;
1737+ }
1738+ control_ptr += group_type::SLOT_PER_GROUP ;
1739+ slot_ptr += group_type::SLOT_PER_GROUP ;
1740+ }
1741+ }
1742+ }
1743+
16841744 template <typename slot_t >
16851745 [[nodiscard]] constexpr hud::pair<control_type *, slot_t *> skip_empty_or_deleted (control_type *control_ptr, slot_t *slot_ptr) const noexcept
16861746 {
0 commit comments