speed improvements
[claws.git] / src / msgcache.c
index 616905c539ab8e86d96c10670e50ab01ed8d8d5a..9ccd7299967e11e8f7de8049856c801032fabe2f 100644 (file)
@@ -30,6 +30,7 @@
 
 struct _MsgCache {
        GHashTable      *msgnum_table;
+       GHashTable      *msgid_table;
        guint            memusage;
        time_t           last_access;
 };
@@ -39,7 +40,8 @@ MsgCache *msgcache_new()
        MsgCache *cache;
        
        cache = g_new0(MsgCache, 1),
-       cache->msgnum_table = g_hash_table_new(NULL, NULL);
+       cache->msgnum_table = g_hash_table_new(g_int_hash, g_int_equal);
+       cache->msgid_table = g_hash_table_new(g_str_hash, g_str_equal);
        cache->last_access = time(NULL);
 
        return cache;
@@ -56,6 +58,7 @@ void msgcache_destroy(MsgCache *cache)
        g_return_if_fail(cache != NULL);
 
        g_hash_table_foreach_remove(cache->msgnum_table, msgcache_msginfo_free_func, NULL);
+       g_hash_table_destroy(cache->msgid_table);
        g_hash_table_destroy(cache->msgnum_table);
        g_free(cache);
 }
@@ -68,11 +71,13 @@ void msgcache_add_msg(MsgCache *cache, MsgInfo *msginfo)
        g_return_if_fail(msginfo != NULL);
 
        newmsginfo = procmsg_msginfo_new_ref(msginfo);
-       g_hash_table_insert(cache->msgnum_table, GINT_TO_POINTER(msginfo->msgnum), newmsginfo);
+       g_hash_table_insert(cache->msgnum_table, &newmsginfo->msgnum, newmsginfo);
+       if(newmsginfo->msgid != NULL)
+               g_hash_table_insert(cache->msgid_table, newmsginfo->msgid, newmsginfo);
        cache->memusage += procmsg_msginfo_memusage(msginfo);
        cache->last_access = time(NULL);
 
-       debug_print(_("Cache size: %d messages, %d byte\n"), g_hash_table_size(cache->msgnum_table), cache->memusage);
+       debug_print("Cache size: %d messages, %d byte\n", g_hash_table_size(cache->msgnum_table), cache->memusage);
 }
 
 void msgcache_remove_msg(MsgCache *cache, guint msgnum)
@@ -82,16 +87,18 @@ void msgcache_remove_msg(MsgCache *cache, guint msgnum)
        g_return_if_fail(cache != NULL);
        g_return_if_fail(msgnum > 0);
 
-       msginfo = (MsgInfo *) g_hash_table_lookup(cache->msgnum_table, GINT_TO_POINTER(msgnum));
+       msginfo = (MsgInfo *) g_hash_table_lookup(cache->msgnum_table, &msgnum);
        if(!msginfo)
                return;
 
        cache->memusage -= procmsg_msginfo_memusage(msginfo);
+       if(msginfo->msgid)
+               g_hash_table_remove(cache->msgid_table, msginfo->msgid);
+       g_hash_table_remove(cache->msgnum_table, &msginfo->msgnum);
        procmsg_msginfo_free(msginfo);
-       g_hash_table_remove(cache->msgnum_table, GINT_TO_POINTER(msgnum));
        cache->last_access = time(NULL);
 
-       debug_print(_("Cache size: %d messages, %d byte\n"), g_hash_table_size(cache->msgnum_table), cache->memusage);
+       debug_print("Cache size: %d messages, %d byte\n", g_hash_table_size(cache->msgnum_table), cache->memusage);
 }
 
 void msgcache_update_msg(MsgCache *cache, MsgInfo *msginfo)
@@ -101,19 +108,22 @@ void msgcache_update_msg(MsgCache *cache, MsgInfo *msginfo)
        g_return_if_fail(cache != NULL);
        g_return_if_fail(msginfo != NULL);
 
-       oldmsginfo = g_hash_table_lookup(cache->msgnum_table, GINT_TO_POINTER(msginfo->msgnum));
+       oldmsginfo = g_hash_table_lookup(cache->msgnum_table, &msginfo->msgnum);
        if(msginfo) {
-               g_hash_table_remove(cache->msgnum_table, GINT_TO_POINTER(oldmsginfo->msgnum));
+               g_hash_table_remove(cache->msgid_table, oldmsginfo->msgid);
+               g_hash_table_remove(cache->msgnum_table, &oldmsginfo->msgnum);
                procmsg_msginfo_free(oldmsginfo);
        }
        cache->memusage -= procmsg_msginfo_memusage(oldmsginfo);
 
        newmsginfo = procmsg_msginfo_new_ref(msginfo);
