Re: [Evolution-hackers] Performance with Exchange 2003




> I will look into it when i can, I've been busy with meetings lately.
> 

Thanks for taking this seriously, I was afraid I was getting blown
off ;-)
I think it was a bit frustrating from both ends, working out the problem and what to do about it.
> I'm concerned that even though your patch fixes this symptom, the
> problem is still in the code somewhere.  So even though the 'normal'
> case will be fixed, if the user sets a search for example, it will
> re-expose the underlying problem. I'd rather have that get fixed too,
> and not just the common case.
> 

Indeed, I have found this to be the case.  Even with my patch,
regenerating the message list can take absurdly long sometimes,
typically when clearing a previous search.

Ok, good, worth looking into then.

> It would be really handy if you could get a backtrace of WHEN it is in
> the middle of one of these >10 second update times(i.e. ctrl-c while
> it is running slow).  Of all threads (thread apply all bt).  That
> should show clearly what all threads are doing and help pinpoint how
> the lock contention (if indeed, thats what it is), is happening.  The
> other trace only has 1 thread, and doesnt show anything other than
> normal expected operation either.  I am guessing a code walkthrough
> will also pick this up, but a backtrace will reduce the doubt and
> search time.

That backtrace was from such a time, and I have found a few spots where

But it only contained 1 thread.  So it doesn't show anything abnormal. Definitely need all threads.  It shouldn't be hard to get.

I had a quick look at the code last night, and nothing grabbed me so far.  At least the entry point for the search code gets the list of messages atomically, so it can't be that.  It is probably something in the vfolder code, which has changed a fair bit from previous versions.

I just had another quick look at the code - there seems to be a few places where we iterate over the folder-summary 1 message at a time, using camel_folder_summary_index, from calculating the number of junk/unread/deleted messages to synchronising vfolders.  These could be great candidates for lock contention - but should be easy to fix too & should free up a tiny amount of processing to boot.  camel_folder_summary_array_free() should also be atomic.

that code path can be optimized a bit.  Specifically there are a few
more places where searches for "" can be better optimized away, that my
patch definitely hides.  It does look like lock contention could be the
main problem.  I'll get a complete backtrace ASAP.

Could you try the attached patch to camel?  It removes most of the one-at-a-time stuff from the core camel objects.

It might make a difference, or it might not - there patches of code in mail which might need similar treatment.

Michael

Index: camel/ChangeLog
===================================================================
RCS file: /cvs/gnome/evolution-data-server/camel/ChangeLog,v
retrieving revision 1.2446
diff -u -p -r1.2446 ChangeLog
--- camel/ChangeLog	27 Apr 2005 08:28:50 -0000	1.2446
+++ camel/ChangeLog	5 May 2005 06:06:34 -0000
@@ -1,3 +1,20 @@
+2005-05-05  Not Zed  <NotZed Ximian com>
+
+	* camel-folder-summary.c (summary_header_save) just access the
+	messages array directly, as folder_summary_save does.
+
+	* camel-vtrash-folder.c (vtrash_getv): 
+
+	* camel-vee-folder.c (vee_folder_remove_folder)
+	(subfolder_renamed_update): 
+
+	* camel-folder.c (folder_getv, get_uids): get all summary items/free all
+	summary items in one go, rather than one at a time.  reduce
+	locking spin.
+
+	* camel-folder-summary.c (camel_folder_summary_array_free): only
+	lock once around the whole array free.
+
 2005-04-26  Ross Burton  <ross burtonini com>
 
 	* camel/broken-date-parser.c:
Index: camel/camel-folder-summary.c
===================================================================
RCS file: /cvs/gnome/evolution-data-server/camel/camel-folder-summary.c,v
retrieving revision 1.141
diff -u -p -r1.141 camel-folder-summary.c
--- camel/camel-folder-summary.c	4 Apr 2005 19:09:20 -0000	1.141
+++ camel/camel-folder-summary.c	5 May 2005 06:06:35 -0000
@@ -388,8 +388,34 @@ camel_folder_summary_array_free(CamelFol
 	int i;
 
 	/* FIXME: do the locking around the whole lot to make it faster */
-	for (i=0;i<array->len;i++)
-		camel_message_info_free(array->pdata[i]);
+
+	CAMEL_SUMMARY_LOCK(s, ref_lock);
+
+	for (i=0;i<array->len;i++) {
+		CamelMessageInfo *mi = array->pdata[i];
+
+		mi->refcount--;
+		if (mi->refcount > 0) {
+			/* still alive, skip freeing it after */
+			g_ptr_array_remove_index_fast(array, i);
+			i--;
+		}
+	}
+
+	CAMEL_SUMMARY_UNLOCK(s, ref_lock);
+
+	for (i=0;i<array->len;i++) {
+		CamelMessageInfo *mi = array->pdata[i];
+
+		/* NB: This is copied from camel_message_info_free */
+		/* FIXME: this is kinda busted, should really be handled by message info free */
+		if (mi->summary->build_content
+		    && ((CamelMessageInfoBase *)mi)->content) {
+			camel_folder_summary_content_info_free(mi->summary, ((CamelMessageInfoBase *)mi)->content);
+		}
+
+		((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(mi->summary)))->message_info_free(mi->summary, mi);
+	}
 
 	g_ptr_array_free(array, TRUE);
 }
