Just, try it ;-)

Philip Van Hoof <[email protected]>
Newsgroups gmane.comp.gnome.evolution.devel
Message-ID <[email protected]>
It's almost working

-- 
Philip Van Hoof, software developer at x-tend 
home: me at pvanhoof dot be 
gnome: pvanhoof at gnome dot org 
work: vanhoof at x-tend dot be 
http://www.pvanhoof.be - http://www.x-tend.be

_______________________________________________
Evolution-hackers mailing list
[email protected]
http://mail.gnome.org/mailman/listinfo/evolution-hackers
camel_folder_summary_with_mmap.diff (text/x-patch, 16.7 KB)
? camel-mime-tables.c
Index: camel-file-utils.c
===================================================================
RCS file: /cvs/gnome/evolution-data-server/camel/camel-file-utils.c,v
retrieving revision 1.17
diff -u -r1.17 camel-file-utils.c
--- camel-file-utils.c	2 Jun 2006 00:52:29 -0000	1.17
+++ camel-file-utils.c	7 Jul 2006 16:14:06 -0000
@@ -269,11 +269,21 @@
 	
 	if ((len = strlen (str)) > 65536)
 		len = 65536;
+
+	if (len==0) len=-1;
 	
 	if (camel_file_util_encode_uint32 (out, len+1) == -1)
 		return -1;
-	if (len == 0 || fwrite (str, len, 1, out) == 1)
-		return 0;
+
+	if (len != 0)
+	{
+		if (fwrite (str, len, 1, out) == 1)
+		{
+			fputc ('\0', out);
+			return 0;
+		}
+	}
+
 	return -1;
 }
 
Index: camel-folder-summary.c
===================================================================
RCS file: /cvs/gnome/evolution-data-server/camel/camel-folder-summary.c,v
retrieving revision 1.149
diff -u -r1.149 camel-folder-summary.c
--- camel-folder-summary.c	6 Jul 2006 19:43:46 -0000	1.149
+++ camel-folder-summary.c	7 Jul 2006 16:14:07 -0000
@@ -50,6 +50,7 @@
 #include "camel-stream-null.h"
 #include "camel-stream-filter.h"
 #include "camel-string-utils.h"
+#include "camel-disco-folder.h"
 
 #include "libedataserver/md5-utils.h"
 #include "libedataserver/e-memory.h"
@@ -66,15 +67,15 @@
 /* this should probably be conditional on it existing */
 #define USE_BSEARCH
 
-#define d(x)
-#define io(x)			/* io debug */
-#define w(x)
+#define d(x)	x
+#define io(x)	x		/* io debug */
+#define w(x)	x
 
 #if 0
 extern int strdup_count, malloc_count, free_count;
 #endif
 
-#define CAMEL_FOLDER_SUMMARY_VERSION (13)
+#define CAMEL_FOLDER_SUMMARY_VERSION (14)
 
 #define _PRIVATE(o) (((CamelFolderSummary *)(o))->priv)
 
@@ -86,13 +87,13 @@
 static struct _node *my_list_append(struct _node **list, struct _node *n);
 static int my_list_size(struct _node **list);
 
-static int summary_header_load(CamelFolderSummary *, FILE *);
-static int summary_header_save(CamelFolderSummary *, FILE *);
+static int summary_header_load(CamelFolderSummary *, FILE *in);
+static int summary_header_save(CamelFolderSummary *, FILE *out);
 
 static CamelMessageInfo * message_info_new_from_header(CamelFolderSummary *, struct _camel_header_raw *);
 static CamelMessageInfo * message_info_new_from_parser(CamelFolderSummary *, CamelMimeParser *);
 static CamelMessageInfo * message_info_new_from_message(CamelFolderSummary *s, CamelMimeMessage *msg);