-       g_hash_table_insert(cache->msgnum_table, GINT_TO_POINTER(msginfo->msgnum), newmsginfo);
+       g_hash_table_insert(cache->msgnum_table, &newmsginfo->msgnum, newmsginfo);
+       if(newmsginfo->msgid)
+               g_hash_table_insert(cache->msgid_table, newmsginfo->msgid, newmsginfo);
        cache->memusage += procmsg_msginfo_memusage(newmsginfo);
        cache->last_access = time(NULL);
        
-       debug_print(_("Cache size: %d messages, %d byte\n"), g_hash_table_size(cache->msgnum_table), cache->memusage);
+       debug_print("Cache size: %d messages, %d byte\n", g_hash_table_size(cache->msgnum_table), cache->memusage);
 
        return;
 }
@@ -155,7 +165,7 @@ static gint msgcache_read_cache_data_str(FILE *fp, gchar **str)
                ret = -1;
 
        if (ret < 0)
-               g_warning(_("Cache data is corrupted\n"));
+               g_warning("Cache data is corrupted\n");
 
        return ret;
 }
@@ -173,7 +183,7 @@ static gint msgcache_read_cache_data_str(FILE *fp, gchar **str)
 #define READ_CACHE_DATA_INT(n, fp) \
 { \
        if (fread(&n, sizeof(n), 1, fp) != 1) { \
-               g_warning(_("Cache data is corrupted\n")); \
+               g_warning("Cache data is corrupted\n"); \
                procmsg_msginfo_free(msginfo); \
                error = TRUE; \
                break; \
@@ -185,7 +195,7 @@ MsgCache *msgcache_read_cache(FolderItem *item, const gchar *cache_file)
        MsgCache *cache;
        FILE *fp;
        MsgInfo *msginfo;
-/*     MsgFlags default_flags; */
+       MsgTmpFlags tmp_flags = 0;
        gchar file_buf[BUFFSIZE];
        gint ver;
        guint num;
@@ -195,21 +205,27 @@ MsgCache *msgcache_read_cache(FolderItem *item, const gchar *cache_file)
        g_return_val_if_fail(item != NULL, NULL);
 
        if ((fp = fopen(cache_file, "rb")) == NULL) {
-               debug_print(_("\tNo cache file\n"));
+               debug_print("\tNo cache file\n");
                return NULL;
        }
        setvbuf(fp, file_buf, _IOFBF, sizeof(file_buf));
 
-       debug_print(_("\tReading message cache from %s...\n"), cache_file);
+       debug_print("\tReading message cache from %s...\n", cache_file);
 
        /* compare cache version */
        if (fread(&ver, sizeof(ver), 1, fp) != 1 ||
            CACHE_VERSION != ver) {
-               debug_print(_("Cache version is different. Discarding it.\n"));
+               debug_print("Cache version is different. Discarding it.\n");
                fclose(fp);
                return NULL;
        }
 
+       if (item->stype == F_QUEUE) {
+               tmp_flags |= MSG_QUEUED;
+       } else if (item->stype == F_DRAFT) {
+               tmp_flags |= MSG_DRAFT;
+       }
+
        cache = msgcache_new();
 
        g_hash_table_freeze(cache->msgnum_table);
@@ -235,13 +251,12 @@ MsgCache *msgcache_read_cache(FolderItem *item, const gchar *cache_file)
                READ_CACHE_DATA(msginfo->references, fp);
                READ_CACHE_DATA(msginfo->xref, fp);
 
-/*
-               MSG_SET_PERM_FLAGS(msginfo->flags, default_flags.perm_flags);
-               MSG_SET_TMP_FLAGS(msginfo->flags, default_flags.tmp_flags);
-*/
                msginfo->folder = item;
+               msginfo->flags.tmp_flags |= tmp_flags;
 
-               g_hash_table_insert(cache->msgnum_table, GINT_TO_POINTER(msginfo->msgnum), msginfo);
+               g_hash_table_insert(cache->msgnum_table, &msginfo->msgnum, msginfo);
+               if(msginfo->msgid)
+                       g_hash_table_insert(cache->msgid_table, msginfo->msgid, msginfo);
                cache->memusage += procmsg_msginfo_memusage(msginfo);
        }
        fclose(fp);
@@ -255,8 +270,8 @@ MsgCache *msgcache_read_cache(FolderItem *item, const gchar *cache_file)
        cache->last_access = time(NULL);
        g_hash_table_thaw(cache->msgnum_table);
 
-       debug_print(_("done. (%d items read)\n"), g_hash_table_size(cache->msgnum_table));
-       debug_print(_("Cache size: %d messages, %d byte\n"), g_hash_table_size(cache->msgnum_table), cache->memusage);
+       debug_print("done. (%d items read)\n", g_hash_table_size(cache->msgnum_table));
+       debug_print("Cache size: %d messages, %d byte\n", g_hash_table_size(cache->msgnum_table), cache->memusage);
 
        return cache;
 }
