mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-08-23 01:36:15 +02:00
Merge branch 'th/hash-steal-extended-set' into 'main'
ghash: fix g_hash_table_steal_extended() when requesting key and value of a set See merge request GNOME/glib!2980
This commit is contained in:
commit
459d4c9085
18
glib/ghash.c
18
glib/ghash.c
@ -1785,8 +1785,9 @@ g_hash_table_steal (GHashTable *hash_table,
|
||||
* of @hash_table are %NULL-safe.
|
||||
*
|
||||
* The dictionary implementation optimizes for having all values identical to
|
||||
* their keys, for example by using g_hash_table_add(). When stealing both the
|
||||
* key and the value from such a dictionary, the value will be %NULL.
|
||||
* their keys, for example by using g_hash_table_add(). Before 2.78, when
|
||||
* stealing both the key and the value from such a dictionary, the value was
|
||||
* %NULL. Now the returned value and the key will be the same.
|
||||
*
|
||||
* Returns: %TRUE if the key was found in the #GHashTable
|
||||
* Since: 2.58
|
||||
@ -1820,10 +1821,15 @@ g_hash_table_steal_extended (GHashTable *hash_table,
|
||||
}
|
||||
|
||||
if (stolen_value != NULL)
|
||||
{
|
||||
*stolen_value = g_hash_table_fetch_key_or_value (hash_table->values, node_index, hash_table->have_big_values);
|
||||
g_hash_table_assign_key_or_value (hash_table->values, node_index, hash_table->have_big_values, NULL);
|
||||
}
|
||||
{
|
||||
if (stolen_key && hash_table->keys == hash_table->values)
|
||||
*stolen_value = *stolen_key;
|
||||
else
|
||||
{
|
||||
*stolen_value = g_hash_table_fetch_key_or_value (hash_table->values, node_index, hash_table->have_big_values);
|
||||
g_hash_table_assign_key_or_value (hash_table->values, node_index, hash_table->have_big_values, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
g_hash_table_remove_node (hash_table, node_index, FALSE);
|
||||
g_hash_table_maybe_resize (hash_table);
|
||||
|
@ -1271,6 +1271,52 @@ test_steal_extended (void)
|
||||
g_assert_cmpuint (g_hash_table_size (hash), ==, 5);
|
||||
|
||||
g_hash_table_unref (hash);
|
||||
|
||||
hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
|
||||
|
||||
g_hash_table_add (hash, g_strdup ("a"));
|
||||
g_hash_table_add (hash, g_strdup ("b"));
|
||||
g_hash_table_add (hash, g_strdup ("c"));
|
||||
g_hash_table_add (hash, g_strdup ("d"));
|
||||
g_hash_table_add (hash, g_strdup ("e"));
|
||||
|
||||
g_assert_true (g_hash_table_steal_extended (hash, "a", (gpointer *) &stolen_key,
|
||||
(gpointer *) &stolen_value));
|
||||
g_assert_cmpstr (stolen_key, ==, "a");
|
||||
g_assert_cmpstr (stolen_value, ==, "a");
|
||||
g_clear_pointer (&stolen_key, g_free);
|
||||
stolen_value = NULL;
|
||||
|
||||
g_assert_true (g_hash_table_steal_extended (hash, "b", (gpointer *) &stolen_key,
|
||||
NULL));
|
||||
g_assert_cmpstr (stolen_key, ==, "b");
|
||||
g_clear_pointer (&stolen_key, g_free);
|
||||
|
||||
g_assert_true (g_hash_table_steal_extended (hash, "c", NULL,
|
||||
(gpointer *) &stolen_value));
|
||||
g_assert_cmpstr (stolen_value, ==, "c");
|
||||
g_clear_pointer (&stolen_value, g_free);
|
||||
|
||||
g_assert_true (g_hash_table_steal_extended (hash, "d", (gpointer *) &stolen_key,
|
||||
(gpointer *) &stolen_value));
|
||||
g_assert_cmpstr (stolen_key, ==, "d");
|
||||
g_assert_cmpstr (stolen_value, ==, "d");
|
||||
g_clear_pointer (&stolen_key, g_free);
|
||||
stolen_value = NULL;
|
||||
|
||||
/* So far, the GHashTable was used like a set (g_hash_table_add()), where all key/values were
|
||||
* identical. Adding one entry where key/value differs, blows the internal representation
|
||||
* up, and the hash table tracks two separate key/value arrays. */
|
||||
g_hash_table_replace (hash, g_strdup ("x"), NULL);
|
||||
|
||||
g_assert_true (g_hash_table_steal_extended (hash, "e", (gpointer *) &stolen_key,
|
||||
(gpointer *) &stolen_value));
|
||||
g_assert_cmpstr (stolen_key, ==, "e");
|
||||
g_assert_cmpstr (stolen_value, ==, "e");
|
||||
g_clear_pointer (&stolen_key, g_free);
|
||||
stolen_value = NULL;
|
||||
|
||||
g_hash_table_unref (hash);
|
||||
}
|
||||
|
||||
/* Test that passing %NULL to the optional g_hash_table_steal_extended()
|
||||
|
Loading…
Reference in New Issue
Block a user