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
This commit is contained in:
Tobias Stoeckmann
2025-09-06 21:54:24 +02:00
parent 4414a42c42
commit 2b51b57f05
2 changed files with 24 additions and 26 deletions

View File

@@ -210,7 +210,7 @@
struct _GHashTable struct _GHashTable
{ {
gsize size; guint size;
gint mod; gint mod;
guint mask; guint mask;
guint nnodes; guint nnodes;
@@ -487,9 +487,9 @@ g_hash_table_lookup_node (GHashTable *hash_table,
* for the key and value of the hash node. * for the key and value of the hash node.
*/ */
static void static void
g_hash_table_remove_node (GHashTable *hash_table, g_hash_table_remove_node (GHashTable *hash_table,
gint i, guint i,
gboolean notify) gboolean notify)
{ {
gpointer key; gpointer key;
gpointer value; gpointer value;
@@ -573,10 +573,10 @@ g_hash_table_remove_all_nodes (GHashTable *hash_table,
gboolean notify, gboolean notify,
gboolean destruction) gboolean destruction)
{ {
int i; guint i;
gpointer key; gpointer key;
gpointer value; gpointer value;
gint old_size; guint old_size;
gpointer *old_keys; gpointer *old_keys;
gpointer *old_values; gpointer *old_values;
guint *old_hashes; 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)); memset (hash_table->hashes, 0, hash_table->size * sizeof (guint));
#ifdef USE_SMALL_ARRAYS #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->keys, 0, (size_t) 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->values, 0, (size_t) hash_table->size * (hash_table->have_big_values ? BIG_ENTRY_SIZE : SMALL_ENTRY_SIZE));
#else #else
memset (hash_table->keys, 0, hash_table->size * sizeof (gpointer)); memset (hash_table->keys, 0, hash_table->size * sizeof (gpointer));
memset (hash_table->values, 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) g_hash_table_resize (GHashTable *hash_table)
{ {
guint32 *reallocated_buckets_bitmap; guint32 *reallocated_buckets_bitmap;
gsize old_size; guint old_size;
gboolean is_a_set; gboolean is_a_set;
old_size = hash_table->size; old_size = hash_table->size;
@@ -866,8 +866,8 @@ g_hash_table_resize (GHashTable *hash_table)
static inline void static inline void
g_hash_table_maybe_resize (GHashTable *hash_table) g_hash_table_maybe_resize (GHashTable *hash_table)
{ {
gsize noccupied = hash_table->noccupied; guint noccupied = hash_table->noccupied;
gsize size = hash_table->size; guint size = hash_table->size;
if ((size > 1 << HASH_TABLE_MIN_SHIFT && (size - 1) / 4 >= hash_table->nnodes) || if ((size > 1 << HASH_TABLE_MIN_SHIFT && (size - 1) / 4 >= hash_table->nnodes) ||
(size <= noccupied + (noccupied / 16))) (size <= noccupied + (noccupied / 16)))
@@ -883,17 +883,16 @@ entry_is_big (gpointer v)
} }
static inline gboolean 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)) if (entry_is_big (v))
{ {
guint *a = (guint *) *a_p; guint *a = (guint *) *a_p;
gpointer *a_new; gpointer *a_new;
gint i;
a_new = g_new (gpointer, ht_size); 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]); 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); g_return_if_fail (ri->version == ri->hash_table->version);
#endif #endif
g_return_if_fail (ri->position != ITER_POSITION_INVALID); 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); 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); g_return_if_fail (ri->version == ri->hash_table->version);
#endif #endif
g_return_if_fail (ri->position != ITER_POSITION_INVALID); 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]; node_hash = ri->hash_table->hashes[ri->position];
@@ -2003,7 +2002,7 @@ g_hash_table_foreach_remove_or_steal (GHashTable *hash_table,
gboolean notify) gboolean notify)
{ {
guint deleted = 0; guint deleted = 0;
gsize i; guint i;
#ifndef G_DISABLE_ASSERT #ifndef G_DISABLE_ASSERT
gint version = hash_table->version; gint version = hash_table->version;
#endif #endif
@@ -2115,7 +2114,7 @@ g_hash_table_foreach (GHashTable *hash_table,
GHFunc func, GHFunc func,
gpointer user_data) gpointer user_data)
{ {
gsize i; guint i;
#ifndef G_DISABLE_ASSERT #ifndef G_DISABLE_ASSERT
gint version; gint version;
#endif #endif
@@ -2173,7 +2172,7 @@ g_hash_table_find (GHashTable *hash_table,
GHRFunc predicate, GHRFunc predicate,
gpointer user_data) gpointer user_data)
{ {
gsize i; guint i;
#ifndef G_DISABLE_ASSERT #ifndef G_DISABLE_ASSERT
gint version; gint version;
#endif #endif
@@ -2245,7 +2244,7 @@ g_hash_table_size (GHashTable *hash_table)
GList * GList *
g_hash_table_get_keys (GHashTable *hash_table) g_hash_table_get_keys (GHashTable *hash_table)
{ {
gsize i; guint i;
GList *retval; GList *retval;
g_return_val_if_fail (hash_table != NULL, NULL); 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) guint *length)
{ {
gpointer *result; gpointer *result;
gsize i, j = 0; guint i, j = 0;
result = g_new (gpointer, hash_table->nnodes + 1); result = g_new (gpointer, hash_table->nnodes + 1);
for (i = 0; i < hash_table->size; i++) 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); g_return_val_if_fail (hash_table != NULL, NULL);
array = g_ptr_array_sized_new (hash_table->size); 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])) if (HASH_IS_REAL (hash_table->hashes[i]))
{ {
@@ -2370,13 +2369,12 @@ g_hash_table_get_keys_as_ptr_array (GHashTable *hash_table)
GList * GList *
g_hash_table_get_values (GHashTable *hash_table) g_hash_table_get_values (GHashTable *hash_table)
{ {
gsize i;
GList *retval; GList *retval;
g_return_val_if_fail (hash_table != NULL, NULL); g_return_val_if_fail (hash_table != NULL, NULL);
retval = 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])) 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)); 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); g_return_val_if_fail (hash_table != NULL, NULL);
array = g_ptr_array_sized_new (hash_table->size); 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])) if (HASH_IS_REAL (hash_table->hashes[i]))
{ {

View File

@@ -1471,7 +1471,7 @@ test_new_similar (void)
struct _GHashTable struct _GHashTable
{ {
gsize size; guint size;
gint mod; gint mod;
guint mask; guint mask;
gint nnodes; gint nnodes;