@@ -270,18 +285,18 @@ void msgcache_read_mark(MsgCache *cache, const gchar *mark_file)
        guint num;
 
        if ((fp = fopen(mark_file, "rb")) == NULL) {
-               debug_print(_("Mark file not found.\n"));
+               debug_print("Mark file not found.\n");
                return;
        } else if (fread(&ver, sizeof(ver), 1, fp) != 1 || MARK_VERSION != ver) {
-               debug_print(_("Mark version is different (%d != %d). "
-                             "Discarding it.\n"), ver, MARK_VERSION);
+               debug_print("Mark version is different (%d != %d). "
+                             "Discarding it.\n", ver, MARK_VERSION);
        } else {
-               debug_print(_("\tReading message marks from %s...\n"), mark_file);
+               debug_print("\tReading message marks from %s...\n", mark_file);
 
                while (fread(&num, sizeof(num), 1, fp) == 1) {
                        if (fread(&perm_flags, sizeof(perm_flags), 1, fp) != 1) break;
 
-                       msginfo = g_hash_table_lookup(cache->msgnum_table, GUINT_TO_POINTER(num));
+                       msginfo = g_hash_table_lookup(cache->msgnum_table, &num);
                        if(msginfo) {
                                msginfo->flags.perm_flags = perm_flags;
                        }
@@ -296,13 +311,12 @@ void msgcache_read_mark(MsgCache *cache, const gchar *mark_file)
 #define WRITE_CACHE_DATA(data, fp) \
 { \
        gint len; \
- \
-       if (data == NULL || (len = strlen(data)) == 0) { \
+       if (data == NULL) \
                len = 0; \
-               WRITE_CACHE_DATA_INT(len, fp); \
-       } else { \
+       else \
                len = strlen(data); \
-               WRITE_CACHE_DATA_INT(len, fp); \
+       WRITE_CACHE_DATA_INT(len, fp); \
+       if (len > 0) { \
                fwrite(data, len, 1, fp); \
        } \
 }
@@ -367,7 +381,7 @@ gint msgcache_write(const gchar *cache_file, const gchar *mark_file, MsgCache *c
        g_return_val_if_fail(mark_file != NULL, -1);
        g_return_val_if_fail(cache != NULL, -1);
 
-       debug_print(_("\tWriting message cache to %s and %s...\n"), cache_file, mark_file);
+       debug_print("\tWriting message cache to %s and %s...\n", cache_file, mark_file);
 
        if ((fp = fopen(cache_file, "wb")) == NULL) {
                FILE_OP_ERROR(cache_file, "fopen");
@@ -397,7 +411,7 @@ gint msgcache_write(const gchar *cache_file, const gchar *mark_file, MsgCache *c
 
        cache->last_access = time(NULL);
 
-       debug_print(_("done.\n"));
+       debug_print("done.\n");
        return 0;
 }
 
@@ -407,7 +421,7 @@ MsgInfo *msgcache_get_msg(MsgCache *cache, guint num)
 
        g_return_val_if_fail(cache != NULL, NULL);
 
-       msginfo = g_hash_table_lookup(cache->msgnum_table, GINT_TO_POINTER(num));
+       msginfo = g_hash_table_lookup(cache->msgnum_table, &num);
        if(!msginfo)
                return NULL;
        cache->last_access = time(NULL);
@@ -415,6 +429,20 @@ MsgInfo *msgcache_get_msg(MsgCache *cache, guint num)
        return procmsg_msginfo_new_ref(msginfo);
 }
 
+MsgInfo *msgcache_get_msg_by_id(MsgCache *cache, const gchar *msgid)
+{
+       MsgInfo *msginfo;
+       
+       g_return_val_if_fail(cache != NULL, NULL);
+
+       msginfo = g_hash_table_lookup(cache->msgid_table, msgid);
+       if(!msginfo)
+               return NULL;
+       cache->last_access = time(NULL);
+       
+       return procmsg_msginfo_new_ref(msginfo);        
+}
+
 static void msgcache_get_msg_list_func(gpointer key, gpointer value, gpointer user_data)
 {
        GSList **listptr = user_data;
@@ -431,6 +459,8 @@ GSList *msgcache_get_msg_list(MsgCache *cache)
 
        g_hash_table_foreach((GHashTable *)cache->msgnum_table, msgcache_get_msg_list_func, (gpointer)&msg_list);       
        cache->last_access = time(NULL);
+       
+       msg_list = g_slist_reverse(msg_list);
 
        return msg_list;
 }