-static CamelMessageInfo * message_info_load(CamelFolderSummary *, FILE *);
+static CamelMessageInfo * message_info_load(CamelFolderSummary *, FILE *in);
 static int		  message_info_save(CamelFolderSummary *, FILE *, CamelMessageInfo *);
 static void		  message_info_free(CamelFolderSummary *, CamelMessageInfo *);
 
@@ -160,6 +161,11 @@
 	struct _CamelFolderSummaryPrivate *p;
 	CamelFolderSummary *s = (CamelFolderSummary *)obj;
 
+
+	if (s->file)
+		g_mapped_file_free (s->file);
+	s->file = NULL;
+
 	p = _PRIVATE(obj);
 
 	camel_folder_summary_clear(s);
@@ -236,7 +242,7 @@
 	CamelFolderSummary *new = CAMEL_FOLDER_SUMMARY ( camel_object_new (camel_folder_summary_get_type ()));
 
 	new->folder = folder;
-
+	
 	return new;
 }
 
@@ -547,22 +553,25 @@
 	if (s->summary_path == NULL)
 		return 0;
 
-	in = g_fopen(s->summary_path, "rb");
+	if (!s->file)
+		s->file = g_mapped_file_new (s->summary_path, FALSE, NULL);
+
 	if (in == NULL)
 		return -1;
 
 	CAMEL_SUMMARY_LOCK(s, io_lock);
-	if ( ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->summary_header_load(s, in) == -1)
+	if ( ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->summary_header_load(s, NULL) == -1)
 		goto error;
 
 	/* now read in each message ... */
 	for (i=0;i<s->saved_count;i++) {
-		mi = ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->message_info_load(s, in);
+		mi = ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->message_info_load(s, NULL);
 
 		if (mi == NULL)
 			goto error;
 
 		/* FIXME: this should be done differently, how i don't know */
+if (FALSE){
 		if (s->build_content) {
 			((CamelMessageInfoBase *)mi)->content = perform_content_info_load(s, in);
 			if (((CamelMessageInfoBase *)mi)->content == NULL) {
@@ -570,14 +579,11 @@
 				goto error;
 			}
 		}
-
+}
 		camel_folder_summary_add(s, mi);
 	}
 
 	CAMEL_SUMMARY_UNLOCK(s, io_lock);
-	
-	if (fclose (in) != 0)
-		return -1;
 
 	s->flags &= ~CAMEL_SUMMARY_DIRTY;
 
@@ -588,7 +594,6 @@
 		g_warning ("Cannot load summary file: `%s': %s", s->summary_path, g_strerror (errno));
 	
 	CAMEL_SUMMARY_UNLOCK(s, io_lock);
-	fclose (in);
 	s->flags |= ~CAMEL_SUMMARY_DIRTY;
 
 	return -1;
@@ -724,21 +729,18 @@
 int
 camel_folder_summary_header_load(CamelFolderSummary *s)
 {
-	FILE *in;
 	int ret;
 
 	if (s->summary_path == NULL)
 		return 0;
 
-	in = g_fopen(s->summary_path, "rb");
-	if (in == NULL)
-		return -1;
+	if (!s->file)
+		s->file = g_mapped_file_new (s->summary_path, FALSE, NULL);
 
 	CAMEL_SUMMARY_LOCK(s, io_lock);
-	ret = ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->summary_header_load(s, in);
+	ret = ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->summary_header_load(s, NULL);
 	CAMEL_SUMMARY_UNLOCK(s, io_lock);
 	
-	fclose(in);
 	s->flags &= ~CAMEL_SUMMARY_DIRTY;
 	return ret;
 }
