aboutsummaryrefslogtreecommitdiffstats
path: root/camel
diff options
context:
space:
mode:
Diffstat (limited to 'camel')
-rw-r--r--camel/ChangeLog11
-rw-r--r--camel/camel-folder-summary.c42
-rw-r--r--camel/camel-vee-folder.c51
3 files changed, 96 insertions, 8 deletions
diff --git a/camel/ChangeLog b/camel/ChangeLog
index 1fac038131..61d30384d2 100644
--- a/camel/ChangeLog
+++ b/camel/ChangeLog
@@ -1,3 +1,14 @@
+2003-06-17 Not Zed <NotZed@Ximian.com>
+
+ * camel-vee-folder.c (vee_folder_remove_folder): Calculate ranges
+ to remove folder info's more efficiently. affects shutdown
+ performance on big vfolders signifinantly.
+ (vee_folder_build_folder): do the same here, when rebuilding a
+ folder's definition.
+
+ * camel-folder-summary.c (camel_folder_summary_remove_index): new
+ function to drop a range of index entries in one hit.
+
2003-06-16 Not Zed <NotZed@Ximian.com>
** See bug #44322
diff --git a/camel/camel-folder-summary.c b/camel/camel-folder-summary.c
index 0a05d172ef..d584750055 100644
--- a/camel/camel-folder-summary.c
+++ b/camel/camel-folder-summary.c
@@ -1186,6 +1186,48 @@ void camel_folder_summary_remove_index(CamelFolderSummary *s, int index)
}
}
+/**
+ * camel_folder_summary_remove_range:
+ * @s:
+ * @start: initial index
+ * @end: last index to remove
+ *
+ * Removes an indexed range of info records.
+ **/
+void camel_folder_summary_remove_range(CamelFolderSummary *s, int start, int end)
+{
+ if (end <= start+1)
+ return;
+
+ CAMEL_SUMMARY_LOCK(s, summary_lock);
+ if (start < s->messages->len) {
+ CamelMessageInfo **infos;
+ int i;
+
+ end = MIN(end+1, s->messages->len);
+ infos = g_malloc((end-start)*sizeof(infos[0]));
+
+ for (i=start;i<end;i++) {
+ CamelMessageInfo *info = s->messages->pdata[i];
+
+ infos[i-start] = info;
+ g_hash_table_remove(s->messages_uid, camel_message_info_uid(info));
+ }
+
+ memmove(s->messages->pdata+start, s->messages->pdata+end, (s->messages->len-end)*sizeof(s->messages->pdata[0]));
+ g_ptr_array_set_size(s->messages, s->messages->len - (end - start));
+ s->flags |= CAMEL_SUMMARY_DIRTY;
+
+ CAMEL_SUMMARY_UNLOCK(s, summary_lock);
+
+ for (i=start;i<end;i++)
+ camel_folder_summary_info_free(s, infos[i-start]);
+ g_free(infos);
+ } else {
+ CAMEL_SUMMARY_UNLOCK(s, summary_lock);
+ }
+}
+
/* should be sorted, for binary search */
/* This is a tokenisation mechanism for strings written to the
summary - to save space.
diff --git a/camel/camel-vee-folder.c b/camel/camel-vee-folder.c
index a20565f56c..805f800b60 100644
--- a/camel/camel-vee-folder.c
+++ b/camel/camel-vee-folder.c
@@ -896,7 +896,7 @@ vee_folder_add_uid(CamelVeeFolder *vf, CamelFolder *f, const char *inuid, const
static void
vee_folder_remove_folder(CamelVeeFolder *vf, CamelFolder *source, int killun)
{
- int i, count, n, still;
+ int i, count, n, still, start, last;
char *oldkey;
CamelFolder *folder = (CamelFolder *)vf;
char hash[8];
@@ -921,21 +921,34 @@ vee_folder_remove_folder(CamelVeeFolder *vf, CamelFolder *source, int killun)
/* See if we just blow all uid's from this folder away from unmatched, regardless */
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->folder == source) {
- 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--;
+ 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_folder_summary_info_free(((CamelFolder *)folder_unmatched)->summary, (CamelMessageInfo *)mi);
}
}
+ if (last != -1)
+ camel_folder_summary_remove_range(((CamelFolder *)folder_unmatched)->summary, start, last);
}
+ 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);
@@ -944,8 +957,16 @@ vee_folder_remove_folder(CamelVeeFolder *vf, CamelFolder *source, int killun)
const char *uid = camel_message_info_uid(mi);
camel_folder_change_info_remove_uid(vf->changes, uid);
- camel_folder_summary_remove_index(folder->summary, i);
- i--;
+
+ 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) {
if (still) {
if (g_hash_table_lookup_extended(unmatched_uids, uid, (void **)&oldkey, (void **)&n)) {
@@ -970,6 +991,9 @@ vee_folder_remove_folder(CamelVeeFolder *vf, CamelFolder *source, int killun)
}
}
+ if (last != -1)
+ camel_folder_summary_remove_range(folder->summary, start, last);
+
if (camel_folder_change_info_changed(folder_unmatched->changes)) {
unmatched_changes = folder_unmatched->changes;
folder_unmatched->changes = camel_folder_change_info_new();
@@ -1051,7 +1075,7 @@ vee_folder_build_folder(CamelVeeFolder *vf, CamelFolder *source, CamelException
GHashTable *allhash, *matchhash;
CamelFolder *f = source;
CamelFolder *folder = (CamelFolder *)vf;
- int i, n, count;
+ int i, n, count, start, last;
struct _update_data u;
CamelFolderChangeInfo *vf_changes = NULL, *unmatched_changes = NULL;
@@ -1088,6 +1112,8 @@ vee_folder_build_folder(CamelVeeFolder *vf, CamelFolder *source, CamelException
CAMEL_VEE_FOLDER_LOCK(folder_unmatched, summary_lock);
/* 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);
@@ -1097,9 +1123,16 @@ vee_folder_build_folder(CamelVeeFolder *vf, CamelFolder *source, CamelException
char *uid = (char *)camel_message_info_uid(mi), *oldkey;
if (g_hash_table_lookup(matchhash, uid+8) == NULL) {
- camel_folder_summary_remove_index(folder->summary, i);
+ 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));
- i--;
if (!CAMEL_IS_VEE_FOLDER(source)
&& g_hash_table_lookup_extended(unmatched_uids, uid, (void **)&oldkey, (void **)&n)) {
if (n == 1) {
@@ -1116,6 +1149,8 @@ vee_folder_build_folder(CamelVeeFolder *vf, CamelFolder *source, CamelException
camel_folder_summary_info_free(folder->summary, (CamelMessageInfo *)mi);
}
}
+ if (last != -1)
+ camel_folder_summary_remove_range(folder->summary, start, last);
/* now matchhash contains any new uid's, add them, etc */
g_hash_table_foreach(matchhash, (GHFunc)folder_added_uid, &u);