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
{
gsize size;
guint size;
gint mod;
guint mask;
guint nnodes;
@@ -488,7 +488,7 @@ g_hash_table_lookup_node (GHashTable *hash_table,
*/
static void
g_hash_table_remove_node (GHashTable *hash_table,
gint i,
guint i,
gboolean notify)
{
gpointer key;
@@ -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]))
{

View File

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