@@ -1392,40 +1394,74 @@
 static int
 summary_header_load(CamelFolderSummary *s, FILE *in)
 {
-	fseek(in, 0, SEEK_SET);
+	time_t *ptrt;
+	gint32 *ptr32 = g_mapped_file_get_contents (s->file);
 
-	io(printf("Loading header\n"));
 
-	if (camel_file_util_decode_fixed_int32(in, &s->version) == -1)
-		return -1;
+	s->version = g_ntohl (*ptr32); ptr32++; 
 
-	/* Legacy version check, before version 12 we have no upgrade knowledge */
+	io(printf("Loading header %d", (s->version&0xff)));
+
+	/* Legacy version check, before version 13 we have no upgrade knowledge */
 	if ((s->version > 0xff) && (s->version & 0xff) < 12) {
 		io(printf ("Summary header version mismatch"));
 		errno = EINVAL;
 		return -1;
 	}
 
-	if (!(s->version < 0x100 && s->version >= 13))
-		io(printf("Loading legacy summary\n"));
-	else
+	if (s->version != CAMEL_FOLDER_SUMMARY_VERSION) {
+		io(printf ("Summary header version needs upgrade"));
+
+		g_mapped_file_free (s->file);
+		s->file = NULL;
+		s->flags |= CAMEL_SUMMARY_DIRTY;
+
+		 CAMEL_SUMMARY_UNLOCK(s, io_lock);
+
+		s->folder->summary = s;
+
+		/* TODO: Handle offline case */
+
+		/* ((CamelDiscoFolderClass *)(CAMEL_OBJECT_GET_CLASS(s->folder)))->refresh_info_offline (s->folder, NULL); */
+		((CamelDiscoFolderClass *)(CAMEL_OBJECT_GET_CLASS(s->folder)))->refresh_info_online (s->folder, NULL);
+
+		camel_folder_summary_set_build_content (s, TRUE);
+		camel_folder_summary_save (s);
+		camel_folder_summary_set_build_content (s, FALSE);
+
+		 CAMEL_SUMMARY_LOCK(s, io_lock);
+
+		s->file = g_mapped_file_new (s->summary_path, FALSE, NULL);
+		ptr32 = g_mapped_file_get_contents (s->file);
+		s->version = g_ntohl (*ptr32); ptr32++; 
+
+		io(printf("Header upgraded to %d", (s->version&0xff)));
+
+
+	} else
 		io(printf("loading new-format summary\n"));
 
-	/* legacy version */
-	if (camel_file_util_decode_fixed_int32(in, &s->flags) == -1
-	    || camel_file_util_decode_fixed_int32(in, &s->nextuid) == -1
-	    || camel_file_util_decode_time_t(in, &s->time) == -1
-	    || camel_file_util_decode_fixed_int32(in, &s->saved_count) == -1) {
-		return -1;
-	}
+	s->flags = g_ntohl (*ptr32); ptr32++; 
+	s->nextuid = g_ntohl (*ptr32); ptr32++; 
+	ptrt = (time_t*)ptr32;
+	s->time = *ptrt; ptrt++; 
+	ptr32 = (gint32*)ptrt;
+	s->saved_count = g_ntohl (*ptr32); ptr32++; 
+
+
+	if (s->version < 0x100 && s->version >= 13) {
+		s->unread_count = g_ntohl (*ptr32); ptr32++; 
+		s->deleted_count = g_ntohl (*ptr32); ptr32++; 
+		s->junk_count = g_ntohl (*ptr32); ptr32++; 
+	}
+
+	io(printf ("CAMEL: ur:%d, dc:%d, jc:%d, v:%d\n",
+	s->unread_count, s->deleted_count, s->junk_count, s->version));
+     
+	/* The first is the implementation version, the second I don't yet know */
+	ptr32++; ptr32++;
 
-	/* version 13 */
-	if (s->version < 0x100 && s->version >= 13
-	    && (camel_file_util_decode_fixed_int32(in, &s->unread_count) == -1
-		|| camel_file_util_decode_fixed_int32(in, &s->deleted_count) == -1
-		|| camel_file_util_decode_fixed_int32(in, &s->junk_count) == -1)) {
-		return -1;
-	}
+	s->msginfostart = ptr32;
 
 	return 0;
 }
@@ -1681,78 +1717,168 @@
 	return (CamelMessageInfo *)mi;
 }
 
