Index: mail/message-list.c
===================================================================
RCS file: /cvs/gnome/evolution/mail/message-list.c,v
retrieving revision 1.438
diff -u -p -r1.438 message-list.c
--- mail/message-list.c	28 Sep 2006 08:56:51 -0000	1.438
+++ mail/message-list.c	20 Oct 2006 03:11:16 -0000
@@ -106,7 +106,7 @@ struct _MLSelection {
 
 struct _MessageListPrivate {
 	GtkWidget *invisible;	/* 4 selection */
-
+	GStringChunk *string_chunk;
 	struct _MLSelection clipboard;
 	gboolean destroyed;
 };
@@ -412,70 +412,20 @@ get_message_info (MessageList *message_l
 	return info;
 }
 
-static const char *
-get_normalised_string (MessageList *message_list, CamelMessageInfo *info, int col)
+static const gchar *
+get_normalised_string (MessageList *message_list, const gchar *string)
 {
-	const char *string, *str;
-	char *normalised;
-	EPoolv *poolv;
-	int index;
-	
-	switch (col) {
-	case COL_SUBJECT_NORM:
-		string = camel_message_info_subject (info);
-		index = NORMALISED_SUBJECT;
-		break;
-	case COL_FROM_NORM:
-		string = camel_message_info_from (info);
-		index = NORMALISED_FROM;
-		break;
-	case COL_TO_NORM:
-		string = camel_message_info_to (info);
-		index = NORMALISED_TO;
-		break;
-	default:
-		string = NULL;
-		index = NORMALISED_LAST;
-		g_assert_not_reached ();
-	}
-	
-	/* slight optimisation */
-	if (string == NULL || string[0] == '\0')
+	struct _MessageListPrivate *p = message_list->priv;
+	gchar *collation_key, *temp;
+
+	if (string == NULL || *string == '\0')
 		return "";
-	
-	poolv = g_hash_table_lookup (message_list->normalised_hash, camel_message_info_uid (info));
-	if (poolv == NULL) {
-		poolv = e_poolv_new (NORMALISED_LAST);
-		g_hash_table_insert (message_list->normalised_hash, (char *) camel_message_info_uid (info), poolv);
-	} else {
-		str = e_poolv_get (poolv, index);
-		if (*str)
-			return str;
-	}
-	
-	if (col == COL_SUBJECT_NORM) {
-		const unsigned char *subject;
-		
-		subject = (const unsigned char *) string;
-		while (!g_ascii_strncasecmp (subject, "Re:", 3)) {
-			subject += 3;
-			
-			/* jump over any spaces */
-			while (*subject && isspace ((int) *subject))
-				subject++;
-		}
-		
-		/* jump over any spaces */
-		while (*subject && isspace ((int) *subject))
-			subject++;
-		
-		string = (const char *) subject;
-	}
-	
-	normalised = g_utf8_collate_key (string, -1);
-	e_poolv_set (poolv, index, normalised, TRUE);
-	
-	return e_poolv_get (poolv, index);
+
+	temp = g_utf8_collate_key (string, -1);
+	collation_key = g_string_chunk_insert_const (p->string_chunk, temp);
+	g_free (temp);
+
+	return collation_key;
 }
 
 static void
@@ -1283,12 +1233,23 @@ ml_tree_value_at (ETreeModel *etm, ETree
 		str = camel_message_info_from (msg_info);
 		return (void *)(str ? str : "");
 	case COL_FROM_NORM:
-		return (void *) get_normalised_string (message_list, msg_info, col);
+		str = camel_message_info_from (msg_info);
+		return (void *) get_normalised_string (message_list, str);
 	case COL_SUBJECT:
 		str = camel_message_info_subject (msg_info);
 		return (void *)(str ? str : "");
 	case COL_SUBJECT_NORM:
-		return (void *) get_normalised_string (message_list, msg_info, col);
+		str = camel_message_info_subject (msg_info);
+		while (str != NULL && *str != '\0') {
+			/* skip over spaces and reply prefixes */
+			if (g_ascii_strncasecmp (str, "Re:", 3) == 0)
+				str += 3;
+			else if (g_ascii_isspace (*str))
+				str++;
+			else
+				break;
+		}
+		return (void *) get_normalised_string (message_list, str);
 	case COL_SENT: {
 		ETreePath child;
 
@@ -1312,7 +1273,8 @@ ml_tree_value_at (ETreeModel *etm, ETree
 		str = camel_message_info_to (msg_info);
 		return (void *)(str ? str : "");
 	case COL_TO_NORM:
-		return (void *) get_normalised_string (message_list, msg_info, col);
+		str = camel_message_info_to (msg_info);
+		return (void *) get_normalised_string (message_list, str);
 	case COL_SIZE:
 		return GINT_TO_POINTER (camel_message_info_size(msg_info));
 	case COL_DELETED:
@@ -2023,8 +1985,6 @@ message_list_init (MessageList *message_
 	gtk_scrolled_window_set_vadjustment ((GtkScrolledWindow *) message_list, adjustment);
 	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (message_list), GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
 	
-	message_list->normalised_hash = g_hash_table_new (g_str_hash, g_str_equal);
-	
 	message_list->hidden = NULL;
 	message_list->hidden_pool = NULL;
 	message_list->hide_before = ML_HIDE_NONE_START;
@@ -2039,6 +1999,7 @@ message_list_init (MessageList *message_
 
 	/* TODO: Should this only get the selection if we're realised? */
 	p = message_list->priv = g_malloc0(sizeof(*message_list->priv));
+	p->string_chunk = g_string_chunk_new (1024);
 	p->invisible = gtk_invisible_new();
 	p->destroyed = FALSE;
 	g_object_ref(p->invisible);
@@ -2055,14 +2016,6 @@ message_list_init (MessageList *message_
 	g_signal_connect (((GtkScrolledWindow *) message_list)->vscrollbar, "value-changed", G_CALLBACK (ml_scrolled), message_list);
 }
 
-static gboolean
-normalised_free (gpointer key, gpointer value, gpointer user_data)
-{
-	e_poolv_destroy (value);
-	
-	return TRUE;
-}
-
 static void
 message_list_destroy(GtkObject *object)
 {
@@ -2128,9 +2081,6 @@ message_list_finalise (GObject *object)
 	MessageList *message_list = MESSAGE_LIST (object);
 	struct _MessageListPrivate *p = message_list->priv;
 	
-	g_hash_table_foreach (message_list->normalised_hash, (GHFunc) normalised_free, NULL);
-	g_hash_table_destroy (message_list->normalised_hash);
-	
 	if (message_list->thread_tree)
 		camel_folder_thread_messages_unref(message_list->thread_tree);
 
@@ -2152,6 +2102,8 @@ message_list_finalise (GObject *object)
 
 	clear_selection(message_list, &p->clipboard);
 
+	g_string_chunk_free(p->string_chunk);
+
 	g_free(p);
 
 	G_OBJECT_CLASS (message_list_parent_class)->finalize (object);
@@ -2941,17 +2893,6 @@ main_folder_changed (CamelObject *o, gpo
 		d(printf("changed = %d added = %d removed = %d\n",
 			 changes->uid_changed->len, changes->uid_added->len, changes->uid_removed->len));
 		
-		for (i = 0; i < changes->uid_removed->len; i++) {
-			/* uncache the normalised strings for these uids */
-			EPoolv *poolv;
-			
-			poolv = g_hash_table_lookup (ml->normalised_hash, changes->uid_removed->pdata[i]);
-			if (poolv != NULL) {
-				g_hash_table_remove (ml->normalised_hash, changes->uid_removed->pdata[i]);
-				e_poolv_destroy (poolv);
-			}
-		}
-		
 		/* check if the hidden state has changed, if so modify accordingly, then regenerate */
 		if (ml->hidejunk || ml->hidedeleted)
 			mail_folder_hide_by_flag (folder, ml, &changes, (ml->hidejunk ? CAMEL_MESSAGE_JUNK : 0) | (ml->hidedeleted ? CAMEL_MESSAGE_DELETED : 0));
@@ -3027,9 +2968,6 @@ message_list_set_folder (MessageList *me
 		g_source_remove (message_list->idle_id);
 		message_list->idle_id = 0;
 	}
-	
-	/* reset the normalised sort performance hack */
-	g_hash_table_foreach_remove (message_list->normalised_hash, normalised_free, NULL);
 	
 	mail_regen_cancel(message_list);
 	
Index: mail/message-list.h
===================================================================
RCS file: /cvs/gnome/evolution/mail/message-list.h,v
retrieving revision 1.93
diff -u -p -r1.93 message-list.h
--- mail/message-list.h	28 Sep 2006 08:56:51 -0000	1.93
+++ mail/message-list.h	20 Oct 2006 03:11:19 -0000
@@ -101,8 +101,6 @@ struct _MessageList {
 
 	GHashTable *uid_nodemap; /* uid (from info) -> tree node mapping */
 	
-	GHashTable *normalised_hash;
-	
 	/* UID's to hide.  Keys in the mempool */
 	/* IMPORTANT: You MUST have obtained the hide lock, to operate on this data */
 	GHashTable	 *hidden;
