mirror of https://github.com/GNOME/gimp.git
Bug 604175 - gimp_vectors_import() is O(n**2) in gimp_list_uniquefy_name(), for some data
Switch off unique names for all individual item stacks and make sure that all items in a GimpItemTree have unique names across all containers. Uses a hash table and thus gets rid of the O(n**2) complexity of the unique name code in GimpList.
This commit is contained in:
parent
2034a3676c
commit
8a7f2e8f51
|
@ -220,7 +220,6 @@ gimp_drawable_stack_new (GType drawable_type)
|
|||
"name", g_type_name (drawable_type),
|
||||
"children-type", drawable_type,
|
||||
"policy", GIMP_CONTAINER_POLICY_STRONG,
|
||||
"unique-names", TRUE,
|
||||
NULL);
|
||||
}
|
||||
|
||||
|
|
|
@ -112,7 +112,6 @@ gimp_item_stack_new (GType item_type)
|
|||
"name", g_type_name (item_type),
|
||||
"children-type", item_type,
|
||||
"policy", GIMP_CONTAINER_POLICY_STRONG,
|
||||
"unique-names", TRUE,
|
||||
NULL);
|
||||
}
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <gegl.h>
|
||||
|
@ -53,6 +54,8 @@ struct _GimpItemTreePrivate
|
|||
GType item_type;
|
||||
|
||||
GimpItem *active_item;
|
||||
|
||||
GHashTable *name_hash;
|
||||
};
|
||||
|
||||
#define GIMP_ITEM_TREE_GET_PRIVATE(object) \
|
||||
|
@ -79,6 +82,10 @@ static void gimp_item_tree_get_property (GObject *object,
|
|||
static gint64 gimp_item_tree_get_memsize (GimpObject *object,
|
||||
gint64 *gui_size);
|
||||
|
||||
static void gimp_item_tree_uniquefy_name (GimpItemTree *tree,
|
||||
GimpItem *item,
|
||||
const gchar *new_name);
|
||||
|
||||
|
||||
G_DEFINE_TYPE (GimpItemTree, gimp_item_tree, GIMP_TYPE_OBJECT)
|
||||
|
||||
|
@ -131,6 +138,9 @@ gimp_item_tree_class_init (GimpItemTreeClass *klass)
|
|||
static void
|
||||
gimp_item_tree_init (GimpItemTree *tree)
|
||||
{
|
||||
GimpItemTreePrivate *private = GIMP_ITEM_TREE_GET_PRIVATE (tree);
|
||||
|
||||
private->name_hash = g_hash_table_new (g_str_hash, g_str_equal);
|
||||
}
|
||||
|
||||
static GObject *
|
||||
|
@ -156,7 +166,6 @@ gimp_item_tree_constructor (GType type,
|
|||
"name", g_type_name (private->item_type),
|
||||
"children-type", private->item_type,
|
||||
"policy", GIMP_CONTAINER_POLICY_STRONG,
|
||||
"unique-names", TRUE,
|
||||
NULL);
|
||||
|
||||
return object;
|
||||
|
@ -166,6 +175,13 @@ static void
|
|||
gimp_item_tree_finalize (GObject *object)
|
||||
{
|
||||
GimpItemTree *tree = GIMP_ITEM_TREE (object);
|
||||
GimpItemTreePrivate *private = GIMP_ITEM_TREE_GET_PRIVATE (tree);
|
||||
|
||||
if (private->name_hash)
|
||||
{
|
||||
g_hash_table_unref (private->name_hash);
|
||||
private->name_hash = NULL;
|
||||
}
|
||||
|
||||
if (tree->container)
|
||||
{
|
||||
|
@ -377,6 +393,8 @@ gimp_item_tree_add_item (GimpItemTree *tree,
|
|||
g_return_if_fail (! gimp_item_is_attached (item));
|
||||
g_return_if_fail (gimp_item_get_image (item) == private->image);
|
||||
|
||||
gimp_item_tree_uniquefy_name (tree, item, NULL);
|
||||
|
||||
if (parent)
|
||||
container = gimp_viewable_get_children (GIMP_VIEWABLE (parent));
|
||||
else
|
||||
|
@ -541,6 +559,65 @@ gimp_item_tree_rename_item (GimpItemTree *tree,
|
|||
if (push_undo)
|
||||
gimp_image_undo_push_item_rename (item->image, undo_desc, item);
|
||||
|
||||
gimp_object_set_name (GIMP_OBJECT (item), new_name);
|
||||
gimp_item_tree_uniquefy_name (tree, item, new_name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* private functions */
|
||||
|
||||
static void
|
||||
gimp_item_tree_uniquefy_name (GimpItemTree *tree,
|
||||
GimpItem *item,
|
||||
const gchar *new_name)
|
||||
{
|
||||
GimpItemTreePrivate *private = GIMP_ITEM_TREE_GET_PRIVATE (tree);
|
||||
|
||||
if (new_name)
|
||||
{
|
||||
g_hash_table_remove (private->name_hash,
|
||||
gimp_object_get_name (item));
|
||||
|
||||
gimp_object_set_name (GIMP_OBJECT (item), new_name);
|
||||
}
|
||||
|
||||
while (g_hash_table_lookup (private->name_hash,
|
||||
gimp_object_get_name (item)))
|
||||
{
|
||||
gchar *name = g_strdup (gimp_object_get_name (item));
|
||||
gchar *ext = strrchr (name, '#');
|
||||
gint number = 0;
|
||||
|
||||
if (ext)
|
||||
{
|
||||
gchar *ext_str;
|
||||
|
||||
number = atoi (ext + 1);
|
||||
|
||||
ext_str = g_strdup_printf ("%d", number);
|
||||
|
||||
/* check if the extension really is of the form "#<n>" */
|
||||
if (! strcmp (ext_str, ext + 1))
|
||||
{
|
||||
*ext = '\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
number = 0;
|
||||
}
|
||||
|
||||
g_free (ext_str);
|
||||
}
|
||||
|
||||
number++;
|
||||
|
||||
gimp_object_take_name (GIMP_OBJECT (item),
|
||||
g_strdup_printf ("%s#%d", name, number));
|
||||
|
||||
g_free (name);
|
||||
}
|
||||
|
||||
g_hash_table_insert (private->name_hash,
|
||||
(gpointer) gimp_object_get_name (item),
|
||||
item);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue