Skip to content

Commit 63d23e7

Browse files
Copilotjll63
andcommitted
Fix M calculation for minimal perfect hash to ensure enough bits
Co-authored-by: jll63 <[email protected]>
1 parent 530de74 commit 63d23e7

File tree

1 file changed

+21
-5
lines changed

1 file changed

+21
-5
lines changed

include/boost/openmethod/policies/minimal_perfect_hash.hpp

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -169,18 +169,34 @@ void minimal_perfect_hash::fn<Registry>::initialize(
169169
mult = 1;
170170
return;
171171
}
172+
173+
if (hash_size == 1) {
174+
// Special case: only one type, any hash function works
175+
min_value = 0;
176+
max_value = 0;
177+
shift = 8 * sizeof(type_id); // Shift everything away, result is always 0
178+
mult = 1;
179+
buckets.resize(1);
180+
for (auto iter = ctx.classes_begin(); iter != ctx.classes_end(); ++iter) {
181+
for (auto type_iter = iter->type_id_begin();
182+
type_iter != iter->type_id_end(); ++type_iter) {
183+
buckets[0] = *type_iter;
184+
}
185+
}
186+
return;
187+
}
172188

173189
std::default_random_engine rnd(13081963);
174190
std::size_t total_attempts = 0;
175191

176-
// Calculate M (number of bits needed to represent hash_size)
192+
// Calculate M (number of bits needed for the hash range)
193+
// We need 2^M >= hash_size, so M = ceil(log2(hash_size))
177194
std::size_t M = 0;
178-
for (auto size = hash_size; size > 0; size >>= 1) {
195+
std::size_t power = 1;
196+
while (power < hash_size) {
197+
power <<= 1;
179198
++M;
180199
}
181-
if (M > 0) {
182-
M--;
183-
}
184200

185201
std::uniform_int_distribution<std::size_t> uniform_dist;
186202

0 commit comments

Comments
 (0)