# HG changeset patch # User Eric Warmenhoven # Date 1001157779 0 # Node ID 60c716c32c4013b59090e1103e7725ac2b9b2d32 # Parent dd5f18429dd96cd4011833d602a9d4c96e4a0d7c [gaim-migrate @ 2362] (Names changed to protect the innocent.) blue:~/gaim/app/src $ ls -l ~/.gaim/logs/mid.log -rw-r--r-- 1 eric eric 607043 Sep 20 03:28 /home/eric/.gaim/logs/mid.log Previously on my 1.4GHz Athlon, displaying this 600k log file in the Log Viewer took 42 seconds: time start: 1001157353 time end : 1001157395 Now, with the new smiley checker, it takes 23: time start: 1001157199 time end : 1001157222 That's still horrible, but it's only a little more than half the time it previously took. committer: Tailor Script diff -r dd5f18429dd9 -r 60c716c32c40 src/gtkimhtml.c --- a/src/gtkimhtml.c Sat Sep 22 10:36:29 2001 +0000 +++ b/src/gtkimhtml.c Sat Sep 22 11:22:59 2001 +0000 @@ -73,6 +73,161 @@ typedef struct _GtkIMHtmlBit GtkIMHtmlBit; typedef struct _FontDetail FontDetail; +struct _GtkSmileyTree { + GString *values; + GtkSmileyTree **children; + gchar **image; +}; + +static GtkSmileyTree* +gtk_smiley_tree_new () +{ + return g_new0 (GtkSmileyTree, 1); +} + +static void +gtk_smiley_tree_insert (GtkSmileyTree *tree, + const gchar *text, + gchar **image) +{ + GtkSmileyTree *t = tree; + const gchar *x = text; + + if (!strlen (x)) + return; + + while (*x) { + gchar *pos; + gint index; + + if (!t->values) + t->values = g_string_new (""); + + pos = strchr (t->values->str, *x); + if (!pos) { + t->values = g_string_append_c (t->values, *x); + index = t->values->len - 1; + t->children = g_realloc (t->children, t->values->len * sizeof (GtkSmileyTree *)); + t->children [index] = g_new0 (GtkSmileyTree, 1); + } else + index = (int) pos - (int) t->values->str; + + t = t->children [index]; + + x++; + } + + t->image = image; +} + +static void +gtk_smiley_tree_remove (GtkSmileyTree *tree, + const gchar *text) +{ + GtkSmileyTree *t = tree; + const gchar *x = text; + gint len = 0; + + while (*x) { + gchar *pos; + + if (t->image) { + t->image = NULL; + return; + } + + if (!t->values) + return; + + pos = strchr (t->values->str, *x); + if (pos) + t = t->children [(int) pos - (int) t->values->str]; + else + return; + + x++; len++; + } + + if (t->image) + t->image = NULL; +} + +static gint +gtk_smiley_tree_lookup (GtkSmileyTree *tree, + const gchar *text) +{ + GtkSmileyTree *t = tree; + const gchar *x = text; + gint len = 0; + + while (*x) { + gchar *pos; + + if (t->image) + return len; + + if (!t->values) + return 0; + + pos = strchr (t->values->str, *x); + if (pos) + t = t->children [(int) pos - (int) t->values->str]; + else + return 0; + + x++; len++; + } + + if (t->image) + return len; + + return 0; +} + +static gchar** +gtk_smiley_tree_image (GtkSmileyTree *tree, + const gchar *text) +{ + GtkSmileyTree *t = tree; + const gchar *x = text; + + while (*x) { + gchar *pos; + + if (!t->values) + return NULL; + + pos = strchr (t->values->str, *x); + if (pos) { + t = t->children [(int) pos - (int) t->values->str]; + } else + return NULL; + + x++; + } + + return t->image; +} + +static void +gtk_smiley_tree_destroy (GtkSmileyTree *tree) +{ + GSList *list = g_slist_append (NULL, tree); + + while (list) { + GtkSmileyTree *t = list->data; + gint i; + list = g_slist_remove(list, t); + if (t->values) { + for (i = 0; i < t->values->len; i++) + list = g_slist_append (list, t->children [i]); + g_string_free (t->values, TRUE); + g_free (t->children); + } + g_free (t); + } +} + struct _GtkIMHtmlBit { gint type; @@ -200,9 +355,7 @@ gdk_cursor_destroy (imhtml->hand_cursor); gdk_cursor_destroy (imhtml->arrow_cursor); - g_hash_table_destroy (imhtml->smiley_hash); - if (imhtml->smiley_start) - g_string_free (imhtml->smiley_start, TRUE); + gtk_smiley_tree_destroy (imhtml->smiley_data); if (GTK_OBJECT_CLASS (parent_class)->destroy != NULL) (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); @@ -1797,12 +1950,12 @@ } static void -gtk_imhtml_init_smiley_hash (GtkIMHtml *imhtml) +gtk_imhtml_init_smileys (GtkIMHtml *imhtml) { g_return_if_fail (imhtml != NULL); g_return_if_fail (GTK_IS_IMHTML (imhtml)); - imhtml->smiley_hash = g_hash_table_new (g_str_hash, g_str_equal); + imhtml->smiley_data = gtk_smiley_tree_new (); gtk_imhtml_associate_smiley (imhtml, ":)", smile_xpm); gtk_imhtml_associate_smiley (imhtml, ":-)", smile_xpm); @@ -1858,9 +2011,7 @@ imhtml->smileys = TRUE; imhtml->comments = FALSE; - imhtml->smin = G_MAXINT; - imhtml->smax = 0; - gtk_imhtml_init_smiley_hash (imhtml); + gtk_imhtml_init_smileys (imhtml); return GTK_WIDGET (imhtml); } @@ -1922,22 +2073,10 @@ g_return_if_fail (GTK_IS_IMHTML (imhtml)); g_return_if_fail (text != NULL); - if (strlen (text) < imhtml->smin) - imhtml->smin = strlen (text); - - if (strlen (text) > imhtml->smax) - imhtml->smax = strlen (text); - - if (!imhtml->smiley_start) - imhtml->smiley_start = g_string_new (""); - - if (!strchr (imhtml->smiley_start->str, text [0])) - imhtml->smiley_start = g_string_append_c (imhtml->smiley_start, text [0]); - if (xpm == NULL) - g_hash_table_remove (imhtml->smiley_hash, text); + gtk_smiley_tree_remove (imhtml->smiley_data, text); else - g_hash_table_insert (imhtml->smiley_hash, text, xpm); + gtk_smiley_tree_insert (imhtml->smiley_data, text, xpm); } static void @@ -2248,32 +2387,7 @@ gtk_imhtml_is_smiley (GtkIMHtml *imhtml, const gchar *text) { - gchar *tmp; - gint i; - - g_return_val_if_fail (imhtml != NULL, 0); - g_return_val_if_fail (GTK_IS_IMHTML (imhtml), 0); - g_return_val_if_fail (text != NULL, 0); - - if (!imhtml->smiley_start || !strchr (imhtml->smiley_start->str, text [0])) - return 0; - - tmp = g_malloc (imhtml->smax + 1); - - for (i = imhtml->smin; i <= imhtml->smax; i++) { - if (strlen (text) < i) { - g_free (tmp); - return 0; - } - g_snprintf (tmp, i + 1, "%s", text); - if (g_hash_table_lookup (imhtml->smiley_hash, tmp)) { - g_free (tmp); - return i; - } - } - - g_free (tmp); - return 0; + return gtk_smiley_tree_lookup (imhtml->smiley_data, text); } static GtkIMHtmlBit * @@ -2351,7 +2465,7 @@ bit->pm = gdk_pixmap_create_from_xpm_d (GTK_WIDGET (imhtml)->window, &bit->bm, clr, - g_hash_table_lookup (imhtml->smiley_hash, text)); + gtk_smiley_tree_image (imhtml->smiley_data, text)); } return bit; diff -r dd5f18429dd9 -r 60c716c32c40 src/gtkimhtml.h --- a/src/gtkimhtml.h Sat Sep 22 10:36:29 2001 +0000 +++ b/src/gtkimhtml.h Sat Sep 22 11:22:59 2001 +0000 @@ -37,6 +37,8 @@ typedef gchar** (*GtkIMHtmlImage) (gchar *url); +typedef struct _GtkSmileyTree GtkSmileyTree; + typedef struct _GtkIMHtml GtkIMHtml; typedef struct _GtkIMHtmlClass GtkIMHtmlClass; @@ -74,9 +76,7 @@ gboolean smileys; gboolean comments; - GHashTable *smiley_hash; - GString *smiley_start; - gint smin, smax; + GtkSmileyTree *smiley_data; }; struct _GtkIMHtmlClass {