+static unsigned char*
+decode_uint32 (unsigned char *start, guint32 *dest)
+{
+	guint32 value = 0;
+	unsigned char uv = *start;
+	int v;
+
+     /* until we get the last byte, keep decoding 7 bits at a time */
+
+
+io(printf ("START at %02x\n", uv));
+
+        while ( ((v = uv) & 0x80) == 0 ) {
+io(printf ("HAVE NEXT at %02x\n", v));
+                value |= v;
+                value <<= 7;
+		start++; uv = *start;
+        }
+
+	//if (v == EOF) {
+	//	*dest = value >> 7;
+	//	return -1;
+	//}
+
+	*dest = value | (v & 0x7f);
+
+printf ("length = %d\n", *dest);
+
+	return ++start;
+
+	/* until we get the last byte, keep decoding 7 bits at a time */
+	while ( ((v = uv) & 0x80) == 0 ) {
+		value |= v;
+		value <<= 7;
+		start++; uv=*start;
+	}
+	*dest = value | (uv & 0x7f);
+
+
+	return ++start;
+}
+
 static CamelMessageInfo *
 message_info_load(CamelFolderSummary *s, FILE *in)
 {
 	CamelMessageInfoBase *mi;
-	guint count;
+	guint count, len, nlen;
+	unsigned char *ptrchr = s->msginfostart;
+	gint32 *ptr32;
+	time_t *ptrt;   
 	int i;
-	char *subject, *from, *to, *cc, *mlist, *uid;
 
 	mi = (CamelMessageInfoBase *)camel_message_info_new(s);
 
 	io(printf("Loading message info\n"));
 
-	camel_file_util_decode_string(in, &uid);
-	camel_file_util_decode_uint32(in, &mi->flags);
-	camel_file_util_decode_uint32(in, &mi->size);
-	camel_file_util_decode_time_t(in, &mi->date_sent);
-	camel_file_util_decode_time_t(in, &mi->date_received);
-	camel_file_util_decode_string(in, &subject);
-	camel_file_util_decode_string(in, &from);
-	camel_file_util_decode_string(in, &to);
-	camel_file_util_decode_string(in, &cc);
-	camel_file_util_decode_string(in, &mlist);
-	
-	mi->uid = uid;
-	mi->subject = camel_pstring_add (subject, TRUE);
-	mi->from = camel_pstring_add (from, TRUE);
-	mi->to = camel_pstring_add (to, TRUE);
-	mi->cc = camel_pstring_add (cc, TRUE);
-	mi->mlist = camel_pstring_add (mlist, TRUE);
-	
+	ptrchr = decode_uint32 ((unsigned char*)ptrchr, &len);
+	io(printf ("uid len = %d, str=%s\n", len, ptrchr));
+	mi->uid = ptrchr;
+	ptrchr += len;
+       
+	ptrchr = decode_uint32 ((unsigned char*)ptrchr, &len);
+	mi->flags = ptrchr;
+
+	ptrchr = decode_uint32 ((unsigned char*)ptrchr, &len);
+	mi->size = ptrchr;
+       
+	ptrt = ptrchr;
+	mi->date_sent = ptrt; ptrt++;
+	mi->date_received = ptrt; ptrt++;
+
+	ptrchr = ptrt;
+       
+	ptrchr = decode_uint32 ((unsigned char*)ptrchr, &len);
+	mi->subject = ptrchr;
+	ptrchr += len;
+
+	ptrchr = decode_uint32 ((unsigned char*)ptrchr, &len);
+	mi->from = ptrchr;
+	ptrchr += len;
+
+	ptrchr = decode_uint32 ((unsigned char*)ptrchr, &len);
+	mi->to = ptrchr;
+	ptrchr += len;
+
+	ptrchr = decode_uint32 ((unsigned char*)ptrchr, &len);
+	mi->cc = ptrchr;
+	ptrchr += len;
+
+	ptrchr = decode_uint32 ((unsigned char*)ptrchr, &len);
+	mi->mlist = ptrchr;
+	ptrchr += len;	
+
+
+printf ("%s\n%s\n%s\n%s\n%s\n%s\n", mi->uid, mi->subject, mi->from, mi->to, mi->cc, mi->mlist);
+
 	mi->content = NULL;
 
-	camel_file_util_decode_fixed_int32(in, &mi->message_id.id.part.hi);
-	camel_file_util_decode_fixed_int32(in, &mi->message_id.id.part.lo);
+	ptr32 = ptrchr;
+
+	mi->message_id.id.part.hi = g_ntohl (*ptr32); ptr32++;
+	mi->message_id.id.part.lo = g_ntohl (*ptr32); ptr32++;
+
+	ptrchr = ptr32;
+	ptrchr = decode_uint32 ((unsigned char*)ptrchr, &count);
+	ptr32 = ptrchr;
 
-	if (camel_file_util_decode_uint32(in, &count) == -1 || count > 500)
+	if (count > 500)
 		goto error;
 
-	if (count > 0) {
-		mi->references = g_malloc(sizeof(*mi->references) + ((count-1) * sizeof(mi->references->references[0])));
-		mi->references->size = count;
-		for (i=0;i<count;i++) {
-			camel_file_util_decode_fixed_int32(in, &mi->references->references[i].id.part.hi);
-			camel_file_util_decode_fixed_int32(in, &mi->references->references[i].id.part.lo);
-		}
+	mi->references = g_malloc(sizeof(*mi->references) + ((count-1) * sizeof(mi->references->references[0])));
+	mi->references->size = count;
+	
+	for (i=0;i<count;i++) {
+		mi->references->references[i].id.part.hi = g_ntohl (*ptr32); ptr32++;
+		mi->references->references[i].id.part.lo = g_ntohl (*ptr32); ptr32++;
 	}
 
-	if (camel_file_util_decode_uint32(in, &count) == -1 || count > 500)
+	ptrchr = ptr32;
+	ptrchr = decode_uint32 ((unsigned char*)ptrchr, &count);
+	ptrchr--;
+
+	if (count > 500)
 		goto error;
 
 	for (i=0;i<count;i++) {
 		char *name;
-		if (camel_file_util_decode_string(in, &name) == -1 || name == NULL)
+
+		ptrchr = decode_uint32 ((unsigned char*)ptrchr, &len);
+		name = ptrchr;
+		ptrchr += len;
+
+		if (name == NULL)
 			goto error;
+
 		camel_flag_set(&mi->user_flags, name, TRUE);
-		g_free(name);
 	}
 
-	if (camel_file_util_decode_uint32(in, &count) == -1 || count > 500)
+	ptrchr = decode_uint32 ((unsigned char*)ptrchr, &count);
+	ptrchr--;
+
+	if (count > 500)
 		goto error;
 
 	for (i=0;i<count;i++) {
 		char *name, *value;
-		if (camel_file_util_decode_string(in, &name) == -1 || name == NULL
-		    || camel_file_util_decode_string(in, &value) == -1)
+
+		ptrchr = decode_uint32 ((unsigned char*)ptrchr, &len);
+		name = ptrchr;
+		ptrchr += len;
+
+		if (name == NULL)
 			goto error;
+
+		ptrchr = decode_uint32 ((unsigned char*)ptrchr, &len);
+		value = ptrchr;
+		ptrchr += len;
+
 		camel_tag_set(&mi->user_tags, name, value);
-		g_free(name);
-		g_free(value);
 	}
 
-	if (!ferror(in))
+
 		return (CamelMessageInfo *)mi;
 
 error:
Index: camel-folder-summary.h
===================================================================
RCS file: /cvs/gnome/evolution-data-server/camel/camel-folder-summary.h,v
retrieving revision 1.86
diff -u -r1.86 camel-folder-summary.h
--- camel-folder-summary.h	31 Aug 2005 04:21:56 -0000	1.86
+++ camel-folder-summary.h	7 Jul 2006 16:14:07 -0000
@@ -224,6 +224,9 @@
 	GHashTable *messages_uid; /* CamelMessageInfo's by uid */
 
 	struct _CamelFolder *folder; /* parent folder, for events */
+
+	GMappedFile *file;
+	void *msginfostart;
 };
 
 struct _CamelFolderSummaryClass {
Index: camel-string-utils.c
===================================================================
RCS file: /cvs/gnome/evolution-data-server/camel/camel-string-utils.c,v
retrieving revision 1.6
diff -u -r1.6 camel-string-utils.c
--- camel-string-utils.c	6 Jul 2006 19:43:47 -0000	1.6
+++ camel-string-utils.c	7 Jul 2006 16:14:07 -0000
@@ -164,10 +164,10 @@
 	char *pstr;
 	int count;
 	
-	if (s == NULL)
+	if (str == NULL)
 		return NULL;
 	
-	if (s[0] == '\0') {
+	if (str[0] == '\0') {
 		if (own)
 			g_free (str);
 		return "";
@@ -180,6 +180,7 @@
 	if (g_hash_table_lookup_extended (pstring_table, str, (void **) &pstr, &pcount)) {
 		count = GPOINTER_TO_INT (pcount) + 1;
 		g_hash_table_insert (pstring_table, pstr, GINT_TO_POINTER (count));
+		g_free (str);
 	} else {
 		pstr = own ? str : g_strdup (str);
 		g_hash_table_insert (pstring_table, pstr, GINT_TO_POINTER (1));
Index: providers/imap/camel-imap-summary.c
===================================================================
RCS file: /cvs/gnome/evolution-data-server/camel/providers/imap/camel-imap-summary.c,v
retrieving revision 1.25
diff -u -r1.25 camel-imap-summary.c
--- providers/imap/camel-imap-summary.c	31 Aug 2005 04:26:02 -0000	1.25
+++ providers/imap/camel-imap-summary.c	7 Jul 2006 16:14:07 -0000
@@ -152,16 +152,16 @@
 	if (camel_imap_summary_parent->summary_header_load (s, in) == -1)
 		return -1;
 
-	/* Legacy version */
+	/* Legacy version 
 	if (s->version == 0x30c)
 		return camel_file_util_decode_uint32(in, &ims->validity);
 
-	/* Version 1 */
+	* Version 1 *
 	if (camel_file_util_decode_fixed_int32(in, &ims->version) == -1)
 		return -1;
 	
 	if (ims->version == 2) {
-		/* Version 2: for compat with version 2 of the imap4 summary files */
+		* Version 2: for compat with version 2 of the imap4 summary files *
 		int have_mlist;
 		
 		if (camel_file_util_decode_fixed_int32 (in, &have_mlist) == -1)
@@ -176,7 +176,7 @@
 		errno = EINVAL;
 		return -1;
 	}
-
+*/
 	return 0;
 }
 
@@ -212,6 +212,7 @@
 	CamelImapMessageInfo *iinfo;
 
 	info = camel_imap_summary_parent->message_info_load (s, in);
+/*
 	if (info) {
 		iinfo = (CamelImapMessageInfo *)info;
 
@@ -220,7 +221,7 @@
 
 		label_to_flags(iinfo);
 	}
-
+*/
 	return info;
 error:
 	camel_message_info_free(info);
@@ -254,10 +255,11 @@
 static CamelMessageContentInfo *
 content_info_load (CamelFolderSummary *s, FILE *in)
 {
-	if (fgetc (in))
-		return camel_imap_summary_parent->content_info_load (s, in);
-	else
-		return camel_folder_summary_content_info_new (s);
+printf ("Disabled loading content info\n");
+	//if (fgetc (in))
+	//	return camel_imap_summary_parent->content_info_load (s, in);
+	//else
+	//	return camel_folder_summary_content_info_new (s);
 }
 
 static int
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.