[Evolution-hackers] cached messages, persistent vfolder state, unfinished patch




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.


Michael Zucchi <notzed ximian com>

Ximian Evolution and Free Software Developer


Novell, Inc.
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]