@@ -1387,14 +1413,11 @@ summary_header_save(CamelFolderSummary *
 	camel_file_util_encode_fixed_int32(out, s->nextuid);
 	camel_file_util_encode_time_t(out, s->time);
 
-	count = camel_folder_summary_count(s);
+	count = s->messages->len;
 	for (i=0; i<count; i++) {
-		CamelMessageInfo *info = camel_folder_summary_index(s, i);
+		CamelMessageInfo *info = s->messages->pdata[i];
 		guint32 flags;
 
-		if (info == NULL)
-			continue;
-
 		flags = camel_message_info_flags(info);
 		if ((flags & CAMEL_MESSAGE_SEEN) == 0)
 			unread++;
@@ -1402,8 +1425,6 @@ summary_header_save(CamelFolderSummary *
 			deleted++;
 		if ((flags & CAMEL_MESSAGE_JUNK) != 0)
 			junk++;
-
-		camel_message_info_free(info);
 	}
 
 	camel_file_util_encode_fixed_int32(out, count);
Index: camel/camel-folder.c
===================================================================
RCS file: /cvs/gnome/evolution-data-server/camel/camel-folder.c,v
retrieving revision 1.207
diff -u -p -r1.207 camel-folder.c
--- camel/camel-folder.c	2 Dec 2004 08:03:30 -0000	1.207
+++ camel/camel-folder.c	5 May 2005 06:06:35 -0000
@@ -345,26 +345,25 @@ folder_getv(CamelObject *object, CamelEx
 			/* This is so we can get the values atomically, and also so we can calculate them only once */
 			if (unread == -1) {
 				int j;
-				CamelMessageInfo *info;
+				GPtrArray *summary;
 
 				/* TODO: Locking? */
 				unread = 0;
-				count = camel_folder_summary_count(folder->summary);
-				for (j=0; j<count; j++) {
-					if ((info = camel_folder_summary_index(folder->summary, j))) {
-						guint32 flags = camel_message_info_flags(info);
-
-						if ((flags & (CAMEL_MESSAGE_SEEN|CAMEL_MESSAGE_DELETED|CAMEL_MESSAGE_JUNK)) == 0)
-							unread++;
-						if (flags & CAMEL_MESSAGE_DELETED)
-							deleted++;
-						if (flags & CAMEL_MESSAGE_JUNK)
-							junked++;
-						if ((flags & (CAMEL_MESSAGE_DELETED|CAMEL_MESSAGE_JUNK)) == 0)
-							visible++;
-						camel_message_info_free(info);
-					}
+				summary = camel_folder_summary_array(folder->summary);
+				for (j=0; j<summary->len; j++) {
+					CamelMessageInfo *info = summary->pdata[j];
+					guint32 flags = camel_message_info_flags(info);
+
+					if ((flags & (CAMEL_MESSAGE_SEEN|CAMEL_MESSAGE_DELETED|CAMEL_MESSAGE_JUNK)) == 0)
+						unread++;
+					if (flags & CAMEL_MESSAGE_DELETED)
+						deleted++;
+					if (flags & CAMEL_MESSAGE_JUNK)
+						junked++;
+					if ((flags & (CAMEL_MESSAGE_DELETED|CAMEL_MESSAGE_JUNK)) == 0)
+						visible++;
 				}
+				camel_folder_summary_array_free(folder->summary, summary);
 			}
 
 			switch (tag & CAMEL_ARG_TAG) {
@@ -386,18 +385,18 @@ folder_getv(CamelObject *object, CamelEx
 			break;
 		case CAMEL_FOLDER_ARG_UID_ARRAY: {
 			int j;
-			CamelMessageInfo *info;
+			GPtrArray *summary;
 			GPtrArray *array;
 
-			count = camel_folder_summary_count(folder->summary);
+			summary = camel_folder_summary_array(folder->summary);
 			array = g_ptr_array_new();
-			g_ptr_array_set_size(array, count);
-			for (j=0; j<count; j++) {
-				if ((info = camel_folder_summary_index(folder->summary, j))) {
-					array->pdata[i] = g_strdup(camel_message_info_uid(info));
-					camel_message_info_free(info);
-				}
+			g_ptr_array_set_size(array, summary->len);
+			for (j=0; j<summary->len; j++) {
+				CamelMessageInfo *info = summary->pdata[j];
+
+				array->pdata[j] = g_strdup(camel_message_info_uid(info));
 			}
+			camel_folder_summary_array_free(folder->summary, summary);
 			*arg->ca_ptr = array;
 			break; }
 		case CAMEL_FOLDER_ARG_INFO_ARRAY:
@@ -1052,26 +1051,22 @@ camel_folder_get_message (CamelFolder *f
 static GPtrArray *
 get_uids(CamelFolder *folder)
 {
+	int j;
+	GPtrArray *summary;
 	GPtrArray *array;
-	int i, j, count;
 
 	array = g_ptr_array_new();
-
 	g_return_val_if_fail(folder->summary != NULL, array);
 
-	count = camel_folder_summary_count(folder->summary);
-	g_ptr_array_set_size(array, count);
-	for (i = 0, j = 0; i < count; i++) {
-		CamelMessageInfo *info = camel_folder_summary_index(folder->summary, i);
-		
-		if (info) {
-			array->pdata[j++] = g_strdup (camel_message_info_uid (info));
-			camel_message_info_free(info);
-		}
+	summary = camel_folder_summary_array(folder->summary);
+	g_ptr_array_set_size(array, summary->len);
+	for (j=0; j<summary->len; j++) {
+		CamelMessageInfo *info = summary->pdata[j];
+
+		array->pdata[j] = g_strdup(camel_message_info_uid(info));
 	}
-	
-	g_ptr_array_set_size (array, j);
-	
+	camel_folder_summary_array_free(folder->summary, summary);
+
 	return array;
 }
 
@@ -1083,6 +1078,8 @@ get_uids(CamelFolder *folder)
  * for finding what messages are available when the folder does not
  * support summaries. The returned array shoudl not be modified, and
  * must be freed by passing it to camel_folder_free_uids().
+ *
+ * This api is DEPRECATED.  Use camel_object_get(CAMEL_FOLDER_UID_ARRAY) instead.
  *
  * Return value: GPtrArray of UIDs corresponding to the messages
  * available in the folder.
Index: camel/camel-vee-folder.c
===================================================================
RCS file: /cvs/gnome/evolution-data-server/camel/camel-vee-folder.c,v
retrieving revision 1.74
diff -u -p -r1.74 camel-vee-folder.c
--- camel/camel-vee-folder.c	1 Feb 2005 08:37:04 -0000	1.74
+++ camel/camel-vee-folder.c	5 May 2005 06:06:36 -0000
@@ -699,7 +699,7 @@ vee_folder_add_uid(CamelVeeFolder *vf, C
 static void
 vee_folder_remove_folder(CamelVeeFolder *vf, CamelFolder *source)
 {
-	int i, count, n, still = FALSE, start, last;
+	int i, n, still = FALSE, start, last;
 	char *oldkey;
 	CamelFolder *folder = (CamelFolder *)vf;
 	char hash[8];
@@ -710,6 +710,7 @@ vee_folder_remove_folder(CamelVeeFolder 
 	GHashTable *unmatched_uids = vf->parent_vee_store ? vf->parent_vee_store->unmatched_uids : NULL;
 	CamelFolderSummary *ssummary = source->summary;
 	int killun = FALSE;
+	GPtrArray *sarray;
 
 	if (vf == folder_unmatched)
 		return;
@@ -734,79 +735,77 @@ vee_folder_remove_folder(CamelVeeFolder 
 		if (killun) {
 			start = -1;
 			last = -1;
-			count = camel_folder_summary_count(((CamelFolder *)folder_unmatched)->summary);
-			for (i=0;i<count;i++) {
-				CamelVeeMessageInfo *mi = (CamelVeeMessageInfo *)camel_folder_summary_index(((CamelFolder *)folder_unmatched)->summary, i);
-				
-				if (mi) {
-					if (mi->real->summary == ssummary) {
-						camel_folder_change_info_remove_uid(folder_unmatched->changes, camel_message_info_uid(mi));
-						if (last == -1) {
-							last = start = i;
-						} else if (last+1 == i) {
-							last = i;
-						} else {
-							camel_folder_summary_remove_range(((CamelFolder *)folder_unmatched)->summary, start, last);
-							i -= (last-start)+1;
-							start = last = i;
-						}
+			sarray = camel_folder_summary_array(((CamelFolder *)folder_unmatched)->summary);
+			for (i=0;i<sarray->len;i++) {
+				CamelVeeMessageInfo *mi = sarray->pdata[i];
+
+				if (mi->real->summary == ssummary) {
+					camel_folder_change_info_remove_uid(folder_unmatched->changes, camel_message_info_uid(mi));
+					if (last == -1) {
+						last = start = i;
+					} else if (last+1 == i) {
+						last = i;
+					} else {
+						camel_folder_summary_remove_range(((CamelFolder *)folder_unmatched)->summary, start, last);
+						i -= (last-start)+1;
+						start = last = i;
 					}
-					camel_message_info_free((CamelMessageInfo *)mi);
 				}
 			}
 			if (last != -1)
 				camel_folder_summary_remove_range(((CamelFolder *)folder_unmatched)->summary, start, last);
+			camel_folder_summary_array_free(((CamelFolder *)folder_unmatched)->summary, sarray);
 		}
 	}
 
 	start = -1;
 	last = -1;
-	count = camel_folder_summary_count(folder->summary);
-	for (i=0;i<count;i++) {
-		CamelVeeMessageInfo *mi = (CamelVeeMessageInfo *)camel_folder_summary_index(folder->summary, i);
-		if (mi) {
-			if (mi->real->summary == ssummary) {
-				const char *uid = camel_message_info_uid(mi);
+	sarray = camel_folder_summary_array(folder->summary);
+	for (i=0;i<sarray->len;i++) {
+		CamelVeeMessageInfo *mi = sarray->pdata[i];
 
-				camel_folder_change_info_remove_uid(vf->changes, uid);
+		if (mi->real->summary == ssummary) {
+			const char *uid = camel_message_info_uid(mi);
 
-				if (last == -1) {
-					last = start = i;
-				} else if (last+1 == i) {
-					last = i;
-				} else {
-					camel_folder_summary_remove_range(folder->summary, start, last);
-					i -= (last-start)+1;
-					start = last = i;
-				}
-				if ((vf->flags & CAMEL_STORE_FOLDER_PRIVATE) == 0 && folder_unmatched != NULL) {
-					if (still) {
-						if (g_hash_table_lookup_extended(unmatched_uids, uid, (void **)&oldkey, &oldval)) {
-							n = GPOINTER_TO_INT (oldval);
-							if (n == 1) {
-								g_hash_table_remove(unmatched_uids, oldkey);
-								if (vee_folder_add_uid(folder_unmatched, source, oldkey+8, hash))
-									camel_folder_change_info_add_uid(folder_unmatched->changes, oldkey);
-								g_free(oldkey);
-							} else {
-								g_hash_table_insert(unmatched_uids, oldkey, GINT_TO_POINTER(n-1));
-							}
-						}
-					} else {
-						if (g_hash_table_lookup_extended(unmatched_uids, camel_message_info_uid(mi), (void **)&oldkey, &oldval)) {
+			camel_folder_change_info_remove_uid(vf->changes, uid);
+
+			if (last == -1) {
+				last = start = i;
+			} else if (last+1 == i) {
+				last = i;
+			} else {
+				camel_folder_summary_remove_range(folder->summary, start, last);
+				i -= (last-start)+1;
+				start = last = i;
+			}
+			if ((vf->flags & CAMEL_STORE_FOLDER_PRIVATE) == 0 && folder_unmatched != NULL) {
+				if (still) {
+					if (g_hash_table_lookup_extended(unmatched_uids, uid, (void **)&oldkey, &oldval)) {
+						n = GPOINTER_TO_INT (oldval);
+						if (n == 1) {
 							g_hash_table_remove(unmatched_uids, oldkey);
+							if (vee_folder_add_uid(folder_unmatched, source, oldkey+8, hash))
+								camel_folder_change_info_add_uid(folder_unmatched->changes, oldkey);
 							g_free(oldkey);
+						} else {
+							g_hash_table_insert(unmatched_uids, oldkey, GINT_TO_POINTER(n-1));
 						}
 					}
+				} else {
+					if (g_hash_table_lookup_extended(unmatched_uids, camel_message_info_uid(mi), (void **)&oldkey, &oldval)) {
+						g_hash_table_remove(unmatched_uids, oldkey);
+						g_free(oldkey);
+					}
 				}
 			}
-			camel_message_info_free((CamelMessageInfo *)mi);
 		}
 	}
 
 	if (last != -1)
 		camel_folder_summary_remove_range(folder->summary, start, last);
 
+	camel_folder_summary_array_free(folder->summary, sarray);
+
 	if (folder_unmatched) {
 		if (camel_folder_change_info_changed(folder_unmatched->changes)) {
 			unmatched_changes = folder_unmatched->changes;
@@ -895,12 +894,13 @@ vee_rebuild_folder(CamelVeeFolder *vf, C
 	GHashTable *allhash, *matchhash;
 	CamelFolder *f = source;
 	CamelFolder *folder = (CamelFolder *)vf;
-	int i, n, count, start, last;
+	int i, n, start, last;
 	struct _update_data u;
 	CamelFolderChangeInfo *vf_changes = NULL, *unmatched_changes = NULL;
 	CamelVeeFolder *folder_unmatched = vf->parent_vee_store ? vf->parent_vee_store->folder_unmatched : NULL;
 	GHashTable *unmatched_uids = vf->parent_vee_store ? vf->parent_vee_store->unmatched_uids : NULL;
 	CamelFolderSummary *ssummary = source->summary;
+	GPtrArray *sarray;
 
 	if (vf == folder_unmatched)
 		return 0;
@@ -940,73 +940,70 @@ vee_rebuild_folder(CamelVeeFolder *vf, C
 	/* scan, looking for "old" uid's to be removed */
 	start = -1;
 	last = -1;
-	count = camel_folder_summary_count(folder->summary);
-	for (i=0;i<count;i++) {
-		CamelVeeMessageInfo *mi = (CamelVeeMessageInfo *)camel_folder_summary_index(folder->summary, i);
+	sarray = camel_folder_summary_array(folder->summary);
+	for (i=0;i<sarray->len;i++) {
+		CamelVeeMessageInfo *mi = sarray->pdata[i];
 
-		if (mi) {
-			if (mi->real->summary == ssummary) {
-				char *uid = (char *)camel_message_info_uid(mi), *oldkey;
-				void *oldval;
-				
-				if (g_hash_table_lookup(matchhash, uid+8) == NULL) {
-					if (last == -1) {
-						last = start = i;
-					} else if (last+1 == i) {
-						last = i;
+		if (mi->real->summary == ssummary) {
+			char *uid = (char *)camel_message_info_uid(mi), *oldkey;
+			void *oldval;
+
+			if (g_hash_table_lookup(matchhash, uid+8) == NULL) {
+				if (last == -1) {
+					last = start = i;
+				} else if (last+1 == i) {
+					last = i;
+				} else {
+					camel_folder_summary_remove_range(folder->summary, start, last);
+					i -= (last-start)+1;
+					start = last = i;
+				}
+				camel_folder_change_info_remove_uid(vf->changes, camel_message_info_uid(mi));
+				if (!CAMEL_IS_VEE_FOLDER(source)
+				    && unmatched_uids != NULL
+				    && g_hash_table_lookup_extended(unmatched_uids, uid, (void **)&oldkey, &oldval)) {
+					n = GPOINTER_TO_INT (oldval);
+					if (n == 1) {
+						g_hash_table_remove(unmatched_uids, oldkey);
+						g_free(oldkey);
 					} else {
-						camel_folder_summary_remove_range(folder->summary, start, last);
-						i -= (last-start)+1;
-						start = last = i;
+						g_hash_table_insert(unmatched_uids, oldkey, GINT_TO_POINTER(n-1));
 					}
-					camel_folder_change_info_remove_uid(vf->changes, camel_message_info_uid(mi));
-					if (!CAMEL_IS_VEE_FOLDER(source)
-					    && unmatched_uids != NULL
-					    && g_hash_table_lookup_extended(unmatched_uids, uid, (void **)&oldkey, &oldval)) {
-						n = GPOINTER_TO_INT (oldval);
-						if (n == 1) {
-							g_hash_table_remove(unmatched_uids, oldkey);
-							g_free(oldkey);
-						} else {
-							g_hash_table_insert(unmatched_uids, oldkey, GINT_TO_POINTER(n-1));
-						}
-					}
-				} else {
-					g_hash_table_remove(matchhash, uid+8);
 				}
+			} else {
+				g_hash_table_remove(matchhash, uid+8);
 			}
-			camel_message_info_free((CamelMessageInfo *)mi);
 		}
 	}
 	if (last != -1)
 		camel_folder_summary_remove_range(folder->summary, start, last);
+	camel_folder_summary_array_free(folder->summary, sarray);
 
 	/* now matchhash contains any new uid's, add them, etc */
 	g_hash_table_foreach(matchhash, (GHFunc)folder_added_uid, &u);
 
 	if (folder_unmatched != NULL) {
 		/* scan unmatched, remove any that have vanished, etc */
-		count = camel_folder_summary_count(((CamelFolder *)folder_unmatched)->summary);
-		for (i=0;i<count;i++) {
-			CamelVeeMessageInfo *mi = (CamelVeeMessageInfo *)camel_folder_summary_index(((CamelFolder *)folder_unmatched)->summary, i);
+		sarray = camel_folder_summary_array(((CamelFolder *)folder_unmatched)->summary);
+		for (i=0;i<sarray->len;i++) {
+			CamelVeeMessageInfo *mi = sarray->pdata[i];
 
-			if (mi) {
-				if (mi->real->summary == ssummary) {
-					char *uid = (char *)camel_message_info_uid(mi);
+			if (mi->real->summary == ssummary) {
+				char *uid = (char *)camel_message_info_uid(mi);
 
-					if (g_hash_table_lookup(allhash, uid+8) == NULL) {
-						/* no longer exists at all, just remove it entirely */
-						camel_folder_summary_remove_index(((CamelFolder *)folder_unmatched)->summary, i);
-						camel_folder_change_info_remove_uid(folder_unmatched->changes, camel_message_info_uid(mi));
-						i--;
-					} else {
-						g_hash_table_remove(allhash, uid+8);
-					}
+				if (g_hash_table_lookup(allhash, uid+8) == NULL) {
+					/* no longer exists at all, just remove it entirely */
+					camel_folder_summary_remove_index(((CamelFolder *)folder_unmatched)->summary, i);
+					camel_folder_change_info_remove_uid(folder_unmatched->changes, camel_message_info_uid(mi));
+					i--;
+				} else {
+					g_hash_table_remove(allhash, uid+8);
 				}
-				camel_message_info_free((CamelMessageInfo *)mi);
 			}
 		}
 
+		camel_folder_summary_array_free(((CamelFolder *)folder_unmatched)->summary, sarray);
+
 		/* now allhash contains all potentially new uid's for the unmatched folder, process */
 		if (!CAMEL_IS_VEE_FOLDER(source))
 			g_hash_table_foreach(allhash, (GHFunc)unmatched_check_uid, &u);
@@ -1473,17 +1470,15 @@ subfolder_renamed_update(CamelVeeFolder 
 	CamelVeeFolder *folder_unmatched = vf->parent_vee_store ? vf->parent_vee_store->folder_unmatched : NULL;
 	GHashTable *unmatched_uids = vf->parent_vee_store ? vf->parent_vee_store->unmatched_uids : NULL;
 	CamelFolderSummary *ssummary = sub->summary;
+	GPtrArray *sarray;
 
 	CAMEL_VEE_FOLDER_LOCK(vf, summary_lock);
 
-	count = camel_folder_summary_count(((CamelFolder *)vf)->summary);
-	for (i=0;i<count;i++) {
-		CamelVeeMessageInfo *mi = (CamelVeeMessageInfo *)camel_folder_summary_index(((CamelFolder *)vf)->summary, i);
+	sarray = camel_folder_summary_array(((CamelFolder *)vf)->summary);
+	for (i=0;i<sarray->len;i++) {
+		CamelVeeMessageInfo *mi = sarray->pdata[i];
 		CamelVeeMessageInfo *vinfo;
 
-		if (mi == NULL)
-			continue;
-
 		if (mi->real->summary == ssummary) {
 			char *uid = (char *)camel_message_info_uid(mi);
 			char *oldkey;
@@ -1508,9 +1503,9 @@ subfolder_renamed_update(CamelVeeFolder 
 				g_free(oldkey);
 			}
 		}
-
-		camel_message_info_free((CamelMessageInfo *)mi);
 	}
+
+	camel_folder_summary_array_free(((CamelFolder *)vf)->summary, sarray);
 
 	if (camel_folder_change_info_changed(vf->changes)) {
 		changes = vf->changes;
Index: camel/camel-vtrash-folder.c
===================================================================
RCS file: /cvs/gnome/evolution-data-server/camel/camel-vtrash-folder.c,v
retrieving revision 1.17
diff -u -p -r1.17 camel-vtrash-folder.c
--- camel/camel-vtrash-folder.c	1 Feb 2005 08:37:04 -0000	1.17
+++ camel/camel-vtrash-folder.c	5 May 2005 06:06:36 -0000
@@ -131,26 +131,25 @@ vtrash_getv(CamelObject *object, CamelEx
 			/* This is so we can get the values atomically, and also so we can calculate them only once */
 			if (unread == -1) {
 				int j;
-				CamelMessageInfo *info;
+				GPtrArray *summary;
 
 				unread = 0;
-				count = camel_folder_summary_count(folder->summary);
-				for (j=0; j<count; j++) {
-					if ((info = camel_folder_summary_index(folder->summary, j))) {
-						guint32 flags = camel_message_info_flags(info);
+				summary = camel_folder_summary_array(folder->summary);
+				for (j=0; j<summary->len; j++) {
+					CamelMessageInfo *info = summary->pdata[j];
+					guint32 flags = camel_message_info_flags(info);
 
-						if ((flags & (CAMEL_MESSAGE_SEEN)) == 0)
-							unread++;
-						if (flags & CAMEL_MESSAGE_DELETED)
-							deleted++;
-						if (flags & CAMEL_MESSAGE_JUNK)
-							junked++;
-						if ((flags & (CAMEL_MESSAGE_DELETED|CAMEL_MESSAGE_JUNK)) == 0)
-							visible++;
-						camel_message_info_free(info);
-					}
+					if ((flags & (CAMEL_MESSAGE_SEEN)) == 0)
+						unread++;
+					if (flags & CAMEL_MESSAGE_DELETED)
+						deleted++;
+					if (flags & CAMEL_MESSAGE_JUNK)
+						junked++;
+					if ((flags & (CAMEL_MESSAGE_DELETED|CAMEL_MESSAGE_JUNK)) == 0)
+						visible++;
 				}
+				camel_folder_summary_array_free(folder->summary, summary);
 			}
 
 			switch (tag & CAMEL_ARG_TAG) {


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]