gdataset: optimize return path in g_datalist_id_update_atomic()

The most common case is that the callback does not change the
data/destroy pointers. Reorder the if checks to favor those cases.
Also, avoid setting the data to the same value.
This commit is contained in:
Thomas Haller 2024-08-13 21:18:02 +02:00
parent 2d5a00707b
commit 357e611825

View File

@ -1095,7 +1095,6 @@ g_datalist_id_update_atomic (GData **datalist,
gpointer result;
GDestroyNotify new_destroy;
guint32 idx;
gboolean to_unlock = TRUE;
if (G_UNLIKELY (already_locked))
{
@ -1121,7 +1120,13 @@ g_datalist_id_update_atomic (GData **datalist,
result = callback (&new_data, &new_destroy, user_data);
if (data && !new_data)
if (data)
{
if (G_LIKELY (data->data == new_data && data->destroy == new_destroy))
{
/* No change. */
}
else if (!new_data)
{
GData *d_to_free;
@ -1134,10 +1139,10 @@ g_datalist_id_update_atomic (GData **datalist,
g_datalist_unlock_and_set (datalist, d);
if (d_to_free)
g_free (d_to_free);
to_unlock = FALSE;
goto return_without_unlock;
}
}
else if (data)
else
{
/* Update. The callback may have provided new pointers to an existing
* entry.
@ -1147,9 +1152,12 @@ g_datalist_id_update_atomic (GData **datalist,
data->data = new_data;
data->destroy = new_destroy;
}
else if (!data && !new_data)
}
else
{
/* Absent. No change. The entry didn't exist and still does not. */
if (G_LIKELY (!new_data))
{
/* No change. The entry didn't exist and still does not. */
}
else
{
@ -1157,13 +1165,14 @@ g_datalist_id_update_atomic (GData **datalist,
if (datalist_append (&d, key_id, new_data, new_destroy))
{
g_datalist_unlock_and_set (datalist, d);
to_unlock = FALSE;
goto return_without_unlock;
}
}
}
if (to_unlock)
g_datalist_unlock (datalist);
return_without_unlock:
return result;
}