From 2b51b57f0583ace523bc64f520f3f7795bbc0f4d Mon Sep 17 00:00:00 2001 From: Tobias Stoeckmann Date: Sat, 6 Sep 2025 21:54:24 +0200 Subject: [PATCH] ghash: Turn size into guint The size attribute is actually a "capacity" instead of a size in a more classical sense: It doesn't represent the byte size but the amount of elements within the hash table. This is always a power of two, capped at 32 bit. This limit is required to satisfy the support of converting a GHash into a GArray, which is capped at G_MAXUINT elements. Treat the size as capacity and bring it to the same data type as nnodes and other element counters for better performance. While at it, turn all variables taking the value of size into a guint as well. Closes: #672 --- glib/ghash.c | 48 +++++++++++++++++++++++------------------------ glib/tests/hash.c | 2 +- 2 files changed, 24 insertions(+), 26 deletions(-) diff --git a/glib/ghash.c b/glib/ghash.c index cdbf2bec1..016239bcc 100644 --- a/glib/ghash.c +++ b/glib/ghash.c @@ -210,7 +210,7 @@ struct _GHashTable { - gsize size; + guint size; gint mod; guint mask; guint nnodes; @@ -487,9 +487,9 @@ g_hash_table_lookup_node (GHashTable *hash_table, * for the key and value of the hash node. */ static void -g_hash_table_remove_node (GHashTable *hash_table, - gint i, - gboolean notify) +g_hash_table_remove_node (GHashTable *hash_table, + guint i, + gboolean notify) { gpointer key; gpointer value; @@ -573,10 +573,10 @@ g_hash_table_remove_all_nodes (GHashTable *hash_table, gboolean notify, gboolean destruction) { - int i; + guint i; gpointer key; gpointer value; - gint old_size; + guint old_size; gpointer *old_keys; gpointer *old_values; guint *old_hashes; @@ -600,8 +600,8 @@ g_hash_table_remove_all_nodes (GHashTable *hash_table, memset (hash_table->hashes, 0, hash_table->size * sizeof (guint)); #ifdef USE_SMALL_ARRAYS - memset (hash_table->keys, 0, hash_table->size * (hash_table->have_big_keys ? BIG_ENTRY_SIZE : SMALL_ENTRY_SIZE)); - memset (hash_table->values, 0, hash_table->size * (hash_table->have_big_values ? BIG_ENTRY_SIZE : SMALL_ENTRY_SIZE)); + memset (hash_table->keys, 0, (size_t) hash_table->size * (hash_table->have_big_keys ? BIG_ENTRY_SIZE : SMALL_ENTRY_SIZE)); + memset (hash_table->values, 0, (size_t) hash_table->size * (hash_table->have_big_values ? BIG_ENTRY_SIZE : SMALL_ENTRY_SIZE)); #else memset (hash_table->keys, 0, hash_table->size * sizeof (gpointer)); memset (hash_table->values, 0, hash_table->size * sizeof (gpointer)); @@ -810,7 +810,7 @@ static void g_hash_table_resize (GHashTable *hash_table) { guint32 *reallocated_buckets_bitmap; - gsize old_size; + guint old_size; gboolean is_a_set; old_size = hash_table->size; @@ -866,8 +866,8 @@ g_hash_table_resize (GHashTable *hash_table) static inline void g_hash_table_maybe_resize (GHashTable *hash_table) { - gsize noccupied = hash_table->noccupied; - gsize size = hash_table->size; + guint noccupied = hash_table->noccupied; + guint size = hash_table->size; if ((size > 1 << HASH_TABLE_MIN_SHIFT && (size - 1) / 4 >= hash_table->nnodes) || (size <= noccupied + (noccupied / 16))) @@ -883,17 +883,16 @@ entry_is_big (gpointer v) } static inline gboolean -g_hash_table_maybe_make_big_keys_or_values (gpointer *a_p, gpointer v, gint ht_size) +g_hash_table_maybe_make_big_keys_or_values (gpointer *a_p, gpointer v, guint ht_size) { if (entry_is_big (v)) { guint *a = (guint *) *a_p; gpointer *a_new; - gint i; a_new = g_new (gpointer, ht_size); - for (i = 0; i < ht_size; i++) + for (guint i = 0; i < ht_size; i++) { a_new[i] = GUINT_TO_POINTER (a[i]); } @@ -1188,7 +1187,7 @@ iter_remove_or_steal (RealIter *ri, gboolean notify) g_return_if_fail (ri->version == ri->hash_table->version); #endif g_return_if_fail (ri->position != ITER_POSITION_INVALID); - g_return_if_fail ((gsize) ri->position < ri->hash_table->size); + g_return_if_fail (ri->position < ri->hash_table->size); g_hash_table_remove_node (ri->hash_table, ri->position, notify); @@ -1372,7 +1371,7 @@ g_hash_table_iter_replace (GHashTableIter *iter, g_return_if_fail (ri->version == ri->hash_table->version); #endif g_return_if_fail (ri->position != ITER_POSITION_INVALID); - g_return_if_fail ((gsize) ri->position < ri->hash_table->size); + g_return_if_fail (ri->position < ri->hash_table->size); node_hash = ri->hash_table->hashes[ri->position]; @@ -2003,7 +2002,7 @@ g_hash_table_foreach_remove_or_steal (GHashTable *hash_table, gboolean notify) { guint deleted = 0; - gsize i; + guint i; #ifndef G_DISABLE_ASSERT gint version = hash_table->version; #endif @@ -2115,7 +2114,7 @@ g_hash_table_foreach (GHashTable *hash_table, GHFunc func, gpointer user_data) { - gsize i; + guint i; #ifndef G_DISABLE_ASSERT gint version; #endif @@ -2173,7 +2172,7 @@ g_hash_table_find (GHashTable *hash_table, GHRFunc predicate, gpointer user_data) { - gsize i; + guint i; #ifndef G_DISABLE_ASSERT gint version; #endif @@ -2245,7 +2244,7 @@ g_hash_table_size (GHashTable *hash_table) GList * g_hash_table_get_keys (GHashTable *hash_table) { - gsize i; + guint i; GList *retval; g_return_val_if_fail (hash_table != NULL, NULL); @@ -2293,7 +2292,7 @@ g_hash_table_get_keys_as_array (GHashTable *hash_table, guint *length) { gpointer *result; - gsize i, j = 0; + guint i, j = 0; result = g_new (gpointer, hash_table->nnodes + 1); for (i = 0; i < hash_table->size; i++) @@ -2336,7 +2335,7 @@ g_hash_table_get_keys_as_ptr_array (GHashTable *hash_table) g_return_val_if_fail (hash_table != NULL, NULL); array = g_ptr_array_sized_new (hash_table->size); - for (gsize i = 0; i < hash_table->size; ++i) + for (guint i = 0; i < hash_table->size; ++i) { if (HASH_IS_REAL (hash_table->hashes[i])) { @@ -2370,13 +2369,12 @@ g_hash_table_get_keys_as_ptr_array (GHashTable *hash_table) GList * g_hash_table_get_values (GHashTable *hash_table) { - gsize i; GList *retval; g_return_val_if_fail (hash_table != NULL, NULL); retval = NULL; - for (i = 0; i < hash_table->size; i++) + for (guint i = 0; i < hash_table->size; i++) { if (HASH_IS_REAL (hash_table->hashes[i])) retval = g_list_prepend (retval, g_hash_table_fetch_key_or_value (hash_table->values, i, hash_table->have_big_values)); @@ -2411,7 +2409,7 @@ g_hash_table_get_values_as_ptr_array (GHashTable *hash_table) g_return_val_if_fail (hash_table != NULL, NULL); array = g_ptr_array_sized_new (hash_table->size); - for (gsize i = 0; i < hash_table->size; ++i) + for (guint i = 0; i < hash_table->size; ++i) { if (HASH_IS_REAL (hash_table->hashes[i])) { diff --git a/glib/tests/hash.c b/glib/tests/hash.c index 0d0d07628..14df5a1e7 100644 --- a/glib/tests/hash.c +++ b/glib/tests/hash.c @@ -1471,7 +1471,7 @@ test_new_similar (void) struct _GHashTable { - gsize size; + guint size; gint mod; guint mask; gint nnodes;