Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 25 additions & 33 deletions bytell_hash_map.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,13 +107,14 @@ struct sherwood_v8_block

static sherwood_v8_block * empty_block()
{
static std::array<int8_t, BlockSize> empty_bytes = []
{
std::array<int8_t, BlockSize> result;
result.fill(sherwood_v8_constants<>::magic_for_empty);
return result;
alignas(sherwood_v8_block) static std::array<std::byte, sizeof(sherwood_v8_block)> storage{};
static const bool initialized = [] {
auto *block = reinterpret_cast<sherwood_v8_block *>(storage.data());
block->fill_control_bytes(sherwood_v8_constants<>::magic_for_empty);
return true;
}();
return reinterpret_cast<sherwood_v8_block *>(&empty_bytes);
(void)initialized;
return reinterpret_cast<sherwood_v8_block *>(storage.data());
}

int first_empty_index() const
Expand Down Expand Up @@ -523,7 +524,7 @@ class sherwood_v8_table : private ByteAlloc, private Hasher, private Equal

void rehash(size_t num_items)
{
num_items = std::max(num_items, static_cast<size_t>(std::ceil(num_elements / static_cast<double>(_max_load_factor))));
num_items = std::max(num_items, static_cast<size_t>(std::ceil(static_cast<double>(num_elements) / static_cast<double>(_max_load_factor))));
if (num_items == 0)
{
reset_to_empty_state();
Expand All @@ -535,14 +536,12 @@ class sherwood_v8_table : private ByteAlloc, private Hasher, private Equal
size_t num_blocks = num_items / BlockSize;
if (num_items % BlockSize)
++num_blocks;
size_t memory_requirement = calculate_memory_requirement(num_blocks);
unsigned char * new_memory = &*AllocatorTraits::allocate(*this, memory_requirement);

BlockPointer new_buckets = reinterpret_cast<BlockPointer>(new_memory);
const size_t total_blocks = num_blocks + 1; // include sentinel block
BlockPointer new_buckets = AllocatorTraits::allocate(*this, total_blocks);

BlockPointer special_end_item = new_buckets + num_blocks;
for (BlockPointer it = new_buckets; it <= special_end_item; ++it)
for (BlockPointer it = new_buckets, end = new_buckets + total_blocks; it != end; ++it) {
it->fill_control_bytes(Constants::magic_for_empty);
}
using std::swap;
swap(entries, new_buckets);
swap(num_slots_minus_one, num_items);
Expand Down Expand Up @@ -749,7 +748,7 @@ class sherwood_v8_table : private ByteAlloc, private Hasher, private Equal

size_t num_buckets_for_reserve(size_t num_elements) const
{
return static_cast<size_t>(std::ceil(num_elements / static_cast<double>(_max_load_factor)));
return static_cast<size_t>(std::ceil(static_cast<double>(num_elements) / static_cast<double>(_max_load_factor)));
}
void rehash_for_other_container(const sherwood_v8_table & other)
{
Expand All @@ -760,7 +759,7 @@ class sherwood_v8_table : private ByteAlloc, private Hasher, private Equal
if (!num_slots_minus_one)
return true;
else
return num_elements + 1 > (num_slots_minus_one + 1) * static_cast<double>(_max_load_factor);
return static_cast<double>(num_elements + 1U) > static_cast<double>(num_slots_minus_one + 1U) * static_cast<double>(_max_load_factor);
}

void swap_pointers(sherwood_v8_table & other)
Expand Down Expand Up @@ -808,7 +807,7 @@ class sherwood_v8_table : private ByteAlloc, private Hasher, private Equal
}
int8_t jump_index() const
{
return Constants::distance_from_metadata(metadata());
return static_cast<int8_t>(Constants::distance_from_metadata(metadata()));
}
int8_t metadata() const
{
Expand Down Expand Up @@ -969,25 +968,18 @@ class sherwood_v8_table : private ByteAlloc, private Hasher, private Equal
rehash(std::max(size_t(10), 2 * bucket_count()));
}

size_t calculate_memory_requirement(size_t num_blocks)
{
size_t memory_required = sizeof(BlockType) * num_blocks;
memory_required += BlockSize; // for metadata of past-the-end pointer
return memory_required;
}

void deallocate_data(BlockPointer begin, size_t num_slots_minus_one)
{
if (begin == BlockType::empty_block())
return;

++num_slots_minus_one;
size_t num_blocks = num_slots_minus_one / BlockSize;
if (num_slots_minus_one % BlockSize)
const size_t num_slots = num_slots_minus_one + 1;
size_t num_blocks = num_slots / BlockSize;
if (num_slots % BlockSize)
++num_blocks;
size_t memory = calculate_memory_requirement(num_blocks);
unsigned char * as_byte_pointer = reinterpret_cast<unsigned char *>(begin);
AllocatorTraits::deallocate(*this, typename AllocatorTraits::pointer(as_byte_pointer), memory);
// Account for sentinel block used for the metadata past-the-end pointer.
++num_blocks;
AllocatorTraits::deallocate(*this, begin, num_blocks);
}

void reset_to_empty_state()
Expand Down Expand Up @@ -1072,7 +1064,7 @@ class bytell_hash_map
E,
detailv8::KeyOrValueEquality<K, std::pair<K, V>, E>,
A,
typename std::allocator_traits<A>::template rebind_alloc<unsigned char>,
typename std::allocator_traits<A>::template rebind_alloc<detailv8::sherwood_v8_block<std::pair<K, V>, detailv8::CalculateBytellBlockSize<K, V>::value>>,
detailv8::CalculateBytellBlockSize<K, V>::value
>
{
Expand All @@ -1085,7 +1077,7 @@ class bytell_hash_map
E,
detailv8::KeyOrValueEquality<K, std::pair<K, V>, E>,
A,
typename std::allocator_traits<A>::template rebind_alloc<unsigned char>,
typename std::allocator_traits<A>::template rebind_alloc<detailv8::sherwood_v8_block<std::pair<K, V>, detailv8::CalculateBytellBlockSize<K, V>::value>>,
detailv8::CalculateBytellBlockSize<K, V>::value
>;
public:
Expand Down Expand Up @@ -1193,7 +1185,7 @@ class bytell_hash_set
E,
detailv8::functor_storage<bool, E>,
A,
typename std::allocator_traits<A>::template rebind_alloc<unsigned char>,
typename std::allocator_traits<A>::template rebind_alloc<detailv8::sherwood_v8_block<T, detailv8::CalculateBytellBlockSize<T>::value>>,
detailv8::CalculateBytellBlockSize<T>::value
>
{
Expand All @@ -1206,7 +1198,7 @@ class bytell_hash_set
E,
detailv8::functor_storage<bool, E>,
A,
typename std::allocator_traits<A>::template rebind_alloc<unsigned char>,
typename std::allocator_traits<A>::template rebind_alloc<detailv8::sherwood_v8_block<T, detailv8::CalculateBytellBlockSize<T>::value>>,
detailv8::CalculateBytellBlockSize<T>::value
>;
public:
Expand Down