mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-01-30 15:56:18 +01:00
gdataset: use lookup index in g_datalist_id_remove_multiple()
In order to reuse datalist_find(), we turn the loops around. First loop over the keys, and then (internally in datalist_find()) loop over the entries.
This commit is contained in:
parent
af4a43b064
commit
3437414dd4
@ -723,7 +723,9 @@ g_data_remove_internal (GData **datalist,
|
|||||||
GData *d_to_free;
|
GData *d_to_free;
|
||||||
gsize found_keys;
|
gsize found_keys;
|
||||||
gsize i_keys;
|
gsize i_keys;
|
||||||
guint32 i_data;
|
|
||||||
|
if (n_keys == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
d = g_datalist_lock_and_get (datalist);
|
d = g_datalist_lock_and_get (datalist);
|
||||||
|
|
||||||
@ -749,33 +751,23 @@ g_data_remove_internal (GData **datalist,
|
|||||||
old = old_to_free;
|
old = old_to_free;
|
||||||
}
|
}
|
||||||
|
|
||||||
i_data = 0;
|
|
||||||
found_keys = 0;
|
found_keys = 0;
|
||||||
while (i_data < d->len && found_keys < n_keys)
|
|
||||||
{
|
|
||||||
GDataElt *data = &d->data[i_data];
|
|
||||||
gboolean remove = FALSE;
|
|
||||||
|
|
||||||
for (i_keys = 0; i_keys < n_keys; i_keys++)
|
for (i_keys = 0; i_keys < n_keys; i_keys++)
|
||||||
{
|
{
|
||||||
if (data->key == keys[i_keys])
|
GDataElt *data_elt;
|
||||||
{
|
guint32 idx;
|
||||||
/* We must invoke the destroy notifications in the order of @keys.
|
|
||||||
* Hence, build up the list @old at index @i_keys. */
|
|
||||||
old[i_keys] = *data;
|
|
||||||
found_keys++;
|
|
||||||
remove = TRUE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!remove)
|
data_elt = datalist_find (d, keys[i_keys], &idx);
|
||||||
{
|
if (!data_elt)
|
||||||
i_data++;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
datalist_remove (d, i_data);
|
/* We must destroy the keys in the order in which they are specified.
|
||||||
|
* We achieve that here.
|
||||||
|
*
|
||||||
|
* Note that even if @keys contains duplicates, we correctly only
|
||||||
|
* find them once, as we remove the found entry right away. */
|
||||||
|
old[found_keys++] = *data_elt;
|
||||||
|
datalist_remove (d, idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (found_keys > 0 && datalist_shrink (&d, &d_to_free))
|
if (found_keys > 0 && datalist_shrink (&d, &d_to_free))
|
||||||
@ -787,14 +779,11 @@ g_data_remove_internal (GData **datalist,
|
|||||||
else
|
else
|
||||||
g_datalist_unlock (datalist);
|
g_datalist_unlock (datalist);
|
||||||
|
|
||||||
if (found_keys > 0)
|
for (i_keys = 0; i_keys < found_keys; i_keys++)
|
||||||
{
|
|
||||||
for (i_keys = 0; i_keys < n_keys; i_keys++)
|
|
||||||
{
|
{
|
||||||
if (old[i_keys].destroy)
|
if (old[i_keys].destroy)
|
||||||
old[i_keys].destroy (old[i_keys].data);
|
old[i_keys].destroy (old[i_keys].data);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (G_UNLIKELY (old_to_free))
|
if (G_UNLIKELY (old_to_free))
|
||||||
g_free (old_to_free);
|
g_free (old_to_free);
|
||||||
@ -996,9 +985,8 @@ g_datalist_id_set_data_full (GData **datalist,
|
|||||||
* This is more efficient than calling g_datalist_id_remove_data()
|
* This is more efficient than calling g_datalist_id_remove_data()
|
||||||
* multiple times in a row.
|
* multiple times in a row.
|
||||||
*
|
*
|
||||||
* Before 2.80, @n_keys had to be not larger than 16. Now it can be larger, but
|
* Before 2.80, @n_keys had to be not larger than 16.
|
||||||
* note that GData does a linear search, so an excessive number of keys will
|
* Since 2.84, performance is improved for larger number of keys.
|
||||||
* perform badly.
|
|
||||||
*
|
*
|
||||||
* Since: 2.74
|
* Since: 2.74
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user