[Evolution-hackers] cached messages, persistent vfolder state, unfinished patch
- From: Not Zed <notzed ximian com>
- To: evolution-hackers ximian com
- Subject: [Evolution-hackers] cached messages, persistent vfolder state, unfinished patch
- Date: Thu, 20 May 2004 14:18:46 +0800
Whilst looking at
http://bugzilla.ximian.com/show_bug.cgi?id=58388 i started down the path of 'i wonder if we could keep the message around in the vfolder if its busy', and came up with the following patch.
Then of course i realised 'duh that wont help, the message isn't in use, only the uid is'. Although there are related bugs like 'messages vanishes from vfolder and vanishes from popup view too' (although for some strange reason, that appears not to be the case anymore).
It could be an interesting idea, although it can't go in yet without a lot of changes.
This is because a change like this makes messages memory-persistent singleton instances rather than being loaded every time you access one. Which means any changes, like is used to generate replies and so forth would reflected in all copies, and you would also need non-const accessors for all the fields to avoid races, etc.
Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/evolution/camel/ChangeLog,v
retrieving revision 1.2137
diff -u -3 -r1.2137 ChangeLog
--- ChangeLog 20 May 2004 02:30:46 -0000 1.2137
+++ ChangeLog 20 May 2004 06:10:13 -0000
@@ -1,5 +1,11 @@
2004-05-20 Not Zed <NotZed Ximian com>
+ * camel-vee-folder.c (vee_get_message): whenever we open a
+ message, store it in our message bag.
+ (folder_changed_change): if we were going to remove a message
+ because it no longer matches, don't if the message is busy.
+ (vee_folder_build_folder): same.
+
* providers/nntp/camel-nntp-folder.c (nntp_folder_get_message):
oops, poke the right uid to get the article number.
(nntp_folder_cache_message): & here too. Somehow fixes #58700,
Index: camel-private.h
===================================================================
RCS file: /cvs/gnome/evolution/camel/camel-private.h,v
retrieving revision 1.30
diff -u -3 -r1.30 camel-private.h
--- camel-private.h 3 May 2004 07:48:46 -0000 1.30
+++ camel-private.h 20 May 2004 06:10:13 -0000
@@ -131,10 +131,13 @@
struct _CamelVeeFolderPrivate {
GList *folders; /* lock using subfolder_lock before changing/accessing */
GList *folders_changed; /* for list of folders that have changed between updates */
-
+
GMutex *summary_lock; /* for locking vfolder summary */
GMutex *subfolder_lock; /* for locking the subfolder list */
GMutex *changed_lock; /* for locking the folders-changed list */
+
+ /* holds currently got messages, so they don't 'go away' just because they are unmatched now */
+ struct _CamelObjectBag *message_bag;
};
#define CAMEL_VEE_FOLDER_LOCK(f, l) (g_mutex_lock(((CamelVeeFolder *)f)->priv->l))
Index: camel-vee-folder.c
===================================================================
RCS file: /cvs/gnome/evolution/camel/camel-vee-folder.c,v
retrieving revision 1.68
diff -u -3 -r1.68 camel-vee-folder.c
--- camel-vee-folder.c 19 May 2004 02:17:48 -0000 1.68
+++ camel-vee-folder.c 20 May 2004 06:10:14 -0000
@@ -165,6 +165,8 @@
p->summary_lock = g_mutex_new();
p->subfolder_lock = g_mutex_new();
p->changed_lock = g_mutex_new();
+
+ p->message_bag = camel_object_bag_new(g_str_hash, g_str_equal, (CamelCopyFunc)g_strdup, g_free);
}
static void
@@ -204,6 +206,8 @@
g_mutex_free(p->summary_lock);
g_mutex_free(p->subfolder_lock);
g_mutex_free(p->changed_lock);
+
+ camel_object_bag_destroy(p->message_bag);
g_free(p);
}
@@ -668,7 +672,18 @@
mi = (CamelVeeMessageInfo *)camel_folder_summary_uid(folder->summary, uid);
if (mi) {
- msg = camel_folder_get_message(mi->folder, camel_message_info_uid(mi)+8, ex);
+ const char *uid = camel_message_info_uid(mi);
+
+ msg = camel_object_bag_reserve(((CamelVeeFolder *)folder)->priv->message_bag, uid);
+ if (msg == NULL) {
+ msg = camel_folder_get_message(mi->folder, uid+8, ex);
+
+ if (msg)
+ camel_object_bag_add(((CamelVeeFolder *)folder)->priv->message_bag, uid, msg);
+ else
+ camel_object_bag_abort(((CamelVeeFolder *)folder)->priv->message_bag, uid);
+ }
+
camel_folder_summary_info_free(folder->summary, (CamelMessageInfo *)mi);
} else {
camel_exception_setv(ex, CAMEL_EXCEPTION_FOLDER_INVALID_UID,
@@ -1148,8 +1163,10 @@
if (mi->folder == source) {
char *uid = (char *)camel_message_info_uid(mi), *oldkey;
void *oldval;
-
- if (g_hash_table_lookup(matchhash, uid+8) == NULL) {
+ void *msg = NULL;
+
+ if (g_hash_table_lookup(matchhash, uid+8) == NULL
+ && (msg = camel_object_bag_get(vf->priv->message_bag, uid)) == NULL) {
if (last == -1) {
last = start = i;
} else if (last+1 == i) {
@@ -1171,6 +1188,8 @@
}
}
} else {
+ if (msg)
+ camel_object_unref(msg);
g_hash_table_remove(matchhash, uid+8);
}
}
@@ -1566,9 +1585,21 @@
dd(printf(" changing uid '%s' [still matches]\n", uid));
folder_changed_change_uid(sub, uid, hash, vf);
} else {
- /* No longer matches, remove it, but keep it in unmatched (potentially) */
- dd(printf(" removing uid '%s' [did match]\n", uid));
- folder_changed_remove_uid(sub, uid, hash, TRUE, vf);
+ void *msg;
+
+ /* first, see if its busy */
+ msg = camel_object_bag_get(vf->priv->message_bag, vuid);
+ printf("* checking %s is in use? %s\n", vuid, msg?"yes":"no");
+ if (msg) {
+ /* No longer matches, but busy, keep it but try for changed */
+ folder_changed_change_uid(sub, uid, hash, vf);
+ camel_object_unref(msg);
+ } else {
+ /* No longer matches, remove it, but keep it in unmatched (potentially) */
+
+ dd(printf(" removing uid '%s' [did match]\n", uid));
+ folder_changed_remove_uid(sub, uid, hash, TRUE, vf);
+ }
}
camel_folder_summary_info_free(folder->summary, (CamelMessageInfo *)vinfo);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]