Fix for "agressive" memory segmentation

Philip Van Hoof <[email protected]>
Newsgroups gmane.comp.gnome.evolution.devel,gmane.comp.gnome.evolution.patches
Message-ID <[email protected]>
Camel makes some "aggressive" memory segmentation happen when loading
the folder summary.

This fixes that.

This is NOT yet the mmap() idea. That will come later.


-- 
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_anti_memory_segmentation.diff (text/x-patch, 3.8 KB)
Index: camel-folder-summary.c
===================================================================
RCS file: /cvs/gnome/evolution-data-server/camel/camel-folder-summary.c,v
retrieving revision 1.148
diff -u -r1.148 camel-folder-summary.c
--- camel-folder-summary.c	12 Apr 2006 19:14:13 -0000	1.148
+++ camel-folder-summary.c	6 Jul 2006 18:28:30 -0000
@@ -1625,17 +1625,19 @@
 	if (ct)
 		camel_content_type_unref(ct);
 
-	mi->subject = camel_pstring_strdup(subject);
-	mi->from = camel_pstring_strdup(from);
-	mi->to = camel_pstring_strdup(to);
-	mi->cc = camel_pstring_strdup(cc);
-	mi->mlist = camel_pstring_strdup(mlist);
+	mi->subject = camel_pstring_strdup_or_reuse (subject);
+	mi->from = camel_pstring_strdup_or_reuse (from);
+	mi->to = camel_pstring_strdup_or_reuse(to);
+	mi->cc = camel_pstring_strdup_or_reuse(cc);
+	mi->mlist = camel_pstring_strdup_or_reuse(mlist);
 
+/*
 	g_free(subject);
 	g_free(from);
 	g_free(to);
 	g_free(cc);
 	g_free(mlist);
+*/
 
 	mi->user_flags = NULL;
 	mi->user_tags = NULL;
@@ -1711,18 +1713,19 @@
 	camel_file_util_decode_string(in, &mlist);
 
 	mi->uid = uid;
-	mi->subject = camel_pstring_strdup(subject);
-	mi->from = camel_pstring_strdup(from);
-	mi->to = camel_pstring_strdup(to);
-	mi->cc = camel_pstring_strdup(cc);
-	mi->mlist = camel_pstring_strdup(mlist);
+	mi->subject = camel_pstring_strdup_or_reuse (subject);
+	mi->from = camel_pstring_strdup_or_reuse (from);
+	mi->to = camel_pstring_strdup_or_reuse (to);
+	mi->cc = camel_pstring_strdup_or_reuse (cc);
+	mi->mlist = camel_pstring_strdup_or_reuse (mlist);
 
+/*
 	g_free(subject);
 	g_free(from);
 	g_free(to);
 	g_free(cc);
 	g_free(mlist);
-
+*/
 	mi->content = NULL;
 
 	camel_file_util_decode_fixed_int32(in, &mi->message_id.id.part.hi);
Index: camel-string-utils.c
===================================================================
RCS file: /cvs/gnome/evolution-data-server/camel/camel-string-utils.c,v
retrieving revision 1.5
diff -u -r1.5 camel-string-utils.c
--- camel-string-utils.c	15 Sep 2005 17:35:45 -0000	1.5
+++ camel-string-utils.c	6 Jul 2006 18:28:31 -0000
@@ -186,6 +186,48 @@
 	return p;
 }
 
+
+
+/**
+ * camel_pstring_strdup_or_reuse:
+ * @s: String to copy.
+ * 
+ * Create a new pooled string entry for the string @s.  A pooled
+ * string is a table where common strings are uniquified to the same
+ * pointer value.  They are also refcounted, so freed when no longer
+ * in use.  In a thread-safe manner.
+ * 
+ * The NULL and empty strings are special cased to constant values.
+ *
+ * Return value: A pointer to an equivalent string of @s.  Use
+ * camel_pstring_free() when it is no longer needed.
+ **/
+const char *camel_pstring_strdup_or_reuse (const char *s)
+{
+	char *p;
+	void *pcount;
+	int count;
+
+	if (s == NULL)
+		return NULL;
+	if (s[0] == 0)
+		return "";
+
+	pthread_mutex_lock(&pstring_lock);
+	if (pstring_table == NULL)
+		pstring_table = g_hash_table_new(g_str_hash, g_str_equal);
+
+	if (g_hash_table_lookup_extended(pstring_table, s, (void **)&p, &pcount)) {
+		count = GPOINTER_TO_INT(pcount)+1;
+		g_hash_table_insert(pstring_table, p, GINT_TO_POINTER(count));
+		g_free (s);
+	} else {
+		p = s;
+		g_hash_table_insert(pstring_table, p, GINT_TO_POINTER(1));
+	}
+	pthread_mutex_unlock(&pstring_lock);
+	return p;
+}
 /**
  * camel_pstring_free:
  * @s: String to free.
Index: camel-string-utils.h
===================================================================
RCS file: /cvs/gnome/evolution-data-server/camel/camel-string-utils.h,v
retrieving revision 1.5
diff -u -r1.5 camel-string-utils.h
--- camel-string-utils.h	31 Aug 2005 04:21:56 -0000	1.5
+++ camel-string-utils.h	6 Jul 2006 18:28:31 -0000
@@ -43,6 +43,8 @@
 char camel_toupper(char c);
 
 const char *camel_pstring_strdup(const char *s);
+const char *camel_pstring_strdup_or_reuse (const char *s);
+
 void camel_pstring_free(const char *s);
 
 #ifdef __cplusplus
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.