[glib: 1/2] ghash: Add g_hash_table_new_similar()
- From: Philip Withnall <pwithnall src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib: 1/2] ghash: Add g_hash_table_new_similar()
- Date: Wed, 19 Jan 2022 11:19:08 +0000 (UTC)
commit 283d9e0c15ccfa54bb06e3f6d9e61763508e0bab
Author: Jonas Ã…dahl <jadahl gmail com>
Date: Thu Dec 23 00:58:54 2021 +0100
ghash: Add g_hash_table_new_similar()
This function creates a new hash table, but inherits the functions used
for the hash, comparison, and key/value memory management functions from
another hash table.
The primary use case is to implement a behaviour where you maintain a
hash table by regenerating it, letting the values not migrated be freed.
See the following pseudo code:
```
GHashTable *ht;
init(GList *resources) {
ht = g_hash_table_new (g_str_hash, g_str_equal, g_free, g_free);
for (r in resources)
g_hash_table_insert (ht, strdup (resource_get_key (r)), create_value (r));
}
update(GList *resources) {
GHashTable *new_ht = g_hash_table_new_similar (ht);
for (r in resources) {
if (g_hash_table_steal_extended (ht, resource_get_key (r), &key, &value))
g_hash_table_insert (new_ht, key, value);
else
g_hash_table_insert (new_ht, strdup (resource_get_key (r)), create_value (r));
}
g_hash_table_unref (ht);
ht = new_ht;
}
```
docs/reference/glib/glib-sections.txt | 1 +
glib/ghash.c | 27 +++++++++++++++++++++
glib/ghash.h | 2 ++
glib/tests/hash.c | 44 +++++++++++++++++++++++++++++++++++
4 files changed, 74 insertions(+)
---
diff --git a/docs/reference/glib/glib-sections.txt b/docs/reference/glib/glib-sections.txt
index c8681fa2f..ff080f711 100644
--- a/docs/reference/glib/glib-sections.txt
+++ b/docs/reference/glib/glib-sections.txt
@@ -2851,6 +2851,7 @@ g_trash_stack_height
GHashTable
g_hash_table_new
g_hash_table_new_full
+g_hash_table_new_similar
GHashFunc
GEqualFunc
g_hash_table_insert
diff --git a/glib/ghash.c b/glib/ghash.c
index 48a7db0e2..3d71643c7 100644
--- a/glib/ghash.c
+++ b/glib/ghash.c
@@ -1085,6 +1085,33 @@ g_hash_table_new_full (GHashFunc hash_func,
return hash_table;
}
+/**
+ * g_hash_table_new_similar:
+ * @other_hash_table: (not nullable) (transfer none): Another #GHashTable
+ *
+ * Creates a new #GHashTable like g_hash_table_new_full() with a reference
+ * count of 1.
+ *
+ * It inherits the hash function, the key equal function, the key destroy function,
+ * as well as the value destroy function, from @other_hash_table.
+ *
+ * The returned hash table will be empty; it will not contain the keys
+ * or values from @other_hash_table.
+ *
+ * Returns: (transfer full) (not nullable): a new #GHashTable
+ * Since: 2.72
+ */
+GHashTable *
+g_hash_table_new_similar (GHashTable *other_hash_table)
+{
+ g_return_val_if_fail (other_hash_table, NULL);
+
+ return g_hash_table_new_full (other_hash_table->hash_func,
+ other_hash_table->key_equal_func,
+ other_hash_table->key_destroy_func,
+ other_hash_table->value_destroy_func);
+}
+
/**
* g_hash_table_iter_init:
* @iter: an uninitialized #GHashTableIter
diff --git a/glib/ghash.h b/glib/ghash.h
index e9ce64505..4e81d6263 100644
--- a/glib/ghash.h
+++ b/glib/ghash.h
@@ -61,6 +61,8 @@ GHashTable* g_hash_table_new_full (GHashFunc hash_func,
GEqualFunc key_equal_func,
GDestroyNotify key_destroy_func,
GDestroyNotify value_destroy_func);
+GLIB_AVAILABLE_IN_2_72
+GHashTable *g_hash_table_new_similar (GHashTable *other_hash_table);
GLIB_AVAILABLE_IN_ALL
void g_hash_table_destroy (GHashTable *hash_table);
GLIB_AVAILABLE_IN_ALL
diff --git a/glib/tests/hash.c b/glib/tests/hash.c
index fe72606f8..fe0811aff 100644
--- a/glib/tests/hash.c
+++ b/glib/tests/hash.c
@@ -1345,6 +1345,49 @@ test_lookup_extended (void)
g_hash_table_unref (hash);
}
+static void
+inc_state (gpointer user_data)
+{
+ int *state = user_data;
+ g_assert_cmpint (*state, ==, 0);
+ *state = 1;
+}
+
+static void
+test_new_similar (void)
+{
+ GHashTable *hash1;
+ GHashTable *hash2;
+ int state1;
+ int state2;
+
+ hash1 = g_hash_table_new_full (g_str_hash, g_str_equal,
+ g_free, inc_state);
+ state1 = 0;
+ g_hash_table_insert (hash1,
+ g_strdup ("test"),
+ &state1);
+ g_assert_true (g_hash_table_lookup (hash1, "test") == &state1);
+
+ hash2 = g_hash_table_new_similar (hash1);
+
+ g_assert_true (g_hash_table_lookup (hash1, "test") == &state1);
+ g_assert_null (g_hash_table_lookup (hash2, "test"));
+
+ state2 = 0;
+ g_hash_table_insert (hash2, g_strdup ("test"), &state2);
+ g_assert_true (g_hash_table_lookup (hash2, "test") == &state2);
+ g_hash_table_remove (hash2, "test");
+ g_assert_cmpint (state2, ==, 1);
+
+ g_assert_cmpint (state1, ==, 0);
+ g_hash_table_remove (hash1, "test");
+ g_assert_cmpint (state1, ==, 1);
+
+ g_hash_table_unref (hash1);
+ g_hash_table_unref (hash2);
+}
+
struct _GHashTable
{
gsize size;
@@ -1685,6 +1728,7 @@ main (int argc, char *argv[])
g_test_add_func ("/hash/steal-extended", test_steal_extended);
g_test_add_func ("/hash/steal-extended/optional", test_steal_extended_optional);
g_test_add_func ("/hash/lookup-extended", test_lookup_extended);
+ g_test_add_func ("/hash/new-similar", test_new_similar);
/* tests for individual bugs */
g_test_add_func ("/hash/lookup-null-key", test_lookup_null_key);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]