evolution-data-server r8994 - branches/camel-db-summary/camel
- From: sragavan svn gnome org
- To: svn-commits-list gnome org
- Subject: evolution-data-server r8994 - branches/camel-db-summary/camel
- Date: Tue, 17 Jun 2008 15:55:48 +0000 (UTC)
Author: sragavan
Date: Tue Jun 17 15:55:48 2008
New Revision: 8994
URL: http://svn.gnome.org/viewvc/evolution-data-server?rev=8994&view=rev
Log:
Revamp cfs
Modified:
branches/camel-db-summary/camel/camel-folder-summary.c
Modified: branches/camel-db-summary/camel/camel-folder-summary.c
==============================================================================
--- branches/camel-db-summary/camel/camel-folder-summary.c (original)
+++ branches/camel-db-summary/camel/camel-folder-summary.c Tue Jun 17 15:55:48 2008
@@ -61,6 +61,9 @@
#include "camel-string-utils.h"
#include "camel-store.h"
+/* To switch between e-memchunk and g-alloc */
+#define ALWAYS_ALLOC
+
static pthread_mutex_t info_lock = PTHREAD_MUTEX_INITIALIZER;
/* this lock is ONLY for the standalone messageinfo stuff */
@@ -133,6 +136,8 @@
static void camel_folder_summary_finalize (CamelObject *obj);
static CamelObjectClass *camel_folder_summary_parent;
+static int camel_read_one_mir_callback (void * ref, int ncol, char ** cols, char ** name);
+static CamelMessageInfo * message_info_from_uid (CamelFolderSummary *s, const char *uid);
static void
camel_folder_summary_init (CamelFolderSummary *s)
@@ -198,11 +203,13 @@
g_free(s->summary_path);
+#ifndef ALWAYS_ALLOC
if (s->message_info_chunks)
e_memchunk_destroy(s->message_info_chunks);
if (s->content_info_chunks)
e_memchunk_destroy(s->content_info_chunks);
-
+#endif
+
if (p->filter_index)
camel_object_unref((CamelObject *)p->filter_index);
if (p->filter_64)
@@ -448,20 +455,8 @@
}
-/**
- * camel_folder_summary_uid:
- * @summary: a #CamelFolderSummary object
- * @uid: a uid
- *
- * Retrieve a summary item by uid.
- *
- * A referenced to the summary item is returned, which may be
- * ref'd or free'd as appropriate.
- *
- * Returns the summary item, or %NULL if the uid @uid is not available
- **/
-CamelMessageInfo *
-camel_folder_summary_uid (CamelFolderSummary *s, const char *uid)
+static CamelMessageInfo *
+message_info_from_uid (CamelFolderSummary *s, const char *uid)
{
CamelMessageInfo *info;
int ret;
@@ -485,23 +480,29 @@
CAMEL_SUMMARY_UNLOCK(s, ref_lock);
CAMEL_SUMMARY_UNLOCK(s, summary_lock);
- ret = camel_db_read_message_info_record_with_uid (cdb, folder_name, uid, (gpointer**) &s, camel_read_mir_callback, &ex);
+ ret = camel_db_read_message_info_record_with_uid (cdb, folder_name, uid, (gpointer**) &s, camel_read_one_mir_callback, &ex);
if (ret != 0) {
+ // if (strcmp (folder_name, "UNMATCHED"))
+ g_warning ("Unable to read uid %s from folder %s: %s", uid, folder_name, camel_exception_get_description(&ex));
+
return NULL;
}
CAMEL_SUMMARY_LOCK(s, summary_lock);
CAMEL_SUMMARY_LOCK(s, ref_lock);
-
- info = g_hash_table_lookup (s->loaded_infos, uid);
+ /* We would have double reffed at camel_read_one_mir_callback */
+ info = g_hash_table_lookup (s->loaded_infos, uid);
+
if (!info) {
/* Makes no sense now as the exception is local as of now. FIXME: Pass exception from caller */
camel_exception_set (&ex, CAMEL_EXCEPTION_SYSTEM, _(g_strdup_printf ("no uid [%s] exists", uid)));
+ // if (strcmp (folder_name, "UNMATCHED"))
+ g_warning ("No uid[%s] exists in %s\n", uid, folder_name);
+ camel_exception_clear (&ex);
}
- }
-
- if (info)
+ } else
info->refcount++;
+
CAMEL_SUMMARY_UNLOCK(s, ref_lock);
CAMEL_SUMMARY_UNLOCK(s, summary_lock);
@@ -511,6 +512,24 @@
/**
+ * camel_folder_summary_uid:
+ * @summary: a #CamelFolderSummary object
+ * @uid: a uid
+ *
+ * Retrieve a summary item by uid.
+ *
+ * A referenced to the summary item is returned, which may be
+ * ref'd or free'd as appropriate.
+ *
+ * Returns the summary item, or %NULL if the uid @uid is not available
+ **/
+CamelMessageInfo *
+camel_folder_summary_uid (CamelFolderSummary *s, const char *uid)
+{
+ return ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->message_info_from_uid(s, uid);
+}
+
+/**
* camel_folder_summary_next_uid:
* @summary: a #CamelFolderSummary object
*
@@ -637,25 +656,28 @@
}
#warning "FIXME: I should have a better LRU algorithm "
-gboolean
+static void
remove_item (char *key, CamelMessageInfo *info, CamelFolderSummary *s)
{
- printf("ref %d\t", info->refcount); //camel_message_info_dump (info);
- if (info->refcount == 1) {
+ printf("%d\t", info->refcount); //camel_message_info_dump (info);
+ CAMEL_SUMMARY_LOCK(info->summary, ref_lock);
+ if (info->refcount == 1 && !info->dirty) {
+ CAMEL_SUMMARY_UNLOCK(info->summary, ref_lock);
/* Noone seems to need it. Why not free it then. */
- //camel_message_info_free (info);
- //return TRUE;
- }
- return FALSE;
+ camel_message_info_free (info);
+ return;
+ }
+ CAMEL_SUMMARY_UNLOCK(info->summary, ref_lock);
+ return ;
}
static gboolean
remove_cache (CamelFolderSummary *s)
{
struct _CamelFolderSummaryPrivate *p = _PRIVATE(s);
- printf("removing cache... %s %d\n", s->folder->full_name, g_hash_table_size (s->loaded_infos));
+ printf("removing cache for %s %d\n", s->folder->full_name, g_hash_table_size (s->loaded_infos));
#warning "hack. fix it"
CAMEL_SUMMARY_LOCK (s, summary_lock);
- g_hash_table_foreach_remove (s->loaded_infos, remove_item, s);
+ g_hash_table_foreach (s->loaded_infos, remove_item, s);
CAMEL_SUMMARY_UNLOCK (s, summary_lock);
printf("done .. now %d\n",g_hash_table_size (s->loaded_infos));
return TRUE;
@@ -683,20 +705,15 @@
ret = camel_db_read_message_info_records (cdb, folder_name, (gpointer**) &s, camel_read_mir_callback, ex);
#warning "LRU please and not timeouts"
- //g_timeout_add_seconds (10, remove_cache, s);
+ g_timeout_add_seconds (30, remove_cache, s);
return ret;
}
-static int
-camel_read_mir_callback (void * ref, int ncol, char ** cols, char ** name)
+static void
+mir_from_cols (CamelMIRecord *mir, CamelFolderSummary *s, int ncol, char ** cols, char ** name)
{
- CamelFolderSummary *s = * (CamelFolderSummary **) ref;
- CamelMIRecord *mir;
- CamelMessageInfo *info;
int i;
-
- mir = g_new0 (CamelMIRecord , 1);
-
+
for (i = 0; i < ncol; ++i) {
if ( !strcmp (name [i], "uid") )
@@ -748,7 +765,20 @@
else if ( !strcmp (name [i], "bdata") )
mir->bdata = g_strdup (cols [i]);
- }
+ }
+}
+
+static int
+camel_read_mir_callback (void * ref, int ncol, char ** cols, char ** name)
+{
+ CamelFolderSummary *s = * (CamelFolderSummary **) ref;
+ CamelMIRecord *mir;
+ CamelMessageInfo *info;
+ int i;
+
+ mir = g_new0 (CamelMIRecord , 1);
+
+ mir_from_cols (mir, s, ncol, cols, name);
info = ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->message_info_from_db (s, mir);
@@ -779,6 +809,47 @@
return 0;
}
+static int
+camel_read_one_mir_callback (void * ref, int ncol, char ** cols, char ** name)
+{
+ CamelFolderSummary *s = * (CamelFolderSummary **) ref;
+ CamelMIRecord *mir;
+ CamelMessageInfo *info;
+ int i;
+
+ mir = g_new0 (CamelMIRecord , 1);
+
+ mir_from_cols (mir, s, ncol, cols, name);
+
+ info = ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->message_info_from_db (s, mir);
+
+ if (info) {
+
+ if (s->build_content) {
+ /* FIXME: this should be done differently, how i don't know */
+ ((CamelMessageInfoBase *)info)->content = perform_content_info_load_from_db (s, mir);
+ if (((CamelMessageInfoBase *)info)->content == NULL) {
+ camel_message_info_free(info);
+ info = NULL;
+ }
+ }
+
+ /* Just now we are reading from the DB, it can't be dirty. */
+ ((CamelMessageInfoBase *)info)->dirty = FALSE;
+ //((CamelMessageInfoBase *)info)->flags &= ~CAMEL_MESSAGE_DB_DIRTY;
+ /* double reffing, because, at times frees before, I could read it. */
+ camel_message_info_ref(info);
+ camel_folder_summary_insert (s, info, TRUE);
+
+ d(g_print ("\nAdding messageinfo to db from db \n"));
+ } else
+ g_warning ("Loading messageinfo from db failed");
+
+ camel_db_camel_mir_free (mir);
+
+ return 0;
+}
+
/**
* camel_folder_summary_load:
* @summary: a #CamelFolderSummary object
@@ -940,10 +1011,10 @@
if (camel_db_prepare_message_info_table (cdb, folder_name, ex) != 0) {
return -1;
}
-
+ CAMEL_SUMMARY_LOCK(s, summary_lock);
/* Push MessageInfo-es */
g_hash_table_foreach (s->loaded_infos, save_to_db_cb, ex);
-
+ CAMEL_SUMMARY_UNLOCK(s, summary_lock);
#warning "make sure we free the message infos that are loaded are freed if not used anymore or should we leave that to the timer? "
return 0;
@@ -1282,6 +1353,36 @@
}
+void
+camel_folder_summary_insert (CamelFolderSummary *s, CamelMessageInfo *info, gboolean load)
+{
+ if (info == NULL)
+ return;
+
+ CAMEL_SUMMARY_LOCK(s, summary_lock);
+
+/* unnecessary for pooled vectors */
+#ifdef DOESTRV
+ /* this is vitally important, and also if this is ever modified, then
+ the hash table needs to be resynced */
+ info->strings = e_strv_pack(info->strings);
+#endif
+
+ /* Summary always holds a ref for the loaded infos */
+ //camel_message_info_ref(info); //FIXME: Check how things are loaded.
+ #warning "FIXME: SHould we ref it or redesign it later on"
+ /* The uid array should have its own memory. We will unload the infos when not reqd.*/
+ if (!load)
+ g_ptr_array_add (s->uids, g_strdup(camel_message_info_uid(info)));
+
+ g_hash_table_insert (s->loaded_infos, camel_message_info_uid (info), info);
+ if (!load)
+ s->flags |= CAMEL_SUMMARY_DIRTY;
+
+ CAMEL_SUMMARY_UNLOCK(s, summary_lock);
+}
+
+
/**
* camel_folder_summary_add_from_header:
* @summary: a #CamelFolderSummary object
@@ -1685,6 +1786,33 @@
}
}
+void
+camel_folder_summary_remove_index_fast (CamelFolderSummary *s, int index)
+{
+ const char *uid = s->uids->pdata[index];
+ CamelMessageInfo *oldinfo;
+ char *olduid;
+ int i;
+
+ CAMEL_SUMMARY_LOCK(s, summary_lock);
+ CAMEL_SUMMARY_LOCK(s, ref_lock);
+
+ if (g_hash_table_lookup_extended(s->loaded_infos, uid, (void *)&olduid, (void *)&oldinfo)) {
+ /* make sure it doesn't vanish while we're removing it */
+ g_hash_table_remove (s->loaded_infos, uid);
+ g_ptr_array_remove_index(s->uids, i);
+ CAMEL_SUMMARY_UNLOCK(s, ref_lock);
+ CAMEL_SUMMARY_UNLOCK(s, summary_lock);
+ camel_message_info_free(oldinfo);
+ } else {
+ /* Info isn't loaded into the memory. We must just remove the UID*/
+ g_ptr_array_remove_index(s->uids, i);
+ CAMEL_SUMMARY_UNLOCK(s, ref_lock);
+ CAMEL_SUMMARY_UNLOCK(s, summary_lock);
+
+
+ }
+}
/**
* camel_folder_summary_remove_index:
@@ -2250,9 +2378,13 @@
CamelMessageContentInfo *ci;
CAMEL_SUMMARY_LOCK(s, alloc_lock);
+#ifndef ALWAYS_ALLOC
if (s->content_info_chunks == NULL)
s->content_info_chunks = e_memchunk_new(32, s->content_info_size);
ci = e_memchunk_alloc(s->content_info_chunks);
+#else
+ ci = g_malloc (s->content_info_size);
+#endif
CAMEL_SUMMARY_UNLOCK(s, alloc_lock);
memset(ci, 0, s->content_info_size);
@@ -2692,7 +2824,11 @@
if (s)
- e_memchunk_free(s->message_info_chunks, mi);
+#ifndef ALWAYS_ALLOC
+ e_memchunk_free(s->message_info_chunks, mi);
+#else
+ g_free(mi);
+#endif
else
g_free(mi);
}
@@ -2917,7 +3053,10 @@
g_free(ci->id);
g_free(ci->description);
g_free(ci->encoding);
+#ifndef ALWAYS_ALLOC
e_memchunk_free(s->content_info_chunks, ci);
+#endif
+ g_free(ci);
}
static char *
@@ -3554,9 +3693,13 @@
if (s) {
CAMEL_SUMMARY_LOCK(s, alloc_lock);
+#ifndef ALWAYS_ALLOC
if (s->message_info_chunks == NULL)
s->message_info_chunks = e_memchunk_new(32, s->message_info_size);
info = e_memchunk_alloc0(s->message_info_chunks);
+#else
+ info = g_malloc0(s->message_info_size);
+#endif
CAMEL_SUMMARY_UNLOCK(s, alloc_lock);
} else {
info = g_malloc0(sizeof(CamelMessageInfoBase));
@@ -4101,7 +4244,8 @@
klass->meta_message_info_save = meta_message_info_save;
klass->message_info_free = message_info_free;
klass->message_info_clone = message_info_clone;
-
+ klass->message_info_from_uid = message_info_from_uid;
+
klass->content_info_new_from_header = content_info_new_from_header;
klass->content_info_new_from_parser = content_info_new_from_parser;
klass->content_info_new_from_message = content_info_new_from_message;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]