Skip to content

Commit

Permalink
MVM_uni_hash_build now takes an entry count for the hash.
Browse files Browse the repository at this point in the history
  • Loading branch information
nwc10 committed Aug 12, 2020
1 parent 6438f31 commit 6a8c289
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 7 deletions.
20 changes: 16 additions & 4 deletions src/core/uni_hash_table.c
Expand Up @@ -35,9 +35,21 @@ MVM_STATIC_INLINE void hash_allocate_common(MVMUniHashTable *hashtable) {
hashtable->metadata[actual_items] = 1;
}

MVM_STATIC_INLINE void hash_initial_allocate(MVMUniHashTable *hashtable) {
hashtable->key_right_shift = UNI_INITIAL_KEY_RIGHT_SHIFT;
hashtable->official_size = UNI_INITIAL_SIZE;
void MVM_uni_hash_initial_allocate(MVMThreadContext *tc,
MVMUniHashTable *hashtable,
MVMuint32 entries) {
if (entries <= UNI_INITIAL_SIZE * UNI_LOAD_FACTOR) {
/* "Too small" - use our original defaults. */
hashtable->key_right_shift = UNI_INITIAL_KEY_RIGHT_SHIFT;
hashtable->official_size = UNI_INITIAL_SIZE;
} else {
/* Minimum size we need to allocate, given the load factor. */
MVMuint32 min_needed = entries * (1.0 / UNI_LOAD_FACTOR);
MVMuint32 initial_size_base2 = MVM_round_up_log_base2(min_needed);

hashtable->key_right_shift = (8 * sizeof(MVMuint32) - initial_size_base2);
hashtable->official_size = 1 << initial_size_base2;
}

hash_allocate_common(hashtable);
}
Expand Down Expand Up @@ -131,7 +143,7 @@ MVM_STATIC_INLINE void *MVM_uni_hash_lvalue_fetch(MVMThreadContext *tc,
MVMUniHashTable *hashtable,
const char *key) {
if (MVM_UNLIKELY(hashtable->entries == NULL)) {
hash_initial_allocate(hashtable);
MVM_uni_hash_initial_allocate(tc, hashtable, 0);
}
else if (MVM_UNLIKELY(hashtable->cur_items >= hashtable->max_items)) {
/* We should avoid growing the hash if we don't need to.
Expand Down
15 changes: 12 additions & 3 deletions src/core/uni_hash_table_funcs.h
Expand Up @@ -3,12 +3,21 @@
void MVM_uni_hash_demolish(MVMThreadContext *tc, MVMUniHashTable *hashtable);
/* and then free memory if you allocated it */

void MVM_uni_hash_initial_allocate(MVMThreadContext *tc,
MVMUniHashTable *hashtable,
MVMuint32 entries);

/* Call this before you use the hashtable, to initialise it.
* Doesn't allocate memory - you can embed the struct within a larger struct if
* you wish.
* Doesn't allocate memory for the hashtable struct itself - you can embed the
* struct within a larger struct if you wish.
*/
MVM_STATIC_INLINE void MVM_uni_hash_build(MVMThreadContext *tc, MVMUniHashTable *hashtable) {
MVM_STATIC_INLINE void MVM_uni_hash_build(MVMThreadContext *tc,
MVMUniHashTable *hashtable,
MVMuint32 entries) {
memset(hashtable, 0, sizeof(*hashtable));
if (entries) {
MVM_uni_hash_initial_allocate(tc, hashtable, entries);
}
}

/* Unicode names (etc) are not under the control of an external attacker [:-)]
Expand Down
4 changes: 4 additions & 0 deletions src/strings/unicode_ops.c
Expand Up @@ -884,6 +884,8 @@ static MVMUniHashTable property_codes_by_seq_names;
static void generate_property_codes_by_names_aliases(MVMThreadContext *tc) {
MVMuint32 num_names = num_unicode_property_keypairs;

MVM_uni_hash_build(tc, &property_codes_by_names_aliases, num_names);

while (num_names--) {
MVM_uni_hash_insert(tc, &property_codes_by_names_aliases,
unicode_property_keypairs[num_names].name,
Expand All @@ -894,6 +896,8 @@ static void generate_property_codes_by_names_aliases(MVMThreadContext *tc) {
static void generate_property_codes_by_seq_names(MVMThreadContext *tc) {
MVMuint32 num_names = num_unicode_seq_keypairs;

MVM_uni_hash_build(tc, &property_codes_by_seq_names, num_names);

while (num_names--) {
MVM_uni_hash_insert(tc, &property_codes_by_seq_names,
uni_seq_pairs[num_names].name,
Expand Down

0 comments on commit 6a8c289

Please sign in to comment.