Merge branch 'wip/chergert/g_ref_string_equal' into 'main'

refstring: add GEqualFunc for ref-counted strings

See merge request GNOME/glib!4196
This commit is contained in:
Philip Withnall 2024-08-27 13:51:06 +00:00
commit 2135a2419d
3 changed files with 75 additions and 0 deletions

View File

@ -234,3 +234,29 @@ g_ref_string_length (char *str)
return g_atomic_rc_box_get_size (str) - 1;
}
/**
* g_ref_string_equal:
* @str1: a reference counted string
* @str2: a reference counted string
*
* Compares two ref-counted strings for byte-by-byte equality.
*
* It can be passed to [func@GLib.HashTable.new] as the key equality function,
* and behaves exactly the same as [func@GLib.str_equal] (or `strcmp()`), but
* can return slightly faster as it can check the string lengths before checking
* all the bytes.
*
* Returns: `TRUE` if the strings are equal, otherwise `FALSE`
*
* Since: 2.84
*/
gboolean
g_ref_string_equal (const char *str1,
const char *str2)
{
if (g_atomic_rc_box_get_size ((char *) str1) != g_atomic_rc_box_get_size ((char *) str2))
return FALSE;
return strcmp (str1, str2) == 0;
}

View File

@ -56,4 +56,8 @@ gsize g_ref_string_length (char *str);
*/
typedef char GRefString;
GLIB_AVAILABLE_IN_2_84
gboolean g_ref_string_equal (const char *str1,
const char *str2);
G_END_DECLS

View File

@ -102,6 +102,49 @@ test_refstring_intern (void)
g_ref_string_release (s);
}
static void
test_refstring_hash_equal (void)
{
GHashTable *ht = g_hash_table_new (g_str_hash, (GEqualFunc)g_ref_string_equal);
char *ref1 = g_ref_string_new ("string one");
char *ref2 = g_ref_string_new ("string 2");
char *ref3 = g_ref_string_new ("string one");
char *ref4 = g_ref_string_new ("string two");
g_test_summary ("Test g_ref_string_equal() in GHashTable");
g_hash_table_add (ht, ref1);
g_assert_true (g_hash_table_contains (ht, ref1));
g_assert_false (g_hash_table_contains (ht, ref2));
g_assert_true (g_hash_table_contains (ht, ref3));
g_assert_false (g_hash_table_contains (ht, ref4));
g_hash_table_unref (ht);
g_ref_string_release (ref1);
g_ref_string_release (ref2);
g_ref_string_release (ref3);
g_ref_string_release (ref4);
}
static void
test_refstring_equal (void)
{
char *ref1 = g_ref_string_new ("string one");
char *ref2 = g_ref_string_new ("string 2");
char *ref3 = g_ref_string_new ("string one");
g_test_summary ("Test g_ref_string_equal() standalone");
g_assert_true (g_ref_string_equal (ref1, ref1));
g_assert_false (g_ref_string_equal (ref1, ref2));
g_assert_true (g_ref_string_equal (ref1, ref3));
g_ref_string_release (ref1);
g_ref_string_release (ref2);
g_ref_string_release (ref3);
}
int
main (int argc,
char *argv[])
@ -113,6 +156,8 @@ main (int argc,
g_test_add_func ("/refstring/length-auto", test_refstring_length_auto);
g_test_add_func ("/refstring/length-nuls", test_refstring_length_nuls);
g_test_add_func ("/refstring/intern", test_refstring_intern);
g_test_add_func ("/refstring/hash_equal", test_refstring_hash_equal);
g_test_add_func ("/refstring/equal", test_refstring_equal);
return g_test_run ();
}