CamelFolderSummary API changes
authorMilan Crha <mcrha@redhat.com>
Thu, 6 Oct 2011 14:57:51 +0000 (16:57 +0200)
committerMilan Crha <mcrha@redhat.com>
Thu, 6 Oct 2011 14:57:51 +0000 (16:57 +0200)
40 files changed:
camel/camel-db.c
camel/camel-db.h
camel/camel-disco-folder.c
camel/camel-folder-search.c
camel/camel-folder-summary.c
camel/camel-folder-summary.h
camel/camel-folder-thread.c
camel/camel-folder.c
camel/camel-store-summary.c
camel/camel-store-summary.h
camel/camel-vee-folder.c
camel/camel-vee-summary.c
camel/camel-vee-summary.h
camel/camel-vtrash-folder.c
camel/providers/imap/camel-imap-folder.c
camel/providers/imap/camel-imap-message-cache.c
camel/providers/imap/camel-imap-store.c
camel/providers/imap/camel-imap-summary.c
camel/providers/imap/camel-imap-utils.c
camel/providers/imapx/camel-imapx-folder.c
camel/providers/imapx/camel-imapx-server.c
camel/providers/imapx/camel-imapx-store.c
camel/providers/imapx/camel-imapx-summary.c
camel/providers/imapx/camel-imapx-utils.c
camel/providers/imapx/camel-imapx-utils.h
camel/providers/local/camel-local-folder.c
camel/providers/local/camel-local-summary.c
camel/providers/local/camel-local-summary.h
camel/providers/local/camel-maildir-folder.c
camel/providers/local/camel-maildir-store.c
camel/providers/local/camel-maildir-summary.c
camel/providers/local/camel-mbox-folder.c
camel/providers/local/camel-mbox-store.c
camel/providers/local/camel-mbox-summary.c
camel/providers/local/camel-mh-folder.c
camel/providers/local/camel-mh-store.c
camel/providers/local/camel-mh-summary.c
camel/providers/local/camel-spool-summary.c
camel/providers/nntp/camel-nntp-folder.c
camel/providers/nntp/camel-nntp-summary.c

index bef5e24..5d8d67f 100644 (file)
@@ -1070,33 +1070,42 @@ camel_db_delete_uid_from_vfolder_transaction (CamelDB *db,
 }
 
 static gint
-read_uids_callback (gpointer ref,
+read_uids_callback (gpointer ref_array,
                     gint ncol,
                     gchar **cols,
                     gchar **name)
 {
-       GPtrArray *array = (GPtrArray *) ref;
+       GPtrArray *array = ref_array;
 
-       #if 0
-       gint i;
-       for (i = 0; i < ncol; ++i) {
-               if (!name[i] || !cols[i])
-                       continue;
+       g_return_val_if_fail (ncol == 1, 0);
 
-               if (!strcmp (name [i], "uid"))
-                       g_ptr_array_add (array, (gchar *) (camel_pstring_strdup (cols[i])));
-       }
-       #else
-               if (cols[0])
-                       g_ptr_array_add (array, (gchar *) (camel_pstring_strdup (cols[0])));
-       #endif
+       if (cols[0])
+               g_ptr_array_add (array, (gchar *) (camel_pstring_strdup (cols[0])));
 
-        return 0;
+       return 0;
+}
+
+static gint
+read_uids_to_hash_callback (gpointer ref_hash,
+                           gint ncol,
+                           gchar **cols,
+                           gchar **name)
+{
+       GHashTable *hash = ref_hash;
+
+       g_return_val_if_fail (ncol == 2, 0);
+
+       if (cols[0])
+               g_hash_table_insert (hash, (gchar *) camel_pstring_strdup (cols[0]), GUINT_TO_POINTER (cols[1] ? strtoul (cols[1], NULL, 10) : 0));
+
+       return 0;
 }
 
 /**
  * camel_db_get_folder_uids:
  *
+ * Fills hash with uid->GUINT_TO_POINTER (flag)
+ *
  * Since: 2.24
  **/
 gint
@@ -1104,15 +1113,15 @@ camel_db_get_folder_uids (CamelDB *db,
                           const gchar *folder_name,
                           const gchar *sort_by,
                           const gchar *collate,
-                          GPtrArray *array,
+                          GHashTable *hash,
                           GError **error)
 {
         gchar *sel_query;
         gint ret;
 
-        sel_query = sqlite3_mprintf("SELECT uid FROM %Q%s%s%s%s", folder_name, sort_by ? " order by " : "", sort_by ? sort_by: "", (sort_by && collate) ? " collate " : "", (sort_by && collate) ? collate : "");
+        sel_query = sqlite3_mprintf("SELECT uid,flags FROM %Q%s%s%s%s", folder_name, sort_by ? " order by " : "", sort_by ? sort_by: "", (sort_by && collate) ? " collate " : "", (sort_by && collate) ? collate : "");
 
-        ret = camel_db_select (db, sel_query, read_uids_callback, array, error);
+        ret = camel_db_select (db, sel_query, read_uids_to_hash_callback, hash, error);
         sqlite3_free (sel_query);
 
         return ret;
@@ -1172,13 +1181,19 @@ camel_db_get_folder_deleted_uids (CamelDB *db,
         return array;
 }
 
+struct ReadPreviewData
+{
+       GHashTable *columns_hash;
+       GHashTable *hash;
+};
+
 static gint
 read_preview_callback (gpointer ref,
                        gint ncol,
                        gchar **cols,
                        gchar **name)
 {
-       GHashTable *hash = (GHashTable *) ref;
+       struct ReadPreviewData *rpd = ref;
        const gchar *uid = NULL;
        gchar *msg = NULL;
        gint i;
@@ -1187,13 +1202,20 @@ read_preview_callback (gpointer ref,
                if (!name[i] || !cols[i])
                        continue;
 
-               if (!strcmp (name [i], "uid"))
-                       uid = camel_pstring_strdup (cols[i]);
-               else if (!strcmp (name [i], "preview"))
-                       msg = g_strdup (cols[i]);
+               switch (camel_db_get_column_ident (&rpd->columns_hash, i, ncol, name)) {
+                       case CAMEL_DB_COLUMN_UID:
+                               uid = camel_pstring_strdup (cols[i]);
+                               break;
+                       case CAMEL_DB_COLUMN_PREVIEW:
+                               msg = g_strdup (cols[i]);
+                               break;
+                       default:
+                               g_warn_if_reached ();
+                               break;
+               }
        }
 
-       g_hash_table_insert (hash, (gchar *) uid, msg);
+       g_hash_table_insert (rpd->hash, (gchar *) uid, msg);
 
        return 0;
 }
@@ -1208,21 +1230,28 @@ camel_db_get_folder_preview (CamelDB *db,
                              const gchar *folder_name,
                              GError **error)
 {
-        gchar *sel_query;
-        gint ret;
-        GHashTable *hash = g_hash_table_new (g_str_hash, g_str_equal);
+       gchar *sel_query;
+       gint ret;
+       struct ReadPreviewData rpd;
+       GHashTable *hash = g_hash_table_new (g_str_hash, g_str_equal);
 
-        sel_query = sqlite3_mprintf("SELECT uid, preview FROM '%q_preview'", folder_name);
+       sel_query = sqlite3_mprintf ("SELECT uid, preview FROM '%q_preview'", folder_name);
 
-        ret = camel_db_select (db, sel_query, read_preview_callback, hash, error);
-        sqlite3_free (sel_query);
+       rpd.columns_hash = NULL;
+       rpd.hash = hash;
 
-        if (!g_hash_table_size (hash) || ret != 0) {
-                g_hash_table_destroy (hash);
-                hash = NULL;
-        }
+       ret = camel_db_select (db, sel_query, read_preview_callback, &rpd, error);
+       sqlite3_free (sel_query);
+
+       if (rpd.columns_hash)
+               g_hash_table_destroy (rpd.columns_hash);
 
-        return hash;
+       if (!g_hash_table_size (hash) || ret != 0) {
+               g_hash_table_destroy (hash);
+               hash = NULL;
+       }
+
+       return hash;
 }
 
 /**
@@ -1256,20 +1285,8 @@ read_vuids_callback (gpointer ref,
 {
        GPtrArray *array = (GPtrArray *) ref;
 
-       #if 0
-       gint i;
-
-       for (i = 0; i < ncol; ++i) {
-               if (!name[i] || !cols[i] || strlen (cols[i]) <= 8)
-                       continue;
-
-               if (!strcmp (name [i], "vuid"))
-                       g_ptr_array_add (array, (gchar *) (camel_pstring_strdup (cols[i]+8)));
-       }
-       #else
-               if (cols[0] && strlen (cols[0]) > 8)
-                       g_ptr_array_add (array, (gchar *) (camel_pstring_strdup (cols[0]+8)));
-       #endif
+       if (cols[0] && strlen (cols[0]) > 8)
+               g_ptr_array_add (array, (gchar *) (camel_pstring_strdup (cols[0]+8)));
 
        return 0;
 }
@@ -1768,13 +1785,19 @@ camel_db_write_folder_info_record (CamelDB *cdb,
        return ret;
 }
 
+struct ReadFirData
+{
+       GHashTable *columns_hash;
+       CamelFIRecord *record;
+};
+
 static gint
 read_fir_callback (gpointer ref,
                    gint ncol,
                    gchar **cols,
                    gchar **name)
 {
-       CamelFIRecord *record = *(CamelFIRecord **) ref;
+       struct ReadFirData *rfd = ref;
        gint i;
 
        d(g_print ("\nread_fir_callback called \n"));
@@ -1783,39 +1806,47 @@ read_fir_callback (gpointer ref,
                if (!name[i] || !cols[i])
                        continue;
 
-               if (!strcmp (name [i], "folder_name"))
-                       record->folder_name = g_strdup (cols[i]);
-
-               else if (!strcmp (name [i], "version"))
-                       record->version = cols[i] ? strtoul (cols[i], NULL, 10) : 0;
-
-               else if (!strcmp (name [i], "flags"))
-                       record->flags = cols[i] ? strtoul (cols[i], NULL, 10) : 0;
-
-               else if (!strcmp (name [i], "nextuid"))
-                       record->nextuid = cols[i] ? strtoul (cols[i], NULL, 10) : 0;
-
-               else if (!strcmp (name [i], "time"))
-                       record->time = cols[i] ? strtoul (cols[i], NULL, 10) : 0;
-
-               else if (!strcmp (name [i], "saved_count"))
-                       record->saved_count = cols[i] ? strtoul (cols[i], NULL, 10) : 0;
-
-               else if (!strcmp (name [i], "unread_count"))
-                       record->unread_count = cols[i] ? strtoul (cols[i], NULL, 10) : 0;
-
-               else if (!strcmp (name [i], "deleted_count"))
-                       record->deleted_count = cols[i] ? strtoul (cols[i], NULL, 10) : 0;
-
-               else if (!strcmp (name [i], "junk_count"))
-                       record->junk_count = cols[i] ? strtoul (cols[i], NULL, 10) : 0;
-               else if (!strcmp (name [i], "visible_count"))
-                       record->visible_count = cols[i] ? strtoul (cols[i], NULL, 10) : 0;
-               else if (!strcmp (name [i], "jnd_count"))
-                       record->jnd_count = cols[i] ? strtoul (cols[i], NULL, 10) : 0;
-               else if (!strcmp (name [i], "bdata"))
-                       record->bdata = g_strdup (cols[i]);
-
+               switch (camel_db_get_column_ident (&rfd->columns_hash, i, ncol, name)) {
+                       case CAMEL_DB_COLUMN_FOLDER_NAME:
+                               rfd->record->folder_name = g_strdup (cols[i]);
+                               break;
+                       case CAMEL_DB_COLUMN_VERSION:
+                               rfd->record->version = cols[i] ? strtoul (cols[i], NULL, 10) : 0;
+                               break;
+                       case CAMEL_DB_COLUMN_FLAGS:
+                               rfd->record->flags = cols[i] ? strtoul (cols[i], NULL, 10) : 0;
+                               break;
+                       case CAMEL_DB_COLUMN_NEXTUID:
+                               rfd->record->nextuid = cols[i] ? strtoul (cols[i], NULL, 10) : 0;
+                               break;
+                       case CAMEL_DB_COLUMN_TIME:
+                               rfd->record->time = cols[i] ? strtoul (cols[i], NULL, 10) : 0;
+                               break;
+                       case CAMEL_DB_COLUMN_SAVED_COUNT:
+                               rfd->record->saved_count = cols[i] ? strtoul (cols[i], NULL, 10) : 0;
+                               break;
+                       case CAMEL_DB_COLUMN_UNREAD_COUNT:
+                               rfd->record->unread_count = cols[i] ? strtoul (cols[i], NULL, 10) : 0;
+                               break;
+                       case CAMEL_DB_COLUMN_DELETED_COUNT:
+                               rfd->record->deleted_count = cols[i] ? strtoul (cols[i], NULL, 10) : 0;
+                               break;
+                       case CAMEL_DB_COLUMN_JUNK_COUNT:
+                               rfd->record->junk_count = cols[i] ? strtoul (cols[i], NULL, 10) : 0;
+                               break;
+                       case CAMEL_DB_COLUMN_VISIBLE_COUNT:
+                               rfd->record->visible_count = cols[i] ? strtoul (cols[i], NULL, 10) : 0;
+                               break;
+                       case CAMEL_DB_COLUMN_JND_COUNT:
+                               rfd->record->jnd_count = cols[i] ? strtoul (cols[i], NULL, 10) : 0;
+                               break;
+                       case CAMEL_DB_COLUMN_BDATA:
+                               rfd->record->bdata = g_strdup (cols[i]);
+                               break;
+                       default:
+                               g_warn_if_reached ();
+                               break;
+               }
        }
 
        return 0;
@@ -1829,17 +1860,24 @@ read_fir_callback (gpointer ref,
 gint
 camel_db_read_folder_info_record (CamelDB *cdb,
                                   const gchar *folder_name,
-                                  CamelFIRecord **record,
+                                  CamelFIRecord *record,
                                   GError **error)
 {
+       struct ReadFirData rfd;
        gchar *query;
        gint ret;
 
-       query = sqlite3_mprintf ("SELECT * FROM folders WHERE folder_name = %Q", folder_name);
-       ret = camel_db_select (cdb, query, read_fir_callback, record, error);
+       rfd.columns_hash = NULL;
+       rfd.record = record;
 
+       query = sqlite3_mprintf ("SELECT * FROM folders WHERE folder_name = %Q", folder_name);
+       ret = camel_db_select (cdb, query, read_fir_callback, &rfd, error);
        sqlite3_free (query);
-       return (ret);
+
+       if (rfd.columns_hash)
+               g_hash_table_destroy (rfd.columns_hash);
+
+       return ret;
 }
 
 /**
@@ -2370,3 +2408,94 @@ camel_db_flush_in_memory_transactions (CamelDB *cdb,
 
        return ret;
 }
+
+static struct _known_column_names {
+       const gchar *name;
+       CamelDBKnownColumnNames ident;
+} known_column_names[] = {
+       { "attachment",                 CAMEL_DB_COLUMN_ATTACHMENT },
+       { "bdata",                      CAMEL_DB_COLUMN_BDATA },
+       { "bodystructure",              CAMEL_DB_COLUMN_BODYSTRUCTURE },
+       { "cinfo",                      CAMEL_DB_COLUMN_CINFO },
+       { "deleted",                    CAMEL_DB_COLUMN_DELETED },
+       { "deleted_count",              CAMEL_DB_COLUMN_DELETED_COUNT },
+       { "dreceived",                  CAMEL_DB_COLUMN_DRECEIVED },
+       { "dsent",                      CAMEL_DB_COLUMN_DSENT },
+       { "flags",                      CAMEL_DB_COLUMN_FLAGS },
+       { "folder_name",                CAMEL_DB_COLUMN_FOLDER_NAME },
+       { "followup_completed_on",      CAMEL_DB_COLUMN_FOLLOWUP_COMPLETED_ON },
+       { "followup_due_by",            CAMEL_DB_COLUMN_FOLLOWUP_DUE_BY },
+       { "followup_flag",              CAMEL_DB_COLUMN_FOLLOWUP_FLAG },
+       { "important",                  CAMEL_DB_COLUMN_IMPORTANT },
+       { "jnd_count",                  CAMEL_DB_COLUMN_JND_COUNT },
+       { "junk",                       CAMEL_DB_COLUMN_JUNK },
+       { "junk_count",                 CAMEL_DB_COLUMN_JUNK_COUNT },
+       { "labels",                     CAMEL_DB_COLUMN_LABELS },
+       { "mail_cc",                    CAMEL_DB_COLUMN_MAIL_CC },
+       { "mail_from",                  CAMEL_DB_COLUMN_MAIL_FROM },
+       { "mail_to",                    CAMEL_DB_COLUMN_MAIL_TO },
+       { "mlist",                      CAMEL_DB_COLUMN_MLIST },
+       { "nextuid",                    CAMEL_DB_COLUMN_NEXTUID },
+       { "part",                       CAMEL_DB_COLUMN_PART },
+       { "preview",                    CAMEL_DB_COLUMN_PREVIEW },
+       { "read",                       CAMEL_DB_COLUMN_READ },
+       { "replied",                    CAMEL_DB_COLUMN_REPLIED },
+       { "saved_count",                CAMEL_DB_COLUMN_SAVED_COUNT },
+       { "size",                       CAMEL_DB_COLUMN_SIZE },
+       { "subject",                    CAMEL_DB_COLUMN_SUBJECT },
+       { "time",                       CAMEL_DB_COLUMN_TIME },
+       { "uid",                        CAMEL_DB_COLUMN_UID },
+       { "unread_count",               CAMEL_DB_COLUMN_UNREAD_COUNT },
+       { "usertags",                   CAMEL_DB_COLUMN_USERTAGS },
+       { "version",                    CAMEL_DB_COLUMN_VERSION },
+       { "visible_count",              CAMEL_DB_COLUMN_VISIBLE_COUNT },
+       { "vuid",                       CAMEL_DB_COLUMN_VUID }
+};
+
+/**
+ * camel_db_get_column_ident:
+ * Traverses column name from index @index into an enum #CamelDBKnownColumnNames value;
+ * The @col_names contains @ncols columns. First time this is called is created
+ * the @hash from col_names indexes into the enum, and this is reused for every other call.
+ * The function expects that column names are returned always in the same order.
+ * When all rows are read the @hash table can be freed with g_hash_table_destroy().
+ **/
+CamelDBKnownColumnNames
+camel_db_get_column_ident (GHashTable **hash, gint index, gint ncols, gchar **col_names)
+{
+       gpointer value = NULL;
+
+       g_return_val_if_fail (hash != NULL, CAMEL_DB_COLUMN_UNKNOWN);
+       g_return_val_if_fail (col_names != NULL, CAMEL_DB_COLUMN_UNKNOWN);
+       g_return_val_if_fail (ncols > 0, CAMEL_DB_COLUMN_UNKNOWN);
+       g_return_val_if_fail (index >= 0, CAMEL_DB_COLUMN_UNKNOWN);
+       g_return_val_if_fail (index < ncols, CAMEL_DB_COLUMN_UNKNOWN);
+
+       if (!*hash) {
+               gint ii, jj, from, max = G_N_ELEMENTS (known_column_names);
+
+               *hash = g_hash_table_new (g_direct_hash, g_direct_equal);
+
+               for (ii = 0, jj = 0; ii < ncols; ii++) {
+                       const gchar *name = col_names[ii];
+                       gboolean first = TRUE;
+
+                       if (!name)
+                               continue;
+
+                       for (from = jj; first || jj != from; jj = (jj + 1) % max, first = FALSE) {
+                               if (g_str_equal (name, known_column_names[jj].name)) {
+                                       g_hash_table_insert (*hash, GINT_TO_POINTER (ii), GINT_TO_POINTER (known_column_names[jj].ident));
+                                       break;
+                               }
+                       }
+
+                       if (from == jj && !first)
+                               g_warning ("%s: missing column name '%s' in a list of known columns", G_STRFUNC, name);
+               }
+       }
+
+       g_return_val_if_fail (g_hash_table_lookup_extended (*hash, GINT_TO_POINTER (index), NULL, &value), CAMEL_DB_COLUMN_UNKNOWN);
+
+       return GPOINTER_TO_INT (value);
+}
index ad89225..b4c1721 100644 (file)
@@ -200,6 +200,49 @@ typedef struct _CamelFIRecord {
 
 typedef struct _CamelDB CamelDB;
 
+typedef enum {
+       CAMEL_DB_COLUMN_UNKNOWN = -1,
+       CAMEL_DB_COLUMN_ATTACHMENT,
+       CAMEL_DB_COLUMN_BDATA,
+       CAMEL_DB_COLUMN_BODYSTRUCTURE,
+       CAMEL_DB_COLUMN_CINFO,
+       CAMEL_DB_COLUMN_DELETED,
+       CAMEL_DB_COLUMN_DELETED_COUNT,
+       CAMEL_DB_COLUMN_DRECEIVED,
+       CAMEL_DB_COLUMN_DSENT,
+       CAMEL_DB_COLUMN_FLAGS,
+       CAMEL_DB_COLUMN_FOLDER_NAME,
+       CAMEL_DB_COLUMN_FOLLOWUP_COMPLETED_ON,
+       CAMEL_DB_COLUMN_FOLLOWUP_DUE_BY,
+       CAMEL_DB_COLUMN_FOLLOWUP_FLAG,
+       CAMEL_DB_COLUMN_IMPORTANT,
+       CAMEL_DB_COLUMN_JND_COUNT,
+       CAMEL_DB_COLUMN_JUNK,
+       CAMEL_DB_COLUMN_JUNK_COUNT,
+       CAMEL_DB_COLUMN_LABELS,
+       CAMEL_DB_COLUMN_MAIL_CC,
+       CAMEL_DB_COLUMN_MAIL_FROM,
+       CAMEL_DB_COLUMN_MAIL_TO,
+       CAMEL_DB_COLUMN_MLIST,
+       CAMEL_DB_COLUMN_NEXTUID,
+       CAMEL_DB_COLUMN_PART,
+       CAMEL_DB_COLUMN_PREVIEW,
+       CAMEL_DB_COLUMN_READ,
+       CAMEL_DB_COLUMN_REPLIED,
+       CAMEL_DB_COLUMN_SAVED_COUNT,
+       CAMEL_DB_COLUMN_SIZE,
+       CAMEL_DB_COLUMN_SUBJECT,
+       CAMEL_DB_COLUMN_TIME,
+       CAMEL_DB_COLUMN_UID,
+       CAMEL_DB_COLUMN_UNREAD_COUNT,
+       CAMEL_DB_COLUMN_USERTAGS,
+       CAMEL_DB_COLUMN_VERSION,
+       CAMEL_DB_COLUMN_VISIBLE_COUNT,
+       CAMEL_DB_COLUMN_VUID
+} CamelDBKnownColumnNames;
+
+CamelDBKnownColumnNames camel_db_get_column_ident (GHashTable **hash, gint index, gint ncols, gchar **col_names);
+
 /**
  * CamelDBSelectCB:
  *
@@ -231,7 +274,7 @@ gint camel_db_create_folders_table (CamelDB *cdb, GError **error);
 gint camel_db_select (CamelDB *cdb, const gchar * stmt, CamelDBSelectCB callback, gpointer data, GError **error);
 
 gint camel_db_write_folder_info_record (CamelDB *cdb, CamelFIRecord *record, GError **error);
-gint camel_db_read_folder_info_record (CamelDB *cdb, const gchar *folder_name, CamelFIRecord **record, GError **error);
+gint camel_db_read_folder_info_record (CamelDB *cdb, const gchar *folder_name, CamelFIRecord *record, GError **error);
 
 gint camel_db_prepare_message_info_table (CamelDB *cdb, const gchar *folder_name, GError **error);
 
@@ -260,7 +303,7 @@ GPtrArray * camel_db_get_vuids_from_vfolder (CamelDB *db, const gchar *folder_na
 gint camel_db_add_to_vfolder (CamelDB *db, gchar *folder_name, gchar *vuid, GError **error);
 gint camel_db_add_to_vfolder_transaction (CamelDB *db, const gchar *folder_name, const gchar *vuid, GError **error);
 
-gint camel_db_get_folder_uids (CamelDB *db, const gchar *folder_name, const gchar *sort_by, const gchar *collate, GPtrArray *array, GError **error);
+gint camel_db_get_folder_uids (CamelDB *db, const gchar *folder_name, const gchar *sort_by, const gchar *collate, GHashTable *hash, GError **error);
 
 GPtrArray * camel_db_get_folder_junk_uids (CamelDB *db, gchar *folder_name, GError **error);
 GPtrArray * camel_db_get_folder_deleted_uids (CamelDB *db, const gchar *folder_name, GError **error);
@@ -282,5 +325,5 @@ gint camel_db_write_preview_record (CamelDB *db, const gchar *folder_name, const
 
 gint
 camel_db_reset_folder_version (CamelDB *cdb, const gchar *folder_name, gint reset_version, GError **error);
-#endif
 
+#endif
index 81e54a8..56440b2 100644 (file)
@@ -262,25 +262,27 @@ disco_expunge_sync (CamelFolder *folder,
 {
        GPtrArray *uids;
        gint i;
-       guint count;
        CamelMessageInfo *info;
        gboolean success;
+       GPtrArray *known_uids;
 
        uids = g_ptr_array_new ();
        camel_folder_summary_prepare_fetch_all (folder->summary, NULL);
-       count = camel_folder_summary_count (folder->summary);
-       for (i = 0; i < count; i++) {
-               info = camel_folder_summary_index (folder->summary, i);
+       known_uids = camel_folder_summary_get_array (folder->summary);
+       for (i = 0; known_uids && i < known_uids->len; i++) {
+               const gchar *uid = g_ptr_array_index (known_uids, i);
+
+               info = camel_folder_summary_get (folder->summary, uid);
                if (camel_message_info_flags (info) & CAMEL_MESSAGE_DELETED)
-                       g_ptr_array_add (uids, g_strdup (camel_message_info_uid (info)));
+                       g_ptr_array_add (uids, (gpointer) uid);
                camel_message_info_free (info);
        }
 
        success = disco_expunge_uids (folder, uids, cancellable, error);
 
-       for (i = 0; i < uids->len; i++)
-               g_free (uids->pdata[i]);
        g_ptr_array_free (uids, TRUE);
+       if (known_uids)
+               camel_folder_summary_free_array (known_uids);
 
        return success;
 }
index 5d71725..364c539 100644 (file)
@@ -883,7 +883,7 @@ search_match_all (struct _ESExp *f,
        for (i = 0; i < v->len; i++) {
                const gchar *uid;
 
-               search->current = camel_folder_summary_uid (search->folder->summary, v->pdata[i]);
+               search->current = camel_folder_summary_get (search->folder->summary, v->pdata[i]);
                if (!search->current)
                        continue;
                uid = camel_message_info_uid (search->current);
index d0cf62f..354b255 100644 (file)
@@ -84,6 +84,24 @@ struct _CamelFolderSummaryPrivate {
 
        gboolean need_preview;
        GHashTable *preview_updates;
+
+       guint32 nextuid;        /* next uid? */
+       guint32 saved_count;    /* how many were saved/loaded */
+       guint32 unread_count;   /* handy totals */
+       guint32 deleted_count;
+       guint32 junk_count;
+       guint32 junk_not_deleted_count;
+       guint32 visible_count;
+
+       gchar *summary_path;
+       gboolean build_content; /* do we try and parse/index the content, or not? */
+
+       GHashTable *uids; /* uids of all known message infos; the 'value' are used flags for the message info */
+       GHashTable *loaded_infos; /* uid->CamelMessageInfo*, those currently in memory */
+
+       struct _CamelFolder *folder; /* parent folder, for events */
+       time_t cache_load_time;
+       guint timeout_handle;
 };
 
 static GStaticMutex info_lock = G_STATIC_MUTEX_INIT;
@@ -101,8 +119,6 @@ static GStaticMutex info_lock = G_STATIC_MUTEX_INIT;
 
 #define CAMEL_FOLDER_SUMMARY_VERSION (14)
 
-#define META_SUMMARY_SUFFIX_LEN 5 /* strlen("-meta") */
-
 /* trivial lists, just because ... */
 struct _node {
        struct _node *next;
@@ -138,6 +154,19 @@ static CamelMessageContentInfo * summary_build_content_info_message (CamelFolder
 
 static CamelMessageInfo * message_info_from_uid (CamelFolderSummary *s, const gchar *uid);
 
+enum {
+       PROP_0,
+       PROP_FOLDER,
+       PROP_SAVED_COUNT,
+       PROP_UNREAD_COUNT,
+       PROP_DELETED_COUNT,
+       PROP_JUNK_COUNT,
+       PROP_JUNK_NOT_DELETED_COUNT,
+       PROP_VISIBLE_COUNT,
+       PROP_BUILD_CONTENT,
+       PROP_NEED_PREVIEW
+};
+
 G_DEFINE_TYPE (CamelFolderSummary, camel_folder_summary, CAMEL_TYPE_OBJECT)
 
 static void
@@ -204,36 +233,216 @@ static void
 folder_summary_finalize (GObject *object)
 {
        CamelFolderSummary *summary = CAMEL_FOLDER_SUMMARY (object);
+       CamelFolderSummaryPrivate *priv = summary->priv;
 
-       if (summary->timeout_handle)
-               g_source_remove (summary->timeout_handle);
-       /*camel_folder_summary_clear(s);*/
-       g_ptr_array_foreach (summary->uids, (GFunc) camel_pstring_free, NULL);
-       g_ptr_array_free (summary->uids, TRUE);
-       g_hash_table_destroy (summary->loaded_infos);
+       if (priv->timeout_handle)
+               g_source_remove (priv->timeout_handle);
 
-       g_hash_table_foreach (summary->priv->filter_charset, free_o_name, NULL);
-       g_hash_table_destroy (summary->priv->filter_charset);
+       g_hash_table_destroy (priv->uids);
+       g_hash_table_destroy (priv->loaded_infos);
 
-       g_hash_table_destroy (summary->priv->preview_updates);
+       g_hash_table_foreach (priv->filter_charset, free_o_name, NULL);
+       g_hash_table_destroy (priv->filter_charset);
 
-       g_free (summary->summary_path);
+       g_hash_table_destroy (priv->preview_updates);
 
-       /* Freeing memory occupied by meta-summary-header */
-       g_free (summary->meta_summary->path);
-       g_free (summary->meta_summary);
+       g_free (priv->summary_path);
 
-       g_static_rec_mutex_free (&summary->priv->summary_lock);
-       g_static_rec_mutex_free (&summary->priv->io_lock);
-       g_static_rec_mutex_free (&summary->priv->filter_lock);
-       g_static_rec_mutex_free (&summary->priv->alloc_lock);
-       g_static_rec_mutex_free (&summary->priv->ref_lock);
+       g_static_rec_mutex_free (&priv->summary_lock);
+       g_static_rec_mutex_free (&priv->io_lock);
+       g_static_rec_mutex_free (&priv->filter_lock);
+       g_static_rec_mutex_free (&priv->alloc_lock);
+       g_static_rec_mutex_free (&priv->ref_lock);
 
        /* Chain up to parent's finalize() method. */
        G_OBJECT_CLASS (camel_folder_summary_parent_class)->finalize (object);
 }
 
-static gint
+static void
+folder_summary_set_folder (CamelFolderSummary *summary, CamelFolder *folder)
+{
+       g_return_if_fail (summary != NULL);
+       g_return_if_fail (summary->priv != NULL);
+       g_return_if_fail (summary->priv->folder == NULL);
+       /* folder can be NULL in certain cases, see maildir-store */
+       
+       summary->priv->folder = folder;
+}
+
+static void
+folder_summary_set_property (GObject *object,
+                            guint property_id,
+                            const GValue *value,
+                            GParamSpec *pspec)
+{
+       switch (property_id) {
+               case PROP_FOLDER:
+                       folder_summary_set_folder (
+                               CAMEL_FOLDER_SUMMARY (object),
+                               CAMEL_FOLDER (g_value_get_object (value)));
+                       return;
+
+               case PROP_BUILD_CONTENT:
+                       camel_folder_summary_set_build_content (
+                               CAMEL_FOLDER_SUMMARY (object),
+                               g_value_get_boolean (value));
+                       return;
+
+               case PROP_NEED_PREVIEW:
+                       camel_folder_summary_set_need_preview (
+                               CAMEL_FOLDER_SUMMARY (object),
+                               g_value_get_boolean (value));
+                       return;
+       }
+
+       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+folder_summary_get_property (GObject *object,
+                            guint property_id,
+                            GValue *value,
+                            GParamSpec *pspec)
+{
+       switch (property_id) {
+               case PROP_FOLDER:
+                       g_value_set_object (
+                               value, camel_folder_summary_get_folder (
+                               CAMEL_FOLDER_SUMMARY (object)));
+                       return;
+
+               case PROP_SAVED_COUNT:
+                       g_value_set_uint (
+                               value, camel_folder_summary_get_saved_count (
+                               CAMEL_FOLDER_SUMMARY (object)));
+                       return;
+
+               case PROP_UNREAD_COUNT:
+                       g_value_set_uint (
+                               value, camel_folder_summary_get_unread_count (
+                               CAMEL_FOLDER_SUMMARY (object)));
+                       return;
+
+               case PROP_DELETED_COUNT:
+                       g_value_set_uint (
+                               value, camel_folder_summary_get_deleted_count (
+                               CAMEL_FOLDER_SUMMARY (object)));
+                       return;
+
+               case PROP_JUNK_COUNT:
+                       g_value_set_uint (
+                               value, camel_folder_summary_get_junk_count (
+                               CAMEL_FOLDER_SUMMARY (object)));
+                       return;
+
+               case PROP_JUNK_NOT_DELETED_COUNT:
+                       g_value_set_uint (
+                               value, camel_folder_summary_get_junk_not_deleted_count (
+                               CAMEL_FOLDER_SUMMARY (object)));
+                       return;
+
+               case PROP_VISIBLE_COUNT:
+                       g_value_set_uint (
+                               value, camel_folder_summary_get_visible_count (
+                               CAMEL_FOLDER_SUMMARY (object)));
+                       return;
+
+               case PROP_BUILD_CONTENT:
+                       g_value_set_boolean (
+                               value, camel_folder_summary_get_build_content (
+                               CAMEL_FOLDER_SUMMARY (object)));
+                       return;
+
+               case PROP_NEED_PREVIEW:
+                       g_value_set_boolean (
+                               value, camel_folder_summary_get_need_preview (
+                               CAMEL_FOLDER_SUMMARY (object)));
+                       return;
+       }
+
+       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+/**
+ * folder_summary_update_counts_by_flags:
+ *
+ * Since: 3.0
+ **/
+static void
+folder_summary_update_counts_by_flags (CamelFolderSummary *summary,
+                                       guint32 flags,
+                                       gboolean subtract)
+{
+       gint unread = 0, deleted = 0, junk = 0;
+       gboolean is_junk_folder = FALSE, is_trash_folder = FALSE;
+       GObject *summary_object;
+
+       g_return_if_fail (summary != NULL);
+       g_return_if_fail (summary->priv != NULL);
+
+       summary_object = G_OBJECT (summary);
+
+       if (summary->priv->folder && CAMEL_IS_VTRASH_FOLDER (summary->priv->folder)) {
+               CamelVTrashFolder *vtrash = CAMEL_VTRASH_FOLDER (summary->priv->folder);
+
+               is_junk_folder = vtrash && vtrash->type == CAMEL_VTRASH_FOLDER_JUNK;
+               is_trash_folder = vtrash && vtrash->type == CAMEL_VTRASH_FOLDER_TRASH;
+       }
+
+       if (!(flags & CAMEL_MESSAGE_SEEN))
+               unread = subtract ? -1 : 1;
+
+       if (flags & CAMEL_MESSAGE_DELETED)
+               deleted = subtract ? -1 : 1;
+
+       if (flags & CAMEL_MESSAGE_JUNK)
+               junk = subtract ? -1 : 1;
+
+       dd(printf("%p: %d %d %d | %d %d %d \n", (gpointer) summary, unread, deleted, junk, summary->priv->unread_count, summary->priv->visible_count, summary->priv->saved_count));
+
+       g_object_freeze_notify (summary_object);
+
+       if (deleted) {
+               summary->priv->deleted_count += deleted;
+               g_object_notify (summary_object, "deleted-count");
+       }
+
+       if (junk) {
+               summary->priv->junk_count += junk;
+               g_object_notify (summary_object, "junk-count");
+       }
+
+       if (junk && !deleted) {
+               summary->priv->junk_not_deleted_count += junk;
+               g_object_notify (summary_object, "junk-not-deleted-count");
+       }
+
+       if (!junk && !deleted) {
+               summary->priv->visible_count += subtract ? -1 : 1;
+               g_object_notify (summary_object, "visible-count");
+       }
+
+       if (junk && !is_junk_folder)
+               unread = 0;
+       if (deleted && !is_trash_folder)
+               unread = 0;
+
+       if (unread) {
+               summary->priv->unread_count += unread;
+               g_object_notify (summary_object, "unread-count");
+       }
+
+       summary->priv->saved_count += subtract ? -1 : 1;
+       g_object_notify (summary_object, "saved-count");
+
+       camel_folder_summary_touch (summary);
+
+       g_object_thaw_notify (summary_object);
+
+       dd(printf("%p: %d %d %d | %d %d %d\n", (gpointer) summary, unread, deleted, junk, summary->priv->unread_count, summary->priv->visible_count, summary->priv->saved_count));
+}
+
+static gboolean
 summary_header_from_db (CamelFolderSummary *s,
                         CamelFIRecord *record)
 {
@@ -247,7 +456,7 @@ summary_header_from_db (CamelFolderSummary *s,
        if ((s->version > 0xff) && (s->version & 0xff) < 12) {
                io(printf ("Summary header version mismatch"));
                errno = EINVAL;
-               return -1;
+               return FALSE;
        }
 
        if (!(s->version < 0x100 && s->version >= 13))
@@ -257,17 +466,17 @@ summary_header_from_db (CamelFolderSummary *s,
 #endif
 
        s->flags = record->flags;
-       s->nextuid = record->nextuid;
+       s->priv->nextuid = record->nextuid;
        s->time = record->time;
-       s->saved_count = record->saved_count;
+       s->priv->saved_count = record->saved_count;
 
-       s->unread_count = record->unread_count;
-       s->deleted_count = record->deleted_count;
-       s->junk_count = record->junk_count;
-       s->visible_count = record->visible_count;
-       s->junk_not_deleted_count = record->jnd_count;
+       s->priv->unread_count = record->unread_count;
+       s->priv->deleted_count = record->deleted_count;
+       s->priv->junk_count = record->junk_count;
+       s->priv->visible_count = record->visible_count;
+       s->priv->junk_not_deleted_count = record->jnd_count;
 
-       return 0;
+       return TRUE;
 }
 
 static CamelFIRecord *
@@ -281,8 +490,8 @@ summary_header_to_db (CamelFolderSummary *s,
 
        /* Though we are going to read, we do this during write,
         * so lets use it that way. */
-       table_name = camel_folder_get_full_name (s->folder);
-       parent_store = camel_folder_get_parent_store (s->folder);
+       table_name = camel_folder_get_full_name (s->priv->folder);
+       parent_store = camel_folder_get_parent_store (s->priv->folder);
        db = parent_store->cdb_w;
 
        io(printf("Savining header to db\n"));
@@ -292,7 +501,7 @@ summary_header_to_db (CamelFolderSummary *s,
        /* we always write out the current version */
        record->version = CAMEL_FOLDER_SUMMARY_VERSION;
        record->flags  = s->flags;
-       record->nextuid = s->nextuid;
+       record->nextuid = s->priv->nextuid;
        record->time = s->time;
 
        /* FIXME: Ever heard of Constructors and initializing ? */
@@ -309,11 +518,11 @@ summary_header_to_db (CamelFolderSummary *s,
        if (camel_db_count_junk_not_deleted_message_info (db, table_name, &(record->jnd_count), NULL))
                record->jnd_count = 0;
 
-       s->unread_count = record->unread_count;
-       s->deleted_count = record->deleted_count;
-       s->junk_count = record->junk_count;
-       s->visible_count = record->visible_count;
-       s->junk_not_deleted_count = record->jnd_count;
+       s->priv->unread_count = record->unread_count;
+       s->priv->deleted_count = record->deleted_count;
+       s->priv->junk_count = record->junk_count;
+       s->priv->visible_count = record->visible_count;
+       s->priv->junk_not_deleted_count = record->jnd_count;
 
        return record;
 }
@@ -527,7 +736,7 @@ content_info_from_db (CamelFolderSummary *s,
        return ci;
 }
 
-static gint
+static gboolean
 content_info_to_db (CamelFolderSummary *s,
                     CamelMessageContentInfo *ci,
                     CamelMIRecord *record)
@@ -591,14 +800,15 @@ content_info_to_db (CamelFolderSummary *s,
                g_string_free (str, FALSE);
        }
 
-       return 0;
+       return TRUE;
 }
 
 static gint
 summary_header_save (CamelFolderSummary *s,
                      FILE *out)
 {
-       gint unread = 0, deleted = 0, junk = 0, count, i;
+       gint unread = 0, deleted = 0, junk = 0, i;
+       GPtrArray *known_uids;
 
        fseek (out, 0, SEEK_SET);
 
@@ -607,12 +817,12 @@ summary_header_save (CamelFolderSummary *s,
        /* we always write out the current version */
        camel_file_util_encode_fixed_int32 (out, CAMEL_FOLDER_SUMMARY_VERSION);
        camel_file_util_encode_fixed_int32 (out, s->flags);
-       camel_file_util_encode_fixed_int32 (out, s->nextuid);
+       camel_file_util_encode_fixed_int32 (out, s->priv->nextuid);
        camel_file_util_encode_time_t (out, s->time);
 
-       count = camel_folder_summary_count (s);
-       for (i = 0; i < count; i++) {
-               CamelMessageInfo *info = camel_folder_summary_index (s, i);
+       known_uids = camel_folder_summary_get_array (s);
+       for (i = 0; known_uids && i < known_uids->len; i++) {
+               CamelMessageInfo *info = camel_folder_summary_get (s, g_ptr_array_index (known_uids, i));
                guint32 flags;
 
                if (info == NULL)
@@ -629,13 +839,70 @@ summary_header_save (CamelFolderSummary *s,
                camel_message_info_free (info);
        }
 
-       camel_file_util_encode_fixed_int32 (out, count);
+       camel_folder_summary_free_array (known_uids);
+
+       camel_file_util_encode_fixed_int32 (out, i); /* total count */
        camel_file_util_encode_fixed_int32 (out, unread);
        camel_file_util_encode_fixed_int32 (out, deleted);
 
        return camel_file_util_encode_fixed_int32 (out, junk);
 }
 
+static gboolean
+folder_summary_replace_flags (CamelFolderSummary *summary, CamelMessageInfo *info)
+{
+       guint32 used_flags;
+       GObject *summary_object;
+       guint32 old_saved_count, old_unread_count, old_deleted_count, old_junk_count;
+       guint32 old_junk_not_deleted_count, old_visible_count;
+
+       g_return_val_if_fail (summary != NULL, FALSE);
+       g_return_val_if_fail (summary->priv != NULL, FALSE);
+       g_return_val_if_fail (info != NULL, FALSE);
+
+       if (!camel_message_info_uid (info) ||
+           !camel_folder_summary_check_uid (summary, camel_message_info_uid (info)))
+               return FALSE;
+
+       summary_object = G_OBJECT (summary);
+
+       camel_folder_summary_lock (summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
+       g_object_freeze_notify (summary_object);
+
+       used_flags = GPOINTER_TO_UINT (g_hash_table_lookup (summary->priv->uids, camel_message_info_uid (info)));
+
+       old_saved_count = summary->priv->saved_count;
+       old_unread_count = summary->priv->unread_count;
+       old_deleted_count = summary->priv->deleted_count;
+       old_junk_count = summary->priv->junk_count;
+       old_junk_not_deleted_count = summary->priv->junk_not_deleted_count;
+       old_visible_count = summary->priv->visible_count;
+
+       /* decrement counts with old flags */
+       folder_summary_update_counts_by_flags (summary, used_flags, TRUE);
+
+       /* update current flags on the summary */
+       g_hash_table_insert (summary->priv->uids,
+               (gpointer) camel_pstring_strdup (camel_message_info_uid (info)),
+               GUINT_TO_POINTER (camel_message_info_flags (info)));
+
+       /* increment counts with new flags */
+       folder_summary_update_counts_by_flags (summary, camel_message_info_flags (info), FALSE);
+
+       /* this approach generates false notifications at least for "saved-count",
+          but is it an issue? I suppose not.
+       */
+       g_object_thaw_notify (summary_object);
+       camel_folder_summary_unlock (summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
+
+       return  old_saved_count != summary->priv->saved_count ||
+               old_unread_count != summary->priv->unread_count ||
+               old_deleted_count != summary->priv->deleted_count ||
+               old_junk_count != summary->priv->junk_count ||
+               old_junk_not_deleted_count != summary->priv->junk_not_deleted_count ||
+               old_visible_count != summary->priv->visible_count;
+}
+
 static CamelMessageInfo *
 message_info_clone (CamelFolderSummary *s,
                     const CamelMessageInfo *mi)
@@ -773,15 +1040,15 @@ info_set_user_flag (CamelMessageInfo *info,
 
        res = camel_flag_set (&mi->user_flags, name, value);
 
-       /* TODO: check this item is still in the summary first */
-       if (mi->summary && res && mi->summary->folder && mi->uid) {
+       if (mi->summary && res && mi->summary->priv->folder && mi->uid
+           && camel_folder_summary_check_uid (mi->summary, mi->uid)) {
                CamelFolderChangeInfo *changes = camel_folder_change_info_new ();
 
                mi->flags |= CAMEL_MESSAGE_FOLDER_FLAGGED;
                mi->dirty = TRUE;
                camel_folder_summary_touch (mi->summary);
                camel_folder_change_info_change_uid (changes, camel_message_info_uid (info));
-               camel_folder_changed (mi->summary->folder, changes);
+               camel_folder_changed (mi->summary->priv->folder, changes);
                camel_folder_change_info_free (changes);
        }
 
@@ -798,14 +1065,15 @@ info_set_user_tag (CamelMessageInfo *info,
 
        res = camel_tag_set (&mi->user_tags, name, value);
 
-       if (mi->summary && res && mi->summary->folder && mi->uid) {
+       if (mi->summary && res && mi->summary->priv->folder && mi->uid
+           && camel_folder_summary_check_uid (mi->summary, mi->uid)) {
                CamelFolderChangeInfo *changes = camel_folder_change_info_new ();
 
                mi->flags |= CAMEL_MESSAGE_FOLDER_FLAGGED;
                mi->dirty = TRUE;
                camel_folder_summary_touch (mi->summary);
                camel_folder_change_info_change_uid (changes, camel_message_info_uid (info));
-               camel_folder_changed (mi->summary->folder, changes);
+               camel_folder_changed (mi->summary->priv->folder, changes);
                camel_folder_change_info_free (changes);
        }
 
@@ -819,19 +1087,9 @@ info_set_flags (CamelMessageInfo *info,
 {
        guint32 old;
        CamelMessageInfoBase *mi = (CamelMessageInfoBase *) info;
-       gint read = 0, deleted = 0, junk = 0;
-       /* TODO: locking? */
-
-       if (flags & CAMEL_MESSAGE_SEEN && ((set & CAMEL_MESSAGE_SEEN) != (mi->flags & CAMEL_MESSAGE_SEEN)))
-       { read = set & CAMEL_MESSAGE_SEEN ? 1 : -1; d(printf("Setting read as %d\n", set & CAMEL_MESSAGE_SEEN ? 1 : 0));}
-
-       if (flags & CAMEL_MESSAGE_DELETED && ((set & CAMEL_MESSAGE_DELETED) != (mi->flags & CAMEL_MESSAGE_DELETED)))
-       { deleted = set & CAMEL_MESSAGE_DELETED ? 1 : -1; d(printf("Setting deleted as %d\n", set & CAMEL_MESSAGE_DELETED ? 1 : 0));}
-
-       if (flags & CAMEL_MESSAGE_JUNK && ((set & CAMEL_MESSAGE_JUNK) != (mi->flags & CAMEL_MESSAGE_JUNK)))
-       { junk = set & CAMEL_MESSAGE_JUNK ? 1 : -1; d(printf("Setting junk as %d\n", set & CAMEL_MESSAGE_JUNK ? 1 : 0));}
+       gboolean counts_changed = FALSE;
 
-       old = mi->flags;
+       old = camel_message_info_flags (info);
        mi->flags = (old & ~flags) | (set & flags);
        if (old != mi->flags) {
                mi->flags |= CAMEL_MESSAGE_FOLDER_FLAGGED;
@@ -840,38 +1098,33 @@ info_set_flags (CamelMessageInfo *info,
                        camel_folder_summary_touch (mi->summary);
        }
 
-       if (((old & ~CAMEL_MESSAGE_SYSTEM_MASK) == (mi->flags & ~CAMEL_MESSAGE_SYSTEM_MASK)) && !((set & CAMEL_MESSAGE_JUNK_LEARN) && !(set & CAMEL_MESSAGE_JUNK)))
+       if (mi->summary) {
+               camel_folder_summary_lock (mi->summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
+               g_object_freeze_notify (G_OBJECT (mi->summary));
+               counts_changed = folder_summary_replace_flags (mi->summary, info);
+       }
+
+       if (!counts_changed && ((old & ~CAMEL_MESSAGE_SYSTEM_MASK) == (mi->flags & ~CAMEL_MESSAGE_SYSTEM_MASK)) && !((set & CAMEL_MESSAGE_JUNK_LEARN) && !(set & CAMEL_MESSAGE_JUNK))) {
+               if (mi->summary) {
+                       g_object_thaw_notify (G_OBJECT (mi->summary));
+                       camel_folder_summary_unlock (mi->summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
+               }
                return FALSE;
+       }
 
        if (mi->summary) {
-               if (read && junk == 0 && !(mi->flags & CAMEL_MESSAGE_JUNK))
-                       mi->summary->unread_count -= read;
-               else if (junk > 0)
-                       mi->summary->unread_count -= (old & CAMEL_MESSAGE_SEEN) ? 0 : 1;
-               else if (junk < 0)
-                       mi->summary->unread_count -= (old & CAMEL_MESSAGE_SEEN) ? 0 : -1;
-
-               if (deleted)
-                       mi->summary->deleted_count += deleted;
-               if (junk)
-                       mi->summary->junk_count += junk;
-               if (junk && !deleted)
-                       mi->summary->junk_not_deleted_count += junk;
-               else if ((mi->flags & CAMEL_MESSAGE_JUNK) && deleted)
-                       mi->summary->junk_not_deleted_count -= deleted;
-
-               if (((junk && !(mi->flags & CAMEL_MESSAGE_DELETED))) || (deleted && !(mi->flags & CAMEL_MESSAGE_JUNK)))
-                       mi->summary->visible_count -= junk ? junk : deleted;
-       }
-       if (mi->summary && mi->summary->folder && mi->uid) {
+               g_object_thaw_notify (G_OBJECT (mi->summary));
+               camel_folder_summary_unlock (mi->summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
+       }
+
+       if (mi->summary && mi->summary->priv->folder && mi->uid) {
                CamelFolderChangeInfo *changes = camel_folder_change_info_new ();
 
                camel_folder_change_info_change_uid (changes, camel_message_info_uid (info));
-               camel_folder_changed (mi->summary->folder, changes);
+               camel_folder_changed (mi->summary->priv->folder, changes);
                camel_folder_change_info_free (changes);
        }
 
-       d(printf("%d %d %d %d %d\n", mi->summary->unread_count, mi->summary->deleted_count, mi->summary->junk_count, mi->summary->junk_not_deleted_count, mi->summary->visible_count));
        return TRUE;
 }
 
@@ -883,6 +1136,8 @@ camel_folder_summary_class_init (CamelFolderSummaryClass *class)
        g_type_class_add_private (class, sizeof (CamelFolderSummaryPrivate));
 
        object_class = G_OBJECT_CLASS (class);
+       object_class->set_property = folder_summary_set_property;
+       object_class->get_property = folder_summary_get_property;
        object_class->dispose = folder_summary_dispose;
        object_class->finalize = folder_summary_finalize;
 
@@ -926,6 +1181,140 @@ camel_folder_summary_class_init (CamelFolderSummaryClass *class)
 
        class->info_set_flags = info_set_flags;
 
+       /**
+        * CamelFolderSummary:folder
+        *
+        * The #CamelFolder to which the folder summary belongs.
+        **/
+       g_object_class_install_property (
+               object_class,
+               PROP_FOLDER,
+               g_param_spec_object (
+                       "folder",
+                       "Folder",
+                       "The folder to which the folder summary belongs",
+                       CAMEL_TYPE_FOLDER,
+                       G_PARAM_READWRITE |
+                       G_PARAM_CONSTRUCT_ONLY));
+
+       /**
+        * CamelFolderSummary:saved-count
+        *
+        * How many infos is saved in a summary.
+        **/
+       g_object_class_install_property (
+               object_class,
+               PROP_SAVED_COUNT,
+               g_param_spec_uint (
+                       "saved-count",
+                       "Saved count",
+                       "How many infos is savef in a summary",
+                       0,  G_MAXUINT32,
+                       0, G_PARAM_READABLE));
+
+       /**
+        * CamelFolderSummary:unread-count
+        *
+        * How many unread infos is saved in a summary.
+        **/
+       g_object_class_install_property (
+               object_class,
+               PROP_UNREAD_COUNT,
+               g_param_spec_uint (
+                       "unread-count",
+                       "Unread count",
+                       "How many unread infos is saved in a summary",
+                       0,  G_MAXUINT32,
+                       0, G_PARAM_READABLE));
+
+       /**
+        * CamelFolderSummary:deleted-count
+        *
+        * How many deleted infos is saved in a summary.
+        **/
+       g_object_class_install_property (
+               object_class,
+               PROP_DELETED_COUNT,
+               g_param_spec_uint (
+                       "deleted-count",
+                       "Deleted count",
+                       "How many deleted infos is saved in a summary",
+                       0,  G_MAXUINT32,
+                       0, G_PARAM_READABLE));
+
+       /**
+        * CamelFolderSummary:junk-count
+        *
+        * How many junk infos is saved in a summary.
+        **/
+       g_object_class_install_property (
+               object_class,
+               PROP_JUNK_COUNT,
+               g_param_spec_uint (
+                       "junk-count",
+                       "Junk count",
+                       "How many junk infos is saved in a summary",
+                       0,  G_MAXUINT32,
+                       0, G_PARAM_READABLE));
+
+       /**
+        * CamelFolderSummary:junk-not-deleted-count
+        *
+        * How many junk and not deleted infos is saved in a summary.
+        **/
+       g_object_class_install_property (
+               object_class,
+               PROP_JUNK_NOT_DELETED_COUNT,
+               g_param_spec_uint (
+                       "junk-not-deleted-count",
+                       "Junk not deleted count",
+                       "How many junk and not deleted infos is saved in a summary",
+                       0,  G_MAXUINT32,
+                       0, G_PARAM_READABLE));
+
+       /**
+        * CamelFolderSummary:visible-count
+        *
+        * How many visible (not deleted and not junk) infos is saved in a summary.
+        **/
+       g_object_class_install_property (
+               object_class,
+               PROP_VISIBLE_COUNT,
+               g_param_spec_uint (
+                       "visible-count",
+                       "Visible count",
+                       "How many visible (not deleted and not junk) infos is saved in a summary",
+                       0,  G_MAXUINT32,
+                       0, G_PARAM_READABLE));
+
+       /**
+        * CamelFolderSummary:build-content
+        *
+        * Whether to build CamelMessageInfo.content.
+        **/
+       g_object_class_install_property (
+               object_class,
+               PROP_BUILD_CONTENT,
+               g_param_spec_boolean (
+                       "build-content",
+                       "Build content",
+                       "Whether to build CamelMessageInfo.content",
+                       FALSE,
+                       G_PARAM_READWRITE));
+
+       /**
+        * CamelFolderSummary:need-preview
+        *
+        **/
+       g_object_class_install_property (
+               object_class,
+               PROP_NEED_PREVIEW,
+               g_param_spec_boolean (
+                       "need-preview",
+                       "Need preview",
+                       "",
+                       FALSE,
+                       G_PARAM_READWRITE));
 }
 
 static void
@@ -934,24 +1323,19 @@ camel_folder_summary_init (CamelFolderSummary *summary)
        summary->priv = G_TYPE_INSTANCE_GET_PRIVATE (
                summary, CAMEL_TYPE_FOLDER_SUMMARY, CamelFolderSummaryPrivate);
 
+       summary->version = CAMEL_FOLDER_SUMMARY_VERSION;
+       summary->flags = 0;
+       summary->time = 0;
+
        summary->priv->filter_charset = g_hash_table_new (
                camel_strcase_hash, camel_strcase_equal);
 
-       summary->message_info_chunks = NULL;
-       summary->content_info_chunks = NULL;
        summary->priv->need_preview = FALSE;
        summary->priv->preview_updates = g_hash_table_new (g_str_hash, g_str_equal);
-#if defined (DOESTRV) || defined (DOEPOOLV)
-       summary->message_info_strings = CAMEL_MESSAGE_INFO_LAST;
-#endif
 
-       summary->version = CAMEL_FOLDER_SUMMARY_VERSION;
-       summary->flags = 0;
-       summary->time = 0;
-       summary->nextuid = 1;
-
-       summary->uids = g_ptr_array_new ();
-       summary->loaded_infos = g_hash_table_new (g_str_hash, g_str_equal);
+       summary->priv->nextuid = 1;
+       summary->priv->uids = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify) camel_pstring_free, NULL);
+       summary->priv->loaded_infos = g_hash_table_new (g_str_hash, g_str_equal);
 
        g_static_rec_mutex_init (&summary->priv->summary_lock);
        g_static_rec_mutex_init (&summary->priv->io_lock);
@@ -959,14 +1343,8 @@ camel_folder_summary_init (CamelFolderSummary *summary)
        g_static_rec_mutex_init (&summary->priv->alloc_lock);
        g_static_rec_mutex_init (&summary->priv->ref_lock);
 
-       summary->meta_summary = g_malloc0 (sizeof (CamelFolderMetaSummary));
-
-       /* Default is 20, any implementor having UIDs that has length
-        * exceeding 20, has to override this value
-       */
-       summary->meta_summary->uid_len = 20;
-       summary->cache_load_time = 0;
-       summary->timeout_handle = 0;
+       summary->priv->cache_load_time = 0;
+       summary->priv->timeout_handle = 0;
 }
 
 /**
@@ -978,284 +1356,535 @@ camel_folder_summary_init (CamelFolderSummary *summary)
  * Returns: a new #CamelFolderSummary object
  **/
 CamelFolderSummary *
-camel_folder_summary_new (struct _CamelFolder *folder)
+camel_folder_summary_new (CamelFolder *folder)
 {
-       CamelFolderSummary *new;
-
-       new = g_object_new (CAMEL_TYPE_FOLDER_SUMMARY, NULL);
-       new->folder = folder;
-
-       return new;
+       return g_object_new (CAMEL_TYPE_FOLDER_SUMMARY, "folder", folder, NULL);
 }
 
 /**
- * camel_folder_summary_set_filename:
+ * camel_folder_summary_get_index:
  * @summary: a #CamelFolderSummary object
- * @filename: a filename
  *
- * Set the filename where the summary will be loaded to/saved from.
+ * Returns: a #CamelFolder to which the summary if associated.
+ *
+ * Since: 3.4
  **/
-void
-camel_folder_summary_set_filename (CamelFolderSummary *s,
-                                   const gchar *name)
+CamelFolder *
+camel_folder_summary_get_folder        (CamelFolderSummary *summary)
 {
-       camel_folder_summary_lock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
+       CamelFolderSummaryPrivate *priv;
 
-       g_free (s->summary_path);
-       s->summary_path = g_strdup (name);
+       g_return_val_if_fail (summary != NULL, NULL);
+       g_return_val_if_fail (summary->priv != NULL, NULL);
 
-       g_free (s->meta_summary->path);
-       s->meta_summary->path = g_strconcat(name, "-meta", NULL);
+       priv = summary->priv;
 
-       camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
+       return priv->folder;
 }
 
 /**
- * camel_folder_summary_set_index:
+ * camel_folder_summary_get_saved_count:
  * @summary: a #CamelFolderSummary object
- * @index: a #CamelIndex
  *
- * Set the index used to index body content.  If the index is %NULL, or
- * not set (the default), no indexing of body content will take place.
+ * Returns: Count of saved infos.
  *
- * Unlike earlier behaviour, build_content need not be set to perform indexing.
+ * Since: 3.4
  **/
-void
-camel_folder_summary_set_index (CamelFolderSummary *s,
-                                CamelIndex *index)
+guint32
+camel_folder_summary_get_saved_count (CamelFolderSummary *summary)
 {
-       struct _CamelFolderSummaryPrivate *p = s->priv;
+       CamelFolderSummaryPrivate *priv;
 
-       if (p->index)
-               g_object_unref (p->index);
+       g_return_val_if_fail (summary != NULL, 0);
+       g_return_val_if_fail (summary->priv != NULL, 0);
 
-       p->index = index;
-       if (index)
-               g_object_ref (index);
-}
+       priv = summary->priv;
 
-/**
- * camel_folder_summary_set_build_content:
- * @summary: a #CamelFolderSummary object
- * @state: to build or not to build the content
- *
- * Set a flag to tell the summary to build the content info summary
- * (#CamelMessageInfo.content).  The default is not to build content
- * info summaries.
- **/
-void
-camel_folder_summary_set_build_content (CamelFolderSummary *s,
-                                        gboolean state)
-{
-       s->build_content = state;
+       return priv->saved_count;
 }
 
 /**
- * camel_folder_summary_count:
+ * camel_folder_summary_get_saved_count:
  * @summary: a #CamelFolderSummary object
  *
- * Get the number of summary items stored in this summary.
+ * Returns: Count of unread infos.
  *
- * Returns: the number of items in the summary
+ * Since: 3.4
  **/
-guint
-camel_folder_summary_count (CamelFolderSummary *s)
+guint32
+camel_folder_summary_get_unread_count (CamelFolderSummary *summary)
 {
-       return s->uids->len;
+       CamelFolderSummaryPrivate *priv;
+
+       g_return_val_if_fail (summary != NULL, 0);
+       g_return_val_if_fail (summary->priv != NULL, 0);
+
+       priv = summary->priv;
+
+       return priv->unread_count;
 }
 
 /**
- * camel_folder_summary_index:
+ * camel_folder_summary_get_deleted_count:
  * @summary: a #CamelFolderSummary object
- * @index: item index
  *
- * Retrieve a summary item by index number.
+ * Returns: Count of deleted infos.
  *
- * 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 @index is out of range
+ * Since: 3.4
  **/
-CamelMessageInfo *
-camel_folder_summary_index (CamelFolderSummary *s,
-                            gint i)
+guint32
+camel_folder_summary_get_deleted_count (CamelFolderSummary *summary)
 {
-       CamelMessageInfo *info = NULL;
-
-       camel_folder_summary_lock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
-       camel_folder_summary_lock (s, CAMEL_FOLDER_SUMMARY_REF_LOCK);
-
-       if (i < s->uids->len) {
-               gchar *uid;
-               uid = g_ptr_array_index (s->uids, i);
-
-               /* FIXME: Get exception from caller
-               and pass it on below */
-
-               camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_REF_LOCK);
-               camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
+       CamelFolderSummaryPrivate *priv;
 
-               return camel_folder_summary_uid (s, uid);
-       }
+       g_return_val_if_fail (summary != NULL, 0);
+       g_return_val_if_fail (summary->priv != NULL, 0);
 
-       camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_REF_LOCK);
-       camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
+       priv = summary->priv;
 
-       return info;
+       return priv->deleted_count;
 }
 
-/* FIXME[disk-summary] Implement - camel_folder_summary_uid_exist -
- * directly through db than manual strcmp */
-
 /**
- * camel_folder_summary_uid_from_index:
- * @s: a #CamelFolderSummary object
- * @i: item index
- *
- * Retrieve a summary item's uid  by index number.
- *
- * A newly allocated uid is returned, which must be
- * free'd as appropriate.
+ * camel_folder_summary_get_junk_count:
+ * @summary: a #CamelFolderSummary object
  *
- * Returns: the summary item's uid , or %NULL if @index is out of range
+ * Returns: Count of junk infos.
  *
- * Since: 2.24
+ * Since: 3.4
  **/
-gchar *
-camel_folder_summary_uid_from_index (CamelFolderSummary *s,
-                                     gint i)
+guint32
+camel_folder_summary_get_junk_count (CamelFolderSummary *summary)
 {
-       gchar *uid = NULL;
-       camel_folder_summary_lock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
-
-       if (i < s->uids->len)
-               uid = g_strdup (g_ptr_array_index (s->uids, i));
+       CamelFolderSummaryPrivate *priv;
 
-       camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
+       g_return_val_if_fail (summary != NULL, 0);
+       g_return_val_if_fail (summary->priv != NULL, 0);
 
-       return uid;
+       priv = summary->priv;
 
+       return priv->junk_count;
 }
 
 /**
- * camel_folder_summary_check_uid
- * @s: a #CamelFolderSummary object
- * @uid: a uid
- *
- * Check if the uid is valid. This isn't very efficient, so it shouldn't be called iteratively.
- *
+ * camel_folder_summary_get_junk_not_deleted_count:
+ * @summary: a #CamelFolderSummary object
  *
- * Returns: if the uid is present in the summary or not  (%TRUE or %FALSE)
+ * Returns: Count of junk and not deleted infos.
  *
- * Since: 2.24
+ * Since: 3.4
  **/
-gboolean
-camel_folder_summary_check_uid (CamelFolderSummary *s,
-                                const gchar *uid)
+guint32
+camel_folder_summary_get_junk_not_deleted_count (CamelFolderSummary *summary)
 {
-       gboolean ret = FALSE;
-       gint i;
-
-       camel_folder_summary_lock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
+       CamelFolderSummaryPrivate *priv;
 
-       for (i = 0; i < s->uids->len; i++) {
-               if (strcmp (s->uids->pdata[i], uid) == 0) {
-                       camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
-                       return TRUE;
-               }
-       }
+       g_return_val_if_fail (summary != NULL, 0);
+       g_return_val_if_fail (summary->priv != NULL, 0);
 
-       camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
+       priv = summary->priv;
 
-       return ret;
+       return priv->junk_not_deleted_count;
 }
 
 /**
- * camel_folder_summary_array:
+ * camel_folder_summary_get_visible_count:
  * @summary: a #CamelFolderSummary object
  *
- * Obtain a copy of the summary array.  This is done atomically,
- * so cannot contain empty entries.
- *
- * It must be freed using g_ptr_array_free
+ * Returns: Count of visible (not junk and not deleted) infos.
  *
- * Returns: a #GPtrArray of uids
+ * Since: 3.4
  **/
-GPtrArray *
-camel_folder_summary_array (CamelFolderSummary *s)
+guint32
+camel_folder_summary_get_visible_count (CamelFolderSummary *summary)
 {
-       GPtrArray *res = g_ptr_array_new ();
-       gint i;
-
-       camel_folder_summary_lock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
+       CamelFolderSummaryPrivate *priv;
 
-       g_ptr_array_set_size (res, s->uids->len);
-       for (i = 0; i < s->uids->len; i++)
-               res->pdata[i] = (gpointer) camel_pstring_strdup ((gchar *) g_ptr_array_index (s->uids, i));
+       g_return_val_if_fail (summary != NULL, 0);
+       g_return_val_if_fail (summary->priv != NULL, 0);
 
-       camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
+       priv = summary->priv;
 
-       return res;
+       return priv->visible_count;
 }
 
 /**
- * camel_folder_summary_get_hashtable:
+ * camel_folder_summary_set_index:
  * @summary: a #CamelFolderSummary object
+ * @index: a #CamelIndex
  *
- * Obtain a copy of the summary array in the hashtable.  This is done atomically,
+ * Set the index used to index body content.  If the index is %NULL, or
+ * not set (the default), no indexing of body content will take place.
+ *
+ * Unlike earlier behaviour, build_content need not be set to perform indexing.
+ **/
+void
+camel_folder_summary_set_index (CamelFolderSummary *summary,
+                                CamelIndex *index)
+{
+       CamelFolderSummaryPrivate *priv;
+
+       g_return_if_fail (summary != NULL);
+       g_return_if_fail (summary->priv != NULL);
+
+       priv = summary->priv;
+
+       if (index)
+               g_object_ref (index);
+
+       if (priv->index)
+               g_object_unref (priv->index);
+
+       priv->index = index;
+}
+
+/**
+ * camel_folder_summary_get_index:
+ * @summary: a #CamelFolderSummary object
+ *
+ * Returns: a #CamelIndex used to index body content.
+ *
+ * Since: 3.4
+ **/
+CamelIndex *
+camel_folder_summary_get_index (CamelFolderSummary *summary)
+{
+       CamelFolderSummaryPrivate *priv;
+
+       g_return_val_if_fail (summary != NULL, NULL);
+       g_return_val_if_fail (summary->priv != NULL, NULL);
+
+       priv = summary->priv;
+
+       return priv->index;
+}
+
+/**
+ * camel_folder_summary_set_build_content:
+ * @summary: a #CamelFolderSummary object
+ * @state: to build or not to build the content
+ *
+ * Set a flag to tell the summary to build the content info summary
+ * (#CamelMessageInfo.content).  The default is not to build content
+ * info summaries.
+ **/
+void
+camel_folder_summary_set_build_content (CamelFolderSummary *summary,
+                                        gboolean state)
+{
+       CamelFolderSummaryPrivate *priv;
+
+       g_return_if_fail (summary != NULL);
+       g_return_if_fail (summary->priv != NULL);
+
+       priv = summary->priv;
+
+       if ((priv->build_content ? 1 : 0) == (state ? 1 : 0))
+               return;
+
+       priv->build_content = state;
+
+       g_object_notify (G_OBJECT (summary), "build-content");
+}
+
+/**
+ * camel_folder_summary_get_build_content:
+ * @summary: a #CamelFolderSummary object
+ *
+ * Returns: Whether to build #CamelMessageInfo.content.
+ *
+ * Since: 3.4
+ **/
+gboolean
+camel_folder_summary_get_build_content (CamelFolderSummary *summary)
+{
+       CamelFolderSummaryPrivate *priv;
+
+       g_return_val_if_fail (summary != NULL, FALSE);
+       g_return_val_if_fail (summary->priv != NULL, FALSE);
+
+       priv = summary->priv;
+
+       return priv->build_content;
+}
+
+/**
+ * camel_folder_summary_set_need_preview:
+ *
+ * Since: 2.28
+ **/
+void
+camel_folder_summary_set_need_preview (CamelFolderSummary *summary,
+                                       gboolean preview)
+{
+       CamelFolderSummaryPrivate *priv;
+
+       g_return_if_fail (summary != NULL);
+       g_return_if_fail (summary->priv != NULL);
+
+       priv = summary->priv;
+
+       priv->need_preview = preview;
+}
+
+/**
+ * camel_folder_summary_get_need_preview:
+ *
+ * Since: 2.28
+ **/
+gboolean
+camel_folder_summary_get_need_preview (CamelFolderSummary *summary)
+{
+       CamelFolderSummaryPrivate *priv;
+
+       g_return_val_if_fail (summary != NULL, FALSE);
+       g_return_val_if_fail (summary->priv != NULL, FALSE);
+
+       priv = summary->priv;
+
+       return priv->need_preview;
+}
+
+/**
+ * camel_folder_summary_next_uid:
+ * @summary: a #CamelFolderSummary object
+ *
+ * Generate a new unique uid value as an integer.  This
+ * may be used to create a unique sequence of numbers.
+ *
+ * Returns: the next unique uid value
+ **/
+guint32
+camel_folder_summary_next_uid (CamelFolderSummary *s)
+{
+       guint32 uid;
+
+       camel_folder_summary_lock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
+
+       uid = s->priv->nextuid++;
+       camel_folder_summary_touch (s);
+
+       camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
+
+       return uid;
+}
+
+/**
+ * camel_folder_summary_set_next_uid:
+ * @summary: a #CamelFolderSummary object
+ * @uid: The next minimum uid to assign.  To avoid clashing
+ * uid's, set this to the uid of a given messages + 1.
+ *
+ * Set the next minimum uid available.  This can be used to
+ * ensure new uid's do not clash with existing uid's.
+ **/
+void
+camel_folder_summary_set_next_uid (CamelFolderSummary *s,
+                                  guint32 uid)
+{
+       camel_folder_summary_lock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
+
+       s->priv->nextuid = MAX (s->priv->nextuid, uid);
+       camel_folder_summary_touch (s);
+
+       camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
+}
+
+/**
+ * camel_folder_summary_get_next_uid:
+ * @summary: a #CamelFolderSummary object
+ *
+ * Returns: Next uid currently awaiting for assignment. The difference from
+ *    camel_folder_summary_next_uid() is that this function returns actual
+ *    value and doesn't increment it before returning.
+ *
+ * Since: 3.4
+ **/
+guint32
+camel_folder_summary_get_next_uid (CamelFolderSummary *summary)
+{
+       guint32 res;
+
+       g_return_val_if_fail (summary != NULL, 0);
+       g_return_val_if_fail (summary->priv != NULL, 0);
+
+       camel_folder_summary_lock (summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
+
+       res = summary->priv->nextuid;
+
+       camel_folder_summary_unlock (summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
+
+       return res;
+}
+
+/**
+ * camel_folder_summary_next_uid_string:
+ * @summary: a #CamelFolderSummary object
+ *
+ * Retrieve the next uid, but as a formatted string.
+ *
+ * Returns: the next uid as an unsigned integer string.
+ * This string must be freed by the caller.
+ **/
+gchar *
+camel_folder_summary_next_uid_string (CamelFolderSummary *summary)
+{
+       CamelFolderSummaryClass *class;
+
+       g_return_val_if_fail (CAMEL_IS_FOLDER_SUMMARY (summary), NULL);
+
+       class = CAMEL_FOLDER_SUMMARY_GET_CLASS (summary);
+       g_return_val_if_fail (class->next_uid_string != NULL, NULL);
+
+       return class->next_uid_string (summary);
+}
+
+/**
+ * camel_folder_summary_set_filename:
+ * @summary: a #CamelFolderSummary object
+ * @filename: a filename
+ *
+ * Set the filename where the summary will be loaded to/saved from.
+ **/
+void
+camel_folder_summary_set_filename (CamelFolderSummary *s,
+                                   const gchar *name)
+{
+       camel_folder_summary_lock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
+
+       g_free (s->priv->summary_path);
+       s->priv->summary_path = g_strdup (name);
+
+       camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
+}
+
+/**
+ * camel_folder_summary_count:
+ * @summary: a #CamelFolderSummary object
+ *
+ * Get the number of summary items stored in this summary.
+ *
+ * Returns: the number of items in the summary
+ **/
+guint
+camel_folder_summary_count (CamelFolderSummary *summary)
+{
+       g_return_val_if_fail (summary != NULL, 0);
+       g_return_val_if_fail (summary->priv != NULL, 0);
+
+       return g_hash_table_size (summary->priv->uids);
+}
+
+/**
+ * camel_folder_summary_check_uid
+ * @s: a #CamelFolderSummary object
+ * @uid: a uid
+ *
+ * Check if the uid is valid. This isn't very efficient, so it shouldn't be called iteratively.
+ *
+ *
+ * Returns: if the uid is present in the summary or not  (%TRUE or %FALSE)
+ *
+ * Since: 2.24
+ **/
+gboolean
+camel_folder_summary_check_uid (CamelFolderSummary *s,
+                                const gchar *uid)
+{
+       gboolean ret;
+
+       g_return_val_if_fail (s != NULL, FALSE);
+       g_return_val_if_fail (s->priv != NULL, FALSE);
+       g_return_val_if_fail (uid != NULL, FALSE);
+
+       camel_folder_summary_lock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
+
+       ret = g_hash_table_lookup_extended (s->priv->uids, uid, NULL, NULL);
+
+       camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
+
+       return ret;
+}
+
+static void
+folder_summary_dupe_uids_to_array (gpointer key_uid, gpointer value_flags, gpointer user_data)
+{
+       g_ptr_array_add (user_data, (gpointer) camel_pstring_strdup (key_uid));
+}
+
+/**
+ * camel_folder_summary_get_array:
+ * @summary: a #CamelFolderSummary object
+ *
+ * Obtain a copy of the summary array.  This is done atomically,
  * so cannot contain empty entries.
  *
- * It must be freed using camel_folder_summary_free_hashtable
+ * Free with camel_folder_summary_free_array()
  *
- * Returns: a #GHashTable of uids
+ * Returns: a #GPtrArray of uids
  *
- * Since: 2.26
+ * Since: 3.4
  **/
-GHashTable *
-camel_folder_summary_get_hashtable (CamelFolderSummary *s)
+GPtrArray *
+camel_folder_summary_get_array (CamelFolderSummary *s)
 {
-       GHashTable *hash = g_hash_table_new (g_str_hash, g_str_equal);
-       gint i;
+       GPtrArray *res;
+
+       g_return_val_if_fail (s != NULL, NULL);
+       g_return_val_if_fail (s->priv != NULL, NULL);
 
        camel_folder_summary_lock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
-       for (i = 0; i < s->uids->len; i++)
-               g_hash_table_insert (hash, (gpointer) camel_pstring_strdup ((gchar *) g_ptr_array_index (s->uids, i)), GINT_TO_POINTER (1));
+       res = g_ptr_array_sized_new (g_hash_table_size (s->priv->uids));
+       g_hash_table_foreach (s->priv->uids, folder_summary_dupe_uids_to_array, res);
 
        camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
-       return hash;
+       return res;
 }
 
 /**
- * camel_folder_summary_free_hashtable:
+ * camel_folder_summary_free_array:
+ * @array: a #GPtrArray returned from camel_folder_summary_get_array()
  *
- * Since: 2.26
+ * Free's array and its elements returned from camel_folder_summary_get_array().
+ *
+ * Since: 3.4
  **/
 void
-camel_folder_summary_free_hashtable (GHashTable *ht)
+camel_folder_summary_free_array        (GPtrArray *array)
 {
-       g_hash_table_foreach (ht, (GHFunc) camel_pstring_free, NULL);
-       g_hash_table_destroy (ht);
+       if (!array)
+               return;
+
+       g_ptr_array_foreach (array, (GFunc) camel_pstring_free, NULL);
+       g_ptr_array_free (array, TRUE);
 }
 
 /**
- * camel_folder_summary_peek_info:
+ * camel_folder_summary_peek_loaded:
  *
  * Since: 2.26
  **/
 CamelMessageInfo *
-camel_folder_summary_peek_info (CamelFolderSummary *s,
-                                const gchar *uid)
+camel_folder_summary_peek_loaded (CamelFolderSummary *s,
+                                 const gchar *uid)
 {
-       CamelMessageInfo *info = g_hash_table_lookup (s->loaded_infos, uid);
+       CamelMessageInfo *info;
+
+       g_return_val_if_fail (s != NULL, NULL);
+       g_return_val_if_fail (s->priv != NULL, NULL);
+
+       info = g_hash_table_lookup (s->priv->loaded_infos, uid);
 
        if (info)
                camel_message_info_ref (info);
+
        return info;
 }
 
 struct _db_pass_data {
+       GHashTable *columns_hash;
        CamelFolderSummary *summary;
        gboolean add; /* or just insert to hashtable */
 };
@@ -1269,7 +1898,7 @@ message_info_from_uid (CamelFolderSummary *s,
 
        camel_folder_summary_lock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
-       info = g_hash_table_lookup (s->loaded_infos, uid);
+       info = g_hash_table_lookup (s->priv->loaded_infos, uid);
 
        if (!info) {
                CamelDB *cdb;
@@ -1277,25 +1906,27 @@ message_info_from_uid (CamelFolderSummary *s,
                const gchar *folder_name;
                struct _db_pass_data data;
 
-               d(printf ("\ncamel_folder_summary_uid called \n"));
-
-               folder_name = camel_folder_get_full_name (s->folder);
-               parent_store = camel_folder_get_parent_store (s->folder);
+               folder_name = camel_folder_get_full_name (s->priv->folder);
+               parent_store = camel_folder_get_parent_store (s->priv->folder);
                cdb = parent_store->cdb_r;
 
+               data.columns_hash = NULL;
                data.summary = s;
                data.add = FALSE;
 
                ret = camel_db_read_message_info_record_with_uid (
                        cdb, folder_name, uid, &data,
                        camel_read_mir_callback, NULL);
+               if (data.columns_hash)
+                       g_hash_table_destroy (data.columns_hash);
+
                if (ret != 0) {
                        camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
                        return NULL;
                }
 
                /* We would have double reffed at camel_read_mir_callback */
-               info = g_hash_table_lookup (s->loaded_infos, uid);
+               info = g_hash_table_lookup (s->priv->loaded_infos, uid);
 
                cfs_schedule_info_release_timer (s);
        }
@@ -1309,7 +1940,7 @@ message_info_from_uid (CamelFolderSummary *s,
 }
 
 /**
- * camel_folder_summary_uid:
+ * camel_folder_summary_get:
  * @summary: a #CamelFolderSummary object
  * @uid: a uid
  *
@@ -1321,8 +1952,8 @@ message_info_from_uid (CamelFolderSummary *s,
  * Returns: the summary item, or %NULL if the uid @uid is not available
  **/
 CamelMessageInfo *
-camel_folder_summary_uid (CamelFolderSummary *summary,
-                          const gchar *uid)
+camel_folder_summary_get (CamelFolderSummary *summary,
+                             const gchar *uid)
 {
        CamelFolderSummaryClass *class;
 
@@ -1335,74 +1966,6 @@ camel_folder_summary_uid (CamelFolderSummary *summary,
        return class->message_info_from_uid (summary, uid);
 }
 
-/**
- * camel_folder_summary_next_uid:
- * @summary: a #CamelFolderSummary object
- *
- * Generate a new unique uid value as an integer.  This
- * may be used to create a unique sequence of numbers.
- *
- * Returns: the next unique uid value
- **/
-guint32
-camel_folder_summary_next_uid (CamelFolderSummary *s)
-{
-       guint32 uid;
-
-       camel_folder_summary_lock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
-
-       uid = s->nextuid++;
-
-       camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
-
-       /* FIXME: sync this to disk */
-/*     summary_header_save(s);*/
-       return uid;
-}
-
-/**
- * camel_folder_summary_set_uid:
- * @summary: a #CamelFolderSummary object
- * @uid: The next minimum uid to assign.  To avoid clashing
- * uid's, set this to the uid of a given messages + 1.
- *
- * Set the next minimum uid available.  This can be used to
- * ensure new uid's do not clash with existing uid's.
- **/
-void
-camel_folder_summary_set_uid (CamelFolderSummary *s,
-                              guint32 uid)
-{
-       /* TODO: sync to disk? */
-       camel_folder_summary_lock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
-
-       s->nextuid = MAX (s->nextuid, uid);
-
-       camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
-}
-
-/**
- * camel_folder_summary_next_uid_string:
- * @summary: a #CamelFolderSummary object
- *
- * Retrieve the next uid, but as a formatted string.
- *
- * Returns: the next uid as an unsigned integer string.
- * This string must be freed by the caller.
- **/
-gchar *
-camel_folder_summary_next_uid_string (CamelFolderSummary *summary)
-{
-       CamelFolderSummaryClass *class;
-
-       g_return_val_if_fail (CAMEL_IS_FOLDER_SUMMARY (summary), NULL);
-
-       class = CAMEL_FOLDER_SUMMARY_GET_CLASS (summary);
-       g_return_val_if_fail (class->next_uid_string != NULL, NULL);
-
-       return class->next_uid_string (summary);
-}
-
 static CamelMessageContentInfo *
 perform_content_info_load_from_db (CamelFolderSummary *s,
                                    CamelMIRecord *mir)
@@ -1492,7 +2055,7 @@ camel_folder_summary_get_changed (CamelFolderSummary *s)
         * from DB and merge */
 
        camel_folder_summary_lock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
-       g_hash_table_foreach (s->loaded_infos, (GHFunc) append_changed_uids, res);
+       g_hash_table_foreach (s->priv->loaded_infos, (GHFunc) append_changed_uids, res);
        camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
        return res;
@@ -1513,23 +2076,22 @@ cfs_count_dirty (CamelFolderSummary *s)
        gint count = 0;
 
        camel_folder_summary_lock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
-       g_hash_table_foreach (s->loaded_infos, (GHFunc) count_changed_uids, &count);
+       g_hash_table_foreach (s->priv->loaded_infos, (GHFunc) count_changed_uids, &count);
        camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
        return count;
 }
 
-/* FIXME[disk-summary] I should have a better LRU algorithm  */
 static gboolean
-remove_item (gchar *key,
+remove_item (gchar *uid,
              CamelMessageInfoBase *info,
-             GList **to_free_list)
+             GSList **to_remove_infos)
 {
-       d(printf("%d(%d)\t", info->refcount, info->dirty)); /* camel_message_info_dump (info); */
-       if (info->refcount == 1 && !info->dirty && !(info->flags & CAMEL_MESSAGE_FOLDER_FLAGGED)) {
-               *to_free_list = g_list_prepend (*to_free_list, info);
+       if (info->refcount == 1 && !info->dirty && (info->flags & CAMEL_MESSAGE_FOLDER_FLAGGED) == 0) {
+               *to_remove_infos = g_slist_prepend (*to_remove_infos, info);
                return TRUE;
        }
+
        return FALSE;
 }
 
@@ -1539,32 +2101,25 @@ remove_cache (CamelSession *session,
               CamelFolderSummary *summary,
               GError **error)
 {
-       GList *to_free_list = NULL, *l;
+       GSList *to_remove_infos = NULL;
 
        CAMEL_DB_RELEASE_SQLITE_MEMORY;
 
-       if (time (NULL) - summary->cache_load_time < SUMMARY_CACHE_DROP)
+       if (time (NULL) - summary->priv->cache_load_time < SUMMARY_CACHE_DROP)
                return;
 
-       /* FIXME[disk-summary] hack. fix it */
-       camel_folder_summary_lock (
-               summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
+       camel_folder_summary_lock (summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
        camel_folder_summary_lock (summary, CAMEL_FOLDER_SUMMARY_REF_LOCK);
-       g_hash_table_foreach_remove (
-               summary->loaded_infos, (GHRFunc) remove_item, &to_free_list);
+       g_hash_table_foreach_remove (summary->priv->loaded_infos, (GHRFunc) remove_item, &to_remove_infos);
        camel_folder_summary_unlock (summary, CAMEL_FOLDER_SUMMARY_REF_LOCK);
 
-       /* Deferred freeing as _free function will try to remove
-        * entries from the hash_table in foreach_remove otherwise */
-       for (l = to_free_list; l; l = l->next)
-               camel_message_info_free (l->data);
-       g_list_free (to_free_list);
+       g_slist_foreach (to_remove_infos, (GFunc) camel_message_info_free, NULL);
+       g_slist_free (to_remove_infos);
 
-       camel_folder_summary_unlock (
-               summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
+       camel_folder_summary_unlock (summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
-       summary->cache_load_time = time (NULL);
+       summary->priv->cache_load_time = time (NULL);
 }
 
 static gboolean
@@ -1574,16 +2129,16 @@ cfs_try_release_memory (CamelFolderSummary *summary)
        CamelSession *session;
 
        /* If folder is freed or if the cache is nil then clean up */
-       if (!summary->folder || !g_hash_table_size (summary->loaded_infos)) {
-               summary->cache_load_time = 0;
-               summary->timeout_handle = 0;
+       if (!summary->priv->folder || !g_hash_table_size (summary->priv->loaded_infos)) {
+               summary->priv->cache_load_time = 0;
+               summary->priv->timeout_handle = 0;
                return FALSE;
        }
 
-       parent_store = camel_folder_get_parent_store (summary->folder);
+       parent_store = camel_folder_get_parent_store (summary->priv->folder);
        session = camel_service_get_session (CAMEL_SERVICE (parent_store));
 
-       if (time (NULL) - summary->cache_load_time < SUMMARY_CACHE_DROP)
+       if (time (NULL) - summary->priv->cache_load_time < SUMMARY_CACHE_DROP)
                return TRUE;
 
        camel_session_submit_job (
@@ -1600,7 +2155,7 @@ cfs_schedule_info_release_timer (CamelFolderSummary *s)
 {
        g_return_if_fail (CAMEL_IS_FOLDER_SUMMARY (s));
 
-       if (!s->timeout_handle) {
+       if (!s->priv->timeout_handle) {
                static gboolean know_can_do = FALSE, can_do = TRUE;
 
                if (!know_can_do) {
@@ -1610,21 +2165,21 @@ cfs_schedule_info_release_timer (CamelFolderSummary *s)
 
                /* FIXME[disk-summary] LRU please and not timeouts */
                if (can_do)
-                       s->timeout_handle = g_timeout_add_seconds (SUMMARY_CACHE_DROP, (GSourceFunc) cfs_try_release_memory, s);
+                       s->priv->timeout_handle = g_timeout_add_seconds (SUMMARY_CACHE_DROP, (GSourceFunc) cfs_try_release_memory, s);
        }
 
        /* update also cache load time to the actual, to not release something just loaded */
-       s->cache_load_time = time (NULL);
+       s->priv->cache_load_time = time (NULL);
 }
 
 static gint
 cfs_cache_size (CamelFolderSummary *s)
 {
        /* FIXME[disk-summary] this is a timely hack. fix it well */
-       if (!CAMEL_IS_VEE_FOLDER (s->folder))
-               return g_hash_table_size (s->loaded_infos);
+       if (!CAMEL_IS_VEE_FOLDER (s->priv->folder))
+               return g_hash_table_size (s->priv->loaded_infos);
        else
-               return s->uids->len;
+               return g_hash_table_size (s->priv->uids);
 }
 
 /* Update preview of cached messages */
@@ -1634,7 +2189,7 @@ msg_update_preview (const gchar *uid,
                     gpointer value,
                     CamelFolder *folder)
 {
-       CamelMessageInfoBase *info = (CamelMessageInfoBase *) camel_folder_summary_uid (folder->summary, uid);
+       CamelMessageInfoBase *info = (CamelMessageInfoBase *) camel_folder_summary_get (folder->summary, uid);
        CamelMimeMessage *msg;
        CamelStore *parent_store;
        const gchar *full_name;
@@ -1660,6 +2215,15 @@ pick_uids (const gchar *uid,
                g_ptr_array_add (array, (gchar *) camel_pstring_strdup (uid));
 }
 
+static void
+copy_all_uids_to_hash (gpointer uid,
+                      gpointer hash)
+{
+       g_return_if_fail (uid != NULL);
+
+       g_hash_table_insert (hash, (gchar *) camel_pstring_strdup (uid), GINT_TO_POINTER (1));
+}
+
 static gboolean
 fill_mi (const gchar *uid,
          const gchar *msg,
@@ -1667,7 +2231,7 @@ fill_mi (const gchar *uid,
 {
        CamelMessageInfoBase *info;
 
-       info = g_hash_table_lookup (folder->summary->loaded_infos, uid);
+       info = g_hash_table_lookup (folder->summary->priv->loaded_infos, uid);
        if (info) /* We re assign the memory of msg */
                info->preview = (gchar *) msg;
        camel_pstring_free (uid); /* unref the uid */
@@ -1682,13 +2246,19 @@ preview_update (CamelSession *session,
                 GError **error)
 {
        /* FIXME: Either lock & use or copy & use.*/
-       GPtrArray *uids_uncached= camel_folder_get_uncached_uids (folder, folder->summary->uids, NULL);
-       GHashTable *hash = camel_folder_summary_get_hashtable (folder->summary);
-       GHashTable *preview_data;
+       GPtrArray *uids_uncached, *uids_array;
+       GHashTable *preview_data, *uids_hash;
        CamelStore *parent_store;
        const gchar *full_name;
        gint i;
 
+       uids_array = camel_folder_summary_get_array (folder->summary);
+       uids_hash = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify) camel_pstring_free, NULL);
+       g_ptr_array_foreach (uids_array, copy_all_uids_to_hash, uids_hash);
+       uids_uncached = camel_folder_get_uncached_uids (folder, uids_array, NULL);
+       camel_folder_summary_free_array (uids_array);
+       uids_array = NULL;
+
        full_name = camel_folder_get_full_name (folder);
        parent_store = camel_folder_get_parent_store (folder);
        preview_data = camel_db_get_folder_preview (parent_store->cdb_r, full_name, NULL);
@@ -1698,21 +2268,20 @@ preview_update (CamelSession *session,
        }
 
        camel_folder_summary_lock (folder->summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
-       g_hash_table_foreach (folder->summary->loaded_infos, (GHFunc) pick_uids, uids_uncached);
+       g_hash_table_foreach (folder->summary->priv->loaded_infos, (GHFunc) pick_uids, uids_uncached);
        camel_folder_summary_unlock (folder->summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
        for (i = 0; i < uids_uncached->len; i++) {
-               g_hash_table_remove (hash, uids_uncached->pdata[i]);
-               camel_pstring_free (uids_uncached->pdata[i]); /* unref the hash table key */
+               g_hash_table_remove (uids_hash, uids_uncached->pdata[i]);
        }
 
        camel_folder_lock (folder, CAMEL_FOLDER_REC_LOCK);
        camel_db_begin_transaction (parent_store->cdb_w, NULL);
-       g_hash_table_foreach (hash, (GHFunc) msg_update_preview, folder);
+       g_hash_table_foreach (uids_hash, (GHFunc) msg_update_preview, folder);
        camel_db_end_transaction (parent_store->cdb_w, NULL);
        camel_folder_unlock (folder, CAMEL_FOLDER_REC_LOCK);
        camel_folder_free_uids (folder, uids_uncached);
-       camel_folder_summary_free_hashtable (hash);
+       g_hash_table_destroy (uids_hash);
 }
 
 /* end */
@@ -1732,25 +2301,29 @@ cfs_reload_from_db (CamelFolderSummary *s,
         * load better. */
        d(printf ("\ncamel_folder_summary_reload_from_db called \n"));
 
-       folder_name = camel_folder_get_full_name (s->folder);
-       parent_store = camel_folder_get_parent_store (s->folder);
+       folder_name = camel_folder_get_full_name (s->priv->folder);
+       parent_store = camel_folder_get_parent_store (s->priv->folder);
        session = camel_service_get_session (CAMEL_SERVICE (parent_store));
        cdb = parent_store->cdb_r;
 
-       /* FIXME FOR SANKAR: No need to pass the address of summary here. */
+       data.columns_hash = NULL;
        data.summary = s;
        data.add = FALSE;
+
        ret = camel_db_read_message_info_records (
                cdb, folder_name, (gpointer) &data,
                camel_read_mir_callback, NULL);
 
+       if (data.columns_hash)
+               g_hash_table_destroy (data.columns_hash);
+
        cfs_schedule_info_release_timer (s);
 
        if (s->priv->need_preview)
                camel_session_submit_job (
                        session,
                        (CamelSessionCallback) preview_update,
-                       g_object_ref (s->folder),
+                       g_object_ref (s->priv->folder),
                        (GDestroyNotify) g_object_unref);
 
        return ret == 0 ? 0 : -1;
@@ -1800,7 +2373,7 @@ camel_folder_summary_prepare_fetch_all (CamelFolderSummary *s,
        }
 
        /* update also cache load time, even when not loaded anything */
-       s->cache_load_time = time (NULL);
+       s->priv->cache_load_time = time (NULL);
 }
 
 /**
@@ -1808,7 +2381,7 @@ camel_folder_summary_prepare_fetch_all (CamelFolderSummary *s,
  *
  * Since: 2.24
  **/
-gint
+gboolean
 camel_folder_summary_load_from_db (CamelFolderSummary *s,
                                    GError **error)
 {
@@ -1818,23 +2391,24 @@ camel_folder_summary_load_from_db (CamelFolderSummary *s,
        gint ret = 0;
        GError *local_error = NULL;
 
+       g_return_val_if_fail (s != NULL, FALSE);
+       g_return_val_if_fail (s->priv != NULL, FALSE);
+
        camel_folder_summary_save_to_db (s, NULL);
 
        /* struct _db_pass_data data; */
        d(printf ("\ncamel_folder_summary_load_from_db called \n"));
 
-       full_name = camel_folder_get_full_name (s->folder);
-       parent_store = camel_folder_get_parent_store (s->folder);
-       ret = camel_folder_summary_header_load_from_db (s, parent_store, full_name, error);
-
-       if (ret)
-               return ret;
+       full_name = camel_folder_get_full_name (s->priv->folder);
+       parent_store = camel_folder_get_parent_store (s->priv->folder);
+       if (!camel_folder_summary_header_load_from_db (s, parent_store, full_name, error))
+               return FALSE;
 
        cdb = parent_store->cdb_r;
 
        ret = camel_db_get_folder_uids (
                cdb, full_name, s->sort_by, s->collate,
-               s->uids, &local_error);
+               s->priv->uids, &local_error);
 
        if (local_error != NULL && local_error->message != NULL &&
                strstr (local_error->message, "no such table") != NULL) {
@@ -1843,12 +2417,13 @@ camel_folder_summary_load_from_db (CamelFolderSummary *s,
        } else if (local_error != NULL)
                g_propagate_error (error, local_error);
 
-       return ret == 0 ? 0 : -1;
+       return ret == 0;
 }
 
 static void
 mir_from_cols (CamelMIRecord *mir,
                CamelFolderSummary *s,
+              GHashTable **columns_hash,
                gint ncol,
                gchar **cols,
                gchar **name)
@@ -1859,58 +2434,87 @@ mir_from_cols (CamelMIRecord *mir,
                if (!name[i] || !cols[i])
                        continue;
 
-               if (!strcmp (name [i], "uid"))
-                       mir->uid = (gchar *) camel_pstring_strdup (cols[i]);
-               else if (!strcmp (name [i], "flags"))
-                       mir->flags = cols[i] ? strtoul (cols[i], NULL, 10) : 0;
-               else if (!strcmp (name [i], "read"))
-                       mir->read =  (cols[i]) ? ( ((strtoul (cols[i], NULL, 10)) ? TRUE : FALSE)) : FALSE;
-               else if (!strcmp (name [i], "deleted"))
-                       mir->deleted = (cols[i]) ? ( ((strtoul (cols[i], NULL, 10)) ? TRUE : FALSE)) : FALSE;
-               else if (!strcmp (name [i], "replied"))
-                       mir->replied = (cols[i]) ? ( ((strtoul (cols[i], NULL, 10)) ? TRUE : FALSE)) : FALSE;
-               else if (!strcmp (name [i], "important"))
-                       mir->important = (cols[i]) ? ( ((strtoul (cols[i], NULL, 10)) ? TRUE : FALSE)) : FALSE;
-               else if (!strcmp (name [i], "junk"))
-                       mir->junk = (cols[i]) ? ( ((strtoul (cols[i], NULL, 10)) ? TRUE : FALSE)) : FALSE;
-               else if (!strcmp (name [i], "attachment"))
-                       mir->attachment = (cols[i]) ? ( ((strtoul (cols[i], NULL, 10)) ? TRUE : FALSE)) : FALSE;
-               else if (!strcmp (name [i], "size"))
-                       mir->size =  cols[i] ? strtoul (cols[i], NULL, 10) : 0;
-               else if (!strcmp (name [i], "dsent"))
-                       mir->dsent = cols[i] ? strtol (cols[i], NULL, 10) : 0;
-               else if (!strcmp (name [i], "dreceived"))
-                       mir->dreceived = cols[i] ? strtol (cols[i], NULL, 10) : 0;
-               else if (!strcmp (name [i], "subject"))
-                       mir->subject = (gchar *) camel_pstring_strdup (cols[i]);
-               else if (!strcmp (name [i], "mail_from"))
-                       mir->from = (gchar *) camel_pstring_strdup (cols[i]);
-               else if (!strcmp (name [i], "mail_to"))
-                       mir->to = (gchar *) camel_pstring_strdup (cols[i]);
-               else if (!strcmp (name [i], "mail_cc"))
-                       mir->cc = (gchar *) camel_pstring_strdup (cols[i]);
-               else if (!strcmp (name [i], "mlist"))
-                       mir->mlist = (gchar *) camel_pstring_strdup (cols[i]);
-               else if (!strcmp (name [i], "followup_flag"))
-                       mir->followup_flag = (gchar *) camel_pstring_strdup (cols[i]);
-               else if (!strcmp (name [i], "followup_completed_on"))
-                       mir->followup_completed_on = (gchar *) camel_pstring_strdup (cols[i]);
-               else if (!strcmp (name [i], "followup_due_by"))
-                       mir->followup_due_by = (gchar *) camel_pstring_strdup (cols[i]);
-               else if (!strcmp (name [i], "part"))
-                       mir->part = g_strdup (cols[i]);
-               else if (!strcmp (name [i], "labels"))
-                       mir->labels = g_strdup (cols[i]);
-               else if (!strcmp (name [i], "usertags"))
-                       mir->usertags = g_strdup (cols[i]);
-               else if (!strcmp (name [i], "cinfo"))
-                       mir->cinfo = g_strdup (cols[i]);
-               else if (!strcmp (name [i], "bdata"))
-                       mir->bdata = g_strdup (cols[i]);
-               /* Evolution itself doesn't yet use this, ignoring
-               else if (!strcmp (name [i], "bodystructure"))
-                       mir->bodystructure = g_strdup (cols[i]); */
-
+               switch (camel_db_get_column_ident (columns_hash, i, ncol, name)) {
+                       case CAMEL_DB_COLUMN_UID:
+                               mir->uid = (gchar *) camel_pstring_strdup (cols[i]);
+                               break;
+                       case CAMEL_DB_COLUMN_FLAGS:
+                               mir->flags = cols[i] ? strtoul (cols[i], NULL, 10) : 0;
+                               break;
+                       case CAMEL_DB_COLUMN_READ:
+                               mir->read =  (cols[i]) ? ( ((strtoul (cols[i], NULL, 10)) ? TRUE : FALSE)) : FALSE;
+                               break;
+                       case CAMEL_DB_COLUMN_DELETED:
+                               mir->deleted = (cols[i]) ? ( ((strtoul (cols[i], NULL, 10)) ? TRUE : FALSE)) : FALSE;
+                               break;
+                       case CAMEL_DB_COLUMN_REPLIED:
+                               mir->replied = (cols[i]) ? ( ((strtoul (cols[i], NULL, 10)) ? TRUE : FALSE)) : FALSE;
+                               break;
+                       case CAMEL_DB_COLUMN_IMPORTANT:
+                               mir->important = (cols[i]) ? ( ((strtoul (cols[i], NULL, 10)) ? TRUE : FALSE)) : FALSE;
+                               break;
+                       case CAMEL_DB_COLUMN_JUNK:
+                               mir->junk = (cols[i]) ? ( ((strtoul (cols[i], NULL, 10)) ? TRUE : FALSE)) : FALSE;
+                               break;
+                       case CAMEL_DB_COLUMN_ATTACHMENT:
+                               mir->attachment = (cols[i]) ? ( ((strtoul (cols[i], NULL, 10)) ? TRUE : FALSE)) : FALSE;
+                               break;
+                       case CAMEL_DB_COLUMN_SIZE:
+                               mir->size =  cols[i] ? strtoul (cols[i], NULL, 10) : 0;
+                               break;
+                       case CAMEL_DB_COLUMN_DSENT:
+                               mir->dsent = cols[i] ? strtol (cols[i], NULL, 10) : 0;
+                               break;
+                       case CAMEL_DB_COLUMN_DRECEIVED:
+                               mir->dreceived = cols[i] ? strtol (cols[i], NULL, 10) : 0;
+                               break;
+                       case CAMEL_DB_COLUMN_SUBJECT:
+                               mir->subject = (gchar *) camel_pstring_strdup (cols[i]);
+                               break;
+                       case CAMEL_DB_COLUMN_MAIL_FROM:
+                               mir->from = (gchar *) camel_pstring_strdup (cols[i]);
+                               break;
+                       case CAMEL_DB_COLUMN_MAIL_TO:
+                               mir->to = (gchar *) camel_pstring_strdup (cols[i]);
+                               break;
+                       case CAMEL_DB_COLUMN_MAIL_CC:
+                               mir->cc = (gchar *) camel_pstring_strdup (cols[i]);
+                               break;
+                       case CAMEL_DB_COLUMN_MLIST:
+                               mir->mlist = (gchar *) camel_pstring_strdup (cols[i]);
+                               break;
+                       case CAMEL_DB_COLUMN_FOLLOWUP_FLAG:
+                               mir->followup_flag = (gchar *) camel_pstring_strdup (cols[i]);
+                               break;
+                       case CAMEL_DB_COLUMN_FOLLOWUP_COMPLETED_ON:
+                               mir->followup_completed_on = (gchar *) camel_pstring_strdup (cols[i]);
+                               break;
+                       case CAMEL_DB_COLUMN_FOLLOWUP_DUE_BY:
+                               mir->followup_due_by = (gchar *) camel_pstring_strdup (cols[i]);
+                               break;
+                       case CAMEL_DB_COLUMN_PART:
+                               mir->part = g_strdup (cols[i]);
+                               break;
+                       case CAMEL_DB_COLUMN_LABELS:
+                               mir->labels = g_strdup (cols[i]);
+                               break;
+                       case CAMEL_DB_COLUMN_USERTAGS:
+                               mir->usertags = g_strdup (cols[i]);
+                               break;
+                       case CAMEL_DB_COLUMN_CINFO:
+                               mir->cinfo = g_strdup (cols[i]);
+                               break;
+                       case CAMEL_DB_COLUMN_BDATA:
+                               mir->bdata = g_strdup (cols[i]);
+                               break;
+                       case CAMEL_DB_COLUMN_BODYSTRUCTURE:
+                               /* Evolution itself doesn't yet use this, ignoring */
+                               /* mir->bodystructure = g_strdup (cols[i]); */
+                               break;
+                       default:
+                               g_warn_if_reached ();
+                               break;
+               }
        }
 }
 
@@ -1927,10 +2531,10 @@ camel_read_mir_callback (gpointer ref,
        gint ret = 0;
 
        mir = g_new0 (CamelMIRecord , 1);
-       mir_from_cols (mir, s, ncol, cols, name);
+       mir_from_cols (mir, s, &data->columns_hash, ncol, cols, name);
 
        camel_folder_summary_lock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
-       if (!mir->uid || g_hash_table_lookup (s->loaded_infos, mir->uid)) {
+       if (!mir->uid || g_hash_table_lookup (s->priv->loaded_infos, mir->uid)) {
                /* Unlock and better return */
                camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
                camel_db_camel_mir_free (mir);
@@ -1942,7 +2546,7 @@ camel_read_mir_callback (gpointer ref,
 
        if (info) {
 
-               if (s->build_content) {
+               if (s->priv->build_content) {
                        gchar *tmp;
                        tmp = mir->cinfo;
                        /* FIXME: this should be done differently, how i don't know */
@@ -1993,22 +2597,22 @@ camel_folder_summary_migrate_infos (CamelFolderSummary *s)
        CamelDB *cdb;
        CamelFIRecord *record;
 
-       parent_store = camel_folder_get_parent_store (s->folder);
+       parent_store = camel_folder_get_parent_store (s->priv->folder);
        cdb = parent_store->cdb_w;
 
        /* Kick off the gc thread cycle. */
-       if (s->timeout_handle)
-               g_source_remove (s->timeout_handle);
-       s->timeout_handle = 0;
+       if (s->priv->timeout_handle)
+               g_source_remove (s->priv->timeout_handle);
+       s->priv->timeout_handle = 0;
 
        d(g_print ("\ncamel_folder_summary_load from FLAT FILE called \n"));
 
-       if (s->summary_path == NULL) {
+       if (s->priv->summary_path == NULL) {
                g_warning ("No summary path set. Unable to migrate\n");
                return -1;
        }
 
-       in = g_fopen(s->summary_path, "rb");
+       in = g_fopen (s->priv->summary_path, "rb");
        if (in == NULL)
                return -1;
 
@@ -2016,7 +2620,7 @@ camel_folder_summary_migrate_infos (CamelFolderSummary *s)
                goto error;
 
        /* now read in each message ... */
-       for (i = 0; i < s->saved_count; i++) {
+       for (i = 0; i < s->priv->saved_count; i++) {
                CamelTag *tag;
 
                mi = CAMEL_FOLDER_SUMMARY_GET_CLASS (s)->message_info_migrate (s, in);
@@ -2025,7 +2629,7 @@ camel_folder_summary_migrate_infos (CamelFolderSummary *s)
                        goto error;
 
                /* FIXME: this should be done differently, how i don't know */
-               if (s->build_content) {
+               if (s->priv->build_content) {
                        ((CamelMessageInfoBase *) mi)->content = perform_content_info_migrate (s, in);
                        if (((CamelMessageInfoBase *) mi)->content == NULL) {
                                camel_message_info_free (mi);
@@ -2043,7 +2647,7 @@ camel_folder_summary_migrate_infos (CamelFolderSummary *s)
                }
 
                mi->dirty = TRUE;
-               g_hash_table_insert (s->loaded_infos, (gpointer) mi->uid, mi);
+               g_hash_table_insert (s->priv->loaded_infos, (gpointer) mi->uid, mi);
        }
 
        if (fclose (in) != 0)
@@ -2079,7 +2683,7 @@ camel_folder_summary_migrate_infos (CamelFolderSummary *s)
 
 error:
        if (errno != EINVAL)
-               g_warning ("Cannot load summary file: '%s': %s", s->summary_path, g_strerror (errno));
+               g_warning ("Cannot load summary file: '%s': %s", s->priv->summary_path, g_strerror (errno));
 
        fclose (in);
 
@@ -2088,7 +2692,7 @@ error:
 }
 
 /* saves the content descriptions, recursively */
-static gint
+static gboolean
 perform_content_info_save_to_db (CamelFolderSummary *s,
                                  CamelMessageContentInfo *ci,
                                  CamelMIRecord *record)
@@ -2096,8 +2700,8 @@ perform_content_info_save_to_db (CamelFolderSummary *s,
        CamelMessageContentInfo *part;
        gchar *oldr;
 
-       if (CAMEL_FOLDER_SUMMARY_GET_CLASS (s)->content_info_to_db (s, ci, record) == -1)
-               return -1;
+       if (!CAMEL_FOLDER_SUMMARY_GET_CLASS (s)->content_info_to_db (s, ci, record))
+               return FALSE;
 
        oldr = record->cinfo;
        record->cinfo = g_strdup_printf ("%s %d", oldr, my_list_size ((struct _node **)&ci->childs));
@@ -2106,11 +2710,11 @@ perform_content_info_save_to_db (CamelFolderSummary *s,
        part = ci->childs;
        while (part) {
                if (perform_content_info_save_to_db (s, part, record) == -1)
-                       return -1;
+                       return FALSE;
                part = part->next;
        }
 
-       return 0;
+       return TRUE;
 }
 
 typedef struct {
@@ -2133,8 +2737,8 @@ save_to_db_cb (gpointer key,
        CamelDB *cdb;
        CamelMIRecord *mir;
 
-       full_name = camel_folder_get_full_name (s->folder);
-       parent_store = camel_folder_get_parent_store (s->folder);
+       full_name = camel_folder_get_full_name (s->priv->folder);
+       parent_store = camel_folder_get_parent_store (s->priv->folder);
        cdb = parent_store->cdb_w;
 
        if (!args->migration && !mi->dirty)
@@ -2142,8 +2746,8 @@ save_to_db_cb (gpointer key,
 
        mir = CAMEL_FOLDER_SUMMARY_GET_CLASS (s)->message_info_to_db (s, (CamelMessageInfo *) mi);
 
-       if (mir && s->build_content) {
-               if (perform_content_info_save_to_db (s, ((CamelMessageInfoBase *) mi)->content, mir) == -1) {
+       if (mir && s->priv->build_content) {
+               if (!perform_content_info_save_to_db (s, ((CamelMessageInfoBase *) mi)->content, mir)) {
                        g_warning ("unable to save mir+cinfo for uid: %s\n", mir->uid);
                        camel_db_camel_mir_free (mir);
                        /* FIXME: Add exception here */
@@ -2152,24 +2756,24 @@ save_to_db_cb (gpointer key,
        }
 
        if (!args->migration) {
-                       if (camel_db_write_message_info_record (cdb, full_name, mir, error) != 0) {
-                                       camel_db_camel_mir_free (mir);
-                                       return;
-                       }
+               if (camel_db_write_message_info_record (cdb, full_name, mir, error) != 0) {
+                               camel_db_camel_mir_free (mir);
+                               return;
+               }
        } else {
-                       if (camel_db_write_fresh_message_info_record (cdb, CAMEL_DB_IN_MEMORY_TABLE, mir, error) != 0) {
-                                       camel_db_camel_mir_free (mir);
-                                       return;
-                       }
+               if (camel_db_write_fresh_message_info_record (cdb, CAMEL_DB_IN_MEMORY_TABLE, mir, error) != 0) {
+                               camel_db_camel_mir_free (mir);
+                               return;
+               }
 
-                       if (args->progress > CAMEL_DB_IN_MEMORY_TABLE_LIMIT) {
-                           g_print ("BULK INsert limit reached \n");
-                               camel_db_flush_in_memory_transactions (cdb, full_name, error);
-                               camel_db_start_in_memory_transactions (cdb, error);
-                               args->progress = 0;
-                       } else {
-                               args->progress++;
-                       }
+               if (args->progress > CAMEL_DB_IN_MEMORY_TABLE_LIMIT) {
+                   g_print ("BULK INsert limit reached \n");
+                       camel_db_flush_in_memory_transactions (cdb, full_name, error);
+                       camel_db_start_in_memory_transactions (cdb, error);
+                       args->progress = 0;
+               } else {
+                       args->progress++;
+               }
        }
 
        /* Reset the dirty flag which decides if the changes are synced to the DB or not.
@@ -2194,8 +2798,8 @@ save_message_infos_to_db (CamelFolderSummary *s,
        args.migration = fresh_mirs;
        args.progress = 0;
 
-       full_name = camel_folder_get_full_name (s->folder);
-       parent_store = camel_folder_get_parent_store (s->folder);
+       full_name = camel_folder_get_full_name (s->priv->folder);
+       parent_store = camel_folder_get_parent_store (s->priv->folder);
        cdb = parent_store->cdb_w;
 
        if (camel_db_prepare_message_info_table (cdb, full_name, error) != 0)
@@ -2205,12 +2809,11 @@ save_message_infos_to_db (CamelFolderSummary *s,
 
        /* Push MessageInfo-es */
        camel_db_begin_transaction (cdb, NULL);
-       g_hash_table_foreach (s->loaded_infos, save_to_db_cb, &args);
+       g_hash_table_foreach (s->priv->loaded_infos, save_to_db_cb, &args);
        camel_db_end_transaction (cdb, NULL);
 
        camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
-       /* FIXME[disk-summary] make sure we free the message infos that are loaded
-        * are freed if not used anymore or should we leave that to the timer? */
+       cfs_schedule_info_release_timer (s);
 
        return 0;
 }
@@ -2235,7 +2838,7 @@ msg_save_preview (const gchar *uid,
  *
  * Since: 2.24
  **/
-gint
+gboolean
 camel_folder_summary_save_to_db (CamelFolderSummary *s,
                                  GError **error)
 {
@@ -2245,9 +2848,9 @@ camel_folder_summary_save_to_db (CamelFolderSummary *s,
        gint ret, count;
 
        if (!(s->flags & CAMEL_SUMMARY_DIRTY))
-               return 0;
+               return TRUE;
 
-       parent_store = camel_folder_get_parent_store (s->folder);
+       parent_store = camel_folder_get_parent_store (s->priv->folder);
        cdb = parent_store->cdb_w;
 
        d(printf ("\ncamel_folder_summary_save_to_db called \n"));
@@ -2255,7 +2858,7 @@ camel_folder_summary_save_to_db (CamelFolderSummary *s,
                camel_folder_summary_lock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
                camel_db_begin_transaction (parent_store->cdb_w, NULL);
-               g_hash_table_foreach (s->priv->preview_updates, (GHFunc) msg_save_preview, s->folder);
+               g_hash_table_foreach (s->priv->preview_updates, (GHFunc) msg_save_preview, s->priv->folder);
                g_hash_table_remove_all (s->priv->preview_updates);
                camel_db_end_transaction (parent_store->cdb_w, NULL);
 
@@ -2272,7 +2875,7 @@ camel_folder_summary_save_to_db (CamelFolderSummary *s,
        if (ret != 0) {
                /* Failed, so lets reset the flag */
                s->flags |= CAMEL_SUMMARY_DIRTY;
-               return -1;
+               return FALSE;
        }
 
        /* XXX So... if an error is set, how do we even reach this point
@@ -2281,7 +2884,7 @@ camel_folder_summary_save_to_db (CamelFolderSummary *s,
                strstr ((*error)->message, "26 columns but 28 values") != NULL) {
                const gchar *full_name;
 
-               full_name = camel_folder_get_full_name (s->folder);
+               full_name = camel_folder_get_full_name (s->priv->folder);
                g_warning ("Fixing up a broken summary migration on %s\n", full_name);
 
                /* Begin everything again. */
@@ -2292,14 +2895,14 @@ camel_folder_summary_save_to_db (CamelFolderSummary *s,
                ret = save_message_infos_to_db (s, FALSE, error);
                if (ret != 0) {
                        s->flags |= CAMEL_SUMMARY_DIRTY;
-                       return -1;
+                       return FALSE;
                }
        }
 
        record = CAMEL_FOLDER_SUMMARY_GET_CLASS (s)->summary_header_to_db (s, error);
        if (!record) {
                s->flags |= CAMEL_SUMMARY_DIRTY;
-               return -1;
+               return FALSE;
        }
 
        camel_db_begin_transaction (cdb, NULL);
@@ -2311,12 +2914,12 @@ camel_folder_summary_save_to_db (CamelFolderSummary *s,
        if (ret != 0) {
                camel_db_abort_transaction (cdb, NULL);
                s->flags |= CAMEL_SUMMARY_DIRTY;
-               return -1;
+               return FALSE;
        }
 
        camel_db_end_transaction (cdb, NULL);
 
-       return ret;
+       return ret == 0;
 }
 
 /**
@@ -2324,7 +2927,7 @@ camel_folder_summary_save_to_db (CamelFolderSummary *s,
  *
  * Since: 2.24
  **/
-gint
+gboolean
 camel_folder_summary_header_save_to_db (CamelFolderSummary *s,
                                         GError **error)
 {
@@ -2333,14 +2936,14 @@ camel_folder_summary_header_save_to_db (CamelFolderSummary *s,
        CamelDB *cdb;
        gint ret;
 
-       parent_store = camel_folder_get_parent_store (s->folder);
+       parent_store = camel_folder_get_parent_store (s->priv->folder);
        cdb = parent_store->cdb_w;
 
        d(printf ("\ncamel_folder_summary_header_save_to_db called \n"));
 
        record = CAMEL_FOLDER_SUMMARY_GET_CLASS (s)->summary_header_to_db (s, error);
        if (!record) {
-               return -1;
+               return FALSE;
        }
 
        camel_db_begin_transaction (cdb, NULL);
@@ -2351,12 +2954,12 @@ camel_folder_summary_header_save_to_db (CamelFolderSummary *s,
 
        if (ret != 0) {
                camel_db_abort_transaction (cdb, NULL);
-               return -1;
+               return FALSE;
        }
 
        camel_db_end_transaction (cdb, NULL);
 
-       return ret;
+       return ret == 0;
 }
 
 /**
@@ -2364,7 +2967,7 @@ camel_folder_summary_header_save_to_db (CamelFolderSummary *s,
  *
  * Since: 2.24
  **/
-gint
+gboolean
 camel_folder_summary_header_load_from_db (CamelFolderSummary *s,
                                           CamelStore *store,
                                           const gchar *folder_name,
@@ -2372,22 +2975,21 @@ camel_folder_summary_header_load_from_db (CamelFolderSummary *s,
 {
        CamelDB *cdb;
        CamelFIRecord *record;
-       gint ret = 0;
+       gboolean ret = FALSE;
 
-       d(printf ("\ncamel_folder_summary_load_from_db called \n"));
+       d(printf ("\ncamel_folder_summary_header_load_from_db called \n"));
 
        camel_folder_summary_save_to_db (s, NULL);
 
        cdb = store->cdb_r;
 
        record = g_new0 (CamelFIRecord, 1);
-       camel_db_read_folder_info_record (cdb, folder_name, &record, error);
+       camel_db_read_folder_info_record (cdb, folder_name, record, error);
 
        if (record) {
-               if (CAMEL_FOLDER_SUMMARY_GET_CLASS (s)->summary_header_from_db (s, record) == -1)
-                       ret = -1;
+               ret = CAMEL_FOLDER_SUMMARY_GET_CLASS (s)->summary_header_from_db (s, record);
        } else {
-               ret = -1;
+               ret = FALSE;
        }
 
        g_free (record->folder_name);
@@ -2397,7 +2999,7 @@ camel_folder_summary_header_load_from_db (CamelFolderSummary *s,
        return ret;
 }
 
-static gint
+static gboolean
 summary_assign_uid (CamelFolderSummary *s,
                     CamelMessageInfo *info)
 {
@@ -2413,11 +3015,11 @@ summary_assign_uid (CamelFolderSummary *s,
 
        camel_folder_summary_lock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
-       while ((mi = g_hash_table_lookup (s->loaded_infos, uid))) {
+       while ((mi = g_hash_table_lookup (s->priv->loaded_infos, uid))) {
                camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
                if (mi == info)
-                       return 0;
+                       return FALSE;
 
                d(printf ("Trying to insert message with clashing uid (%s).  new uid re-assigned", camel_message_info_uid (info)));
 
@@ -2430,7 +3032,7 @@ summary_assign_uid (CamelFolderSummary *s,
 
        camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
-       return 1;
+       return TRUE;
 }
 
 /**
@@ -2450,21 +3052,32 @@ void
 camel_folder_summary_add (CamelFolderSummary *s,
                           CamelMessageInfo *info)
 {
+       CamelMessageInfoBase *base_info;
+
+       g_return_if_fail (s != NULL);
+       g_return_if_fail (s->priv != NULL);
+
        if (info == NULL)
                return;
 
-       if (summary_assign_uid (s, info) == 0)
+       camel_folder_summary_lock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
+       if (!summary_assign_uid (s, info)) {
+               camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
                return;
+       }
 
-       camel_folder_summary_lock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
+       base_info = (CamelMessageInfoBase *) info;
+       folder_summary_update_counts_by_flags (s, camel_message_info_flags (info), FALSE);
+       base_info->flags |= CAMEL_MESSAGE_FOLDER_FLAGGED;
+       base_info->dirty = TRUE;
+
+       g_hash_table_insert (s->priv->uids,
+               (gpointer) camel_pstring_strdup (camel_message_info_uid (info)),
+               GUINT_TO_POINTER (camel_message_info_flags (info)));
 
        /* Summary always holds a ref for the loaded infos */
-       /* camel_message_info_ref(info); FIXME: Check how things are loaded. */
-       /* FIXME[disk-summary] 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.*/
-       g_ptr_array_add (s->uids, (gpointer) camel_pstring_strdup ((camel_message_info_uid (info))));
+       g_hash_table_insert (s->priv->loaded_infos, (gpointer) camel_message_info_uid (info), info);
 
-       g_hash_table_insert (s->loaded_infos, (gpointer) camel_message_info_uid (info), info);
        s->flags |= CAMEL_SUMMARY_DIRTY;
 
        camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
@@ -2480,92 +3093,32 @@ camel_folder_summary_insert (CamelFolderSummary *s,
                              CamelMessageInfo *info,
                              gboolean load)
 {
+       g_return_if_fail (s != NULL);
+       g_return_if_fail (s->priv != NULL);
+
        if (info == NULL)
                return;
 
        camel_folder_summary_lock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
-       /* Summary always holds a ref for the loaded infos */
-       /* camel_message_info_ref(info); FIXME: Check how things are loaded. */
-       /* FIXME[disk-summary] 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, (gchar *) camel_pstring_strdup (camel_message_info_uid (info)));
-
-       g_hash_table_insert (s->loaded_infos, (gchar *) camel_message_info_uid (info), info);
-
-       if (!load)
-               s->flags |= CAMEL_SUMMARY_DIRTY;
-
-       camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
-}
-
-/**
- * camel_folder_summary_update_counts_by_flags:
- *
- * Since: 3.0
- **/
-void
-camel_folder_summary_update_counts_by_flags (CamelFolderSummary *summary,
-                                             guint32 flags,
-                                             gboolean subtract)
-{
-       gint unread = 0, deleted = 0, junk = 0;
-       gboolean is_junk_folder = FALSE, is_trash_folder = FALSE;
+       if (!load) {
+               CamelMessageInfoBase *base_info = (CamelMessageInfoBase *) info;
 
-       g_return_if_fail (summary != NULL);
+               folder_summary_update_counts_by_flags (s, camel_message_info_flags (info), FALSE);
+               base_info->flags |= CAMEL_MESSAGE_FOLDER_FLAGGED;
+               base_info->dirty = TRUE;
 
-       if (summary->folder && CAMEL_IS_VTRASH_FOLDER (summary->folder)) {
-               CamelVTrashFolder *vtrash = CAMEL_VTRASH_FOLDER (summary->folder);
+               g_hash_table_insert (s->priv->uids,
+                       (gpointer) camel_pstring_strdup (camel_message_info_uid (info)),
+                       GUINT_TO_POINTER (camel_message_info_flags (info)));
 
-               is_junk_folder = vtrash && vtrash->type == CAMEL_VTRASH_FOLDER_JUNK;
-               is_trash_folder = vtrash && vtrash->type == CAMEL_VTRASH_FOLDER_TRASH;
+               s->flags |= CAMEL_SUMMARY_DIRTY;
        }
 
-       if (!(flags & CAMEL_MESSAGE_SEEN))
-               unread = subtract ? -1 : 1;
-
-       if (flags & CAMEL_MESSAGE_DELETED)
-               deleted = subtract ? -1 : 1;
-
-       if (flags & CAMEL_MESSAGE_JUNK)
-               junk = subtract ? -1 : 1;
-
-       dd(printf("%p: %d %d %d | %d %d %d \n", (gpointer) summary, unread, deleted, junk, summary->unread_count, summary->visible_count, summary->saved_count));
-
-       if (deleted)
-               summary->deleted_count += deleted;
-       if (junk)
-               summary->junk_count += junk;
-       if (junk && !deleted)
-               summary->junk_not_deleted_count += junk;
-       if (!junk && !deleted)
-               summary->visible_count += subtract ? -1 : 1;
-
-       if (junk && !is_junk_folder)
-               unread = 0;
-       if (deleted && !is_trash_folder)
-               unread = 0;
-
-       if (unread)
-               summary->unread_count += unread;
-
-       summary->saved_count += subtract ? -1 : 1;
-       camel_folder_summary_touch (summary);
-
-       dd(printf("%p: %d %d %d | %d %d %d\n", (gpointer) summary, unread, deleted, junk, summary->unread_count, summary->visible_count, summary->saved_count));
-}
-
-static void
-update_summary (CamelFolderSummary *summary,
-                CamelMessageInfoBase *info)
-{
-       g_return_if_fail (summary != NULL);
-       g_return_if_fail (info != NULL);
+       /* Summary always holds a ref for the loaded infos */
+       g_hash_table_insert (s->priv->loaded_infos, (gchar *) camel_message_info_uid (info), info);
 
-       camel_folder_summary_update_counts_by_flags (summary, info->flags, FALSE);
-       info->flags |= CAMEL_MESSAGE_FOLDER_FLAGGED;
-       info->dirty = TRUE;
+       camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 }
 
 /**
@@ -2592,7 +3145,6 @@ camel_folder_summary_add_from_header (CamelFolderSummary *summary,
        info = camel_folder_summary_info_new_from_header (summary, h);
 
        camel_folder_summary_add (summary, info);
-       update_summary (summary, (CamelMessageInfoBase *) info);
 
        return info;
 }
@@ -2622,7 +3174,7 @@ camel_folder_summary_add_from_parser (CamelFolderSummary *s,
        info = camel_folder_summary_info_new_from_parser (s, mp);
 
        camel_folder_summary_add (s, info);
-       update_summary (s, (CamelMessageInfoBase *) info);
+
        return info;
 }
 
@@ -2642,7 +3194,7 @@ camel_folder_summary_add_from_message (CamelFolderSummary *s,
        CamelMessageInfo *info = camel_folder_summary_info_new_from_message (s, msg, NULL);
 
        camel_folder_summary_add (s, info);
-       update_summary (s, (CamelMessageInfoBase *) info);
+
        return info;
 }
 
@@ -2844,103 +3396,55 @@ camel_folder_summary_touch (CamelFolderSummary *s)
  *
  * Empty the summary contents.
  **/
-void
-camel_folder_summary_clear (CamelFolderSummary *s)
-{
-       d(printf ("\ncamel_folder_summary_clearcalled \n"));
-       s->flags &= ~CAMEL_SUMMARY_DIRTY;
-
-       camel_folder_summary_lock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
-       if (camel_folder_summary_count (s) == 0) {
-               camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
-               return;
-       }
-
-       g_ptr_array_foreach (s->uids, (GFunc) camel_pstring_free, NULL);
-       g_ptr_array_free (s->uids, TRUE);
-       s->uids = g_ptr_array_new ();
-       s->saved_count = 0;
-       s->unread_count = 0;
-       s->deleted_count = 0;
-       s->junk_count = 0;
-       s->junk_not_deleted_count = 0;
-       s->visible_count = 0;
-
-       g_hash_table_destroy (s->loaded_infos);
-       s->loaded_infos = g_hash_table_new (g_str_hash, g_str_equal);
-
-       camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
-}
-
-/**
- * camel_folder_summary_clear_db:
- *
- * Since: 2.24
- **/
-void
-camel_folder_summary_clear_db (CamelFolderSummary *s)
+gboolean
+camel_folder_summary_clear (CamelFolderSummary *s, GError **error)
 {
+       GObject *summary_object;
        CamelStore *parent_store;
        CamelDB *cdb;
        const gchar *folder_name;
+       gboolean res;
 
-       /* FIXME: This is non-sense. Neither an exception is passed,
-       nor a value returned. How is the caller supposed to know,
-       whether the operation is succesful */
-
-       d(printf ("\ncamel_folder_summary_load_from_db called \n"));
-       s->flags &= ~CAMEL_SUMMARY_DIRTY;
-
-       folder_name = camel_folder_get_full_name (s->folder);
-       parent_store = camel_folder_get_parent_store (s->folder);
-       cdb = parent_store->cdb_w;
+       g_return_val_if_fail (s != NULL, FALSE);
+       g_return_val_if_fail (s->priv != NULL, FALSE);
 
        camel_folder_summary_lock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
        if (camel_folder_summary_count (s) == 0) {
                camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
-               return;
+               return TRUE;
        }
 
-       g_ptr_array_foreach (s->uids, (GFunc) camel_pstring_free, NULL);
-       g_ptr_array_free (s->uids, TRUE);
-       s->uids = g_ptr_array_new ();
-       s->saved_count = 0;
-       s->unread_count = 0;
-       s->deleted_count = 0;
-       s->junk_count = 0;
-       s->junk_not_deleted_count = 0;
-       s->visible_count = 0;
-
-       g_hash_table_destroy (s->loaded_infos);
-       s->loaded_infos = g_hash_table_new (g_str_hash, g_str_equal);
+       g_hash_table_remove_all (s->priv->uids);
+       g_hash_table_remove_all (s->priv->loaded_infos);
 
-       camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
+       s->priv->saved_count = 0;
+       s->priv->unread_count = 0;
+       s->priv->deleted_count = 0;
+       s->priv->junk_count = 0;
+       s->priv->junk_not_deleted_count = 0;
+       s->priv->visible_count = 0;
 
-       camel_db_clear_folder_summary (cdb, folder_name, NULL);
-}
+       camel_folder_summary_touch (s);
 
-/* This function returns 0 on success. So the caller should not bother,
- * deleting the uid from db when the return value is non-zero */
-static gint
-summary_remove_uid (CamelFolderSummary *s,
-                    const gchar *uid)
-{
-       gint i;
+       folder_name = camel_folder_get_full_name (s->priv->folder);
+       parent_store = camel_folder_get_parent_store (s->priv->folder);
+       cdb = parent_store->cdb_w;
 
-       d(printf ("\nsummary_remove_uid called \n"));
+       res = camel_db_clear_folder_summary (cdb, folder_name, error) == 0;
 
-       /* This could be slower, but no otherway really. FIXME: Callers have to effective and shouldn't call it recursively. */
-       for (i = 0; i < s->uids->len; i++) {
-               if (strcmp (s->uids->pdata[i], uid) == 0) {
-                       /* FIXME: Does using fast remove affect anything ? */
-                       g_ptr_array_remove_index (s->uids, i);
-                       camel_pstring_free (uid);
-                       return 0;
-               }
+       summary_object = G_OBJECT (s);
+       g_object_freeze_notify (summary_object);
+       g_object_notify (summary_object, "saved-count");
+       g_object_notify (summary_object, "unread-count");
+       g_object_notify (summary_object, "deleted-count");
+       g_object_notify (summary_object, "junk-count");
+       g_object_notify (summary_object, "junk-not-deleted-count");
+       g_object_notify (summary_object, "visible-count");
+       g_object_thaw_notify (summary_object);
 
-       }
+       camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
-       return -1;
+       return res;
 }
 
 /**
@@ -2949,34 +3453,23 @@ summary_remove_uid (CamelFolderSummary *s,
  * @info: a #CamelMessageInfo
  *
  * Remove a specific @info record from the summary.
+ *
+ * Returns: Whether the @info was found and removed from the @summary.
  **/
-void
+gboolean
 camel_folder_summary_remove (CamelFolderSummary *s,
                              CamelMessageInfo *info)
 {
-       CamelStore *parent_store;
-       const gchar *full_name;
-       gboolean found;
-       gint ret;
-
-       camel_folder_summary_lock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
-
-       found = g_hash_table_lookup (s->loaded_infos, camel_message_info_uid (info)) != NULL;
-       g_hash_table_remove (s->loaded_infos, camel_message_info_uid (info));
-       ret = summary_remove_uid (s, camel_message_info_uid (info));
-
-       s->flags |= CAMEL_SUMMARY_DIRTY;
-       s->meta_summary->msg_expunged = TRUE;
-       camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
-
-       full_name = camel_folder_get_full_name (s->folder);
-       parent_store = camel_folder_get_parent_store (s->folder);
-
-       if (!ret && camel_db_delete_uid (parent_store->cdb_w, full_name, camel_message_info_uid (info), NULL) != 0)
-               return;
+       g_return_val_if_fail (s != NULL, FALSE);
+       g_return_val_if_fail (s->priv != NULL, FALSE);
+       g_return_val_if_fail (info != NULL, FALSE);
 
-       if (found)
+       if (camel_folder_summary_remove_uid (s, camel_message_info_uid (info))) {
                camel_message_info_free (info);
+               return TRUE;
+       }
+
+       return FALSE;
 }
 
 /**
@@ -2985,193 +3478,45 @@ camel_folder_summary_remove (CamelFolderSummary *s,
  * @uid: a uid
  *
  * Remove a specific info record from the summary, by @uid.
+ *
+ * Returns: Whether the @uid was found and removed from the @summary.
  **/
-void
+gboolean
 camel_folder_summary_remove_uid (CamelFolderSummary *s,
                                  const gchar *uid)
 {
-       CamelMessageInfo *oldinfo;
-       gchar *olduid;
-
-       camel_folder_summary_lock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
-       camel_folder_summary_lock (s, CAMEL_FOLDER_SUMMARY_REF_LOCK);
-       if (g_hash_table_lookup_extended (s->loaded_infos, uid, (gpointer) &olduid, (gpointer) &oldinfo)) {
-               /* make sure it doesn't vanish while we're removing it */
-               camel_message_info_ref (oldinfo);
-               camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_REF_LOCK);
-               camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
-               camel_folder_summary_remove (s, oldinfo);
-               camel_message_info_free (oldinfo);
-       } else {
-               CamelStore *parent_store;
-               const gchar *full_name;
-               gchar *tmpid = g_strdup (uid);
-               gint ret;
-               /* Info isn't loaded into the memory. We must just remove the UID*/
-               ret = summary_remove_uid (s, uid);
-               camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_REF_LOCK);
-               camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
-
-               full_name = camel_folder_get_full_name (s->folder);
-               parent_store = camel_folder_get_parent_store (s->folder);
-               if (!ret && camel_db_delete_uid (parent_store->cdb_w, full_name, tmpid, NULL) != 0) {
-                       g_free (tmpid);
-                       return;
-               }
-               g_free (tmpid);
-       }
-}
-
-/* _fast doesn't deal with db and leaves it to the caller. */
-
-/**
- * camel_folder_summary_remove_uid_fast:
- *
- * Since: 2.24
- **/
-void
-camel_folder_summary_remove_uid_fast (CamelFolderSummary *s,
-                                      const gchar *uid)
-{
-       CamelMessageInfo *oldinfo;
-       gchar *olduid;
-
-       camel_folder_summary_lock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
-       camel_folder_summary_lock (s, CAMEL_FOLDER_SUMMARY_REF_LOCK);
-       if (g_hash_table_lookup_extended (s->loaded_infos, uid, (gpointer) &olduid, (gpointer) &oldinfo)) {
-               /* make sure it doesn't vanish while we're removing it */
-               camel_message_info_ref (oldinfo);
-               camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_REF_LOCK);
-               g_hash_table_remove (s->loaded_infos, olduid);
-               summary_remove_uid (s, olduid);
-               s->flags |= CAMEL_SUMMARY_DIRTY;
-               s->meta_summary->msg_expunged = TRUE;
-               camel_message_info_free (oldinfo);
-               camel_message_info_free (oldinfo);
-               camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
-       } else {
-               gchar *tmpid = g_strdup (uid);
-               /* Info isn't loaded into the memory. We must just remove the UID*/
-               summary_remove_uid (s, uid);
-               camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_REF_LOCK);
-               camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
-               g_free (tmpid);
-       }
-}
+       gpointer ptr_uid = NULL, ptr_flags = NULL;
+       CamelStore *parent_store;
+       const gchar *full_name;
+       const gchar *uid_copy;
+       gboolean res = TRUE;
 
-/**
- * camel_folder_summary_remove_index_fast:
- *
- * Since: 2.24
- **/
-void
-camel_folder_summary_remove_index_fast (CamelFolderSummary *s,
-                                        gint index)
-{
-       const gchar *uid = s->uids->pdata[index];
-       CamelMessageInfo *oldinfo;
-       gchar *olduid;
+       g_return_val_if_fail (s != NULL, FALSE);
+       g_return_val_if_fail (s->priv != NULL, FALSE);
+       g_return_val_if_fail (uid != NULL, FALSE);
 
        camel_folder_summary_lock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
-       camel_folder_summary_lock (s, CAMEL_FOLDER_SUMMARY_REF_LOCK);
-
-       if (g_hash_table_lookup_extended (s->loaded_infos, uid, (gpointer) &olduid, (gpointer) &oldinfo)) {
-               /* make sure it doesn't vanish while we're removing it */
-               g_hash_table_remove (s->loaded_infos, uid);
-               camel_pstring_free (uid);
-               g_ptr_array_remove_index (s->uids, index);
-               camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_REF_LOCK);
-               camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_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, index);
-               camel_pstring_free (uid);
-               camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_REF_LOCK);
+       if (!g_hash_table_lookup_extended (s->priv->uids, uid, &ptr_uid, &ptr_flags)) {
                camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
+               return FALSE;
        }
-}
-
-/**
- * camel_folder_summary_remove_index:
- * @summary: a #CamelFolderSummary object
- * @index: record index
- *
- * Remove a specific info record from the summary, by index.
- **/
-void
-camel_folder_summary_remove_index (CamelFolderSummary *s,
-                                   gint index)
-{
-       const gchar *uid = s->uids->pdata[index];
-
-       camel_folder_summary_remove_uid (s, uid);
-}
-
-/**
- * camel_folder_summary_remove_range:
- * @summary: a #CamelFolderSummary object
- * @start: initial index
- * @end: last index to remove
- *
- * Removes an indexed range of info records.
- **/
-void
-camel_folder_summary_remove_range (CamelFolderSummary *s,
-                                   gint start,
-                                   gint end)
-{
-       d(g_print ("\ncamel_folder_summary_remove_range called \n"));
-       if (end < start)
-               return;
-
-       camel_folder_summary_lock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
-
-       if (start < s->uids->len) {
-
-               gint i;
-               CamelDB *cdb;
-               CamelStore *parent_store;
-               const gchar *folder_name;
-               GList *uids = NULL;
-
-               end = MIN (end + 1, s->uids->len);
-
-               for (i = start; i < end; i++) {
-                       const gchar *uid = s->uids->pdata[i];
-                       gpointer olduid, oldinfo;
-
-                       /* the uid will be freed below and will not be used because of changing size of the s->uids array */
-                       uids = g_list_prepend (uids, (gpointer) uid);
-
-                       if (g_hash_table_lookup_extended (s->loaded_infos, uid, &olduid, &oldinfo)) {
-                               camel_message_info_free (oldinfo);
-                               g_hash_table_remove (s->loaded_infos, uid);
-                       }
-               }
 
-               folder_name = camel_folder_get_full_name (s->folder);
-               parent_store = camel_folder_get_parent_store (s->folder);
-               cdb = parent_store->cdb_w;
+       folder_summary_update_counts_by_flags (s, GPOINTER_TO_UINT (ptr_flags), TRUE);
 
-               /* FIXME[disk-summary] lifecycle of infos should be checked.
-                * Add should add to db and del should del to db. Sync only
-                * the changes at interval and remove those full sync on
-                * folder switch */
-               camel_db_delete_uids (cdb, folder_name, uids, NULL);
+       uid_copy = camel_pstring_strdup (uid);
+       g_hash_table_remove (s->priv->uids, uid_copy);
+       g_hash_table_remove (s->priv->loaded_infos, uid_copy);
 
-               g_list_foreach (uids, (GFunc) camel_pstring_free, NULL);
-               g_list_free (uids);
+       full_name = camel_folder_get_full_name (s->priv->folder);
+       parent_store = camel_folder_get_parent_store (s->priv->folder);
+       if (camel_db_delete_uid (parent_store->cdb_w, full_name, uid_copy, NULL) != 0)
+               res = FALSE;
 
-               memmove (s->uids->pdata + start, s->uids->pdata + end, (s->uids->len - end) * sizeof (s->uids->pdata[0]));
-               g_ptr_array_set_size (s->uids, s->uids->len - (end - start));
+       camel_pstring_free (uid_copy);
 
-               s->flags |= CAMEL_SUMMARY_DIRTY;
+       camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
-               camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
-       } else {
-               camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
-       }
+       return res;
 }
 
 /* should be sorted, for binary search */
@@ -3366,7 +3711,7 @@ static gint
 summary_header_load (CamelFolderSummary *s,
                      FILE *in)
 {
-       if (!s->summary_path)
+       if (!s->priv->summary_path)
                return -1;
 
        fseek (in, 0, SEEK_SET);
@@ -3391,17 +3736,17 @@ summary_header_load (CamelFolderSummary *s,
 
        /* legacy version */
        if (camel_file_util_decode_fixed_int32 (in, (gint32 *) &s->flags) == -1
-           || camel_file_util_decode_fixed_int32 (in, (gint32 *) &s->nextuid) == -1
+           || camel_file_util_decode_fixed_int32 (in, (gint32 *) &s->priv->nextuid) == -1
            || camel_file_util_decode_time_t (in, &s->time) == -1
-           || camel_file_util_decode_fixed_int32 (in, (gint32 *) &s->saved_count) == -1) {
+           || camel_file_util_decode_fixed_int32 (in, (gint32 *) &s->priv->saved_count) == -1) {
                return -1;
        }
 
        /* version 13 */
        if (s->version < 0x100 && s->version >= 13
-           && (camel_file_util_decode_fixed_int32 (in, (gint32 *) &s->unread_count) == -1
-               || camel_file_util_decode_fixed_int32 (in, (gint32 *) &s->deleted_count) == -1
-               || camel_file_util_decode_fixed_int32 (in, (gint32 *) &s->junk_count) == -1)) {
+           && (camel_file_util_decode_fixed_int32 (in, (gint32 *) &s->priv->unread_count) == -1
+               || camel_file_util_decode_fixed_int32 (in, (gint32 *) &s->priv->deleted_count) == -1
+               || camel_file_util_decode_fixed_int32 (in, (gint32 *) &s->priv->junk_count) == -1)) {
                return -1;
        }
 
@@ -3746,8 +4091,12 @@ message_info_free (CamelFolderSummary *s,
        CamelMessageInfoBase *mi = (CamelMessageInfoBase *) info;
 
        if (mi->uid) {
-               if (s && g_hash_table_lookup (s->loaded_infos, mi->uid) == mi) {
-                       g_hash_table_remove (s->loaded_infos, mi->uid);
+               if (s) {
+                       camel_folder_summary_lock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
+                       if (g_hash_table_lookup (s->priv->loaded_infos, mi->uid) == mi) {
+                               g_hash_table_remove (s->priv->loaded_infos, mi->uid);
+                       }
+                       camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
                }
                camel_pstring_free (mi->uid);
        }
@@ -3890,7 +4239,7 @@ summary_build_content_info (CamelFolderSummary *s,
        /* start of this part */
        state = camel_mime_parser_step (mp, &buffer, &len);
 
-       if (s->build_content)
+       if (s->priv->build_content)
                info = CAMEL_FOLDER_SUMMARY_GET_CLASS (s)->content_info_new_from_parser (s, mp);
 
        switch (state) {
@@ -4049,7 +4398,7 @@ summary_build_content_info_message (CamelFolderSummary *s,
        CamelContentType *ct;
        const struct _camel_header_raw *header;
 
-       if (s->build_content)
+       if (s->priv->build_content)
                info = CAMEL_FOLDER_SUMMARY_GET_CLASS (s)->content_info_new_from_message (s, object);
 
        containee = camel_medium_get_content (CAMEL_MEDIUM (object));
@@ -4619,7 +4968,7 @@ camel_message_info_free (gpointer o)
                camel_folder_summary_unlock (mi->summary, CAMEL_FOLDER_SUMMARY_REF_LOCK);
 
                /* FIXME: this is kinda busted, should really be handled by message info free */
-               if (mi->summary->build_content
+               if (mi->summary->priv->build_content
                    && ((CamelMessageInfoBase *) mi)->content) {
                        camel_folder_summary_content_info_free (mi->summary, ((CamelMessageInfoBase *) mi)->content);
                }
@@ -4863,29 +5212,6 @@ camel_message_info_dump (CamelMessageInfo *mi)
        camel_content_info_dump (((CamelMessageInfoBase *) mi)->content, 0);
 }
 
-/**
- * camel_folder_summary_set_need_preview:
- *
- * Since: 2.28
- **/
-void
-camel_folder_summary_set_need_preview (CamelFolderSummary *summary,
-                                       gboolean preview)
-{
-       summary->priv->need_preview = preview;
-}
-
-/**
- * camel_folder_summary_get_need_preview:
- *
- * Since: 2.28
- **/
-gboolean
-camel_folder_summary_get_need_preview (CamelFolderSummary *summary)
-{
-       return summary->priv->need_preview;
-}
-
 static gboolean
 compare_strings (const gchar *str1,
                  const gchar *str2)
@@ -5063,4 +5389,3 @@ bdata_extract_string (/* const */ gchar **part)
 
        return val;
 }
-
index aaba7ae..01a795b 100644 (file)
@@ -65,8 +65,6 @@ typedef struct _CamelFolderSummaryPrivate CamelFolderSummaryPrivate;
 typedef struct _CamelMessageInfo CamelMessageInfo;
 typedef struct _CamelMessageInfoBase CamelMessageInfoBase;
 
-typedef struct _CamelFolderMetaSummary CamelFolderMetaSummary;
-
 typedef struct _CamelMessageContentInfo CamelMessageContentInfo;
 
 /* A tree of message content info structures
@@ -239,31 +237,8 @@ struct _CamelFolderSummary {
 
        /* header info */
        guint32 version;        /* version of file loaded/loading */
-       CamelFolderSummaryFlags flags;
-       guint32 nextuid;        /* next uid? */
        time_t time;            /* timestamp for this summary (for implementors to use) */
-       guint32 saved_count;    /* how many were saved/loaded */
-       guint32 unread_count;   /* handy totals */
-       guint32 deleted_count;
-       guint32 junk_count;
-       guint32 junk_not_deleted_count;
-       guint32 visible_count;
-
-       /* memory allocators (setup automatically) */
-       CamelMemChunk *message_info_chunks;
-       CamelMemChunk *content_info_chunks;
-
-       gchar *summary_path;
-       gboolean build_content; /* do we try and parse/index the content, or not? */
-
-       /* New members to replace the above depreacted members */
-       GPtrArray *uids;
-       GHashTable *loaded_infos;
-
-       struct _CamelFolder *folder; /* parent folder, for events */
-       struct _CamelFolderMetaSummary *meta_summary; /* Meta summary */
-       time_t cache_load_time;
-       guint timeout_handle;
+       CamelFolderSummaryFlags flags;
 
        const gchar *collate;
        const gchar *sort_by;
@@ -287,12 +262,12 @@ struct _CamelFolderSummaryClass {
        gint (*summary_header_save)(CamelFolderSummary *, FILE *);
 
        /* Load/Save folder summary from DB*/
-       gint (*summary_header_from_db)(CamelFolderSummary *, struct _CamelFIRecord *);
+       gboolean (*summary_header_from_db)(CamelFolderSummary *, struct _CamelFIRecord *);
        struct _CamelFIRecord * (*summary_header_to_db)(CamelFolderSummary *, GError **error);
        CamelMessageInfo * (*message_info_from_db) (CamelFolderSummary *, struct _CamelMIRecord *);
        struct _CamelMIRecord * (*message_info_to_db) (CamelFolderSummary *, CamelMessageInfo *);
        CamelMessageContentInfo * (*content_info_from_db) (CamelFolderSummary *, struct _CamelMIRecord *);
-       gint (*content_info_to_db) (CamelFolderSummary *, CamelMessageContentInfo *, struct _CamelMIRecord *);
+       gboolean (*content_info_to_db) (CamelFolderSummary *, CamelMessageContentInfo *, struct _CamelMIRecord *);
 
        /* create/save/load an individual message info */
        CamelMessageInfo * (*message_info_new_from_header)(CamelFolderSummary *, struct _camel_header_raw *);
@@ -326,126 +301,204 @@ struct _CamelFolderSummaryClass {
        gboolean (*info_set_flags)(CamelMessageInfo *mi, guint32 mask, guint32 set);
 };
 
-/* Meta-summary info */
-struct _CamelFolderMetaSummary {
-       guint32 major;          /* Major version of meta-summary */
-       guint32 minor;          /* Minor version of meta-summary */
-       guint32 uid_len;        /* Length of UID (for implementors to use) */
-       gboolean msg_expunged;  /* Whether any message is expunged or not */
-       gchar *path;            /* Path to meta-summary-file */
-};
-
-GType                   camel_folder_summary_get_type  (void);
-CamelFolderSummary      *camel_folder_summary_new      (struct _CamelFolder *folder);
-
-/* Deprecated */
-void camel_folder_summary_set_filename (CamelFolderSummary *summary, const gchar *filename);
-
-void camel_folder_summary_set_index (CamelFolderSummary *summary, CamelIndex *index);
-void camel_folder_summary_set_build_content (CamelFolderSummary *summary, gboolean state);
-
-guint32  camel_folder_summary_next_uid        (CamelFolderSummary *summary);
-gchar    *camel_folder_summary_next_uid_string (CamelFolderSummary *summary);
-void    camel_folder_summary_set_uid         (CamelFolderSummary *summary, guint32 uid);
+GType                  camel_folder_summary_get_type   (void);
+CamelFolderSummary *   camel_folder_summary_new        (struct _CamelFolder *folder);
+
+struct _CamelFolder *  camel_folder_summary_get_folder (CamelFolderSummary *summary);
+CamelFolderSummaryFlags        camel_folder_summary_get_flags  (CamelFolderSummary *summary);
+
+guint32                        camel_folder_summary_get_saved_count
+                                                       (CamelFolderSummary *summary);
+guint32                        camel_folder_summary_get_unread_count
+                                                       (CamelFolderSummary *summary);
+guint32                        camel_folder_summary_get_deleted_count
+                                                       (CamelFolderSummary *summary);
+guint32                        camel_folder_summary_get_junk_count
+                                                       (CamelFolderSummary *summary);
+guint32                        camel_folder_summary_get_junk_not_deleted_count
+                                                       (CamelFolderSummary *summary);
+guint32                        camel_folder_summary_get_visible_count
+                                                       (CamelFolderSummary *summary);
+
+void                   camel_folder_summary_set_index  (CamelFolderSummary *summary,
+                                                        CamelIndex *index);
+CamelIndex *           camel_folder_summary_get_index  (CamelFolderSummary *summary);
+void                   camel_folder_summary_set_build_content
+                                                       (CamelFolderSummary *summary,
+                                                        gboolean state);
+gboolean               camel_folder_summary_get_build_content
+                                                       (CamelFolderSummary *summary);
+void                   camel_folder_summary_set_need_preview
+                                                       (CamelFolderSummary *summary,
+                                                        gboolean preview);
+gboolean               camel_folder_summary_get_need_preview
+                                                       (CamelFolderSummary *summary);
+guint32                        camel_folder_summary_next_uid   (CamelFolderSummary *summary);
+void                   camel_folder_summary_set_next_uid
+                                                       (CamelFolderSummary *summary,
+                                                        guint32 uid);
+guint32                        camel_folder_summary_get_next_uid
+                                                       (CamelFolderSummary *summary);
+gchar *                        camel_folder_summary_next_uid_string
+                                                       (CamelFolderSummary *summary);
 
 /* load/save the full summary from/to the db */
-gint camel_folder_summary_save_to_db (CamelFolderSummary *s, GError **error);
-gint camel_folder_summary_load_from_db (CamelFolderSummary *s, GError **error);
+gboolean               camel_folder_summary_save_to_db (CamelFolderSummary *s,
+                                                        GError **error);
+gboolean               camel_folder_summary_load_from_db
+                                                       (CamelFolderSummary *s,
+                                                        GError **error);
 
 /* only load the header */
-gint camel_folder_summary_header_load_from_db (CamelFolderSummary *s, struct _CamelStore *store, const gchar *folder_name, GError **error);
-gint camel_folder_summary_header_save_to_db (CamelFolderSummary *s, GError **error);
+gboolean               camel_folder_summary_header_load_from_db
+                                                       (CamelFolderSummary *s,
+                                                        struct _CamelStore *store,
+                                                        const gchar *folder_name,
+                                                        GError **error);
+gboolean               camel_folder_summary_header_save_to_db
+                                                       (CamelFolderSummary *s,
+                                                        GError **error);
 
 /* set the dirty bit on the summary */
-void camel_folder_summary_touch (CamelFolderSummary *summary);
+void                   camel_folder_summary_touch      (CamelFolderSummary *summary);
 
-/* add a new raw summary item */
-void camel_folder_summary_add (CamelFolderSummary *summary, CamelMessageInfo *info);
+/* Just build raw summary items */
+CamelMessageInfo *     camel_folder_summary_info_new_from_header
+                                                       (CamelFolderSummary *summary,
+                                                        struct _camel_header_raw *headers);
+CamelMessageInfo *     camel_folder_summary_info_new_from_parser
+                                                       (CamelFolderSummary *summary,
+                                                        CamelMimeParser *parser);
+CamelMessageInfo *     camel_folder_summary_info_new_from_message
+                                                       (CamelFolderSummary *summary,
+                                                        CamelMimeMessage *message,
+                                                        const gchar *bodystructure);
+
+CamelMessageContentInfo *camel_folder_summary_content_info_new
+                                                       (CamelFolderSummary *summary);
+void                   camel_folder_summary_content_info_free
+                                                       (CamelFolderSummary *summary,
+                                                        CamelMessageContentInfo *ci);
+
+void                   camel_folder_summary_add_preview
+                                                       (CamelFolderSummary *s,
+                                                        CamelMessageInfo *info);
 
-/* Peek from mem only */
-CamelMessageInfo * camel_folder_summary_peek_info (CamelFolderSummary *s, const gchar *uid);
+/* Migration code */
+gint                   camel_folder_summary_migrate_infos
+                                                       (CamelFolderSummary *s);
+
+/* build/add raw summary items */
+CamelMessageInfo *     camel_folder_summary_add_from_header
+                                                       (CamelFolderSummary *summary,
+                                                        struct _camel_header_raw *headers);
+CamelMessageInfo *     camel_folder_summary_add_from_parser
+                                                       (CamelFolderSummary *summary,
+                                                        CamelMimeParser *parser);
+CamelMessageInfo *     camel_folder_summary_add_from_message
+                                                       (CamelFolderSummary *summary,
+                                                        CamelMimeMessage *message);
+
+/* add a new raw summary item */
+void                   camel_folder_summary_add        (CamelFolderSummary *summary,
+                                                        CamelMessageInfo *info);
 
-/* Get only the uids of dirty/changed things to sync to server/db */
-GPtrArray * camel_folder_summary_get_changed (CamelFolderSummary *s);
-/* reload the summary at any required point if required */
-void camel_folder_summary_prepare_fetch_all (CamelFolderSummary *s, GError **error);
 /* insert mi to summary */
-void camel_folder_summary_insert (CamelFolderSummary *s, CamelMessageInfo *info, gboolean load);
+void                   camel_folder_summary_insert     (CamelFolderSummary *s,
+                                                        CamelMessageInfo *info,
+                                                        gboolean load);
 
-void camel_folder_summary_remove_index_fast (CamelFolderSummary *s, gint index);
-void camel_folder_summary_remove_uid_fast (CamelFolderSummary *s, const gchar *uid);
+gboolean               camel_folder_summary_remove     (CamelFolderSummary *summary,
+                                                        CamelMessageInfo *info);
 
-/* build/add raw summary items */
-CamelMessageInfo *camel_folder_summary_add_from_header (CamelFolderSummary *summary, struct _camel_header_raw *headers);
-CamelMessageInfo *camel_folder_summary_add_from_parser (CamelFolderSummary *summary, CamelMimeParser *parser);
-CamelMessageInfo *camel_folder_summary_add_from_message (CamelFolderSummary *summary, CamelMimeMessage *message);
+gboolean               camel_folder_summary_remove_uid (CamelFolderSummary *summary,
+                                                        const gchar *uid);
 
-/* Just build raw summary items */
-CamelMessageInfo *camel_folder_summary_info_new_from_header (CamelFolderSummary *summary, struct _camel_header_raw *headers);
-CamelMessageInfo *camel_folder_summary_info_new_from_parser (CamelFolderSummary *summary, CamelMimeParser *parser);
-CamelMessageInfo *camel_folder_summary_info_new_from_message (CamelFolderSummary *summary, CamelMimeMessage *message, const gchar *bodystructure);
+/* remove all items */
+gboolean               camel_folder_summary_clear      (CamelFolderSummary *summary,
+                                                        GError **error);
 
-CamelMessageContentInfo *camel_folder_summary_content_info_new (CamelFolderSummary *summary);
-void camel_folder_summary_content_info_free (CamelFolderSummary *summary, CamelMessageContentInfo *ci);
+/* lookup functions */
+guint                  camel_folder_summary_count      (CamelFolderSummary *summary);
 
-/* removes a summary item, doesn't fix content offsets */
-void camel_folder_summary_remove (CamelFolderSummary *summary, CamelMessageInfo *info);
-void camel_folder_summary_remove_uid (CamelFolderSummary *summary, const gchar *uid);
-void camel_folder_summary_remove_index (CamelFolderSummary *summary, gint index);
-void camel_folder_summary_remove_range (CamelFolderSummary *summary, gint start, gint end);
+gboolean               camel_folder_summary_check_uid  (CamelFolderSummary *s,
+                                                        const gchar *uid);
+CamelMessageInfo *     camel_folder_summary_get        (CamelFolderSummary *summary,
+                                                        const gchar *uid);
+GPtrArray *            camel_folder_summary_get_array  (CamelFolderSummary *summary);
+void                   camel_folder_summary_free_array (GPtrArray *array);
 
-/* remove all items */
-void camel_folder_summary_clear (CamelFolderSummary *summary);
-void camel_folder_summary_clear_db (CamelFolderSummary *s);
+/* Peek from mem only */
+CamelMessageInfo *     camel_folder_summary_peek_loaded
+                                                       (CamelFolderSummary *s,
+                                                        const gchar *uid);
 
-/* update visible/unread/... counts based on message flags */
-void camel_folder_summary_update_counts_by_flags (CamelFolderSummary *summary, guint32 flags, gboolean subtract);
+/* Get only the uids of dirty/changed things to sync to server/db */
+GPtrArray *            camel_folder_summary_get_changed
+                                                       (CamelFolderSummary *s);
 
-/* lookup functions */
-guint camel_folder_summary_count (CamelFolderSummary *summary);
-CamelMessageInfo *camel_folder_summary_index (CamelFolderSummary *summary, gint index);
-CamelMessageInfo *camel_folder_summary_uid (CamelFolderSummary *summary, const gchar *uid);
-gchar * camel_folder_summary_uid_from_index (CamelFolderSummary *s, gint i);
-gboolean camel_folder_summary_check_uid (CamelFolderSummary *s, const gchar *uid);
+/* reload the summary at any required point if required */
+void                   camel_folder_summary_prepare_fetch_all
+                                                       (CamelFolderSummary *s,
+                                                        GError **error);
 
-GPtrArray *camel_folder_summary_array (CamelFolderSummary *summary);
-GHashTable *camel_folder_summary_get_hashtable (CamelFolderSummary *s);
-void camel_folder_summary_free_hashtable (GHashTable *ht);
+/* summary locking */
+void                   camel_folder_summary_lock       (CamelFolderSummary *summary,
+                                                        CamelFolderSummaryLock lock);
+void                   camel_folder_summary_unlock     (CamelFolderSummary *summary,
+                                                        CamelFolderSummaryLock lock);
 
 /* basically like strings, but certain keywords can be compressed and de-cased */
-gint camel_folder_summary_encode_token (FILE *out, const gchar *str);
-gint camel_folder_summary_decode_token (FILE *in, gchar **str);
+gint                   camel_folder_summary_encode_token
+                                                       (FILE *out,
+                                                        const gchar *str);
+gint                   camel_folder_summary_decode_token
+                                                       (FILE *in,
+                                                        gchar **str);
 
 /* message flag operations */
-gboolean       camel_flag_get (CamelFlag **list, const gchar *name);
-gboolean       camel_flag_set (CamelFlag **list, const gchar *name, gboolean value);
-gboolean       camel_flag_list_copy (CamelFlag **to, CamelFlag **from);
-gint           camel_flag_list_size (CamelFlag **list);
-void           camel_flag_list_free (CamelFlag **list);
-
-CamelMessageFlags
-               camel_system_flag (const gchar *name);
-gboolean       camel_system_flag_get (CamelMessageFlags flags, const gchar *name);
+gboolean               camel_flag_get                  (CamelFlag **list,
+                                                        const gchar *name);
+gboolean               camel_flag_set                  (CamelFlag **list,
+                                                        const gchar *name,
+                                                        gboolean value);
+gboolean               camel_flag_list_copy            (CamelFlag **to,
+                                                        CamelFlag **from);
+gint                   camel_flag_list_size            (CamelFlag **list);
+void                   camel_flag_list_free            (CamelFlag **list);
+
+CamelMessageFlags      camel_system_flag               (const gchar *name);
+gboolean               camel_system_flag_get           (CamelMessageFlags flags,
+                                                        const gchar *name);
 
 /* message tag operations */
-const gchar    *camel_tag_get (CamelTag **list, const gchar *name);
-gboolean       camel_tag_set (CamelTag **list, const gchar *name, const gchar *value);
-gboolean       camel_tag_list_copy (CamelTag **to, CamelTag **from);
-gint           camel_tag_list_size (CamelTag **list);
-void           camel_tag_list_free (CamelTag **list);
+const gchar *          camel_tag_get                   (CamelTag **list,
+                                                        const gchar *name);
+gboolean               camel_tag_set                   (CamelTag **list,
+                                                        const gchar *name,
+                                                        const gchar *value);
+gboolean               camel_tag_list_copy             (CamelTag **to,
+                                                        CamelTag **from);
+gint                   camel_tag_list_size             (CamelTag **list);
+void                   camel_tag_list_free             (CamelTag **list);
 
 /* Summary may be null */
 /* Use anonymous pointers to avoid tons of cast crap */
-gpointer camel_message_info_new (CamelFolderSummary *summary);
-gpointer camel_message_info_ref (gpointer info);
-CamelMessageInfo *camel_message_info_new_from_header (CamelFolderSummary *summary, struct _camel_header_raw *header);
-void camel_message_info_free (gpointer info);
-gpointer camel_message_info_clone (gconstpointer info);
+gpointer               camel_message_info_new          (CamelFolderSummary *summary);
+gpointer               camel_message_info_ref          (gpointer info);
+CamelMessageInfo *     camel_message_info_new_from_header
+                                                       (CamelFolderSummary *summary,
+                                                        struct _camel_header_raw *header);
+void                   camel_message_info_free         (gpointer info);
+gpointer               camel_message_info_clone        (gconstpointer info);
 
 /* accessors */
-gconstpointer camel_message_info_ptr (const CamelMessageInfo *mi, gint id);
-guint32 camel_message_info_uint32 (const CamelMessageInfo *mi, gint id);
-time_t camel_message_info_time (const CamelMessageInfo *mi, gint id);
+gconstpointer          camel_message_info_ptr          (const CamelMessageInfo *mi,
+                                                        gint id);
+guint32                        camel_message_info_uint32       (const CamelMessageInfo *mi,
+                                                        gint id);
+time_t                 camel_message_info_time         (const CamelMessageInfo *mi,
+                                                        gint id);
 
 #define camel_message_info_uid(mi) ((const gchar *)((const CamelMessageInfo *)mi)->uid)
 
@@ -497,33 +550,37 @@ time_t camel_message_info_time (const CamelMessageInfo *mi, gint id);
  **/
 #define camel_message_info_content(mi) ((const CamelMessageContentInfo *)camel_message_info_ptr((const CamelMessageInfo *)mi, CAMEL_MESSAGE_INFO_CONTENT))
 
-gboolean camel_message_info_user_flag (const CamelMessageInfo *mi, const gchar *id);
-const gchar *camel_message_info_user_tag (const CamelMessageInfo *mi, const gchar *id);
-
-gboolean camel_message_info_set_flags (CamelMessageInfo *mi, CamelMessageFlags flags, guint32 set);
-gboolean camel_message_info_set_user_flag (CamelMessageInfo *mi, const gchar *id, gboolean state);
-gboolean camel_message_info_set_user_tag (CamelMessageInfo *mi, const gchar *id, const gchar *val);
-
-void camel_folder_summary_set_need_preview (CamelFolderSummary *summary, gboolean preview);
-void camel_folder_summary_add_preview (CamelFolderSummary *s, CamelMessageInfo *info);
-gboolean camel_folder_summary_get_need_preview (CamelFolderSummary *summary);
+gboolean               camel_message_info_user_flag    (const CamelMessageInfo *mi,
+                                                        const gchar *id);
+const gchar *          camel_message_info_user_tag     (const CamelMessageInfo *mi,
+                                                        const gchar *id);
+
+gboolean               camel_message_info_set_flags    (CamelMessageInfo *mi,
+                                                        CamelMessageFlags flags,
+                                                        guint32 set);
+gboolean               camel_message_info_set_user_flag
+                                                       (CamelMessageInfo *mi,
+                                                        const gchar *id,
+                                                        gboolean state);
+gboolean               camel_message_info_set_user_tag (CamelMessageInfo *mi,
+                                                        const gchar *id,
+                                                        const gchar *val);
 
 const CamelMessageContentInfo * camel_folder_summary_guess_content_info (CamelMessageInfo *mi, CamelContentType *ctype);
 
-/* debugging functions */
-void camel_content_info_dump (CamelMessageContentInfo *ci, gint depth);
-
-void camel_message_info_dump (CamelMessageInfo *mi);
-
-/* Migration code */
-gint camel_folder_summary_migrate_infos (CamelFolderSummary *s);
+/* Deprecated */
+void                   camel_folder_summary_set_filename
+                                                       (CamelFolderSummary *summary,
+                                                        const gchar *filename);
 
-void camel_folder_summary_lock   (CamelFolderSummary *summary, CamelFolderSummaryLock lock);
-void camel_folder_summary_unlock (CamelFolderSummary *summary, CamelFolderSummaryLock lock);
+/* debugging functions */
+void                   camel_content_info_dump         (CamelMessageContentInfo *ci,
+                                                        gint depth);
+void                   camel_message_info_dump         (CamelMessageInfo *mi);
 
 /* utility functions for bdata string decomposition */
-gint   bdata_extract_digit (/* const */ gchar **part);
-gchar *bdata_extract_string (/* const */ gchar **part);
+gint                   bdata_extract_digit             (/* const */ gchar **part);
+gchar *                        bdata_extract_string            (/* const */ gchar **part);
 
 G_END_DECLS
 
index 0c3f9b9..d8d5586 100644 (file)
@@ -620,7 +620,7 @@ camel_folder_thread_messages_new (CamelFolder *folder,
 {
        CamelFolderThread *thread;
        GPtrArray *summary;
-       GPtrArray *fsummary;
+       GPtrArray *fsummary = NULL;
        gint i;
 
        thread = g_malloc (sizeof (*thread));
@@ -631,12 +631,13 @@ camel_folder_thread_messages_new (CamelFolder *folder,
        thread->folder = g_object_ref (folder);
 
        camel_folder_summary_prepare_fetch_all (folder->summary, NULL);
-       fsummary = camel_folder_summary_array (folder->summary);
        thread->summary = summary = g_ptr_array_new ();
 
        /* prefer given order from the summary order */
-       if (!uids)
+       if (!uids) {
+               fsummary = camel_folder_summary_get_array (folder->summary);
                uids = fsummary;
+       }
 
        for (i = 0; i < uids->len; i++) {
                CamelMessageInfo *info;
@@ -648,7 +649,8 @@ camel_folder_thread_messages_new (CamelFolder *folder,
                /* FIXME: Check if the info is leaking */
        }
 
-       camel_folder_free_summary (folder, fsummary);
+       if (fsummary)
+               camel_folder_summary_free_array (fsummary);
 
        thread_summary (thread, summary);
 
index 549f15e..015d621 100644 (file)
@@ -528,7 +528,6 @@ folder_dispose (GObject *object)
        }
 
        if (folder->summary) {
-               folder->summary->folder = NULL;
                g_object_unref (folder->summary);
                folder->summary = NULL;
        }
@@ -580,7 +579,7 @@ folder_get_message_flags (CamelFolder *folder,
 
        g_return_val_if_fail (folder->summary != NULL, 0);
 
-       info = camel_folder_summary_uid (folder->summary, uid);
+       info = camel_folder_summary_get (folder->summary, uid);
        if (info == NULL)
                return 0;
 
@@ -601,7 +600,7 @@ folder_set_message_flags (CamelFolder *folder,
 
        g_return_val_if_fail (folder->summary != NULL, FALSE);
 
-       info = camel_folder_summary_uid (folder->summary, uid);
+       info = camel_folder_summary_get (folder->summary, uid);
        if (info == NULL)
                return FALSE;
 
@@ -621,7 +620,7 @@ folder_get_message_user_flag (CamelFolder *folder,
 
        g_return_val_if_fail (folder->summary != NULL, FALSE);
 
-       info = camel_folder_summary_uid (folder->summary, uid);
+       info = camel_folder_summary_get (folder->summary, uid);
        if (info == NULL)
                return FALSE;
 
@@ -641,7 +640,7 @@ folder_set_message_user_flag (CamelFolder *folder,
 
        g_return_if_fail (folder->summary != NULL);
 
-       info = camel_folder_summary_uid (folder->summary, uid);
+       info = camel_folder_summary_get (folder->summary, uid);
        if (info == NULL)
                return;
 
@@ -659,7 +658,7 @@ folder_get_message_user_tag (CamelFolder *folder,
 
        g_return_val_if_fail (folder->summary != NULL, NULL);
 
-       info = camel_folder_summary_uid (folder->summary, uid);
+       info = camel_folder_summary_get (folder->summary, uid);
        if (info == NULL)
                return NULL;
 
@@ -679,7 +678,7 @@ folder_set_message_user_tag (CamelFolder *folder,
 
        g_return_if_fail (folder->summary != NULL);
 
-       info = camel_folder_summary_uid (folder->summary, uid);
+       info = camel_folder_summary_get (folder->summary, uid);
        if (info == NULL)
                return;
 
@@ -692,7 +691,7 @@ folder_get_uids (CamelFolder *folder)
 {
        g_return_val_if_fail (folder->summary != NULL, NULL);
 
-       return camel_folder_summary_array (folder->summary);
+       return camel_folder_summary_get_array (folder->summary);
 }
 
 static GPtrArray *
@@ -717,11 +716,7 @@ static void
 folder_free_uids (CamelFolder *folder,
                   GPtrArray *array)
 {
-       gint i;
-
-       for (i = 0; i < array->len; i++)
-               camel_pstring_free (array->pdata[i]);
-       g_ptr_array_free (array, TRUE);
+       camel_folder_summary_free_array (array);
 }
 
 static gint
@@ -749,15 +744,14 @@ folder_get_summary (CamelFolder *folder)
 {
        g_return_val_if_fail (folder->summary != NULL, NULL);
 
-       return camel_folder_summary_array (folder->summary);
+       return camel_folder_summary_get_array (folder->summary);
 }
 
 static void
 folder_free_summary (CamelFolder *folder,
-                     GPtrArray *summary)
+                     GPtrArray *array)
 {
-       g_ptr_array_foreach (summary, (GFunc) camel_pstring_free, NULL);
-       g_ptr_array_free (summary, TRUE);
+       camel_folder_summary_free_array (array);
 }
 
 static void
@@ -777,7 +771,7 @@ folder_get_message_info (CamelFolder *folder,
 {
        g_return_val_if_fail (folder->summary != NULL, NULL);
 
-       return camel_folder_summary_uid (folder->summary, uid);
+       return camel_folder_summary_get (folder->summary, uid);
 }
 
 static void
@@ -802,7 +796,7 @@ static void
 folder_delete (CamelFolder *folder)
 {
        if (folder->summary)
-               camel_folder_summary_clear (folder->summary);
+               camel_folder_summary_clear (folder->summary, NULL);
 }
 
 static void
@@ -1959,7 +1953,7 @@ camel_folder_get_unread_message_count (CamelFolder *folder)
        g_return_val_if_fail (CAMEL_IS_FOLDER (folder), -1);
        g_return_val_if_fail (folder->summary != NULL, -1);
 
-       return folder->summary->unread_count;
+       return camel_folder_summary_get_unread_count (folder->summary);
 }
 
 /**
@@ -1975,7 +1969,7 @@ camel_folder_get_deleted_message_count (CamelFolder *folder)
        g_return_val_if_fail (CAMEL_IS_FOLDER (folder), -1);
        g_return_val_if_fail (folder->summary != NULL, -1);
 
-       return folder->summary->deleted_count;
+       return camel_folder_summary_get_deleted_count (folder->summary);
 }
 
 /**
index 5a90759..8b51e77 100644 (file)
@@ -36,6 +36,7 @@
 
 #include "camel-file-utils.h"
 #include "camel-store-summary.h"
+#include "camel-folder-summary.h"
 #include "camel-url.h"
 #include "camel-win32.h"
 
 #define CAMEL_STORE_SUMMARY_VERSION (2)
 
 struct _CamelStoreSummaryPrivate {
-       GMutex *summary_lock;   /* for the summary hashtable/array */
-       GMutex *io_lock;        /* load/save lock, for access to saved_count, etc */
-       GMutex *ref_lock;       /* for reffing/unreffing messageinfo's ALWAYS obtain before CAMEL_STORE_SUMMARY_SUMMARY_LOCK */
+       GStaticRecMutex summary_lock;   /* for the summary hashtable/array */
+       GStaticRecMutex io_lock;        /* load/save lock, for access to saved_count, etc */
+       GStaticRecMutex ref_lock;       /* for reffing/unreffing messageinfo's ALWAYS obtain before CAMEL_STORE_SUMMARY_SUMMARY_LOCK */
+
+       GHashTable *folder_summaries; /* CamelFolderSummary->path; doesn't add reference to CamelFolderSummary */
 };
 
 G_DEFINE_TYPE (CamelStoreSummary, camel_store_summary, CAMEL_TYPE_OBJECT)
@@ -65,15 +68,16 @@ store_summary_finalize (GObject *object)
        camel_store_summary_clear (summary);
        g_ptr_array_free (summary->folders, TRUE);
        g_hash_table_destroy (summary->folders_path);
+       g_hash_table_destroy (summary->priv->folder_summaries);
 
        g_free (summary->summary_path);
 
        if (summary->store_info_chunks != NULL)
                camel_memchunk_destroy (summary->store_info_chunks);
 
-       g_mutex_free (summary->priv->summary_lock);
-       g_mutex_free (summary->priv->io_lock);
-       g_mutex_free (summary->priv->ref_lock);
+       g_static_rec_mutex_free (&summary->priv->summary_lock);
+       g_static_rec_mutex_free (&summary->priv->io_lock);
+       g_static_rec_mutex_free (&summary->priv->ref_lock);
 
        /* Chain up to parent's finalize() method. */
        G_OBJECT_CLASS (camel_store_summary_parent_class)->finalize (object);
@@ -309,10 +313,11 @@ camel_store_summary_init (CamelStoreSummary *summary)
 
        summary->folders = g_ptr_array_new ();
        summary->folders_path = g_hash_table_new (g_str_hash, g_str_equal);
+       summary->priv->folder_summaries = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_free);
 
-       summary->priv->summary_lock = g_mutex_new ();
-       summary->priv->io_lock = g_mutex_new ();
-       summary->priv->ref_lock = g_mutex_new ();
+       g_static_rec_mutex_init (&summary->priv->summary_lock);
+       g_static_rec_mutex_init (&summary->priv->io_lock);
+       g_static_rec_mutex_init (&summary->priv->ref_lock);
 }
 
 /**
@@ -1051,13 +1056,13 @@ camel_store_summary_lock (CamelStoreSummary *summary,
 
        switch (lock) {
                case CAMEL_STORE_SUMMARY_SUMMARY_LOCK:
-                       g_mutex_lock (summary->priv->summary_lock);
+                       g_static_rec_mutex_lock (&summary->priv->summary_lock);
                        break;
                case CAMEL_STORE_SUMMARY_IO_LOCK:
-                       g_mutex_lock (summary->priv->io_lock);
+                       g_static_rec_mutex_lock (&summary->priv->io_lock);
                        break;
                case CAMEL_STORE_SUMMARY_REF_LOCK:
-                       g_mutex_lock (summary->priv->ref_lock);
+                       g_static_rec_mutex_lock (&summary->priv->ref_lock);
                        break;
                default:
                        g_return_if_reached ();
@@ -1081,15 +1086,138 @@ camel_store_summary_unlock (CamelStoreSummary *summary,
 
        switch (lock) {
                case CAMEL_STORE_SUMMARY_SUMMARY_LOCK:
-                       g_mutex_unlock (summary->priv->summary_lock);
+                       g_static_rec_mutex_unlock (&summary->priv->summary_lock);
                        break;
                case CAMEL_STORE_SUMMARY_IO_LOCK:
-                       g_mutex_unlock (summary->priv->io_lock);
+                       g_static_rec_mutex_unlock (&summary->priv->io_lock);
                        break;
                case CAMEL_STORE_SUMMARY_REF_LOCK:
-                       g_mutex_unlock (summary->priv->ref_lock);
+                       g_static_rec_mutex_unlock (&summary->priv->ref_lock);
                        break;
                default:
                        g_return_if_reached ();
        }
 }
+
+static void
+store_summary_sync_folder_summary_count_cb (CamelFolderSummary *folder_summary, GParamSpec *param, CamelStoreSummary *summary)
+{
+       const gchar *path;
+       CamelStoreInfo *si;
+
+       g_return_if_fail (folder_summary != NULL);
+       g_return_if_fail (param != NULL);
+       g_return_if_fail (summary != NULL);
+       g_return_if_fail (summary->priv != NULL);
+
+       path = g_hash_table_lookup (summary->priv->folder_summaries, folder_summary);
+       g_return_if_fail (path != NULL);
+
+       camel_store_summary_lock (summary, CAMEL_STORE_SUMMARY_SUMMARY_LOCK);
+       si = camel_store_summary_path (summary, path);
+       if (!si) {
+               camel_store_summary_unlock (summary, CAMEL_STORE_SUMMARY_SUMMARY_LOCK);
+               g_warning ("%s: Store summary %p doesn't hold path '%s'", G_STRFUNC, summary, path);
+               return;
+       }
+
+       if (g_strcmp0 (g_param_spec_get_name (param), "saved-count") == 0) {
+               si->total = camel_folder_summary_get_saved_count (folder_summary);
+               camel_store_summary_touch (summary);
+       } else if (g_strcmp0 (g_param_spec_get_name (param), "unread-count") == 0) {
+               si->unread = camel_folder_summary_get_unread_count (folder_summary);
+               camel_store_summary_touch (summary);
+       } else {
+               g_warn_if_reached ();
+       }
+
+       camel_store_summary_info_free (summary, si);
+
+       camel_store_summary_unlock (summary, CAMEL_STORE_SUMMARY_SUMMARY_LOCK);
+}
+
+/**
+ * camel_store_summary_connect_folder_summary:
+ * @summary: a #CamelStoreSummary object
+ * @path: used path for @folder_summary
+ * @folder_summary: a #CamelFolderSummary object
+ *
+ * Connects listeners for count changes on @folder_summary to keep CamelStoreInfo.total
+ * and CamelStoreInfo.unread in sync transparently. The @folder_summary is stored
+ * in @summary as @path. Use camel_store_summary_disconnect_folder_summary()
+ * to disconnect from listening.
+ *
+ * Returns: Whether successfully connect callbacks for count change notifications.
+ *
+ * Since: 3.4
+ **/
+gboolean
+camel_store_summary_connect_folder_summary (CamelStoreSummary *summary, const gchar *path, CamelFolderSummary *folder_summary)
+{
+       CamelStoreInfo *si;
+
+       g_return_val_if_fail (summary != NULL, FALSE);
+       g_return_val_if_fail (summary->priv != NULL, FALSE);
+       g_return_val_if_fail (path != NULL, FALSE);
+       g_return_val_if_fail (folder_summary != NULL, FALSE);
+
+       camel_store_summary_lock (summary, CAMEL_STORE_SUMMARY_SUMMARY_LOCK);
+
+       si = camel_store_summary_path (summary, path);
+       if (!si) {
+               camel_store_summary_unlock (summary, CAMEL_STORE_SUMMARY_SUMMARY_LOCK);
+               g_warning ("%s: Store summary %p doesn't hold path '%s'", G_STRFUNC, summary, path);
+               return FALSE;
+       }
+
+       camel_store_summary_info_free (summary, si);
+
+       if (g_hash_table_lookup (summary->priv->folder_summaries, folder_summary)) {
+               camel_store_summary_unlock (summary, CAMEL_STORE_SUMMARY_SUMMARY_LOCK);
+               g_warning ("%s: Store summary %p already listens on folder summary %p", G_STRFUNC, summary, folder_summary);
+               return FALSE;
+       }
+
+       g_hash_table_insert (summary->priv->folder_summaries, folder_summary, g_strdup (path));
+       g_signal_connect (folder_summary, "notify::saved-count", G_CALLBACK (store_summary_sync_folder_summary_count_cb), summary);
+       g_signal_connect (folder_summary, "notify::unread-count", G_CALLBACK (store_summary_sync_folder_summary_count_cb), summary);
+
+       camel_store_summary_unlock (summary, CAMEL_STORE_SUMMARY_SUMMARY_LOCK);
+
+       return TRUE;
+}
+
+/**
+ * camel_store_summary_disconnect_folder_summary:
+ * @summary: a #CamelStoreSummary object
+ * @folder_summary: a #CamelFolderSummary object
+ *
+ * Diconnects count change listeners previously connected
+ * by camel_store_summary_connect_folder_summary().
+ *
+ * Returns: Whether such connection existed and whether was successfully removed.
+ *
+ * Since: 3.4
+ **/
+gboolean
+camel_store_summary_disconnect_folder_summary (CamelStoreSummary *summary, CamelFolderSummary *folder_summary)
+{
+       g_return_val_if_fail (summary != NULL, FALSE);
+       g_return_val_if_fail (summary->priv != NULL, FALSE);
+       g_return_val_if_fail (folder_summary != NULL, FALSE);
+
+       camel_store_summary_lock (summary, CAMEL_STORE_SUMMARY_SUMMARY_LOCK);
+
+       if (!g_hash_table_lookup (summary->priv->folder_summaries, folder_summary)) {
+               camel_store_summary_unlock (summary, CAMEL_STORE_SUMMARY_SUMMARY_LOCK);
+               g_warning ("%s: Store summary %p is not connected to folder summary %p", G_STRFUNC, summary, folder_summary);
+               return FALSE;
+       }
+
+       g_signal_handlers_disconnect_by_func (folder_summary, G_CALLBACK (store_summary_sync_folder_summary_count_cb), summary);
+       g_hash_table_remove (summary->priv->folder_summaries, folder_summary);
+
+       camel_store_summary_unlock (summary, CAMEL_STORE_SUMMARY_SUMMARY_LOCK);
+
+       return TRUE;
+}
index 7a2babf..b33a9d6 100644 (file)
@@ -184,6 +184,10 @@ void camel_store_info_set_string (CamelStoreSummary *summary, CamelStoreInfo *in
 void camel_store_summary_lock   (CamelStoreSummary *summary, CamelStoreSummaryLock lock);
 void camel_store_summary_unlock (CamelStoreSummary *summary, CamelStoreSummaryLock lock);
 
+struct _CamelFolderSummary;
+gboolean camel_store_summary_connect_folder_summary (CamelStoreSummary *summary, const gchar *path, struct _CamelFolderSummary *folder_summary);
+gboolean camel_store_summary_disconnect_folder_summary (CamelStoreSummary *summary, struct _CamelFolderSummary *folder_summary);
+
 G_END_DECLS
 
 #endif /* CAMEL_STORE_SUMMARY_H */
index 5a3d275..93c95f9 100644 (file)
@@ -172,13 +172,12 @@ folder_changed_add_uid (CamelFolder *sub,
                }
                vinfo = (CamelVeeMessageInfo *) camel_folder_get_message_info ((CamelFolder *) folder_unmatched, vuid);
                if (vinfo) {
-                       camel_folder_summary_update_counts_by_flags (CAMEL_FOLDER (folder_unmatched)->summary, vinfo->old_flags, TRUE);
                        camel_folder_change_info_remove_uid (
                                folder_unmatched->changes, vuid);
 
                        *unm_added_l = g_list_prepend (*unm_added_l, (gpointer) camel_pstring_strdup (vuid));
 
-                       camel_folder_summary_remove_uid_fast (
+                       camel_folder_summary_remove_uid (
                                CAMEL_FOLDER (folder_unmatched)->summary, vuid);
                        camel_folder_free_message_info (
                                CAMEL_FOLDER (folder_unmatched),
@@ -211,17 +210,11 @@ folder_changed_remove_uid (CamelFolder *sub,
        memcpy (vuid, hash, 8);
        strcpy (vuid + 8, uid);
 
-       vinfo = (CamelVeeMessageInfo *) camel_folder_summary_uid (folder->summary, vuid);
-       if (vinfo) {
-               camel_folder_summary_update_counts_by_flags (folder->summary, vinfo->old_flags, TRUE);
-               camel_message_info_free ((CamelMessageInfo *) vinfo);
-       }
-
        camel_folder_change_info_remove_uid (vf->changes, vuid);
        if (use_db)
                *m_removed_l = g_list_prepend (*m_removed_l, (gpointer) camel_pstring_strdup (vuid));
 
-       camel_folder_summary_remove_uid_fast (folder->summary, vuid);
+       camel_folder_summary_remove_uid (folder->summary, vuid);
 
        if ((vf->flags & CAMEL_STORE_FOLDER_PRIVATE) == 0 && !CAMEL_IS_VEE_FOLDER (sub) && folder_unmatched != NULL) {
                if (keep) {
@@ -247,13 +240,12 @@ folder_changed_remove_uid (CamelFolder *sub,
 
                        vinfo = (CamelVeeMessageInfo *) camel_folder_get_message_info ((CamelFolder *) folder_unmatched, vuid);
                        if (vinfo) {
-                               camel_folder_summary_update_counts_by_flags (CAMEL_FOLDER (folder_unmatched)->summary, vinfo->old_flags, TRUE);
                                camel_folder_change_info_remove_uid (
                                        folder_unmatched->changes, vuid);
 
                                *unm_removed_l = g_list_prepend (*unm_removed_l, (gpointer) camel_pstring_strdup (vuid));
 
-                               camel_folder_summary_remove_uid_fast (
+                               camel_folder_summary_remove_uid (
                                        CAMEL_FOLDER (folder_unmatched)->summary, vuid);
                                camel_folder_free_message_info (
                                        CAMEL_FOLDER (folder_unmatched),
@@ -264,18 +256,6 @@ folder_changed_remove_uid (CamelFolder *sub,
 }
 
 static void
-update_old_flags (CamelFolderSummary *summary,
-                  CamelVeeMessageInfo *vinfo)
-{
-       g_return_if_fail (summary != NULL);
-       g_return_if_fail (vinfo != NULL);
-
-       camel_folder_summary_update_counts_by_flags (summary, vinfo->old_flags, TRUE);
-       vinfo->old_flags = camel_message_info_flags ((CamelMessageInfo *) vinfo);
-       camel_folder_summary_update_counts_by_flags (summary, vinfo->old_flags, FALSE);
-}
-
-static void
 folder_changed_change_uid (CamelFolder *sub,
                            const gchar *uid,
                            const gchar hash[8],
@@ -294,21 +274,23 @@ folder_changed_change_uid (CamelFolder *sub,
        memcpy (vuid, hash, 8);
        strcpy (vuid + 8, uid);
 
-       vinfo = (CamelVeeMessageInfo *) camel_folder_summary_uid (folder->summary, vuid);
+       vinfo = (CamelVeeMessageInfo *) camel_folder_summary_get (folder->summary, vuid);
        if (folder_unmatched != NULL)
-               uinfo = (CamelVeeMessageInfo *) camel_folder_summary_uid (((CamelFolder *) folder_unmatched)->summary, vuid);
+               uinfo = (CamelVeeMessageInfo *) camel_folder_summary_get (((CamelFolder *) folder_unmatched)->summary, vuid);
        if (vinfo || uinfo) {
                info = camel_folder_get_message_info (sub, uid);
                if (info) {
                        if (vinfo) {
                                camel_folder_change_info_change_uid (vf->changes, vuid);
-                               update_old_flags (folder->summary, vinfo);
+                               vinfo->old_flags = camel_message_info_flags ((CamelMessageInfo *) vinfo);
+                               vinfo->info.flags |= (vinfo->old_flags & ~CAMEL_MESSAGE_FOLDER_FLAGGED);
                                camel_message_info_free ((CamelMessageInfo *) vinfo);
                        }
 
                        if (uinfo) {
                                camel_folder_change_info_change_uid (folder_unmatched->changes, vuid);
-                               update_old_flags (CAMEL_FOLDER (folder_unmatched)->summary, uinfo);
+                               uinfo->old_flags = camel_message_info_flags ((CamelMessageInfo *) uinfo);
+                               uinfo->info.flags |= (uinfo->old_flags & ~CAMEL_MESSAGE_FOLDER_FLAGGED);
                                camel_message_info_free ((CamelMessageInfo *) uinfo);
                        }
 
@@ -414,7 +396,7 @@ folder_changed_change (CamelSession *session,
                                }
                                memcpy (vuid, hash, 8);
                                strcpy (vuid + 8, uid);
-                               vinfo = (CamelVeeMessageInfo *) camel_folder_summary_uid (folder->summary, vuid);
+                               vinfo = (CamelVeeMessageInfo *) camel_folder_summary_get (folder->summary, vuid);
                                if (vinfo == NULL) {
                                        g_ptr_array_add (newchanged, (gchar *) uid);
                                } else {
@@ -526,7 +508,7 @@ folder_changed_change (CamelSession *session,
                        }
                        memcpy (vuid, hash, 8);
                        strcpy (vuid + 8, uid);
-                       vinfo = (CamelVeeMessageInfo *) camel_folder_summary_uid (folder->summary, vuid);
+                       vinfo = (CamelVeeMessageInfo *) camel_folder_summary_get (folder->summary, vuid);
                        if (vinfo == NULL) {
                                if (g_hash_table_lookup (matches_hash, uid)) {
                                        /* A uid we dont have, but now it matches, add it */
@@ -649,37 +631,33 @@ subfolder_renamed_update (CamelVeeFolder *vf,
                           CamelFolder *sub,
                           gchar hash[8])
 {
-       gint count, i;
+       gint i;
        CamelFolderChangeInfo *changes = NULL;
        CamelVeeFolder *folder_unmatched = vf->parent_vee_store ? vf->parent_vee_store->folder_unmatched : NULL;
        GHashTable *unmatched_uids = vf->parent_vee_store ? vf->parent_vee_store->unmatched_uids : NULL;
        CamelFolderSummary *ssummary = sub->summary;
+       GPtrArray *known_uids;
 
        camel_vee_folder_lock (vf, CAMEL_VEE_FOLDER_SUMMARY_LOCK);
 
        camel_folder_summary_prepare_fetch_all (((CamelFolder *) vf)->summary, NULL);
 
-       count = camel_folder_summary_count (((CamelFolder *) vf)->summary);
-       for (i = 0; i < count; i++) {
-               CamelVeeMessageInfo *mi = (CamelVeeMessageInfo *) camel_folder_summary_index (((CamelFolder *) vf)->summary, i);
+       known_uids = camel_folder_summary_get_array (((CamelFolder *) vf)->summary);
+       for (i = 0; known_uids && i < known_uids->len; i++) {
+               CamelVeeMessageInfo *mi = (CamelVeeMessageInfo *) camel_folder_summary_get (((CamelFolder *) vf)->summary, g_ptr_array_index (known_uids, i));
                CamelVeeMessageInfo *vinfo;
 
                if (mi == NULL)
                        continue;
 
-               if (mi->summary == ssummary) {
+               if (mi->orig_summary == ssummary) {
                        gchar *uid = (gchar *) camel_message_info_uid (mi);
                        gchar *oldkey;
                        gpointer oldval;
 
                        camel_folder_change_info_remove_uid (vf->changes, uid);
-                       camel_folder_summary_update_counts_by_flags (CAMEL_FOLDER (vf)->summary, mi->old_flags, TRUE);
                        camel_folder_summary_remove (((CamelFolder *) vf)->summary, (CamelMessageInfo *) mi);
 
-                       /* works since we always append on the end */
-                       i--;
-                       count--;
-
                        vinfo = vee_folder_add_uid (vf, sub, uid + 8, hash);
                        if (vinfo) {
                                camel_folder_change_info_add_uid (vf->changes, camel_message_info_uid (vinfo));
@@ -699,6 +677,8 @@ subfolder_renamed_update (CamelVeeFolder *vf,
                camel_message_info_free ((CamelMessageInfo *) mi);
        }
 
+       camel_folder_summary_free_array (known_uids);
+
        if (camel_folder_change_info_changed (vf->changes)) {
                changes = vf->changes;
                vf->changes = camel_folder_change_info_new ();
@@ -733,14 +713,12 @@ unmatched_check_uid (gchar *uidin,
                if (vee_folder_add_uid_test (u->folder_unmatched, u->source, uidin, u->hash))
                        camel_folder_change_info_add_uid (u->folder_unmatched->changes, uid);
        } else {
-               CamelVeeMessageInfo *mi = (CamelVeeMessageInfo *) camel_folder_summary_uid (((CamelFolder *) u->folder_unmatched)->summary, uid);
+               CamelVeeMessageInfo *mi = (CamelVeeMessageInfo *) camel_folder_summary_get (((CamelFolder *) u->folder_unmatched)->summary, uid);
                if (mi) {
-                       camel_folder_summary_update_counts_by_flags (CAMEL_FOLDER (u->folder_unmatched)->summary, mi->old_flags, TRUE);
-
                        if (u->message_uids != NULL)
                                g_queue_push_tail (u->message_uids, g_strdup (uid));
 
-                       camel_folder_summary_remove_uid_fast (
+                       camel_folder_summary_remove_uid (
                                ((CamelFolder *) u->folder_unmatched)->summary, uid);
                        camel_folder_change_info_remove_uid (
                                u->folder_unmatched->changes, uid);
@@ -801,22 +779,22 @@ summary_header_to_db (CamelFolderSummary *s,
        const gchar *full_name;
 
        /* We do this during write, so lets use write handle, though we gonna read */
-       full_name = camel_folder_get_full_name (s->folder);
+       full_name = camel_folder_get_full_name (camel_folder_summary_get_folder (s));
 
        record->folder_name = g_strdup (full_name);
 
        /* we always write out the current version */
        record->version = 13;  /* FIXME: CAMEL_FOLDER_SUMMARY_VERSION; */
        record->flags  = s->flags;
-       record->nextuid = s->nextuid;
+       record->nextuid = camel_folder_summary_get_next_uid (s);
        record->time = s->time;
 
-       record->saved_count = s->uids->len;
-       record->junk_count = s->junk_count;
-       record->deleted_count = s->deleted_count;
-       record->unread_count = s->unread_count;
-       record->visible_count = s->visible_count;
-       record->jnd_count = s->junk_not_deleted_count;
+       record->saved_count = camel_folder_summary_count (s);
+       record->junk_count = camel_folder_summary_get_junk_count (s);
+       record->deleted_count = camel_folder_summary_get_deleted_count (s);
+       record->unread_count = camel_folder_summary_get_unread_count (s);
+       record->visible_count = camel_folder_summary_get_visible_count (s);
+       record->jnd_count = camel_folder_summary_get_junk_not_deleted_count (s);
 
        return record;
 }
@@ -1074,13 +1052,13 @@ vee_folder_search_by_expression (CamelFolder *folder,
        GHashTable *searched = g_hash_table_new (NULL, NULL);
        CamelVeeFolder *folder_unmatched = vf->parent_vee_store ? vf->parent_vee_store->folder_unmatched : NULL;
        gboolean is_folder_unmatched = vf == folder_unmatched && folder_unmatched;
-       GHashTable *folder_unmatched_hash = NULL;
+       CamelFolderSummary *folder_unmatched_summary = NULL;
 
        vee_folder_propagate_skipped_changes (vf);
 
        if (is_folder_unmatched) {
                expr = g_strdup (expression);
-               folder_unmatched_hash = camel_folder_summary_get_hashtable (((CamelFolder *) folder_unmatched)->summary);
+               folder_unmatched_summary = ((CamelFolder *) folder_unmatched)->summary;
        } else {
                expr = g_strdup_printf ("(and %s %s)", vf->expression ? vf->expression : "", expression);
        }
@@ -1103,7 +1081,7 @@ vee_folder_search_by_expression (CamelFolder *folder,
                                        memcpy (vuid, hash, 8);
                                        strcpy (vuid + 8, uid);
 
-                                       if (!is_folder_unmatched || g_hash_table_lookup (folder_unmatched_hash, vuid) != NULL)
+                                       if (!is_folder_unmatched || camel_folder_summary_check_uid (folder_unmatched_summary, vuid))
                                                g_ptr_array_add (result, (gpointer) camel_pstring_strdup (vuid));
                                        g_free (vuid);
                                }
@@ -1114,8 +1092,6 @@ vee_folder_search_by_expression (CamelFolder *folder,
                node = g_list_next (node);
        }
 
-       if (folder_unmatched_hash)
-               camel_folder_summary_free_hashtable (folder_unmatched_hash);
        g_free (expr);
 
        g_hash_table_destroy (searched);
@@ -1330,10 +1306,10 @@ vee_folder_get_message_sync (CamelFolder *folder,
        CamelVeeMessageInfo *mi;
        CamelMimeMessage *msg = NULL;
 
-       mi = (CamelVeeMessageInfo *) camel_folder_summary_uid (folder->summary, uid);
+       mi = (CamelVeeMessageInfo *) camel_folder_summary_get (folder->summary, uid);
        if (mi) {
                msg = camel_folder_get_message_sync (
-                       mi->summary->folder, camel_message_info_uid (mi) + 8,
+                       camel_folder_summary_get_folder (mi->orig_summary), camel_message_info_uid (mi) + 8,
                        cancellable, error);
                camel_message_info_free ((CamelMessageInfo *) mi);
        } else {
@@ -1426,22 +1402,21 @@ vee_folder_synchronize_sync (CamelFolder *folder,
                CamelStore *parent_store;
                const gchar *full_name;
                GList *del = NULL;
-               gint i, count;
+               gint i;
+               GPtrArray *known_uids;
 
                camel_folder_summary_prepare_fetch_all (folder->summary, NULL);
-               count = camel_folder_summary_count (folder->summary);
-               for (i = 0; i < count; i++) {
-                       CamelVeeMessageInfo *mi = (CamelVeeMessageInfo *) camel_folder_summary_index (folder->summary, i);
+               known_uids = camel_folder_summary_get_array (folder->summary);
+               for (i = 0; known_uids && i < known_uids->len; i++) {
+                       CamelVeeMessageInfo *mi = (CamelVeeMessageInfo *) camel_folder_summary_get (folder->summary, g_ptr_array_index (known_uids, i));
                        if (mi->old_flags & CAMEL_MESSAGE_DELETED) {
                                del = g_list_prepend (del, (gpointer) camel_pstring_strdup (((CamelMessageInfo *) mi)->uid));
-                               camel_folder_summary_update_counts_by_flags (folder->summary, mi->old_flags, TRUE);
-                               camel_folder_summary_remove_index_fast (folder->summary, i);
-                               count--;
-                               i--;
+                               camel_folder_summary_remove_uid (folder->summary, ((CamelMessageInfo *) mi)->uid);
 
                        }
                        camel_message_info_free (mi);
                }
+               camel_folder_summary_free_array (known_uids);
 
                full_name = camel_folder_get_full_name (folder);
                parent_store = camel_folder_get_parent_store (folder);
@@ -1500,7 +1475,7 @@ vee_folder_set_expression (CamelVeeFolder *vee_folder,
                parent_store = camel_folder_get_parent_store (folder);
                summary = folder->summary;
 
-               camel_folder_summary_clear (summary);
+               camel_folder_summary_clear (summary, NULL);
                camel_db_recreate_vfolder (parent_store->cdb_w, full_name, NULL);
        }
 
@@ -1537,7 +1512,7 @@ static void
 vee_folder_remove_folder_helper (CamelVeeFolder *vf,
                                  CamelFolder *source)
 {
-       gint i, count, n, still = FALSE, start, last;
+       gint i, n, still = FALSE;
        gchar *oldkey;
        CamelFolder *folder = (CamelFolder *) vf;
        gchar hash[8];
@@ -1547,6 +1522,7 @@ vee_folder_remove_folder_helper (CamelVeeFolder *vf,
        GHashTable *unmatched_uids = vf->parent_vee_store ? vf->parent_vee_store->unmatched_uids : NULL;
        CamelFolderSummary *ssummary = source->summary;
        gint killun = FALSE;
+       GPtrArray *known_uids;
 
        if (vf == folder_unmatched)
                return;
@@ -1569,58 +1545,36 @@ vee_folder_remove_folder_helper (CamelVeeFolder *vf,
 
                /* See if we just blow all uid's from this folder away from unmatched, regardless */
                if (killun) {
-                       start = -1;
-                       last = -1;
                        camel_folder_summary_prepare_fetch_all (((CamelFolder *) folder_unmatched)->summary, NULL);
-                       count = camel_folder_summary_count (((CamelFolder *) folder_unmatched)->summary);
-                       for (i = 0; i < count; i++) {
-                               CamelVeeMessageInfo *mi = (CamelVeeMessageInfo *) camel_folder_summary_index (((CamelFolder *) folder_unmatched)->summary, i);
+                       known_uids = camel_folder_summary_get_array (((CamelFolder *) folder_unmatched)->summary);
+                       for (i = 0; known_uids && i < known_uids->len; i++) {
+                               CamelVeeMessageInfo *mi = (CamelVeeMessageInfo *)
+                                       camel_folder_summary_get (((CamelFolder *) folder_unmatched)->summary, g_ptr_array_index (known_uids, i));
 
                                if (mi) {
-                                       if (mi->summary == ssummary) {
+                                       if (mi->orig_summary == ssummary) {
                                                camel_folder_change_info_remove_uid (folder_unmatched->changes, camel_message_info_uid (mi));
-                                               camel_folder_summary_update_counts_by_flags (CAMEL_FOLDER (folder_unmatched)->summary, mi->old_flags, TRUE);
-                                               if (last == -1) {
-                                                       last = start = i;
-                                               } else if (last + 1 == i) {
-                                                       last = i;
-                                               } else {
-                                                       camel_folder_summary_remove_range (((CamelFolder *) folder_unmatched)->summary, start, last);
-                                                       i -= (last - start) + 1;
-                                                       start = last = i;
-                                               }
+                                               camel_folder_summary_remove_uid (((CamelFolder *) folder_unmatched)->summary, camel_message_info_uid (mi));
                                        }
                                        camel_message_info_free ((CamelMessageInfo *) mi);
                                }
                        }
-                       if (last != -1)
-                               camel_folder_summary_remove_range (((CamelFolder *) folder_unmatched)->summary, start, last);
+                       camel_folder_summary_free_array (known_uids);
                }
        }
 
        /*FIXME: This can be optimized a lot like, searching for UID in the summary uids */
-       start = -1;
-       last = -1;
        camel_folder_summary_prepare_fetch_all (folder->summary, NULL);
-       count = camel_folder_summary_count (folder->summary);
-       for (i = 0; i < count; i++) {
-               CamelVeeMessageInfo *mi = (CamelVeeMessageInfo *) camel_folder_summary_index (folder->summary, i);
+       known_uids = camel_folder_summary_get_array (folder->summary);
+       for (i = 0; known_uids && i < known_uids->len; i++) {
+               CamelVeeMessageInfo *mi = (CamelVeeMessageInfo *) camel_folder_summary_get (folder->summary, g_ptr_array_index (known_uids, i));
                if (mi) {
-                       if (mi->summary == ssummary) {
+                       if (mi->orig_summary == ssummary) {
                                const gchar *uid = camel_message_info_uid (mi);
 
                                camel_folder_change_info_remove_uid (vf->changes, uid);
-                               camel_folder_summary_update_counts_by_flags (folder->summary, mi->old_flags, TRUE);
+                               camel_folder_summary_remove_uid (folder->summary, uid);
 
-                               if (last == -1) {
-                                       last = start = i;
-                               } else if (last + 1 == i) {
-                                       last = i;
-                               } else {
-                                       camel_folder_summary_remove_range (folder->summary, start, last);
-                                       i -= (last - start) + 1;
-                                       start = last = i;
-                               }
                                if ((vf->flags & CAMEL_STORE_FOLDER_PRIVATE) == 0 && folder_unmatched != NULL) {
                                        if (still) {
                                                if (g_hash_table_lookup_extended (unmatched_uids, uid, (gpointer *) &oldkey, &oldval)) {
@@ -1646,9 +1600,7 @@ vee_folder_remove_folder_helper (CamelVeeFolder *vf,
                        camel_message_info_free ((CamelMessageInfo *) mi);
                }
        }
-
-       if (last != -1)
-               camel_folder_summary_remove_range (folder->summary, start, last);
+       camel_folder_summary_free_array (known_uids);
 
        if (folder_unmatched) {
                if (camel_folder_change_info_changed (folder_unmatched->changes)) {
@@ -1711,7 +1663,7 @@ vee_folder_rebuild_folder (CamelVeeFolder *vee_folder,
        GHashTable *allhash, *matchhash, *fullhash;
        GList *del_list = NULL;
        CamelFolder *folder = (CamelFolder *) vee_folder;
-       gint i, n, count, start, last;
+       gint i, n, count;
        struct _update_data u;
        CamelFolderChangeInfo *vee_folder_changes = NULL, *unmatched_changes = NULL;
        CamelVeeFolder *folder_unmatched = vee_folder->parent_vee_store ? vee_folder->parent_vee_store->folder_unmatched : NULL;
@@ -1719,6 +1671,7 @@ vee_folder_rebuild_folder (CamelVeeFolder *vee_folder,
        CamelFolderSummary *ssummary = source->summary;
        gboolean rebuilded = FALSE;
        gchar *shash;
+       GPtrArray *known_uids;
 
        /* Since the source of a correlating vfolder has to be requeried in
         * full every time it changes, caching the results in the db is not
@@ -1774,7 +1727,7 @@ vee_folder_rebuild_folder (CamelVeeFolder *vee_folder,
 
        allhash = g_hash_table_new (g_str_hash, g_str_equal);
        fullhash = g_hash_table_new (g_str_hash, g_str_equal);
-       all = camel_folder_summary_array (source->summary);
+       all = camel_folder_summary_get_array (source->summary);
        for (i = 0; i < all->len; i++) {
                if (g_hash_table_lookup (matchhash, all->pdata[i]) == NULL)
                        g_hash_table_insert (allhash, all->pdata[i], GINT_TO_POINTER (1));
@@ -1800,31 +1753,20 @@ vee_folder_rebuild_folder (CamelVeeFolder *vee_folder,
        /* scan, looking for "old" uid's to be removed. "old" uid's
         * are those that are from previous added sources (not in
         * current source) */
-       start = -1;
-       last = -1;
        camel_folder_summary_prepare_fetch_all (folder->summary, NULL);
-       count = camel_folder_summary_count (folder->summary);
-       for (i = 0; i < count; i++) {
-               CamelVeeMessageInfo *mi = (CamelVeeMessageInfo *) camel_folder_summary_index (folder->summary, i);
+       known_uids = camel_folder_summary_get_array (folder->summary);
+       for (i = 0; known_uids && i < known_uids->len; i++) {
+               CamelVeeMessageInfo *mi = (CamelVeeMessageInfo *) camel_folder_summary_get (folder->summary, g_ptr_array_index (known_uids, i));
 
                if (mi) {
-                       if (mi->summary == ssummary) {
+                       if (mi->orig_summary == ssummary) {
                                gchar *uid = (gchar *) camel_message_info_uid (mi), *oldkey;
                                gpointer oldval;
 
                                if (g_hash_table_lookup (matchhash, uid + 8) == NULL) {
-                                       if (last == -1) {
-                                               last = start = i;
-                                       } else if (last + 1 == i) {
-                                               last = i;
-                                       } else {
-                                               camel_folder_summary_remove_range (folder->summary, start, last);
-                                               i -= (last - start) + 1;
-                                               count -= (last - start) + 1;
-                                               start = last = i;
-                                       }
                                        camel_folder_change_info_remove_uid (vee_folder->changes, camel_message_info_uid (mi));
-                                       camel_folder_summary_update_counts_by_flags (folder->summary, mi->old_flags, TRUE);
+                                       camel_folder_summary_remove_uid (folder->summary, uid);
+
                                        if (!CAMEL_IS_VEE_FOLDER (source)
                                            && unmatched_uids != NULL
                                            && g_hash_table_lookup_extended (unmatched_uids, uid, (gpointer *) &oldkey, &oldval)) {
@@ -1843,8 +1785,7 @@ vee_folder_rebuild_folder (CamelVeeFolder *vee_folder,
                        camel_message_info_free ((CamelMessageInfo *) mi);
                }
        }
-       if (last != -1)
-               camel_folder_summary_remove_range (folder->summary, start, last);
+       camel_folder_summary_free_array (known_uids);
 
        if (rebuilded && !correlating)
                u.message_uids = g_queue_new ();
@@ -1878,29 +1819,26 @@ vee_folder_rebuild_folder (CamelVeeFolder *vee_folder,
 
        if (folder_unmatched != NULL) {
                /* scan unmatched, remove any that have vanished, etc */
-               count = camel_folder_summary_count (((CamelFolder *) folder_unmatched)->summary);
-               for (i = 0; i < count; i++) {
-                       gchar *uid = camel_folder_summary_uid_from_index (((CamelFolder *) folder_unmatched)->summary, i);
-
-                       if (uid) {
-                               if (strncmp (uid, u.hash, 8) == 0) {
-                                       if (g_hash_table_lookup (allhash, uid + 8) == NULL) {
-                                               CamelVeeMessageInfo *vinfo = (CamelVeeMessageInfo *) camel_folder_summary_index (CAMEL_FOLDER (folder_unmatched)->summary, i);
-                                               if (vinfo) {
-                                                       camel_folder_summary_update_counts_by_flags (CAMEL_FOLDER (folder_unmatched)->summary, vinfo->old_flags, TRUE);
-                                                       camel_message_info_free (vinfo);
+               GPtrArray *known_uids;
+
+               known_uids = camel_folder_summary_get_array (((CamelFolder *) folder_unmatched)->summary);
+               if (known_uids != NULL) {
+                       for (i = 0; i < known_uids->len; i++) {
+                               const gchar *uid = g_ptr_array_index (known_uids, i);
+
+                               if (uid) {
+                                       if (strncmp (uid, u.hash, 8) == 0) {
+                                               if (g_hash_table_lookup (allhash, uid + 8) == NULL) {
+                                                       /* no longer exists at all, just remove it entirely */
+                                                       camel_folder_summary_remove_uid (((CamelFolder *) folder_unmatched)->summary, uid);
+                                                       camel_folder_change_info_remove_uid (folder_unmatched->changes, uid);
+                                               } else {
+                                                       g_hash_table_remove (allhash, uid + 8);
                                                }
-                                               /* no longer exists at all, just remove it entirely */
-                                               camel_folder_summary_remove_index_fast (((CamelFolder *) folder_unmatched)->summary, i);
-                                               camel_folder_change_info_remove_uid (folder_unmatched->changes, uid);
-                                               i--;
-                                               count--;
-                                       } else {
-                                               g_hash_table_remove (allhash, uid + 8);
                                        }
                                }
-                               g_free (uid);
                        }
+                       camel_folder_summary_free_array (known_uids);
                }
 
                /* now allhash contains all potentially new uid's for the unmatched folder, process */
@@ -1976,7 +1914,7 @@ vee_folder_rebuild_folder (CamelVeeFolder *vee_folder,
                g_ptr_array_free (match, TRUE);
        } else
                camel_folder_search_free (source, match);
-       camel_folder_free_summary (source, all);
+       camel_folder_summary_free_array (all);
 
        if (unmatched_changes) {
                camel_folder_changed (
@@ -2466,7 +2404,7 @@ camel_vee_folder_get_location (CamelVeeFolder *vf,
 {
        CamelFolder *folder;
 
-       folder = vinfo->summary->folder;
+       folder = camel_folder_summary_get_folder (vinfo->orig_summary);
 
        /* locking?  yes?  no?  although the vfolderinfo is valid when obtained
         * the folder in it might not necessarily be so ...? */
index 612874c..e638ed7 100644 (file)
@@ -50,7 +50,7 @@ vee_message_info_free (CamelFolderSummary *s,
        CamelVeeMessageInfo *mi = (CamelVeeMessageInfo *) info;
 
        camel_pstring_free (info->uid);
-       g_object_unref (mi->summary);
+       g_object_unref (mi->orig_summary);
 }
 
 static CamelMessageInfo *
@@ -62,7 +62,7 @@ vee_message_info_clone (CamelFolderSummary *s,
 
        to = (CamelVeeMessageInfo *) camel_message_info_new (s);
 
-       to->summary = g_object_ref (from->summary);
+       to->orig_summary = g_object_ref (from->orig_summary);
        to->info.summary = s;
        to->info.uid = camel_pstring_strdup (from->info.uid);
 
@@ -79,7 +79,7 @@ vee_info_ptr (const CamelMessageInfo *mi,
        CamelMessageInfo *rmi;
        gpointer p;
 
-       rmi = camel_folder_summary_uid (vmi->summary, mi->uid + 8);
+       rmi = camel_folder_summary_get (vmi->orig_summary, mi->uid + 8);
        HANDLE_NULL_INFO (NULL);
        p = (gpointer) camel_message_info_ptr (rmi, id);
        camel_message_info_free (rmi);
@@ -91,7 +91,7 @@ static guint32
 vee_info_uint32 (const CamelMessageInfo *mi,
                  gint id)
 {
-       CamelMessageInfo *rmi = camel_folder_summary_uid (((CamelVeeMessageInfo *) mi)->summary, mi->uid + 8);
+       CamelMessageInfo *rmi = camel_folder_summary_get (((CamelVeeMessageInfo *) mi)->orig_summary, mi->uid + 8);
        guint32 ret;
 
        HANDLE_NULL_INFO (0);
@@ -106,7 +106,7 @@ static time_t
 vee_info_time (const CamelMessageInfo *mi,
                gint id)
 {
-       CamelMessageInfo *rmi = camel_folder_summary_uid (((CamelVeeMessageInfo *) mi)->summary, mi->uid + 8);
+       CamelMessageInfo *rmi = camel_folder_summary_get (((CamelVeeMessageInfo *) mi)->orig_summary, mi->uid + 8);
        time_t ret;
 
        HANDLE_NULL_INFO (0);
@@ -120,7 +120,7 @@ static gboolean
 vee_info_user_flag (const CamelMessageInfo *mi,
                     const gchar *id)
 {
-       CamelMessageInfo *rmi = camel_folder_summary_uid (((CamelVeeMessageInfo *) mi)->summary, mi->uid + 8);
+       CamelMessageInfo *rmi = camel_folder_summary_get (((CamelVeeMessageInfo *) mi)->orig_summary, mi->uid + 8);
        gboolean ret;
 
        HANDLE_NULL_INFO (FALSE);
@@ -134,7 +134,7 @@ static const gchar *
 vee_info_user_tag (const CamelMessageInfo *mi,
                    const gchar *id)
 {
-       CamelMessageInfo *rmi = camel_folder_summary_uid (((CamelVeeMessageInfo *) mi)->summary, mi->uid + 8);
+       CamelMessageInfo *rmi = camel_folder_summary_get (((CamelVeeMessageInfo *) mi)->orig_summary, mi->uid + 8);
        const gchar *ret;
 
        HANDLE_NULL_INFO("");
@@ -150,22 +150,23 @@ vee_info_set_user_flag (CamelMessageInfo *mi,
                         gboolean value)
 {
        gint res = FALSE;
-       CamelVeeFolder *vf = (CamelVeeFolder *) mi->summary->folder;
+       CamelVeeFolder *vf = (CamelVeeFolder *) camel_folder_summary_get_folder (mi->summary);
 
        if (camel_debug("vfolderexp"))
                printf (
                        "Expression for vfolder '%s' is '%s'\n",
-                       camel_folder_get_full_name (mi->summary->folder),
+                       camel_folder_get_full_name (camel_folder_summary_get_folder (mi->summary)),
                        g_strescape (vf->expression, ""));
 
        if (mi->uid) {
-               CamelMessageInfo *rmi = camel_folder_summary_uid (((CamelVeeMessageInfo *) mi)->summary, mi->uid + 8);
+               CamelMessageInfo *rmi = camel_folder_summary_get (((CamelVeeMessageInfo *) mi)->orig_summary, mi->uid + 8);
+
                HANDLE_NULL_INFO (FALSE);
 
                /* ignore changes done in the folder itself,
                 * unless it's a vTrash or vJunk folder */
                if (!CAMEL_IS_VTRASH_FOLDER (vf))
-                       camel_vee_folder_ignore_next_changed_event (vf, rmi->summary->folder);
+                       camel_vee_folder_ignore_next_changed_event (vf, camel_folder_summary_get_folder (rmi->summary));
 
                res = camel_message_info_set_user_flag (rmi, name, value);
 
@@ -183,13 +184,15 @@ vee_info_set_user_tag (CamelMessageInfo *mi,
        gint res = FALSE;
 
        if (mi->uid) {
-               CamelMessageInfo *rmi = camel_folder_summary_uid (((CamelVeeMessageInfo *) mi)->summary, mi->uid + 8);
+               CamelMessageInfo *rmi = camel_folder_summary_get (((CamelVeeMessageInfo *) mi)->orig_summary, mi->uid + 8);
+               CamelFolder *folder = camel_folder_summary_get_folder (mi->summary);
+
                HANDLE_NULL_INFO (FALSE);
 
                /* ignore changes done in the folder itself,
                 * unless it's a vTrash or vJunk folder */
-               if (!CAMEL_IS_VTRASH_FOLDER (mi->summary->folder))
-                       camel_vee_folder_ignore_next_changed_event ((CamelVeeFolder *) mi->summary->folder, rmi->summary->folder);
+               if (!CAMEL_IS_VTRASH_FOLDER (folder))
+                       camel_vee_folder_ignore_next_changed_event ((CamelVeeFolder *) folder, camel_folder_summary_get_folder (rmi->summary));
 
                res = camel_message_info_set_user_tag (rmi, name, value);
                camel_message_info_free (rmi);
@@ -204,47 +207,36 @@ vee_info_set_flags (CamelMessageInfo *mi,
                     guint32 set)
 {
        gint res = FALSE;
-       CamelVeeFolder *vf = (CamelVeeFolder *) mi->summary->folder;
+       CamelVeeFolder *vf = CAMEL_VEE_FOLDER (camel_folder_summary_get_folder (mi->summary));
 
        if (camel_debug("vfolderexp"))
                printf (
                        "Expression for vfolder '%s' is '%s'\n",
-                       camel_folder_get_full_name (mi->summary->folder),
+                       camel_folder_get_full_name (CAMEL_FOLDER (vf)),
                        g_strescape (vf->expression, ""));
 
+       /* first update original message info... */
        if (mi->uid) {
-               CamelMessageInfo *rmi = camel_folder_summary_uid (((CamelVeeMessageInfo *) mi)->summary, mi->uid + 8);
+               CamelMessageInfo *rmi = camel_folder_summary_get (((CamelVeeMessageInfo *) mi)->orig_summary, mi->uid + 8);
 
                HANDLE_NULL_INFO (FALSE);
 
-               camel_folder_summary_update_counts_by_flags (mi->summary, camel_message_info_flags (rmi), TRUE);
-
                /* ignore changes done in the folder itself,
                 * unless it's a vTrash or vJunk folder */
                if (!CAMEL_IS_VTRASH_FOLDER (vf))
-                       camel_vee_folder_ignore_next_changed_event (vf, rmi->summary->folder);
+                       camel_vee_folder_ignore_next_changed_event (vf, camel_folder_summary_get_folder (rmi->summary));
 
-               camel_folder_freeze (rmi->summary->folder);
+               camel_folder_freeze (camel_folder_summary_get_folder (rmi->summary));
                res = camel_message_info_set_flags (rmi, flags, set);
                ((CamelVeeMessageInfo *) mi)->old_flags = camel_message_info_flags (rmi);
-               camel_folder_thaw (rmi->summary->folder);
-
-               /* Keep the summary in sync */
-               camel_folder_summary_update_counts_by_flags (mi->summary, camel_message_info_flags (rmi), FALSE);
-
-               d(printf("VF %d %d %d %d %d\n", mi->summary->unread_count, mi->summary->deleted_count, mi->summary->junk_count, mi->summary->junk_not_deleted_count, mi->summary->visible_count));
-
-               if (res && mi->summary && mi->summary->folder) {
-                       CamelFolderChangeInfo *changes = camel_folder_change_info_new ();
-
-                       camel_folder_change_info_change_uid (changes, camel_message_info_uid (mi));
-                       camel_folder_changed (mi->summary->folder, changes);
-                       camel_folder_change_info_free (changes);
-               }
+               camel_folder_thaw (camel_folder_summary_get_folder (rmi->summary));
 
                camel_message_info_free (rmi);
        }
 
+       if (res)
+               CAMEL_FOLDER_SUMMARY_CLASS (camel_vee_summary_parent_class)->info_set_flags (mi, flags, set);
+
        return res;
 }
 
@@ -254,17 +246,7 @@ message_info_from_uid (CamelFolderSummary *s,
 {
        CamelMessageInfo *info;
 
-       /* FIXME[disk-summary] too bad design. Need to peek it from cfs
-        * instead of hacking ugly like this */
-       camel_folder_summary_lock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
-
-       info = g_hash_table_lookup (s->loaded_infos, uid);
-
-       if (info)
-               camel_message_info_ref (info);
-
-       camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
-
+       info = camel_folder_summary_peek_loaded (s, uid);
        if (!info) {
                CamelVeeMessageInfo *vinfo;
                gchar tmphash[9];
@@ -275,7 +257,8 @@ message_info_from_uid (CamelFolderSummary *s,
                 * Otherwise, the first byte itself would return in strcmp, saving the CPU.
                 */
                if (!camel_folder_summary_check_uid (s, uid)) {
-                       d(g_message ("Unable to find %s in the summary of %s", uid, s->folder->full_name));
+                       d(g_message ("Unable to find %s in the summary of %s", uid,
+                               camel_folder_get_full_name (camel_folder_summary_get_folder (s->folder))));
                        return NULL;
                }
 
@@ -287,10 +270,11 @@ message_info_from_uid (CamelFolderSummary *s,
                info->uid = camel_pstring_strdup (uid);
                strncpy (tmphash, uid, 8);
                tmphash[8] = 0;
-               vinfo->summary = g_hash_table_lookup (((CamelVeeFolder *) s->folder)->hashes, tmphash);
-               g_object_ref (vinfo->summary);
+               vinfo->orig_summary = g_hash_table_lookup (((CamelVeeFolder *) camel_folder_summary_get_folder (s))->hashes, tmphash);
+               g_object_ref (vinfo->orig_summary);
                camel_folder_summary_insert (s, info, FALSE);
        }
+
        return info;
 }
 
@@ -336,17 +320,13 @@ camel_vee_summary_new (CamelFolder *parent)
        CamelStore *parent_store;
        const gchar *full_name;
 
-       s = g_object_new (CAMEL_TYPE_VEE_SUMMARY, NULL);
-       s->summary.folder = parent;
+       s = g_object_new (CAMEL_TYPE_VEE_SUMMARY, "folder", parent, NULL);
 
-        /* FIXME[disk-summary] fix exceptions and note return values */
-       /* FIXME[disk-summary] if Evo's junk/trash vfolders make it VJunk
-        * VTrash instead of .#evolution/Junk-or-whatever */
        full_name = camel_folder_get_full_name (parent);
        parent_store = camel_folder_get_parent_store (parent);
        camel_db_create_vfolder (parent_store->cdb_w, full_name, NULL);
 
-       return &s->summary;
+       return (CamelFolderSummary *) s;
 }
 
 /**
@@ -365,8 +345,8 @@ camel_vee_summary_get_ids (CamelVeeSummary *summary,
        const gchar *full_name;
 
        /* FIXME[disk-summary] fix exception passing */
-       full_name = camel_folder_get_full_name (cfs->folder);
-       parent_store = camel_folder_get_parent_store (cfs->folder);
+       full_name = camel_folder_get_full_name (camel_folder_summary_get_folder (cfs));
+       parent_store = camel_folder_get_parent_store (camel_folder_summary_get_folder (cfs));
        array = camel_db_get_vuids_from_vfolder (parent_store->cdb_r, full_name, shash, NULL);
 
        g_free (shash);
@@ -387,36 +367,30 @@ camel_vee_summary_add (CamelVeeSummary *s,
        memcpy (vuid, hash, 8);
        strcpy (vuid + 8, uid);
 
-       camel_folder_summary_lock (CAMEL_FOLDER_SUMMARY (s), CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
-       mi = (CamelVeeMessageInfo *) g_hash_table_lookup (((CamelFolderSummary *) s)->loaded_infos, vuid);
-       camel_folder_summary_unlock (CAMEL_FOLDER_SUMMARY (s), CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
-
+       mi = (CamelVeeMessageInfo *) camel_folder_summary_peek_loaded (&s->summary, vuid);
        if (mi) {
                /* Possible that the entry is loaded, see if it has the summary */
                d(g_message ("%s - already there\n", vuid));
                g_free (vuid);
-               if (!mi->summary)
-                       mi->summary = g_object_ref (summary);
-
-               camel_message_info_ref (mi);
+               if (!mi->orig_summary)
+                       mi->orig_summary = g_object_ref (summary);
                return mi;
        }
 
        mi = (CamelVeeMessageInfo *) camel_message_info_new (&s->summary);
-       mi->summary = g_object_ref (summary);
+       mi->orig_summary = g_object_ref (summary);
        mi->info.uid = (gchar *) camel_pstring_strdup (vuid);
        g_free (vuid);
        camel_message_info_ref (mi);
 
        /* Get actual flags and store it */
-       rmi = camel_folder_summary_uid (summary, uid);
+       rmi = camel_folder_summary_get (summary, uid);
        if (rmi) {
                mi->old_flags = camel_message_info_flags (rmi);
                camel_message_info_free (rmi);
        }
 
        camel_folder_summary_insert (&s->summary, (CamelMessageInfo *) mi, FALSE);
-       camel_folder_summary_update_counts_by_flags (&s->summary, camel_message_info_flags (mi), FALSE);
 
        return mi;
 }
index 688dcf9..2667e7a 100644 (file)
@@ -59,8 +59,8 @@ typedef struct _CamelVeeSummaryClass CamelVeeSummaryClass;
 typedef struct _CamelVeeMessageInfo CamelVeeMessageInfo;
 
 struct _CamelVeeMessageInfo {
-       CamelMessageInfo info;
-       CamelFolderSummary *summary;
+       CamelMessageInfoBase info;
+       CamelFolderSummary *orig_summary;
        guint32 old_flags;  /* These are just for identifying changed flags */
 };
 
index f3a5038..fff4a39 100644 (file)
@@ -171,18 +171,18 @@ vtrash_folder_transfer_messages_to_sync (CamelFolder *source,
                        continue;
                }
 
-               if (dest == mi->summary->folder) {
+               if (dest == camel_folder_summary_get_folder (mi->orig_summary)) {
                        /* Just unset the flag on the original message */
                        camel_folder_set_message_flags (
                                source, uids->pdata[i], sbit, 0);
                } else {
                        if (batch == NULL)
                                batch = g_hash_table_new (NULL, NULL);
-                       md = g_hash_table_lookup (batch, mi->summary->folder);
+                       md = g_hash_table_lookup (batch, camel_folder_summary_get_folder (mi->orig_summary));
                        if (md == NULL) {
                                md = g_malloc0 (sizeof (*md));
                                md->cancellable = cancellable;
-                               md->folder = g_object_ref (mi->summary->folder);
+                               md->folder = g_object_ref (camel_folder_summary_get_folder (mi->orig_summary));
                                md->uids = g_ptr_array_new ();
                                md->dest = dest;
                                md->delete = delete_originals;
@@ -192,7 +192,7 @@ vtrash_folder_transfer_messages_to_sync (CamelFolder *source,
                                if (cancellable != NULL)
                                        g_object_ref (cancellable);
                                camel_folder_freeze (md->folder);
-                               g_hash_table_insert (batch, mi->summary->folder, md);
+                               g_hash_table_insert (batch, camel_folder_summary_get_folder (mi->orig_summary), md);
                        }
 
                        /* unset the bit temporarily */
index d419e27..97b05f1 100644 (file)
@@ -192,6 +192,7 @@ static void
 imap_folder_dispose (GObject *object)
 {
        CamelImapFolder *imap_folder;
+       CamelStore *parent_store;
 
        imap_folder = CAMEL_IMAP_FOLDER (object);
 
@@ -216,6 +217,13 @@ imap_folder_dispose (GObject *object)
                imap_folder->journal = NULL;
        }
 
+       parent_store = camel_folder_get_parent_store (CAMEL_FOLDER (imap_folder));
+       if (parent_store) {
+               camel_store_summary_disconnect_folder_summary (
+                       (CamelStoreSummary *) ((CamelImapStore *) parent_store)->summary,
+                       CAMEL_FOLDER (imap_folder)->summary);
+       }
+
        /* Chain up to parent's dispose() method. */
        G_OBJECT_CLASS (camel_imap_folder_parent_class)->dispose (object);
 }
@@ -488,6 +496,10 @@ camel_imap_folder_new (CamelStore *parent,
 
        imap_folder->search = camel_imap_search_new (folder_dir);
 
+       camel_store_summary_connect_folder_summary (
+               (CamelStoreSummary *) ((CamelImapStore *) parent)->summary,
+               folder_name, folder->summary);
+
        return folder;
 }
 
@@ -557,7 +569,7 @@ camel_imap_folder_selected (CamelFolder *folder,
        CamelMessageFlags perm_flags = 0;
        GData *fetch_data;
        gint i, count;
-       gchar *resp, *old_uid;
+       gchar *resp;
 
        count = camel_folder_summary_count (folder->summary);
 
@@ -599,7 +611,7 @@ camel_imap_folder_selected (CamelFolder *folder,
                imap_summary->validity = validity;
        else if (validity != imap_summary->validity) {
                imap_summary->validity = validity;
-               camel_folder_summary_clear (folder->summary);
+               camel_folder_summary_clear (folder->summary, NULL);
                CAMEL_IMAP_FOLDER_REC_LOCK (imap_folder, cache_lock);
                camel_imap_message_cache_clear (imap_folder->cache);
                CAMEL_IMAP_FOLDER_REC_UNLOCK (imap_folder, cache_lock);
@@ -614,6 +626,8 @@ camel_imap_folder_selected (CamelFolder *folder,
        else if (count != 0 && !imap_folder->need_rescan) {
                CamelStore *parent_store;
                CamelImapStore *store;
+               GPtrArray *known_uids;
+               const gchar *old_uid;
 
                parent_store = camel_folder_get_parent_store (folder);
                store = CAMEL_IMAP_STORE (parent_store);
@@ -649,13 +663,17 @@ camel_imap_folder_selected (CamelFolder *folder,
                }
                camel_imap_response_free_without_processing (store, response);
 
-               old_uid = camel_folder_summary_uid_from_index (folder->summary, count - 1);
+               known_uids = camel_folder_summary_get_array (folder->summary);
+               camel_folder_sort_uids (folder, known_uids);
+               old_uid = NULL;
+               if (known_uids && count - 1 >= 0 && count - 1 < known_uids->len)
+                       old_uid = g_ptr_array_index (known_uids, count - 1);
                if (old_uid) {
                        val = strtoul (old_uid, NULL, 10);
-                       g_free (old_uid);
                        if (uid == 0 || uid != val)
                                imap_folder->need_rescan = TRUE;
                }
+               camel_folder_summary_free_array (known_uids);
        }
 
        /* Now rescan if we need to */
@@ -882,7 +900,7 @@ imap_refresh_info_sync (CamelFolder *folder,
                guint32 unread, total;
 
                total = camel_folder_summary_count (folder->summary);
-               unread = folder->summary->unread_count;
+               unread = camel_folder_summary_get_unread_count (folder->summary);
 
                if (si->total != total
                    || si->unread != unread) {
@@ -905,7 +923,7 @@ imap_refresh_info_sync (CamelFolder *folder,
                        if (get_folder_status (folder, &server_total, &server_unread, cancellable, &local_error)) {
 
                                total = camel_folder_summary_count (folder->summary);
-                               unread = folder->summary->unread_count;
+                               unread = camel_folder_summary_get_unread_count (folder->summary);
 
                                if (total != server_total || unread != server_unread)
                                        check_rescan = 1;
@@ -1035,6 +1053,7 @@ imap_rescan (CamelFolder *folder,
        gboolean ok;
        CamelFolderChangeInfo *changes = NULL;
        gboolean success;
+       GPtrArray *known_uids;
 
        parent_store = camel_folder_get_parent_store (folder);
        store = CAMEL_IMAP_STORE (parent_store);
@@ -1044,8 +1063,10 @@ imap_rescan (CamelFolder *folder,
 
        imap_folder->need_rescan = FALSE;
 
-       summary_len = camel_folder_summary_count (folder->summary);
+       known_uids = camel_folder_summary_get_array (folder->summary);
+       summary_len = known_uids ? known_uids->len : 0;
        if (summary_len == 0) {
+               camel_folder_summary_free_array (known_uids);
                if (exists)
                        return camel_imap_folder_changed (
                                folder, exists, NULL, cancellable, error);
@@ -1056,19 +1077,22 @@ imap_rescan (CamelFolder *folder,
        camel_operation_push_message (
                cancellable, _("Scanning for changed messages in %s"),
                camel_folder_get_display_name (folder));
-       uid = camel_folder_summary_uid_from_index (folder->summary, summary_len - 1);
 
+       camel_folder_sort_uids (folder, known_uids);
+
+       uid = g_ptr_array_index (known_uids, summary_len - 1);
        if (!uid) {
                camel_operation_pop_message (cancellable);
+               camel_folder_summary_free_array (known_uids);
                return TRUE;
        }
 
        ok = camel_imap_command_start (
                store, folder, cancellable, error,
                "UID FETCH 1:%s (FLAGS)", uid);
-       g_free (uid);
        if (!ok) {
                camel_operation_pop_message (cancellable);
+               camel_folder_summary_free_array (known_uids);
                return FALSE;
        }
 
@@ -1110,6 +1134,7 @@ imap_rescan (CamelFolder *folder,
                g_free (new);
                g_free (resp);
 
+               camel_folder_summary_free_array (known_uids);
                return TRUE;
        }
 
@@ -1126,6 +1151,7 @@ imap_rescan (CamelFolder *folder,
                if (type != CAMEL_IMAP_RESPONSE_ERROR && type != CAMEL_IMAP_RESPONSE_TAGGED)
                        camel_service_unlock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK);
 
+               camel_folder_summary_free_array (known_uids);
                return TRUE;
        }
 
@@ -1146,12 +1172,11 @@ imap_rescan (CamelFolder *folder,
        for (i = 0, j = 0; i < summary_len && new[j].uid; i++) {
                gboolean changed = FALSE;
 
-               uid = camel_folder_summary_uid_from_index (folder->summary, i);
-
+               uid = g_ptr_array_index (known_uids, i);
                if (!uid)
                        continue;
 
-               info = camel_folder_summary_uid (folder->summary, uid);
+               info = camel_folder_summary_get (folder->summary, uid);
                if (!info) {
                        if (g_getenv("CRASH_IMAP")) { /* Debug logs to tackle on hard to get imap crasher */
                                printf ("CRASH: %s: %s",
@@ -1164,40 +1189,6 @@ imap_rescan (CamelFolder *folder,
                iinfo = (CamelImapMessageInfo *) info;
 
                if (strcmp (uid, new[j].uid) != 0) {
-                       g_free (uid);
-
-                       /* these will be deleted from db in a moment. So adjust the counts please */
-                       if (info) {
-                               CamelMessageInfoBase *dinfo = (CamelMessageInfoBase *) info;
-                               gint unread = 0, deleted = 0, junk = 0;
-                               guint32 flags;
-
-                               flags = dinfo->flags;
-                               if (!(flags & CAMEL_MESSAGE_SEEN))
-                                       unread = 1;
-
-                               if (flags & CAMEL_MESSAGE_DELETED)
-                                       deleted = 1;
-
-                               if (flags & CAMEL_MESSAGE_JUNK)
-                                       junk = 1;
-
-                               if (unread)
-                                       folder->summary->unread_count--;
-
-                               if (deleted)
-                                       folder->summary->deleted_count--;
-                               if (junk)
-                                       folder->summary->junk_count--;
-
-                               if (junk && !deleted)
-                                       folder->summary->junk_not_deleted_count--;
-
-                               if (!junk &&  !deleted)
-                                       folder->summary->visible_count--;
-
-                               folder->summary->saved_count--;
-                       }
                        seq = i + 1 - del;
                        del++;
                        g_array_append_val (removed, seq);
@@ -1205,49 +1196,18 @@ imap_rescan (CamelFolder *folder,
                        continue;
                }
 
-               g_free (uid);
-
                /* Update summary flags */
 
                if (new[j].flags != iinfo->server_flags) {
                        guint32 server_set, server_cleared;
-                       gint read = 0, deleted = 0, junk = 0;
 
                        server_set = new[j].flags & ~iinfo->server_flags;
                        server_cleared = iinfo->server_flags & ~new[j].flags;
 
-                       if (server_set & CAMEL_MESSAGE_SEEN)
-                               read = 1;
-                       else if (server_cleared & CAMEL_MESSAGE_SEEN)
-                               read = -1;
-
-                       if (server_set & CAMEL_MESSAGE_DELETED)
-                               deleted = 1;
-                       else if (server_cleared & CAMEL_MESSAGE_DELETED)
-                               deleted = -1;
-
-                       if (server_set & CAMEL_MESSAGE_JUNK)
-                               junk = 1;
-                       else if (server_cleared & CAMEL_MESSAGE_JUNK)
-                               junk = -1;
-
-                       d(printf("%s %s %s %s\n", iinfo->info.uid, read == 1 ? "read" : ( read == -1 ? "unread" : ""),
-                                deleted == 1 ? "deleted" : ( deleted == -1 ? "undeleted" : ""),
-                                junk == 1 ? "junk" : ( junk == -1 ? "unjunked" : "")));
-
-                       if (read)
-                               folder->summary->unread_count -= read;
-                       if (deleted)
-                               folder->summary->deleted_count += deleted;
-                       if (junk)
-                               folder->summary->junk_count += junk;
-                       if (junk && !deleted)
-                               folder->summary->junk_not_deleted_count += junk;
-                       if (junk ||  deleted)
-                               folder->summary->visible_count -= junk ? junk : deleted;
-
-                       iinfo->info.flags = (iinfo->info.flags | server_set) & ~server_cleared;
+                       camel_message_info_set_flags ((CamelMessageInfo *) iinfo, server_set | server_cleared, (iinfo->info.flags | server_set) & ~server_cleared);
                        iinfo->server_flags = new[j].flags;
+                       /* unset folder_flagged, because these are flags received froma server */
+                       iinfo->info.flags = iinfo->info.flags & (~CAMEL_MESSAGE_FOLDER_FLAGGED);
                        iinfo->info.dirty = TRUE;
                        if (info->summary)
                                camel_folder_summary_touch (info->summary);
@@ -1297,41 +1257,8 @@ imap_rescan (CamelFolder *folder,
         */
 
        for (i = seq; i <= summary_len; i++) {
-               CamelMessageInfoBase *dinfo;
                gint j;
-               dinfo = (CamelMessageInfoBase *) camel_folder_summary_index (folder->summary, i - 1);
-               if (dinfo) {
-                       /* these will be deleted from db in a moment. So adjust the counts please */
-                       gint unread = 0, deleted = 0, junk = 0;
-                       guint32 flags;
-
-                       flags = dinfo->flags;
-                       if (!(flags & CAMEL_MESSAGE_SEEN))
-                               unread = 1;
 
-                       if (flags & CAMEL_MESSAGE_DELETED)
-                               deleted = 1;
-
-                       if (flags & CAMEL_MESSAGE_JUNK)
-                               junk = 1;
-
-                       if (unread)
-                               folder->summary->unread_count--;
-
-                       if (deleted)
-                               folder->summary->deleted_count--;
-                       if (junk)
-                               folder->summary->junk_count--;
-
-                       if (junk && !deleted)
-                               folder->summary->junk_not_deleted_count--;
-
-                       if (!junk &&  !deleted)
-                               folder->summary->visible_count--;
-
-                       folder->summary->saved_count--;
-                       camel_message_info_free (dinfo);
-               }
                j = seq - del;
                g_array_append_val (removed, j);
        }
@@ -1341,6 +1268,7 @@ imap_rescan (CamelFolder *folder,
                folder, exists, removed, cancellable, error);
        g_array_free (removed, TRUE);
 
+       camel_folder_summary_free_array (known_uids);
        return success;
 }
 
@@ -1413,7 +1341,7 @@ get_matching (CamelFolder *folder,
                uid = summary->pdata[i];
 
                if (uid) {
-                       info = (CamelImapMessageInfo *) camel_folder_summary_uid (folder->summary, uid);
+                       info = (CamelImapMessageInfo *) camel_folder_summary_get (folder->summary, uid);
                } else
                        continue;
 
@@ -1541,9 +1469,9 @@ imap_sync_offline (CamelFolder *folder,
                full_name = camel_folder_get_full_name (folder);
                si = camel_store_summary_path ((CamelStoreSummary *)((CamelImapStore *) parent_store)->summary, full_name);
                if (si) {
-                       if (si->total != folder->summary->saved_count || si->unread != folder->summary->unread_count) {
-                               si->total = folder->summary->saved_count;
-                               si->unread = folder->summary->unread_count;
+                       if (si->total != camel_folder_summary_get_saved_count (folder->summary) || si->unread != camel_folder_summary_get_unread_count (folder->summary)) {
+                               si->total = camel_folder_summary_get_saved_count (folder->summary);
+                               si->unread = camel_folder_summary_get_unread_count (folder->summary);
                                camel_store_summary_touch ((CamelStoreSummary *)((CamelImapStore *) parent_store)->summary);
                        }
 
@@ -1720,7 +1648,7 @@ imap_synchronize_sync (CamelFolder *folder,
                if (!uid) /* Possibly it was sync by matching flags, which we NULLify */
                        continue;
 
-               if (!(info = (CamelImapMessageInfo *) camel_folder_summary_uid (folder->summary, uid))) {
+               if (!(info = (CamelImapMessageInfo *) camel_folder_summary_get (folder->summary, uid))) {
                        continue;
                }
 
@@ -1922,7 +1850,7 @@ imap_expunge_uids_offline (CamelFolder *folder,
        changes = camel_folder_change_info_new ();
 
        for (i = 0; i < uids->len; i++) {
-               camel_folder_summary_remove_uid_fast (folder->summary, uids->pdata[i]);
+               camel_folder_summary_remove_uid (folder->summary, uids->pdata[i]);
                camel_folder_change_info_remove_uid (changes, uids->pdata[i]);
                list = g_list_prepend (list, (gpointer) uids->pdata[i]);
                /* We intentionally don't remove it from the cache because
@@ -2025,7 +1953,7 @@ imap_expunge_uids_online (CamelFolder *folder,
 
        changes = camel_folder_change_info_new ();
        for (i = 0; i < uids->len; i++) {
-               camel_folder_summary_remove_uid_fast (folder->summary, uids->pdata[i]);
+               camel_folder_summary_remove_uid (folder->summary, uids->pdata[i]);
                camel_folder_change_info_remove_uid (changes, uids->pdata[i]);
                list = g_list_prepend (list, (gpointer) uids->pdata[i]);
                /* We intentionally don't remove it from the cache because
@@ -2050,7 +1978,7 @@ imap_expunge_sync (CamelFolder *folder,
        CamelStore *parent_store;
        GPtrArray *uids = NULL;
        const gchar *full_name;
-       gboolean success;
+       gboolean success, real_trash = FALSE;
 
        full_name = camel_folder_get_full_name (folder);
        parent_store = camel_folder_get_parent_store (folder);
@@ -2066,7 +1994,8 @@ imap_expunge_sync (CamelFolder *folder,
 
                if (local_error == NULL && trash && (folder == trash || g_ascii_strcasecmp (full_name, camel_folder_get_full_name (trash)) == 0)) {
                        /* it's a real trash folder, thus get all mails from there */
-                       uids = camel_folder_summary_array (folder->summary);
+                       real_trash = TRUE;
+                       uids = camel_folder_summary_get_array (folder->summary);
                }
 
                if (local_error != NULL)
@@ -2086,8 +2015,12 @@ imap_expunge_sync (CamelFolder *folder,
                success = imap_expunge_uids_offline (
                        folder, uids, cancellable, error);
 
-       g_ptr_array_foreach (uids, (GFunc) camel_pstring_free, NULL);
-       g_ptr_array_free (uids, TRUE);
+       if (real_trash) {
+               camel_folder_summary_free_array (uids);
+       } else {
+               g_ptr_array_foreach (uids, (GFunc) camel_pstring_free, NULL);
+               g_ptr_array_free (uids, TRUE);
+       }
 
        return success;
 }
@@ -2616,7 +2549,7 @@ imap_transfer_offline (CamelFolder *source,
 
                destuid = get_temp_uid ();
 
-               mi = camel_folder_summary_uid (source->summary, uid);
+               mi = camel_folder_summary_get (source->summary, uid);
                g_return_val_if_fail (mi != NULL, FALSE);
 
                message = camel_folder_get_message_sync (
@@ -2892,7 +2825,7 @@ do_copy (CamelFolder *source,
                                camel_folder_delete_message (
                                        source, uids->pdata[i]);
                                if (mark_moved) {
-                                       CamelMessageInfoBase *info = (CamelMessageInfoBase *) camel_folder_summary_uid (source->summary, uids->pdata[i]);
+                                       CamelMessageInfoBase *info = (CamelMessageInfoBase *) camel_folder_summary_get (source->summary, uids->pdata[i]);
 
                                        if (info)
                                                info->flags |= CAMEL_MESSAGE_IMAP_MOVED;
@@ -3515,7 +3448,7 @@ imap_folder_summary_uid_or_error (CamelFolderSummary *summary,
                                   GError **error)
 {
        CamelImapMessageInfo *mi;
-       mi = (CamelImapMessageInfo *) camel_folder_summary_uid (summary, uid);
+       mi = (CamelImapMessageInfo *) camel_folder_summary_get (summary, uid);
        if (mi == NULL) {
                g_set_error (
                        error, CAMEL_FOLDER_ERROR,
@@ -3570,7 +3503,7 @@ imap_get_message_sync (CamelFolder *folder,
                    || store->braindamaged
                    || mi->info.size < IMAP_SMALL_BODY_SIZE
                    || (!content_info_incomplete (mi->info.content) && !mi->info.content->childs)) {
-                       CamelMessageInfoBase *info = (CamelMessageInfoBase *) camel_folder_summary_uid (folder->summary, uid);
+                       CamelMessageInfoBase *info = (CamelMessageInfoBase *) camel_folder_summary_get (folder->summary, uid);
                        msg = get_message_simple (imap_folder, uid, NULL, cancellable, &local_error);
                        if (info && !info->preview && msg && camel_folder_summary_get_need_preview (folder->summary)) {
                                if (camel_mime_message_build_preview ((CamelMimePart *) msg, (CamelMessageInfo *) info) && info->preview)
@@ -3650,7 +3583,7 @@ imap_get_message_sync (CamelFolder *folder,
                        else
                                msg = get_message (imap_folder, uid, mi->info.content, cancellable, &local_error);
                        if (msg && camel_folder_summary_get_need_preview (folder->summary)) {
-                               CamelMessageInfoBase *info = (CamelMessageInfoBase *) camel_folder_summary_uid (folder->summary, uid);
+                               CamelMessageInfoBase *info = (CamelMessageInfoBase *) camel_folder_summary_get (folder->summary, uid);
                                if (info && !info->preview) {
                                        if (camel_mime_message_build_preview ((CamelMimePart *) msg, (CamelMessageInfo *) info) && info->preview)
                                                camel_folder_summary_add_preview (folder->summary, (CamelMessageInfo *) info);
@@ -3950,41 +3883,6 @@ construct_junk_headers (gchar *header,
        }
 }
 
-static void
-update_summary (CamelFolderSummary *summary,
-                CamelMessageInfoBase *info)
-{
-       gint unread = 0, deleted = 0, junk = 0;
-       guint32 flags = info->flags;
-
-       if (!(flags & CAMEL_MESSAGE_SEEN))
-               unread = 1;
-
-       if (flags & CAMEL_MESSAGE_DELETED)
-               deleted = 1;
-
-       if (flags & CAMEL_MESSAGE_JUNK)
-               junk = 1;
-
-       if (summary) {
-
-               if (unread)
-                       summary->unread_count += unread;
-               if (deleted)
-                       summary->deleted_count += deleted;
-               if (junk)
-                       summary->junk_count += junk;
-               if (junk && !deleted)
-                       summary->junk_not_deleted_count += junk;
-               summary->visible_count++;
-               if (junk ||  deleted)
-                       summary->visible_count -= junk ? junk : deleted;
-
-               summary->saved_count++;
-               camel_folder_summary_touch (summary);
-       }
-}
-
 #define CAMEL_MESSAGE_INFO_HEADERS "DATE FROM TO CC SUBJECT REFERENCES IN-REPLY-TO MESSAGE-ID MIME-VERSION CONTENT-TYPE CONTENT-CLASS X-CALENDAR-ATTACHMENT "
 
 /* FIXME: this needs to be kept in sync with camel-mime-utils.c's list
@@ -4067,11 +3965,19 @@ imap_update_summary (CamelFolder *folder,
        seq = camel_folder_summary_count (folder->summary);
        first = seq + 1;
        if (seq > 0) {
-               tempuid = camel_folder_summary_uid_from_index (folder->summary, seq -1 );
+               GPtrArray *known_uids;
 
-               if (tempuid) {
-                       uidval = strtoul (tempuid, NULL, 10);
-                       g_free (tempuid);
+               known_uids = camel_folder_summary_get_array (folder->summary);
+               if (known_uids) {
+                       camel_folder_sort_uids (folder, known_uids);
+
+                       tempuid = g_ptr_array_index (known_uids, seq - 1);
+                       if (tempuid)
+                               uidval = strtoul (tempuid, NULL, 10);
+                       else
+                               uidval = 0;
+
+                       camel_folder_summary_free_array (known_uids);
                } else
                        uidval = 0;
        } else
@@ -4322,7 +4228,7 @@ imap_update_summary (CamelFolder *folder,
 
                /* FIXME: If it enters if (info) it will always match the exception. So stupid */
                /* FIXME[disk-summary] Use a db query to see if the DB exists */
-/*             info = (CamelImapMessageInfo *)camel_folder_summary_uid(folder->summary, uid); */
+/*             info = (CamelImapMessageInfo *)camel_folder_summary_get (folder->summary, uid); */
 /*             if (info) { */
 /*                     for (seq = 0; seq < camel_folder_summary_count (folder->summary); seq++) { */
 /*                             if (folder->summary->messages->pdata[seq] == info) */
@@ -4333,7 +4239,6 @@ imap_update_summary (CamelFolder *folder,
                if (((CamelMessageInfoBase *) mi)->summary)
                        camel_folder_summary_touch (((CamelMessageInfoBase *) mi)->summary);
                camel_folder_summary_add (folder->summary, (CamelMessageInfo *) mi);
-               update_summary (folder->summary, (CamelMessageInfoBase *) mi);
                camel_folder_change_info_add_uid (changes, camel_message_info_uid (mi));
 
                /* Report all new messages as recent, even without that flag, thus new
@@ -4389,7 +4294,6 @@ camel_imap_folder_changed (CamelFolder *folder,
        CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder);
        CamelFolderChangeInfo *changes;
        gint len;
-       gchar *uid;
        gboolean success = TRUE;
 
        changes = camel_folder_change_info_new ();
@@ -4398,30 +4302,35 @@ camel_imap_folder_changed (CamelFolder *folder,
                gint i, id;
                GList *deleted = NULL;
                const gchar *full_name;
+               const gchar *uid;
+               GPtrArray *known_uids;
 
+               known_uids = camel_folder_summary_get_array (folder->summary);
+               camel_folder_sort_uids (folder, known_uids);
                for (i = 0; i < expunged->len; i++) {
                        id = g_array_index (expunged, int, i);
-                       uid = camel_folder_summary_uid_from_index (folder->summary, id - 1);
+                       uid = id - 1 + i >= 0 && id - 1 + i < known_uids->len ? g_ptr_array_index (known_uids, id - 1 + i) : NULL;
                        if (uid == NULL) {
                                /* FIXME: danw: does this mean that the summary is corrupt? */
                                /* I guess a message that we never retrieved got expunged? */
                                continue;
                        }
 
-                       deleted = g_list_prepend (deleted, uid);
+                       deleted = g_list_prepend (deleted, (gpointer) uid);
                        camel_folder_change_info_remove_uid (changes, uid);
                        CAMEL_IMAP_FOLDER_REC_LOCK (imap_folder, cache_lock);
                        camel_imap_message_cache_remove (imap_folder->cache, uid);
                        CAMEL_IMAP_FOLDER_REC_UNLOCK (imap_folder, cache_lock);
-                       camel_folder_summary_remove_index_fast (folder->summary, id - 1);
+                       camel_folder_summary_remove_uid (folder->summary, uid);
                }
 
                /* Delete all in one transaction */
                full_name = camel_folder_get_full_name (folder);
                parent_store = camel_folder_get_parent_store (folder);
                camel_db_delete_uids (parent_store->cdb_w, full_name, deleted, NULL);
-               g_list_foreach (deleted, (GFunc) g_free, NULL);
                g_list_free (deleted);
+
+               camel_folder_summary_free_array (known_uids);
        }
 
        len = camel_folder_summary_count (folder->summary);
index 8a121a4..be9ec8f 100644 (file)
@@ -190,7 +190,6 @@ camel_imap_message_cache_new (const gchar *path,
        const gchar *dname;
        gchar *uid, *p;
        GPtrArray *deletes;
-       GHashTable *shash;
 
        dir = g_dir_open (path, 0, error);
        if (!dir) {
@@ -204,7 +203,6 @@ camel_imap_message_cache_new (const gchar *path,
        cache->parts = g_hash_table_new (g_str_hash, g_str_equal);
        cache->cached = g_hash_table_new (NULL, NULL);
        deletes = g_ptr_array_new ();
-       shash = camel_folder_summary_get_hashtable (summary);
 
        while ((dname = g_dir_read_name (dir))) {
                if (!isdigit (dname[0]))
@@ -215,7 +213,7 @@ camel_imap_message_cache_new (const gchar *path,
                else
                        uid = g_strdup (dname);
 
-               if (g_hash_table_lookup (shash, uid))
+               if (camel_folder_summary_check_uid (summary, uid))
                        cache_put (cache, uid, dname, NULL);
                else
                        g_ptr_array_add (deletes, g_strdup_printf ("%s/%s", cache->path, dname));
@@ -231,8 +229,6 @@ camel_imap_message_cache_new (const gchar *path,
        }
        g_ptr_array_free (deletes, TRUE);
 
-       camel_folder_summary_free_hashtable (shash);
-
        return cache;
 }
 
index 4aa299a..7838b1c 100644 (file)
@@ -1654,19 +1654,24 @@ static gboolean
 imap_summary_is_dirty (CamelFolderSummary *summary)
 {
        CamelImapMessageInfo *info;
-       gint max, i;
-       gint found = FALSE;
+       gint i;
+       gboolean found = FALSE;
+       GPtrArray *known_uids;
+
+       known_uids = camel_folder_summary_get_array (summary);
+       g_return_val_if_fail (known_uids != NULL, FALSE);
 
-       max = camel_folder_summary_count (summary);
-       for (i = 0; i < max && !found; i++) {
-               info = (CamelImapMessageInfo *) camel_folder_summary_index (summary, i);
+       for (i = 0; i < known_uids->len && !found; i++) {
+               info = (CamelImapMessageInfo *) camel_folder_summary_get (summary, g_ptr_array_index (known_uids, i));
                if (info) {
                        found = info->info.flags & CAMEL_MESSAGE_FOLDER_FLAGGED;
                        camel_message_info_free (info);
                }
        }
 
-       return FALSE;
+       camel_folder_summary_free_array (known_uids);
+
+       return found;
 }
 
 static gboolean
@@ -2878,8 +2883,8 @@ fill_fi (CamelStore *store,
                else
                        ims = (CamelImapSummary *) camel_imap_summary_new (folder, NULL);
 
-               fi->unread = ((CamelFolderSummary *) ims)->unread_count;
-               fi->total = ((CamelFolderSummary *) ims)->saved_count;
+               fi->unread = camel_folder_summary_get_unread_count ((CamelFolderSummary *) ims);
+               fi->total = camel_folder_summary_get_saved_count ((CamelFolderSummary *) ims);
 
                if (!folder->summary)
                        g_object_unref (ims);
@@ -3172,27 +3177,6 @@ get_folder_info_offline (CamelStore *store,
        return fi;
 }
 
-#if 0
-static gboolean
-folder_flags_have_changed (CamelFolder *folder)
-{
-       CamelMessageInfo *info;
-       gint i, max;
-
-       max = camel_folder_summary_count (folder->summary);
-       for (i = 0; i < max; i++) {
-               info = camel_folder_summary_index (folder->summary, i);
-               if (!info)
-                       continue;
-               if (info->flags & CAMEL_MESSAGE_FOLDER_FLAGGED) {
-                       return TRUE;
-               }
-       }
-
-       return FALSE;
-}
-#endif
-
 /* Use this whenever you need to ensure you're both connected and
  * online. */
 gboolean
index c1098dc..fc32104 100644 (file)
@@ -43,11 +43,11 @@ static CamelMessageInfo *message_info_migrate (CamelFolderSummary *s, FILE *in);
 static gboolean info_set_user_flag (CamelMessageInfo *info, const gchar *id, gboolean state);
 static CamelMessageContentInfo *content_info_migrate (CamelFolderSummary *s, FILE *in);
 
-static gint summary_header_from_db (CamelFolderSummary *s, CamelFIRecord *mir);
+static gboolean summary_header_from_db (CamelFolderSummary *s, CamelFIRecord *mir);
 static CamelFIRecord * summary_header_to_db (CamelFolderSummary *s, GError **error);
 static CamelMIRecord * message_info_to_db (CamelFolderSummary *s, CamelMessageInfo *info);
 static CamelMessageInfo * message_info_from_db (CamelFolderSummary *s, CamelMIRecord *mir);
-static gint content_info_to_db (CamelFolderSummary *s, CamelMessageContentInfo *info, CamelMIRecord *mir);
+static gboolean content_info_to_db (CamelFolderSummary *s, CamelMessageContentInfo *info, CamelMIRecord *mir);
 static CamelMessageContentInfo * content_info_from_db (CamelFolderSummary *s, CamelMIRecord *mir);
 
 G_DEFINE_TYPE (CamelImapSummary, camel_imap_summary, CAMEL_TYPE_FOLDER_SUMMARY)
@@ -123,23 +123,6 @@ sort_uid_cmp (gpointer enc,
        return (a1 < a1) ? -1 : (a1 > a2) ? 1 : 0;
 }
 
-static gint
-uid_compare (gconstpointer va,
-             gconstpointer vb)
-{
-       const gchar **sa = (const gchar **) va, **sb = (const gchar **) vb;
-       gulong a, b;
-
-       a = strtoul (*sa, NULL, 10);
-       b = strtoul (*sb, NULL, 10);
-       if (a < b)
-               return -1;
-       else if (a == b)
-               return 0;
-       else
-               return 1;
-}
-
 /**
  * camel_imap_summary_new:
  * @folder: Parent folder.
@@ -159,8 +142,8 @@ camel_imap_summary_new (CamelFolder *folder,
 
        parent_store = camel_folder_get_parent_store (folder);
 
-       summary = g_object_new (CAMEL_TYPE_IMAP_SUMMARY, NULL);
-       summary->folder = folder;
+       summary = g_object_new (CAMEL_TYPE_IMAP_SUMMARY, "folder", folder, NULL);
+
        /* Don't do DB sort. Its pretty slow to load */
        if (folder && 0) {
                camel_db_set_collate (
@@ -173,27 +156,25 @@ camel_imap_summary_new (CamelFolder *folder,
        camel_folder_summary_set_build_content (summary, TRUE);
        camel_folder_summary_set_filename (summary, filename);
 
-       if (camel_folder_summary_load_from_db (summary, NULL) == -1) {
+       if (!camel_folder_summary_load_from_db (summary, NULL)) {
                /* FIXME: Isn't this dangerous ? We clear the summary
                if it cannot be loaded, for some random reason.
                We need to pass the ex and find out why it is not loaded etc. ? */
-               camel_folder_summary_clear_db (summary);
+               camel_folder_summary_clear (summary, NULL);
        }
 
-       g_ptr_array_sort (summary->uids, (GCompareFunc) uid_compare);
-
        return summary;
 }
 
-static gint
+static gboolean
 summary_header_from_db (CamelFolderSummary *s,
                         CamelFIRecord *mir)
 {
        CamelImapSummary *ims = CAMEL_IMAP_SUMMARY (s);
        gchar *part;
 
-       if (CAMEL_FOLDER_SUMMARY_CLASS (camel_imap_summary_parent_class)->summary_header_from_db (s, mir) == -1)
-               return -1;
+       if (!CAMEL_FOLDER_SUMMARY_CLASS (camel_imap_summary_parent_class)->summary_header_from_db (s, mir))
+               return FALSE;
 
        part = mir->bdata;
 
@@ -203,10 +184,10 @@ summary_header_from_db (CamelFolderSummary *s,
        if (ims->version > CAMEL_IMAP_SUMMARY_VERSION) {
                g_warning("Unkown summary version\n");
                errno = EINVAL;
-               return -1;
+               return FALSE;
        }
 
-       return 0;
+       return TRUE;
 }
 
 static gint
@@ -375,7 +356,7 @@ content_info_migrate (CamelFolderSummary *s,
                return camel_folder_summary_content_info_new (s);
 }
 
-static gint
+static gboolean
 content_info_to_db (CamelFolderSummary *s,
                     CamelMessageContentInfo *info,
                     CamelMIRecord *mir)
@@ -390,7 +371,7 @@ content_info_to_db (CamelFolderSummary *s,
                oldr = mir->cinfo;
                mir->cinfo = oldr ? g_strdup_printf("%s 0", oldr) : g_strdup ("0");
                g_free (oldr);
-               return 0;
+               return TRUE;
        }
 }
 
index 5c47f3a..de74c6c 100644 (file)
@@ -1187,15 +1187,18 @@ imap_quote_string (const gchar *str)
 }
 
 static inline gulong
-get_summary_uid_numeric (CamelFolderSummary *summary,
+get_summary_uid_numeric (GPtrArray *known_uids,
                          gint index)
 {
        gulong uid;
-       gchar *suid;
+       const gchar *suid;
 
-       suid = camel_folder_summary_uid_from_index (summary, index);
+       g_return_val_if_fail (known_uids != NULL, 0);
+       g_return_val_if_fail (index >= 0, 0);
+       g_return_val_if_fail (index < known_uids->len, 0);
+
+       suid = g_ptr_array_index (known_uids, index);
        uid = strtoul (suid, NULL, 10);
-       g_free (suid);
 
        return uid;
 }
@@ -1235,20 +1238,26 @@ imap_uid_array_to_set (CamelFolderSummary *summary,
        gint si, scount;
        GString *gset;
        gchar *set;
+       GPtrArray *known_uids;
 
        g_return_val_if_fail (uids->len > uid, NULL);
 
+       known_uids = camel_folder_summary_get_array (summary);
+       g_return_val_if_fail (known_uids != NULL, NULL);
+
+       camel_folder_sort_uids (camel_folder_summary_get_folder (summary), known_uids);
+
        gset = g_string_new (uids->pdata[uid]);
        last_uid = strtoul (uids->pdata[uid], NULL, 10);
        next_summary_uid = 0;
-       scount = camel_folder_summary_count (summary);
+       scount = known_uids->len;
 
        for (uid++, si = 0; uid < uids->len && !UID_SET_FULL (gset->len, maxlen); uid++) {
                /* Find the next UID in the summary after the one we
                 * just wrote out.
                 */
                for (; last_uid >= next_summary_uid && si < scount; si++)
-                       next_summary_uid = get_summary_uid_numeric (summary, si);
+                       next_summary_uid = get_summary_uid_numeric (known_uids, si);
                if (last_uid >= next_summary_uid)
                        next_summary_uid = (gulong) -1;
 
@@ -1274,6 +1283,7 @@ imap_uid_array_to_set (CamelFolderSummary *summary,
 
        set = gset->str;
        g_string_free (gset, FALSE);
+       camel_folder_summary_free_array (known_uids);
 
        return set;
 }
@@ -1299,10 +1309,15 @@ imap_uid_set_to_array (CamelFolderSummary *summary,
                        const gchar *uids)
 {
        GPtrArray *arr;
+       GPtrArray *known_uids;
        gchar *p, *q;
        gulong uid, suid;
        gint si, scount;
 
+       known_uids = camel_folder_summary_get_array (summary);
+       g_return_val_if_fail (known_uids != NULL, NULL);
+
+       camel_folder_sort_uids (camel_folder_summary_get_folder (summary), known_uids);
        arr = g_ptr_array_new ();
        scount = camel_folder_summary_count (summary);
 
@@ -1319,7 +1334,7 @@ imap_uid_set_to_array (CamelFolderSummary *summary,
                         * we just saw.
                         */
                        while (++si < scount) {
-                               suid = get_summary_uid_numeric (summary, si);
+                               suid = get_summary_uid_numeric (known_uids, si);
                                if (suid > uid)
                                        break;
                        }
@@ -1336,7 +1351,7 @@ imap_uid_set_to_array (CamelFolderSummary *summary,
                        while (suid <= uid) {
                                g_ptr_array_add (arr, g_strdup_printf ("%lu", suid));
                                if (++si < scount)
-                                       suid = get_summary_uid_numeric (summary, si);
+                                       suid = get_summary_uid_numeric (known_uids, si);
                                else
                                        suid++;
                        }
@@ -1344,10 +1359,12 @@ imap_uid_set_to_array (CamelFolderSummary *summary,
                        p = q;
        } while (*p++ == ',');
 
+       camel_folder_summary_free_array (known_uids);
        return arr;
 
  lose:
        g_warning ("Invalid uid set %s", uids);
+       camel_folder_summary_free_array (known_uids);
        imap_uid_array_free (arr);
        return NULL;
 }
index 11c3cec..bffcb00 100644 (file)
@@ -125,6 +125,10 @@ camel_imapx_folder_new (CamelStore *store,
 
        g_free (summary_file);
 
+       camel_store_summary_connect_folder_summary (
+               (CamelStoreSummary *) ((CamelIMAPXStore *) store)->summary,
+               folder_name, folder->summary);
+
        return folder;
 }
 
@@ -132,6 +136,7 @@ static void
 imapx_folder_dispose (GObject *object)
 {
        CamelIMAPXFolder *folder = CAMEL_IMAPX_FOLDER (object);
+       CamelStore *parent_store;
 
        if (folder->cache != NULL) {
                g_object_unref (folder->cache);
@@ -143,6 +148,13 @@ imapx_folder_dispose (GObject *object)
                folder->search = NULL;
        }
 
+       parent_store = camel_folder_get_parent_store (CAMEL_FOLDER (folder));
+       if (parent_store) {
+               camel_store_summary_disconnect_folder_summary (
+                       (CamelStoreSummary *) ((CamelIMAPXStore *) parent_store)->summary,
+                       CAMEL_FOLDER (folder)->summary);
+       }
+
        /* Chain up to parent's dispose() method. */
        G_OBJECT_CLASS (camel_imapx_folder_parent_class)->dispose (object);
 }
index a1caa17..430d6f1 100644 (file)
@@ -1252,7 +1252,6 @@ imapx_expunge_uid_from_summary (CamelIMAPXServer *imap,
                                 gchar *uid,
                                 gboolean unsolicited)
 {
-       CamelMessageInfo *mi;
        CamelIMAPXFolder *ifolder = (CamelIMAPXFolder *) imap->select_folder;
 
        if (unsolicited && ifolder->exists_on_server)
@@ -1261,13 +1260,7 @@ imapx_expunge_uid_from_summary (CamelIMAPXServer *imap,
        if (imap->changes == NULL)
                imap->changes = camel_folder_change_info_new ();
 
-       mi = camel_folder_summary_uid (imap->select_folder->summary, uid);
-       if (mi) {
-               imapx_update_summary_for_removed_message (mi, imap->select_folder, unsolicited);
-               camel_message_info_free (mi);
-       }
-
-       camel_folder_summary_remove_uid_fast (imap->select_folder->summary, uid);
+       camel_folder_summary_remove_uid (imap->select_folder->summary, uid);
        imap->expunged = g_list_prepend (imap->expunged, uid);
 
        camel_folder_change_info_remove_uid (imap->changes, uid);
@@ -1287,6 +1280,27 @@ imapx_expunge_uid_from_summary (CamelIMAPXServer *imap,
        }
 }
 
+static gchar *
+imapx_get_uid_from_index (CamelFolderSummary *summary, guint id)
+{
+       GPtrArray *array;
+       gchar *uid;
+
+       g_return_val_if_fail (summary != NULL, NULL);
+
+       array = camel_folder_summary_get_array (summary);
+       g_return_val_if_fail (array != NULL, NULL);
+
+       if (id < array->len) {
+               camel_folder_sort_uids (camel_folder_summary_get_folder (summary), array);
+               uid = g_strdup (g_ptr_array_index (array, id));
+       }
+
+       camel_folder_summary_free_array (array);
+
+       return uid;
+}
+
 static void
 invalidate_local_cache (CamelIMAPXFolder *ifolder,
                         guint64 new_uidvalidity)
@@ -1303,7 +1317,7 @@ invalidate_local_cache (CamelIMAPXFolder *ifolder,
 
        changes = camel_folder_change_info_new ();
 
-       uids = camel_folder_summary_array (cfolder->summary);
+       uids = camel_folder_summary_get_array (cfolder->summary);
        for (ii = 0; uids && ii < uids->len; ii++) {
                const gchar *uid = uids->pdata[ii];
 
@@ -1311,8 +1325,7 @@ invalidate_local_cache (CamelIMAPXFolder *ifolder,
                        camel_folder_change_info_change_uid (changes, uid);
        }
 
-       g_ptr_array_foreach (uids, (GFunc) camel_pstring_free, NULL);
-       g_ptr_array_free (uids, TRUE);
+       camel_folder_summary_free_array (uids);
 
        CAMEL_IMAPX_SUMMARY (cfolder->summary)->validity = new_uidvalidity;
        camel_folder_summary_touch (cfolder->summary);
@@ -1392,11 +1405,12 @@ imapx_untagged (CamelIMAPXServer *imap,
                if (imap->select_folder) {
                        gchar *uid = NULL;
 
-                       uid = camel_folder_summary_uid_from_index (imap->select_folder->summary, expunge - 1);
+                       uid = imapx_get_uid_from_index (imap->select_folder->summary, expunge - 1);
                        if (!uid)
                                break;
 
                        imapx_expunge_uid_from_summary (imap, uid, TRUE);
+                       g_free (uid);
                }
 
                break;
@@ -1534,11 +1548,11 @@ imapx_untagged (CamelIMAPXServer *imap,
                                        uid = finfo->uid;
                                        finfo->uid = NULL;
                                } else {
-                                       uid = camel_folder_summary_uid_from_index (folder->summary, id - 1);
+                                       uid = imapx_get_uid_from_index (folder->summary, id - 1);
                                }
 
                                if (uid) {
-                                       mi = camel_folder_summary_uid (folder->summary, uid);
+                                       mi = camel_folder_summary_get (folder->summary, uid);
                                        if (mi) {
                                                /* It's unsolicited _unless_ imap->select_pending (i.e. during
                                                 * a QRESYNC SELECT */
@@ -2744,8 +2758,8 @@ imapx_select (CamelIMAPXServer *is,
 
                if (total && isum->modseq && ifolder->uidvalidity_on_server) {
 
-                       firstuid = camel_folder_summary_uid_from_index (folder->summary, 0);
-                       lastuid = camel_folder_summary_uid_from_index (folder->summary, total - 1);
+                       firstuid = imapx_get_uid_from_index (folder->summary, 0);
+                       lastuid = imapx_get_uid_from_index (folder->summary, total - 1);
 
                        c(is->tagprefix, "SELECT QRESYNC %" G_GUINT64_FORMAT
                          " %" G_GUINT64_FORMAT "\n",
@@ -2790,7 +2804,7 @@ imapx_select (CamelIMAPXServer *is,
                                         * the summary starts from zero. */
                                        sprintf(buf, "%d", total - i + 1);
                                        g_string_prepend (seqs, buf);
-                                       uid = camel_folder_summary_uid_from_index (folder->summary, total - i);
+                                       uid = imapx_get_uid_from_index (folder->summary, total - i);
                                        g_string_prepend (uids, uid);
                                        g_free (uid);
                                } while (i < total);
@@ -3757,7 +3771,7 @@ imapx_index_next (GPtrArray *uids,
                if (index >= uids->len)
                        break;
 
-               info = camel_folder_summary_uid (s, g_ptr_array_index (uids, index));
+               info = camel_folder_summary_get (s, g_ptr_array_index (uids, index));
                if (!info)
                        continue;
 
@@ -3831,8 +3845,8 @@ imapx_command_step_fetch_done (CamelIMAPXServer *is,
        }
 
        if (camel_folder_summary_count (job->folder->summary)) {
-               gchar *uid = camel_folder_summary_uid_from_index (job->folder->summary,
-                                                 camel_folder_summary_count (job->folder->summary) - 1);
+               gchar *uid = imapx_get_uid_from_index (job->folder->summary,
+                                                      camel_folder_summary_count (job->folder->summary) - 1);
                guint64 uidl = strtoull (uid, NULL, 10);
                g_free (uid);
 
@@ -3930,13 +3944,13 @@ imapx_job_scan_changes_done (CamelIMAPXServer *is,
                 * for all outstanding messages to be uploaded */
 
                /* obtain a copy to be thread safe */
-               uids = camel_folder_summary_array (s);
+               uids = camel_folder_summary_get_array (s);
 
                qsort (infos->data, infos->len, sizeof (struct _refresh_info), imapx_refresh_info_cmp);
                g_ptr_array_sort (uids, (GCompareFunc) imapx_uids_array_cmp);
 
                if (uids->len)
-                       s_minfo = camel_folder_summary_uid (s, g_ptr_array_index (uids, 0));
+                       s_minfo = camel_folder_summary_get (s, g_ptr_array_index (uids, 0));
 
                for (i = 0; i < infos->len; i++) {
                        struct _refresh_info *r = &g_array_index (infos, struct _refresh_info, i);
@@ -3951,7 +3965,7 @@ imapx_job_scan_changes_done (CamelIMAPXServer *is,
 
                                j = imapx_index_next (uids, s, j);
                                if (j < uids->len)
-                                       s_minfo = camel_folder_summary_uid (s, g_ptr_array_index (uids, j));
+                                       s_minfo = camel_folder_summary_get (s, g_ptr_array_index (uids, j));
                        }
 
                        info = NULL;
@@ -3974,14 +3988,14 @@ imapx_job_scan_changes_done (CamelIMAPXServer *is,
 
                        j = imapx_index_next (uids, s, j);
                        if (j < uids->len)
-                               s_minfo = camel_folder_summary_uid (s, g_ptr_array_index (uids, j));
+                               s_minfo = camel_folder_summary_get (s, g_ptr_array_index (uids, j));
                }
 
                if (s_minfo)
                        camel_message_info_free (s_minfo);
 
                while (j < uids->len) {
-                       s_minfo = camel_folder_summary_uid (s, g_ptr_array_index (uids, j));
+                       s_minfo = camel_folder_summary_get (s, g_ptr_array_index (uids, j));
 
                        if (!s_minfo) {
                                j++;
@@ -3996,22 +4010,15 @@ imapx_job_scan_changes_done (CamelIMAPXServer *is,
 
                for (l = removed; l != NULL; l = g_list_next (l)) {
                        gchar *uid = (gchar *) l->data;
-                       CamelMessageInfo *mi;
-
-                       mi = camel_folder_summary_uid (job->folder->summary, uid);
-                       if (mi) {
-                               imapx_update_summary_for_removed_message (mi, job->folder, FALSE);
-                               camel_message_info_free (mi);
-                       }
 
                        camel_folder_change_info_remove_uid (job->u.refresh_info.changes, uid);
-                       camel_folder_summary_remove_uid_fast (s, uid);
+                       camel_folder_summary_remove_uid (s, uid);
                }
 
                if (removed) {
                        const gchar *full_name;
 
-                       full_name = camel_folder_get_full_name (s->folder);
+                       full_name = camel_folder_get_full_name (camel_folder_summary_get_folder (s));
                        camel_db_delete_uids (is->store->cdb_w, full_name, removed, NULL);
                        g_list_foreach (removed, (GFunc) g_free, NULL);
                        g_list_free (removed);
@@ -4023,7 +4030,7 @@ imapx_job_scan_changes_done (CamelIMAPXServer *is,
                        camel_folder_changed (job->folder, job->u.refresh_info.changes);
                camel_folder_change_info_clear (job->u.refresh_info.changes);
 
-               camel_folder_free_uids (job->folder, uids);
+               camel_folder_summary_free_array (uids);
 
                /* If we have any new messages, download their headers, but only a few (100?) at a time */
                if (fetch_new) {
@@ -4056,7 +4063,7 @@ imapx_job_scan_changes_done (CamelIMAPXServer *is,
 
        /* There's no sane way to get the server-side unseen count on the
         * select mailbox. So just work it out from the flags */
-       ((CamelIMAPXFolder *) job->folder)->unread_on_server = job->folder->summary->unread_count;
+       ((CamelIMAPXFolder *) job->folder)->unread_on_server = camel_folder_summary_get_unread_count (job->folder->summary);
 
        g_array_free (job->u.refresh_info.infos, TRUE);
        imapx_job_done (is, job);
@@ -4108,8 +4115,8 @@ imapx_command_fetch_new_messages_done (CamelIMAPXServer *is,
        }
 
        if (camel_folder_summary_count (ic->job->folder->summary)) {
-               gchar *uid = camel_folder_summary_uid_from_index (ic->job->folder->summary,
-                                         camel_folder_summary_count (ic->job->folder->summary) - 1);
+               gchar *uid = imapx_get_uid_from_index (ic->job->folder->summary,
+                                                      camel_folder_summary_count (ic->job->folder->summary) - 1);
                guint64 uidl = strtoull (uid, NULL, 10);
                g_free (uid);
 
@@ -4170,7 +4177,7 @@ imapx_job_fetch_new_messages_start (CamelIMAPXServer *is,
 
        if (total > 0) {
                guint64 uidl;
-               uid = camel_folder_summary_uid_from_index (folder->summary, total - 1);
+               uid = imapx_get_uid_from_index (folder->summary, total - 1);
                uidl = strtoull (uid, NULL, 10);
                g_free (uid);
                uid = g_strdup_printf ("%" G_GUINT64_FORMAT, uidl+1);
@@ -4250,7 +4257,7 @@ imapx_job_refresh_info_start (CamelIMAPXServer *is,
         * message flags, but don't depend on modseq for the selected folder */
        if (total != ifolder->exists_on_server ||
            isum->uidnext != ifolder->uidnext_on_server ||
-           folder->summary->unread_count != ifolder->unread_on_server ||
+           camel_folder_summary_get_unread_count (folder->summary) != ifolder->unread_on_server ||
            (!is_selected && isum->modseq != ifolder->modseq_on_server))
                need_rescan = TRUE;
 
@@ -4309,7 +4316,7 @@ imapx_job_refresh_info_start (CamelIMAPXServer *is,
                /* Recalulate need_rescan */
                if (total != ifolder->exists_on_server ||
                    isum->uidnext != ifolder->uidnext_on_server ||
-                   folder->summary->unread_count != ifolder->unread_on_server ||
+                   camel_folder_summary_get_unread_count (folder->summary) != ifolder->unread_on_server ||
                    (!is_selected && isum->modseq != ifolder->modseq_on_server))
                        need_rescan = TRUE;
 
@@ -4320,7 +4327,7 @@ imapx_job_refresh_info_start (CamelIMAPXServer *is,
 
        e(is->tagprefix, "folder %s is %sselected, total %u / %u, unread %u / %u, modseq %" G_GUINT64_FORMAT " / %" G_GUINT64_FORMAT ", uidnext %u / %u: will %srescan\n",
          full_name, is_selected?"": "not ", total, ifolder->exists_on_server,
-         folder->summary->unread_count, ifolder->unread_on_server,
+         camel_folder_summary_get_unread_count (folder->summary), ifolder->unread_on_server,
          (guint64) isum->modseq, (guint64) ifolder->modseq_on_server,
          isum->uidnext, ifolder->uidnext_on_server,
          need_rescan?"":"not ");
@@ -4352,16 +4359,16 @@ imapx_job_refresh_info_start (CamelIMAPXServer *is,
                isum->modseq = ifolder->modseq_on_server;
                total = camel_folder_summary_count (job->folder->summary);
                if (total != ifolder->exists_on_server ||
-                   folder->summary->unread_count != ifolder->unread_on_server ||
+                   camel_folder_summary_get_unread_count (folder->summary) != ifolder->unread_on_server ||
                    (isum->modseq != ifolder->modseq_on_server)) {
                        c(is->tagprefix, "Eep, after QRESYNC we're out of sync. total %u / %u, unread %u / %u, modseq %" G_GUINT64_FORMAT " / %" G_GUINT64_FORMAT "\n",
                          total, ifolder->exists_on_server,
-                         folder->summary->unread_count, ifolder->unread_on_server,
+                         camel_folder_summary_get_unread_count (folder->summary), ifolder->unread_on_server,
                          isum->modseq, ifolder->modseq_on_server);
                } else {
                        c(is->tagprefix, "OK, after QRESYNC we're still in sync. total %u / %u, unread %u / %u, modseq %" G_GUINT64_FORMAT " / %" G_GUINT64_FORMAT "\n",
                          total, ifolder->exists_on_server,
-                         folder->summary->unread_count, ifolder->unread_on_server,
+                         camel_folder_summary_get_unread_count (folder->summary), ifolder->unread_on_server,
                          isum->modseq, ifolder->modseq_on_server);
                        goto done;
                }
@@ -4402,14 +4409,8 @@ imapx_command_expunge_done (CamelIMAPXServer *is,
                        changes = camel_folder_change_info_new ();
                        for (i = 0; i < uids->len; i++) {
                                gchar *uid = uids->pdata[i];
-                               CamelMessageInfo *mi = camel_folder_summary_uid (folder->summary, uid);
-
-                               if (mi) {
-                                       imapx_update_summary_for_removed_message (mi, folder, FALSE);
-                                       camel_message_info_free (mi);
-                               }
 
-                               camel_folder_summary_remove_uid_fast (folder->summary, uid);
+                               camel_folder_summary_remove_uid (folder->summary, uid);
                                camel_folder_change_info_remove_uid (changes, uids->pdata[i]);
                                removed = g_list_prepend (removed, (gpointer) uids->pdata[i]);
                        }
@@ -4753,7 +4754,7 @@ imapx_command_sync_changes_done (CamelIMAPXServer *is,
                gint i;
 
                for (i = 0; i < job->u.sync_changes.changed_uids->len; i++) {
-                       CamelIMAPXMessageInfo *xinfo = (CamelIMAPXMessageInfo *) camel_folder_summary_uid (job->folder->summary,
+                       CamelIMAPXMessageInfo *xinfo = (CamelIMAPXMessageInfo *) camel_folder_summary_get (job->folder->summary,
                                        job->u.sync_changes.changed_uids->pdata[i]);
 
                        if (!xinfo)
@@ -4779,9 +4780,10 @@ imapx_command_sync_changes_done (CamelIMAPXServer *is,
                        /* ... and store's summary when folder's summary is dirty */
                        si = camel_store_summary_path ((CamelStoreSummary *)((CamelIMAPXStore *) parent_store)->summary, full_name);
                        if (si) {
-                               if (si->total != job->folder->summary->saved_count || si->unread != job->folder->summary->unread_count) {
-                                       si->total = job->folder->summary->saved_count;
-                                       si->unread = job->folder->summary->unread_count;
+                               if (si->total != camel_folder_summary_get_saved_count (job->folder->summary) ||
+                                   si->unread != camel_folder_summary_get_unread_count (job->folder->summary)) {
+                                       si->total = camel_folder_summary_get_saved_count (job->folder->summary);
+                                       si->unread = camel_folder_summary_get_unread_count (job->folder->summary);
                                        camel_store_summary_touch ((CamelStoreSummary *)((CamelIMAPXStore *) parent_store)->summary);
                                }
 
@@ -4820,7 +4822,7 @@ imapx_job_sync_changes_start (CamelIMAPXServer *is,
                        c(is->tagprefix, "checking/storing %s flags '%s'\n", on?"on":"off", flags_table[j].name);
                        imapx_uidset_init (&ss, 0, 100);
                        for (i = 0; i < uids->len; i++) {
-                               CamelIMAPXMessageInfo *info = (CamelIMAPXMessageInfo *) camel_folder_summary_uid
+                               CamelIMAPXMessageInfo *info = (CamelIMAPXMessageInfo *) camel_folder_summary_get
                                                                                (job->folder->summary, uids->pdata[i]);
                                guint32 flags;
                                guint32 sflags;
@@ -5348,7 +5350,7 @@ imapx_server_get_message (CamelIMAPXServer *is,
                return stream;
        }
 
-       mi = camel_folder_summary_uid (folder->summary, uid);
+       mi = camel_folder_summary_get (folder->summary, uid);
        if (!mi) {
                g_set_error (
                        error, CAMEL_FOLDER_ERROR,
@@ -5678,7 +5680,7 @@ imapx_server_sync_changes (CamelIMAPXServer *is,
                CamelFlag *uflags, *suflags;
                guint j = 0;
 
-               info = (CamelIMAPXMessageInfo *) camel_folder_summary_uid (folder->summary, uids->pdata[i]);
+               info = (CamelIMAPXMessageInfo *) camel_folder_summary_get (folder->summary, uids->pdata[i]);
 
                if (!info)
                        continue;
index 3f749c3..c9216d6 100644 (file)
@@ -367,8 +367,8 @@ fill_fi (CamelStore *store,
                else
                        ims = (CamelIMAPXSummary *) camel_imapx_summary_new (folder, NULL);
 
-               fi->unread = ((CamelFolderSummary *) ims)->unread_count;
-               fi->total = ((CamelFolderSummary *) ims)->saved_count;
+               fi->unread = camel_folder_summary_get_unread_count ((CamelFolderSummary *) ims);
+               fi->total = camel_folder_summary_get_saved_count ((CamelFolderSummary *) ims);
 
                if (!folder->summary)
                        g_object_unref (ims);
index a135101..874cd45 100644 (file)
@@ -42,11 +42,11 @@ static CamelMessageInfo *message_info_migrate (CamelFolderSummary *s, FILE *in);
 static gboolean info_set_user_flag (CamelMessageInfo *info, const gchar *id, gboolean state);
 static CamelMessageContentInfo *content_info_migrate (CamelFolderSummary *s, FILE *in);
 
-static gint summary_header_from_db (CamelFolderSummary *s, CamelFIRecord *mir);
+static gboolean summary_header_from_db (CamelFolderSummary *s, CamelFIRecord *mir);
 static CamelFIRecord * summary_header_to_db (CamelFolderSummary *s, GError **error);
 static CamelMIRecord * message_info_to_db (CamelFolderSummary *s, CamelMessageInfo *info);
 static CamelMessageInfo * message_info_from_db (CamelFolderSummary *s, CamelMIRecord *mir);
-static gint content_info_to_db (CamelFolderSummary *s, CamelMessageContentInfo *info, CamelMIRecord *mir);
+static gboolean content_info_to_db (CamelFolderSummary *s, CamelMessageContentInfo *info, CamelMIRecord *mir);
 static CamelMessageContentInfo * content_info_from_db (CamelFolderSummary *s, CamelMIRecord *mir);
 
 G_DEFINE_TYPE (CamelIMAPXSummary, camel_imapx_summary, CAMEL_TYPE_FOLDER_SUMMARY)
@@ -127,23 +127,6 @@ sort_uid_cmp (gpointer enc,
        return (a1 < a1) ? -1 : (a1 > a2) ? 1 : 0;
 }
 
-static gint
-uid_compare (gconstpointer va,
-             gconstpointer vb)
-{
-       const gchar **sa = (const gchar **) va, **sb = (const gchar **) vb;
-       gulong a, b;
-
-       a = strtoul (*sa, NULL, 10);
-       b = strtoul (*sb, NULL, 10);
-       if (a < b)
-               return -1;
-       else if (a == b)
-               return 0;
-       else
-               return 1;
-}
-
 /**
  * camel_imapx_summary_new:
  * @folder: Parent folder.
@@ -164,9 +147,8 @@ camel_imapx_summary_new (CamelFolder *folder,
 
        parent_store = camel_folder_get_parent_store (folder);
 
-       summary = g_object_new (CAMEL_TYPE_IMAPX_SUMMARY, NULL);
+       summary = g_object_new (CAMEL_TYPE_IMAPX_SUMMARY, "folder", folder, NULL);
 
-       summary->folder = folder;
        /* Don't do DB sort. Its pretty slow to load */
        if (folder && 0) {
                camel_db_set_collate (parent_store->cdb_r, "uid", "imapx_uid_sort", (CamelDBCollate)sort_uid_cmp);
@@ -177,21 +159,19 @@ camel_imapx_summary_new (CamelFolder *folder,
        camel_folder_summary_set_build_content (summary, TRUE);
        camel_folder_summary_set_filename (summary, filename);
 
-       if (camel_folder_summary_load_from_db (summary, &local_error) == -1) {
+       if (!camel_folder_summary_load_from_db (summary, &local_error)) {
                /* FIXME: Isn't this dangerous ? We clear the summary
                if it cannot be loaded, for some random reason.
                We need to pass the error and find out why it is not loaded etc. ? */
-               camel_folder_summary_clear_db (summary);
+               camel_folder_summary_clear (summary, NULL);
                g_message ("Unable to load summary: %s\n", local_error->message);
                g_clear_error (&local_error);
        }
 
-       g_ptr_array_sort (summary->uids, (GCompareFunc) uid_compare);
-
        return summary;
 }
 
-static gint
+static gboolean
 summary_header_from_db (CamelFolderSummary *s,
                         CamelFIRecord *mir)
 {
@@ -202,8 +182,8 @@ summary_header_from_db (CamelFolderSummary *s,
        folder_summary_class = CAMEL_FOLDER_SUMMARY_CLASS (
                camel_imapx_summary_parent_class);
 
-       if (folder_summary_class->summary_header_from_db (s, mir) == -1)
-               return -1;
+       if (!folder_summary_class->summary_header_from_db (s, mir))
+               return FALSE;
 
        part = mir->bdata;
 
@@ -218,10 +198,10 @@ summary_header_from_db (CamelFolderSummary *s,
        if (ims->version > CAMEL_IMAPX_SUMMARY_VERSION) {
                g_warning("Unknown summary version\n");
                errno = EINVAL;
-               return -1;
+               return FALSE;
        }
 
-       return 0;
+       return TRUE;
 }
 
 static gint
@@ -427,7 +407,7 @@ content_info_migrate (CamelFolderSummary *s,
                return camel_folder_summary_content_info_new (s);
 }
 
-static gint
+static gboolean
 content_info_to_db (CamelFolderSummary *s,
                     CamelMessageContentInfo *info,
                     CamelMIRecord *mir)
@@ -447,7 +427,7 @@ content_info_to_db (CamelFolderSummary *s,
                oldr = mir->cinfo;
                mir->cinfo = oldr ? g_strdup_printf("%s 0", oldr) : g_strdup ("0");
                g_free (oldr);
-               return 0;
+               return TRUE;
        }
 }
 
index 71b3f02..a9cf44c 100644 (file)
@@ -264,13 +264,10 @@ imapx_update_message_info_flags (CamelMessageInfo *info,
                                  gboolean unsolicited)
 {
        gboolean changed = FALSE;
-       CamelIMAPXFolder *ifolder = (CamelIMAPXFolder *) folder;
        CamelIMAPXMessageInfo *xinfo = (CamelIMAPXMessageInfo *) info;
 
-       if (server_flags != xinfo->server_flags)
-       {
+       if (server_flags != xinfo->server_flags) {
                guint32 server_set, server_cleared;
-               gint read = 0, deleted = 0, junk = 0;
 
                server_set = server_flags & ~xinfo->server_flags;
                server_cleared = xinfo->server_flags & ~server_flags;
@@ -281,44 +278,12 @@ imapx_update_message_info_flags (CamelMessageInfo *info,
                if (permanent_flags > 0)
                        server_cleared &= permanent_flags;
 
-               if (server_set & CAMEL_MESSAGE_SEEN)
-                       read = 1;
-               else if (server_cleared & CAMEL_MESSAGE_SEEN)
-                       read = -1;
-
-               if (server_set & CAMEL_MESSAGE_DELETED)
-                       deleted = 1;
-               else if (server_cleared & CAMEL_MESSAGE_DELETED)
-                       deleted = -1;
-
-               if (server_set & CAMEL_MESSAGE_JUNK)
-                       junk = 1;
-               else if (server_cleared & CAMEL_MESSAGE_JUNK)
-                       junk = -1;
-
-               d('?', "%s %s %s %s\n", xinfo->info.uid, read == 1 ? "read" : ( read == -1 ? "unread" : ""),
-                 deleted == 1 ? "deleted" : ( deleted == -1 ? "undeleted" : ""),
-                 junk == 1 ? "junk" : ( junk == -1 ? "unjunked" : ""));
-
-               if (read) {
-                       folder->summary->unread_count -= read;
-                       if (unsolicited)
-                               ifolder->unread_on_server -= read;
-               }
-               if (deleted)
-                       folder->summary->deleted_count += deleted;
-               if (junk)
-                       folder->summary->junk_count += junk;
-               if (junk && !deleted)
-                       folder->summary->junk_not_deleted_count += junk;
-               if (junk ||  deleted)
-                       folder->summary->visible_count -= junk ? junk : deleted;
-
-               xinfo->info.flags = (xinfo->info.flags | server_set) & ~server_cleared;
+               camel_message_info_set_flags ((CamelMessageInfo *) xinfo, server_set | server_cleared, (xinfo->info.flags | server_set) & ~server_cleared);
+
                xinfo->server_flags = server_flags;
+               xinfo->info.flags = xinfo->info.flags & ~CAMEL_MESSAGE_FOLDER_FLAGGED;
                xinfo->info.dirty = TRUE;
-               if (info->summary)
-                       camel_folder_summary_touch (info->summary);
+
                changed = TRUE;
        }
 
@@ -336,85 +301,17 @@ imapx_set_message_info_flags_for_new_message (CamelMessageInfo *info,
 {
        CamelMessageInfoBase *binfo = (CamelMessageInfoBase *) info;
        CamelIMAPXMessageInfo *xinfo = (CamelIMAPXMessageInfo *) info;
-       gint unread = 0, deleted = 0, junk = 0;
-       guint32 flags;
 
        binfo->flags |= server_flags;
+       camel_message_info_set_flags (info, server_flags, binfo->flags | server_flags);
+
        xinfo->server_flags = server_flags;
 
        if (folder->permanent_flags & CAMEL_MESSAGE_USER)
                imapx_update_user_flags (info, server_user_flags);
 
-       /* update the summary count */
-       flags = binfo->flags;
-
-       if (!(flags & CAMEL_MESSAGE_SEEN))
-               unread = 1;
-
-       if (flags & CAMEL_MESSAGE_DELETED)
-               deleted = 1;
-
-       if (flags & CAMEL_MESSAGE_JUNK)
-               junk = 1;
-
-       if (folder->summary) {
-
-               if (unread)
-                       folder->summary->unread_count += unread;
-               if (deleted)
-                       folder->summary->deleted_count += deleted;
-               if (junk)
-                       folder->summary->junk_count += junk;
-               if (junk && !deleted)
-                       folder->summary->junk_not_deleted_count += junk;
-               folder->summary->visible_count++;
-               if (junk ||  deleted)
-                       folder->summary->visible_count -= junk ? junk : deleted;
-
-               folder->summary->saved_count++;
-               camel_folder_summary_touch (folder->summary);
-       }
-
        binfo->flags &= ~CAMEL_MESSAGE_FOLDER_FLAGGED;
-}
-
-void
-imapx_update_summary_for_removed_message (CamelMessageInfo *info,
-                                          CamelFolder *folder,
-                                          gboolean unsolicited)
-{
-       CamelMessageInfoBase *dinfo = (CamelMessageInfoBase *) info;
-       CamelIMAPXFolder *ifolder = (CamelIMAPXFolder *) folder;
-       gint unread = 0, deleted = 0, junk = 0;
-       guint32 flags;
-
-       flags = dinfo->flags;
-       if (!(flags & CAMEL_MESSAGE_SEEN))
-               unread = 1;
-
-       if (flags & CAMEL_MESSAGE_DELETED)
-               deleted = 1;
-
-       if (flags & CAMEL_MESSAGE_JUNK)
-               junk = 1;
-
-       if (unread) {
-               folder->summary->unread_count--;
-               if (unsolicited)
-                       ifolder->unread_on_server--;
-       }
-       if (deleted)
-               folder->summary->deleted_count--;
-       if (junk)
-               folder->summary->junk_count--;
-
-       if (junk && !deleted)
-               folder->summary->junk_not_deleted_count--;
-
-       if (!junk &&  !deleted)
-               folder->summary->visible_count--;
-
-       folder->summary->saved_count--;
+       binfo->dirty = TRUE;
 }
 
 void
@@ -432,7 +329,7 @@ imapx_update_store_summary (CamelFolder *folder)
                guint32 unread, total;
 
                total = camel_folder_summary_count (folder->summary);
-               unread = folder->summary->unread_count;
+               unread = camel_folder_summary_get_unread_count (folder->summary);
 
                if (si->unread != unread || si->total != total) {
                        si->unread = unread;
index 17e4d80..848c01a 100644 (file)
@@ -89,7 +89,6 @@ void imapx_write_flags (CamelStream *stream, guint32 flags, struct _CamelFlag *u
 gboolean imapx_update_message_info_flags (CamelMessageInfo *info, guint32 server_flags, CamelFlag *server_user_flags, guint32 permanent_flags, CamelFolder *folder, gboolean unsolicited);
 void imapx_set_message_info_flags_for_new_message (CamelMessageInfo *info, guint32 server_flags, CamelFlag *server_user_flags,
                                                        CamelFolder *folder);
-void imapx_update_summary_for_removed_message (CamelMessageInfo *info, CamelFolder *folder, gboolean unsolicited);
 void imapx_update_store_summary (CamelFolder *folder);
 
 /* ********************************************************************** */
index e1c9765..5b68f1e 100644 (file)
@@ -608,7 +608,7 @@ camel_local_folder_construct (CamelLocalFolder *lf,
        }
 
        folder->summary = (CamelFolderSummary *) CAMEL_LOCAL_FOLDER_GET_CLASS (lf)->create_summary (lf, lf->summary_path, lf->folder_path, lf->index);
-       if (!(flags & CAMEL_STORE_IS_MIGRATING) && camel_local_summary_load ((CamelLocalSummary *) folder->summary, forceindex, NULL) == -1) {
+       if (!(flags & CAMEL_STORE_IS_MIGRATING) && !camel_local_summary_load ((CamelLocalSummary *) folder->summary, forceindex, NULL)) {
                /* ? */
                if (need_summary_check &&
                    camel_local_summary_check ((CamelLocalSummary *) folder->summary, lf->changes, cancellable, error) == 0) {
index 92eaf00..2575cbb 100644 (file)
@@ -44,7 +44,7 @@
 #define EXTRACT_FIRST_DIGIT(val) val=strtoul (part, &part, 10);
 
 static CamelFIRecord * summary_header_to_db (CamelFolderSummary *, GError **error);
-static gint summary_header_from_db (CamelFolderSummary *, CamelFIRecord *);
+static gboolean summary_header_from_db (CamelFolderSummary *, CamelFIRecord *);
 
 static gint summary_header_load (CamelFolderSummary *, FILE *);
 static gint summary_header_save (CamelFolderSummary *, FILE *);
@@ -144,7 +144,7 @@ camel_local_summary_construct (CamelLocalSummary *new,
                g_object_ref (index);
 }
 
-static gint
+static gboolean
 local_summary_load (CamelLocalSummary *cls,
                     gint forceindex,
                     GError **error)
@@ -154,7 +154,7 @@ local_summary_load (CamelLocalSummary *cls,
 }
 
 /* load/check the summary */
-gint
+gboolean
 camel_local_summary_load (CamelLocalSummary *cls,
                           gint forceindex,
                           GError **error)
@@ -166,13 +166,13 @@ camel_local_summary_load (CamelLocalSummary *cls,
        class = CAMEL_LOCAL_SUMMARY_GET_CLASS (cls);
 
        if ((forceindex && class->need_index ())
-           || class->load (cls, forceindex, error) == -1) {
+           || !class->load (cls, forceindex, error)) {
                w(g_warning("Could not load summary: flags may be reset"));
-               camel_folder_summary_clear ((CamelFolderSummary *) cls);
-               return -1;
+               camel_folder_summary_clear ((CamelFolderSummary *) cls, NULL);
+               return FALSE;
        }
 
-       return 0;
+       return TRUE;
 }
 
 void camel_local_summary_check_force (CamelLocalSummary *cls)
@@ -295,13 +295,16 @@ camel_local_summary_check (CamelLocalSummary *cls,
        if (ret != -1) {
                gint i;
                CamelFolderSummary *s = (CamelFolderSummary *) cls;
+               GPtrArray *known_uids;
                struct _stat_info stats = { 0 };
 
+               known_uids = camel_folder_summary_get_array (s);
                for (i = 0; i < camel_folder_summary_count (s); i++) {
-                       CamelMessageInfo *info = camel_folder_summary_index (s, i);
+                       CamelMessageInfo *info = camel_folder_summary_get (s, g_ptr_array_index (known_uids, i));
                        do_stat_mi (cls, &stats, info);
                        camel_message_info_free (info);
                }
+               camel_folder_summary_free_array (known_uids);
 
                printf("\nMemory used by summary:\n\n");
                printf("Total of %d messages\n", camel_folder_summary_count(s));
@@ -456,7 +459,7 @@ local_summary_sync (CamelLocalSummary *cls,
 
        folder_summary = CAMEL_FOLDER_SUMMARY (cls);
 
-       if (camel_folder_summary_save_to_db (folder_summary, error) == -1) {
+       if (!camel_folder_summary_save_to_db (folder_summary, error)) {
                g_warning ("Could not save summary for local providers");
                return -1;
        }
@@ -475,42 +478,6 @@ local_summary_need_index (void)
        return 1;
 }
 
-static void
-update_summary (CamelFolderSummary *summary,
-                CamelMessageInfoBase *info,
-                CamelMessageInfoBase *old)
-{
-       gint unread = 0, deleted = 0, junk = 0;
-       guint32 flags = info->flags;
-       guint32 oldflags = old->flags;
-
-       if ((flags & CAMEL_MESSAGE_SEEN) != (oldflags & CAMEL_MESSAGE_SEEN))
-               unread = (oldflags & CAMEL_MESSAGE_SEEN) ? 1 : -1;
-
-       if ((flags & CAMEL_MESSAGE_DELETED) != (oldflags & CAMEL_MESSAGE_DELETED))
-               deleted = (oldflags & CAMEL_MESSAGE_DELETED) ? 1 : -1;
-
-       if ((flags & CAMEL_MESSAGE_JUNK) != (oldflags & CAMEL_MESSAGE_JUNK))
-               junk = (oldflags & CAMEL_MESSAGE_JUNK) ? 1 : -1;
-
-       /* Things would already be flagged */
-
-       if (summary) {
-
-               if (unread)
-                       summary->unread_count -= unread;
-               if (deleted)
-                       summary->deleted_count += deleted;
-               if (junk)
-                       summary->junk_count += junk;
-               if (junk && !deleted)
-                       summary->junk_not_deleted_count += junk;
-               if (junk ||  deleted)
-                       summary->visible_count -= junk ? junk : deleted;
-       }
-
-}
-
 static CamelMessageInfo *
 local_summary_add (CamelLocalSummary *cls,
                    CamelMimeMessage *msg,
@@ -519,7 +486,6 @@ local_summary_add (CamelLocalSummary *cls,
                    GError **error)
 {
        CamelLocalMessageInfo *mi;
-       CamelFolderSummary *s = (CamelFolderSummary *) cls;
        gchar *xev;
 
        d(printf("Adding message to summary\n"));
@@ -541,8 +507,7 @@ local_summary_add (CamelLocalSummary *cls,
                                tag = tag->next;
                        }
 
-                       update_summary (s, (CamelMessageInfoBase *) mi, (CamelMessageInfoBase *) info);
-                       mi->info.flags |= (camel_message_info_flags (info) & 0xffff);
+                       camel_message_info_set_flags ((CamelMessageInfo *) mi, 0xffff, camel_message_info_flags (info));
                        mi->info.size = camel_message_info_size (info);
                }
 
@@ -693,7 +658,7 @@ local_summary_decode_x_evolution (CamelLocalSummary *cls,
        return 0;
 }
 
-static gint
+static gboolean
 summary_header_from_db (CamelFolderSummary *s,
                         CamelFIRecord *fir)
 {
@@ -702,8 +667,8 @@ summary_header_from_db (CamelFolderSummary *s,
 
        /* We dont actually add our own headers, but version that we don't anyway */
 
-       if (CAMEL_FOLDER_SUMMARY_CLASS (camel_local_summary_parent_class)->summary_header_from_db (s, fir) == -1)
-               return -1;
+       if (!CAMEL_FOLDER_SUMMARY_CLASS (camel_local_summary_parent_class)->summary_header_from_db (s, fir))
+               return FALSE;
 
        part = fir->bdata;
        if (part) {
@@ -715,7 +680,7 @@ summary_header_from_db (CamelFolderSummary *s,
        g_free (fir->bdata);
        fir->bdata = tmp;
 
-       return 0;
+       return TRUE;
 }
 
 static gint
index ebcb581..9de024d 100644 (file)
@@ -75,7 +75,7 @@ struct _CamelLocalSummary {
 struct _CamelLocalSummaryClass {
        CamelFolderSummaryClass parent_class;
 
-       gint (*load)(CamelLocalSummary *cls, gint forceindex, GError **error);
+       gboolean (*load)(CamelLocalSummary *cls, gint forceindex, GError **error);
        gint (*check)(CamelLocalSummary *cls, CamelFolderChangeInfo *changeinfo, GCancellable *cancellable, GError **error);
        gint (*sync)(CamelLocalSummary *cls, gboolean expunge, CamelFolderChangeInfo *changeinfo, GCancellable *cancellable, GError **error);
        CamelMessageInfo *(*add)(CamelLocalSummary *cls, CamelMimeMessage *msg, const CamelMessageInfo *info, CamelFolderChangeInfo *, GError **error);
@@ -89,7 +89,7 @@ GType camel_local_summary_get_type    (void);
 void   camel_local_summary_construct   (CamelLocalSummary *new, const gchar *filename, const gchar *local_name, CamelIndex *index);
 
 /* load/check the summary */
-gint camel_local_summary_load (CamelLocalSummary *cls, gint forceindex, GError **error);
+gboolean camel_local_summary_load (CamelLocalSummary *cls, gint forceindex, GError **error);
 /* check for new/removed messages */
 gint camel_local_summary_check (CamelLocalSummary *cls, CamelFolderChangeInfo *, GCancellable *cancellable, GError **error);
 /* perform a folder sync or expunge, if needed */
index bbae5c2..7483546 100644 (file)
@@ -54,8 +54,8 @@ maildir_folder_cmp_uids (CamelFolder *folder,
        g_return_val_if_fail (folder != NULL, 0);
        g_return_val_if_fail (folder->summary != NULL, 0);
 
-       a = camel_folder_summary_uid (folder->summary, uid1);
-       b = camel_folder_summary_uid (folder->summary, uid2);
+       a = camel_folder_summary_get (folder->summary, uid1);
+       b = camel_folder_summary_get (folder->summary, uid2);
 
        g_return_val_if_fail (a != NULL, 0);
        g_return_val_if_fail (b != NULL, 0);
@@ -94,7 +94,7 @@ maildir_folder_get_filename (CamelFolder *folder,
        gchar *res;
 
        /* get the message summary info */
-       if ((info = camel_folder_summary_uid (folder->summary, uid)) == NULL) {
+       if ((info = camel_folder_summary_get (folder->summary, uid)) == NULL) {
                set_cannot_get_message_ex (
                        error, CAMEL_FOLDER_ERROR_INVALID_UID,
                        uid, lf->folder_path, _("No such message"));
@@ -327,7 +327,7 @@ maildir_folder_transfer_messages_to_sync (CamelFolder *source,
                        CamelMaildirMessageInfo *mdi;
                        CamelMessageInfo *info;
 
-                       if ((info = camel_folder_summary_uid (source->summary, uid)) == NULL) {
+                       if ((info = camel_folder_summary_get (source->summary, uid)) == NULL) {
                                set_cannot_get_message_ex (
                                        error, CAMEL_FOLDER_ERROR_INVALID_UID,
                                        uid, lf->folder_path, _("No such message"));
index 95bc8bc..3a5a2b0 100644 (file)
@@ -384,9 +384,9 @@ fill_fi (CamelStore *store,
                }
 
                s = (CamelFolderSummary *) camel_maildir_summary_new (NULL, path, folderpath, NULL);
-               if (camel_folder_summary_header_load_from_db (s, store, fi->full_name, NULL) != -1) {
-                       fi->unread = s->unread_count;
-                       fi->total = s->saved_count;
+               if (camel_folder_summary_header_load_from_db (s, store, fi->full_name, NULL)) {
+                       fi->unread = camel_folder_summary_get_unread_count (s);
+                       fi->total = camel_folder_summary_get_saved_count (s);
                }
                g_object_unref (s);
                g_free (folderpath);
index 0024c42..e673df6 100644 (file)
@@ -150,8 +150,7 @@ CamelMaildirSummary
 {
        CamelMaildirSummary *o;
 
-       o = g_object_new (CAMEL_TYPE_MAILDIR_SUMMARY, NULL);
-       ((CamelFolderSummary *) o)->folder = folder;
+       o = g_object_new (CAMEL_TYPE_MAILDIR_SUMMARY, "folder", folder, NULL);
        if (folder) {
                CamelStore *parent_store;
 
@@ -289,7 +288,7 @@ message_info_new_from_header (CamelFolderSummary *s,
                        mdi->info.info.uid = camel_pstring_add (camel_folder_summary_next_uid_string (s), TRUE);
 
                /* handle 'duplicates' */
-               info = camel_folder_summary_peek_info (s, uid);
+               info = camel_folder_summary_peek_loaded (s, uid);
                if (info) {
                        d(printf("already seen uid '%s', just summarising instead\n", uid));
                        camel_message_info_free (mi);
@@ -550,6 +549,7 @@ maildir_summary_check (CamelLocalSummary *cls,
        gchar *new, *cur;
        gchar *uid;
        struct _remove_data rd = { cls, changes };
+       GPtrArray *known_uids;
 
        g_mutex_lock (((CamelMaildirSummary *) cls)->priv->summary_lock);
 
@@ -580,10 +580,10 @@ maildir_summary_check (CamelLocalSummary *cls,
        /* keeps track of all uid's that have not been processed */
        left = g_hash_table_new (g_str_hash, g_str_equal);
        camel_folder_summary_prepare_fetch_all (s, error);
-       count = camel_folder_summary_count (s);
-       forceindex = count == 0;
-       for (i = 0; i < count; i++) {
-               info = camel_folder_summary_index ((CamelFolderSummary *) cls, i);
+       known_uids = camel_folder_summary_get_array (s);
+       forceindex = !known_uids || known_uids->len == 0;
+       for (i = 0; known_uids && i < known_uids->len; i++) {
+               info = camel_folder_summary_get ((CamelFolderSummary *) cls, g_ptr_array_index (known_uids, i));
                if (info) {
                        g_hash_table_insert (left, (gchar *) camel_message_info_uid (info), info);
                }
@@ -620,7 +620,7 @@ maildir_summary_check (CamelLocalSummary *cls,
                        g_hash_table_remove (left, uid);
                }
 
-               info = camel_folder_summary_uid ((CamelFolderSummary *) cls, uid);
+               info = camel_folder_summary_get ((CamelFolderSummary *) cls, uid);
                if (info == NULL) {
                        /* must be a message incorporated by another client, this is not a 'recent' uid */
                        if (camel_maildir_summary_add (cls, d->d_name, forceindex, cancellable) == 0)
@@ -676,7 +676,7 @@ maildir_summary_check (CamelLocalSummary *cls,
                                continue;
 
                        /* already in summary?  shouldn't happen, but just incase ... */
-                       if ((info = camel_folder_summary_uid ((CamelFolderSummary *) cls, name))) {
+                       if ((info = camel_folder_summary_get ((CamelFolderSummary *) cls, name))) {
                                camel_message_info_free (info);
                                newname = destname = camel_folder_summary_next_uid_string (s);
                        } else {
@@ -720,6 +720,7 @@ maildir_summary_check (CamelLocalSummary *cls,
        g_free (new);
        g_free (cur);
 
+       camel_folder_summary_free_array (known_uids);
        g_mutex_unlock (((CamelMaildirSummary *) cls)->priv->summary_lock);
 
        return 0;
@@ -734,11 +735,12 @@ maildir_summary_sync (CamelLocalSummary *cls,
                       GError **error)
 {
        CamelLocalSummaryClass *local_summary_class;
-       gint count, i;
+       gint i;
        CamelMessageInfo *info;
        CamelMaildirMessageInfo *mdi;
        gchar *name;
        struct stat st;
+       GPtrArray *known_uids;
 
        d(printf("summary_sync(expunge=%s)\n", expunge?"true":"false"));
 
@@ -748,11 +750,11 @@ maildir_summary_sync (CamelLocalSummary *cls,
        camel_operation_push_message (cancellable, _("Storing folder"));
 
        camel_folder_summary_prepare_fetch_all ((CamelFolderSummary *) cls, error);
-       count = camel_folder_summary_count ((CamelFolderSummary *) cls);
-       for (i = count - 1; i >= 0; i--) {
-               camel_operation_progress (cancellable, (count - i) * 100 / count);
+       known_uids = camel_folder_summary_get_array ((CamelFolderSummary *) cls);
+       for (i = (known_uids ? known_uids->len : 0) - 1; i >= 0; i--) {
+               camel_operation_progress (cancellable, (known_uids->len - i) * 100 / known_uids->len);
 
-               info = camel_folder_summary_index ((CamelFolderSummary *) cls, i);
+               info = camel_folder_summary_get ((CamelFolderSummary *) cls, g_ptr_array_index (known_uids, i));
                mdi = (CamelMaildirMessageInfo *) info;
                if (mdi && (mdi->info.info.flags & CAMEL_MESSAGE_DELETED) && expunge) {
                        name = g_strdup_printf("%s/cur/%s", cls->folder_path, camel_maildir_info_filename(mdi));
@@ -801,6 +803,7 @@ maildir_summary_sync (CamelLocalSummary *cls,
                camel_message_info_free (info);
        }
 
+       camel_folder_summary_free_array (known_uids);
        camel_operation_pop_message (cancellable);
 
        /* Chain up to parent's sync() method. */
index f31fcfc..c5d3725 100644 (file)
@@ -59,8 +59,8 @@ mbox_folder_cmp_uids (CamelFolder *folder,
        g_return_val_if_fail (folder != NULL, 0);
        g_return_val_if_fail (folder->summary != NULL, 0);
 
-       a = (CamelMboxMessageInfo *) camel_folder_summary_uid (folder->summary, uid1);
-       b = (CamelMboxMessageInfo *) camel_folder_summary_uid (folder->summary, uid2);
+       a = (CamelMboxMessageInfo *) camel_folder_summary_get (folder->summary, uid1);
+       b = (CamelMboxMessageInfo *) camel_folder_summary_get (folder->summary, uid2);
 
        g_return_val_if_fail (a != NULL, 0);
        g_return_val_if_fail (b != NULL, 0);
@@ -109,7 +109,7 @@ mbox_folder_get_filename (CamelFolder *folder,
        }
 
        /* get the message summary info */
-       info = (CamelMboxMessageInfo *) camel_folder_summary_uid (folder->summary, uid);
+       info = (CamelMboxMessageInfo *) camel_folder_summary_get (folder->summary, uid);
 
        if (info == NULL) {
                set_cannot_get_message_ex (
@@ -317,7 +317,7 @@ mbox_folder_get_message_sync (CamelFolder *folder,
 
 retry:
        /* get the message summary info */
-       info = (CamelMboxMessageInfo *) camel_folder_summary_uid (folder->summary, uid);
+       info = (CamelMboxMessageInfo *) camel_folder_summary_get (folder->summary, uid);
 
        if (info == NULL) {
                set_cannot_get_message_ex (
index f08ce83..9a39c30 100644 (file)
@@ -130,9 +130,9 @@ fill_fi (CamelStore *store,
 
                mbs = (CamelMboxSummary *) camel_mbox_summary_new (NULL, path, folderpath, NULL);
                /* FIXME[disk-summary] track exception */
-               if (camel_folder_summary_header_load_from_db ((CamelFolderSummary *) mbs, store, fi->full_name, NULL) != -1) {
-                       fi->unread = ((CamelFolderSummary *) mbs)->unread_count;
-                       fi->total = ((CamelFolderSummary *) mbs)->saved_count;
+               if (camel_folder_summary_header_load_from_db ((CamelFolderSummary *) mbs, store, fi->full_name, NULL)) {
+                       fi->unread = camel_folder_summary_get_unread_count ((CamelFolderSummary *) mbs);
+                       fi->total = camel_folder_summary_get_saved_count ((CamelFolderSummary *) mbs);
                }
 
                g_object_unref (mbs);
index 4be93e7..dca35d5 100644 (file)
@@ -44,7 +44,7 @@
 #define CAMEL_MBOX_SUMMARY_VERSION (1)
 
 static CamelFIRecord * summary_header_to_db (CamelFolderSummary *, GError **error);
-static gint summary_header_from_db (CamelFolderSummary *, CamelFIRecord *);
+static gboolean summary_header_from_db (CamelFolderSummary *, CamelFIRecord *);
 static CamelMessageInfo * message_info_from_db (CamelFolderSummary *s, CamelMIRecord *record);
 static CamelMIRecord * message_info_to_db (CamelFolderSummary *s, CamelMessageInfo *info);
 
@@ -186,8 +186,7 @@ camel_mbox_summary_new (CamelFolder *folder,
 {
        CamelMboxSummary *new;
 
-       new = g_object_new (CAMEL_TYPE_MBOX_SUMMARY, NULL);
-       ((CamelFolderSummary *) new)->folder = folder;
+       new = g_object_new (CAMEL_TYPE_MBOX_SUMMARY, "folder", folder, NULL);
        if (folder) {
                CamelFolderSummary *summary = (CamelFolderSummary *) new;
                CamelStore *parent_store;
@@ -228,14 +227,15 @@ mbox_summary_encode_x_evolution (CamelLocalSummary *cls,
        }
 }
 
-static gint
+static gboolean
 summary_header_from_db (CamelFolderSummary *s,
                         struct _CamelFIRecord *fir)
 {
        CamelMboxSummary *mbs = CAMEL_MBOX_SUMMARY (s);
        gchar *part;
 
-       CAMEL_FOLDER_SUMMARY_CLASS (camel_mbox_summary_parent_class)->summary_header_from_db (s, fir);
+       if (!CAMEL_FOLDER_SUMMARY_CLASS (camel_mbox_summary_parent_class)->summary_header_from_db (s, fir))
+               return FALSE;
 
        part = fir->bdata;
        if (part) {
@@ -243,7 +243,7 @@ summary_header_from_db (CamelFolderSummary *s,
                mbs->folder_size = bdata_extract_digit (&part);
        }
 
-       return 0;
+       return TRUE;
 }
 
 static gint
@@ -335,7 +335,7 @@ message_info_new_from_header (CamelFolderSummary *s,
                        uid = camel_message_info_uid (mi);
                        d(printf("found valid x-evolution: %s\n", uid));
                        /* If one is there, it should be there already */
-                       info = (CamelMboxMessageInfo *) camel_folder_summary_peek_info (s, uid);
+                       info = (CamelMboxMessageInfo *) camel_folder_summary_peek_loaded (s, uid);
                        if (info) {
                                if ((info->info.info.flags & CAMEL_MESSAGE_FOLDER_NOTSEEN)) {
                                        info->info.info.flags &= ~CAMEL_MESSAGE_FOLDER_NOTSEEN;
@@ -360,7 +360,7 @@ message_info_new_from_header (CamelFolderSummary *s,
                        camel_pstring_free (mi->info.info.uid);
                        mi->info.info.uid = camel_pstring_add (camel_folder_summary_next_uid_string (s), TRUE);
                } else {
-                       camel_folder_summary_set_uid (s, strtoul (camel_message_info_uid (mi), NULL, 10));
+                       camel_folder_summary_set_next_uid (s, strtoul (camel_message_info_uid (mi), NULL, 10));
                }
 #ifdef STATUS_PINE
                if (mbs->xstatus && add&2) {
@@ -465,7 +465,7 @@ summary_update (CamelLocalSummary *cls,
                 GCancellable *cancellable,
                 GError **error)
 {
-       gint i, count;
+       gint i;
        CamelFolderSummary *s = (CamelFolderSummary *) cls;
        CamelMboxSummary *mbs = (CamelMboxSummary *) cls;
        CamelMimeParser *mp;
@@ -477,6 +477,7 @@ summary_update (CamelLocalSummary *cls,
        struct stat st;
        goffset size = 0;
        GList *del = NULL;
+       GPtrArray *known_uids;
 
        d(printf("Calling summary update, from pos %d\n", (gint)offset));
 
@@ -522,15 +523,16 @@ summary_update (CamelLocalSummary *cls,
         * If we're not starting from the start, we must be starting
         * from the old end, so everything must be treated as new */
        camel_folder_summary_prepare_fetch_all (s, NULL);
-       count = camel_folder_summary_count (s);
-       for (i = 0; i < count; i++) {
-               mi = (CamelMboxMessageInfo *) camel_folder_summary_index (s, i);
+       known_uids = camel_folder_summary_get_array (s);
+       for (i = 0; known_uids && i < known_uids->len; i++) {
+               mi = (CamelMboxMessageInfo *) camel_folder_summary_get (s, g_ptr_array_index (known_uids, i));
                if (offset == 0)
                        mi->info.info.flags |= CAMEL_MESSAGE_FOLDER_NOTSEEN;
                else
                        mi->info.info.flags &= ~CAMEL_MESSAGE_FOLDER_NOTSEEN;
                camel_message_info_free (mi);
        }
+       camel_folder_summary_free_array (known_uids);
        mbs->changes = changeinfo;
 
        while (camel_mime_parser_step (mp, NULL, NULL) == CAMEL_MIME_PARSER_STATE_FROM) {
@@ -565,39 +567,34 @@ summary_update (CamelLocalSummary *cls,
 
        g_object_unref (mp);
 
-       count = camel_folder_summary_count (s);
-       for (i = 0; i < count; i++) {
-               mi = (CamelMboxMessageInfo *) camel_folder_summary_index (s, i);
-               /* must've dissapeared from the file? */
-               if (!mi || mi->info.info.flags & CAMEL_MESSAGE_FOLDER_NOTSEEN) {
-                       gchar *uid;
-
-                       if (mi)
-                               uid = g_strdup (camel_message_info_uid (mi));
-                       else
-                               uid = camel_folder_summary_uid_from_index (s, i);
+       known_uids = camel_folder_summary_get_array (s);
+       for (i = 0; known_uids && i < known_uids->len; i++) {
+               const gchar *uid;
 
-                       if (!uid) {
-                               g_debug ("%s: didn't get uid at %d of %d (%d)", G_STRFUNC, i, count, camel_folder_summary_count (s));
-                               continue;
-                       }
+               uid = g_ptr_array_index (known_uids, i);
+               if (!uid)
+                       continue;
 
+               mi = (CamelMboxMessageInfo *) camel_folder_summary_get (s, uid);
+               /* must've dissapeared from the file? */
+               if (!mi || mi->info.info.flags & CAMEL_MESSAGE_FOLDER_NOTSEEN) {
                        d(printf("uid '%s' vanished, removing", uid));
                        if (changeinfo)
                                camel_folder_change_info_remove_uid (changeinfo, uid);
                        del = g_list_prepend (del, (gpointer) camel_pstring_strdup (uid));
-                       camel_folder_summary_remove_index_fast (s, i);
-                       count--;
-                       i--;
-                       g_free (uid);
+                       camel_folder_summary_remove_uid (s, uid);
                }
+
                if (mi)
                        camel_message_info_free (mi);
        }
 
+       if (known_uids)
+               camel_folder_summary_free_array (known_uids);
+
        /* Delete all in one transaction */
-       full_name = camel_folder_get_full_name (s->folder);
-       parent_store = camel_folder_get_parent_store (s->folder);
+       full_name = camel_folder_get_full_name (camel_folder_summary_get_folder (s));
+       parent_store = camel_folder_get_parent_store (camel_folder_summary_get_folder (s));
        camel_db_delete_uids (parent_store->cdb_w, full_name, del, NULL);
        g_list_foreach (del, (GFunc) camel_pstring_free, NULL);
        g_list_free (del);
@@ -629,7 +626,7 @@ mbox_summary_check (CamelLocalSummary *cls,
        CamelFolderSummary *s = (CamelFolderSummary *) cls;
        struct stat st;
        gint ret = 0;
-       gint i, count;
+       gint i;
 
        d(printf("Checking summary\n"));
 
@@ -637,7 +634,7 @@ mbox_summary_check (CamelLocalSummary *cls,
 
        /* check if the summary is up-to-date */
        if (g_stat (cls->folder_path, &st) == -1) {
-               camel_folder_summary_clear (s);
+               camel_folder_summary_clear (s, NULL);
                camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
                g_set_error (
                        error, G_IO_ERROR,
@@ -652,19 +649,22 @@ mbox_summary_check (CamelLocalSummary *cls,
        cls->check_force = 0;
 
        if (st.st_size == 0) {
+               GPtrArray *known_uids;
+
                /* empty?  No need to scan at all */
                d(printf("Empty mbox, clearing summary\n"));
                camel_folder_summary_prepare_fetch_all (s, NULL);
-               count= camel_folder_summary_count (s);
-               for (i = 0; i < count; i++) {
-                       CamelMessageInfo *info = camel_folder_summary_index (s, i);
+               known_uids = camel_folder_summary_get_array (s);
+               for (i = 0; known_uids && i < known_uids->len; i++) {
+                       CamelMessageInfo *info = camel_folder_summary_get (s, g_ptr_array_index (known_uids, i));
 
                        if (info) {
                                camel_folder_change_info_remove_uid (changes, camel_message_info_uid (info));
                                camel_message_info_free (info);
                        }
                }
-               camel_folder_summary_clear (s);
+               camel_folder_summary_free_array (known_uids);
+               camel_folder_summary_clear (s, NULL);
                ret = 0;
        } else {
                /* is the summary uptodate? */
@@ -822,8 +822,8 @@ cms_sort_frompos (gpointer a,
        gint ret = 0;
 
        /* Things are in memory already. Sorting speeds up syncing, if things are sorted by from pos. */
-       info1 = (CamelMboxMessageInfo *) camel_folder_summary_uid (summary, *(gchar **) a);
-       info2 = (CamelMboxMessageInfo *) camel_folder_summary_uid (summary, *(gchar **) b);
+       info1 = (CamelMboxMessageInfo *) camel_folder_summary_get (summary, *(gchar **) a);
+       info2 = (CamelMboxMessageInfo *) camel_folder_summary_get (summary, *(gchar **) b);
 
        if (info1->frompos > info2->frompos)
                ret = 1;
@@ -905,7 +905,7 @@ mbox_summary_sync_quick (CamelMboxSummary *mbs,
 
                camel_operation_progress (cancellable, pc);
 
-               info = (CamelMboxMessageInfo *) camel_folder_summary_uid (s, summary->pdata[i]);
+               info = (CamelMboxMessageInfo *) camel_folder_summary_get (s, summary->pdata[i]);
 
                d(printf("Checking message %s %08x\n", camel_message_info_uid(info), ((CamelMessageInfoBase *)info)->flags));
 
@@ -1040,14 +1040,14 @@ mbox_summary_sync (CamelLocalSummary *cls,
                return -1;
        }
 
-       full_name = camel_folder_get_full_name (s->folder);
-       parent_store = camel_folder_get_parent_store (s->folder);
+       full_name = camel_folder_get_full_name (camel_folder_summary_get_folder (s));
+       parent_store = camel_folder_get_parent_store (camel_folder_summary_get_folder (s));
 
        /* Sync only the changes */
 
        summary = camel_folder_summary_get_changed ((CamelFolderSummary *) mbs);
        for (i = 0; i < summary->len; i++) {
-               CamelMboxMessageInfo *info = (CamelMboxMessageInfo *) camel_folder_summary_uid (s, summary->pdata[i]);
+               CamelMboxMessageInfo *info = (CamelMboxMessageInfo *) camel_folder_summary_get (s, summary->pdata[i]);
 
                if ((expunge && (info->info.info.flags & CAMEL_MESSAGE_DELETED)) ||
                    (info->info.info.flags & (CAMEL_MESSAGE_FOLDER_NOXEV | CAMEL_MESSAGE_FOLDER_XEVCHANGE)))
@@ -1127,7 +1127,7 @@ camel_mbox_summary_sync_mbox (CamelMboxSummary *cls,
        CamelMimeParser *mp = NULL;
        CamelStore *parent_store;
        const gchar *full_name;
-       gint i, count;
+       gint i;
        CamelMboxMessageInfo *info = NULL;
        gchar *buffer, *xevnew = NULL;
        gsize len;
@@ -1135,6 +1135,7 @@ camel_mbox_summary_sync_mbox (CamelMboxSummary *cls,
        gint lastdel = FALSE;
        gboolean touched = FALSE;
        GList *del = NULL;
+       GPtrArray *known_uids = NULL;
 #ifdef STATUS_PINE
        gchar statnew[8], xstatnew[8];
 #endif
@@ -1161,13 +1162,13 @@ camel_mbox_summary_sync_mbox (CamelMboxSummary *cls,
        camel_mime_parser_init_with_fd (mp, fd);
 
        camel_folder_summary_prepare_fetch_all (s, NULL);
-       count = camel_folder_summary_count (s);
-       for (i = 0; i < count; i++) {
-               gint pc = (i + 1) * 100 / count;
+       known_uids = camel_folder_summary_get_array (s);
+       for (i = 0; known_uids && i < known_uids->len; i++) {
+               gint pc = (i + 1) * 100 / known_uids->len;
 
                camel_operation_progress (cancellable, pc);
 
-               info = (CamelMboxMessageInfo *) camel_folder_summary_index (s, i);
+               info = (CamelMboxMessageInfo *) camel_folder_summary_get (s, g_ptr_array_index (known_uids, i));
 
                if (!info)
                        continue;
@@ -1197,28 +1198,16 @@ camel_mbox_summary_sync_mbox (CamelMboxSummary *cls,
                lastdel = FALSE;
                if ((flags&1) && info->info.info.flags & CAMEL_MESSAGE_DELETED) {
                        const gchar *uid = camel_message_info_uid (info);
-                       guint32 flags = camel_message_info_flags (info);
-                       gint read, junk;
                        d(printf("Deleting %s\n", uid));
 
                        if (((CamelLocalSummary *) cls)->index)
                                camel_index_delete_name (((CamelLocalSummary *) cls)->index, uid);
 
                        /* remove it from the change list */
-                       junk = flags & CAMEL_MESSAGE_JUNK;
-                       read = flags & CAMEL_MESSAGE_SEEN;
-                       s->saved_count--;
-                       if (junk)
-                               s->junk_count--;
-                       if (!read)
-                               s->unread_count--;
-                       s->deleted_count--;
                        camel_folder_change_info_remove_uid (changeinfo, uid);
-                       camel_folder_summary_remove_index_fast (s, i);
+                       camel_folder_summary_remove_uid (s, uid);
                        del = g_list_prepend (del, (gpointer) camel_pstring_strdup (uid));
                        camel_message_info_free ((CamelMessageInfo *) info);
-                       count--;
-                       i--;
                        info = NULL;
                        lastdel = TRUE;
                        touched = TRUE;
@@ -1303,8 +1292,8 @@ camel_mbox_summary_sync_mbox (CamelMboxSummary *cls,
                }
        }
 
-       full_name = camel_folder_get_full_name (s->folder);
-       parent_store = camel_folder_get_parent_store (s->folder);
+       full_name = camel_folder_get_full_name (camel_folder_summary_get_folder (s));
+       parent_store = camel_folder_get_parent_store (camel_folder_summary_get_folder (s));
        camel_db_delete_uids (parent_store->cdb_w, full_name, del, NULL);
        g_list_foreach (del, (GFunc) camel_pstring_free, NULL);
        g_list_free (del);
@@ -1318,8 +1307,8 @@ camel_mbox_summary_sync_mbox (CamelMboxSummary *cls,
        g_object_unref (mp);
 
        /* clear working flags */
-       for (i = 0; i < count; i++) {
-               info = (CamelMboxMessageInfo *) camel_folder_summary_index (s, i);
+       for (i = 0; known_uids && i < known_uids->len; i++) {
+               info = (CamelMboxMessageInfo *) camel_folder_summary_get (s, g_ptr_array_index (known_uids, i));
                if (info) {
                        if (info->info.info.flags & (CAMEL_MESSAGE_FOLDER_NOXEV | CAMEL_MESSAGE_FOLDER_FLAGGED | CAMEL_MESSAGE_FOLDER_XEVCHANGE)) {
                                info->info.info.flags &= ~(CAMEL_MESSAGE_FOLDER_NOXEV
@@ -1333,6 +1322,8 @@ camel_mbox_summary_sync_mbox (CamelMboxSummary *cls,
                }
        }
 
+       camel_folder_summary_free_array (known_uids);
+
        if (touched)
                camel_folder_summary_header_save_to_db (s, NULL);
 
@@ -1347,6 +1338,7 @@ camel_mbox_summary_sync_mbox (CamelMboxSummary *cls,
        if (info)
                camel_message_info_free ((CamelMessageInfo *) info);
 
+       camel_folder_summary_free_array (known_uids);
        camel_folder_summary_unlock (s, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
 
        return -1;
index f8b6286..b99f283 100644 (file)
@@ -150,7 +150,7 @@ mh_folder_get_message_sync (CamelFolder *folder,
                return NULL;
 
        /* get the message summary info */
-       if ((info = camel_folder_summary_uid (folder->summary, uid)) == NULL) {
+       if ((info = camel_folder_summary_get (folder->summary, uid)) == NULL) {
                set_cannot_get_message_ex (
                        error, CAMEL_FOLDER_ERROR_INVALID_UID,
                        uid, lf->folder_path, _("No such message"));
index 0f3baab..2c7d221 100644 (file)
@@ -218,9 +218,9 @@ fill_fi (CamelStore *store,
                s = (CamelFolderSummary *) camel_mh_summary_new (
                        NULL, path, folderpath, NULL);
                if (camel_folder_summary_header_load_from_db (
-                       s, store, fi->full_name, NULL) != -1) {
-                       fi->unread = s->unread_count;
-                       fi->total = s->saved_count;
+                       s, store, fi->full_name, NULL)) {
+                       fi->unread = camel_folder_summary_get_unread_count (s);
+                       fi->total = camel_folder_summary_get_saved_count (s);
                }
                g_object_unref (s);
                g_free (folderpath);
index ada6ee5..2d9de03 100644 (file)
@@ -98,8 +98,7 @@ camel_mh_summary_new (CamelFolder *folder,
 {
        CamelMhSummary *o;
 
-       o = g_object_new (CAMEL_TYPE_MH_SUMMARY, NULL);
-       ((CamelFolderSummary *) o)->folder = folder;
+       o = g_object_new (CAMEL_TYPE_MH_SUMMARY, "folder", folder, NULL);
        if (folder) {
                CamelStore *parent_store;
 
@@ -127,7 +126,7 @@ mh_summary_next_uid_string (CamelFolderSummary *s)
        if (mhs->priv->current_uid) {
                uidstr = g_strdup (mhs->priv->current_uid);
                /* tell the summary of this, so we always append numbers to the end */
-               camel_folder_summary_set_uid (s, strtoul (uidstr, NULL, 10) + 1);
+               camel_folder_summary_set_next_uid (s, strtoul (uidstr, NULL, 10) + 1);
        } else {
                /* else scan for one - and create it too, to make sure */
                do {
@@ -210,8 +209,9 @@ mh_summary_check (CamelLocalSummary *cls,
        CamelMessageInfo *info;
        CamelFolderSummary *s = (CamelFolderSummary *) cls;
        GHashTable *left;
-       gint i, count;
-       gint forceindex;
+       gint i;
+       gboolean forceindex;
+       GPtrArray *known_uids;
 
        /* FIXME: Handle changeinfo */
 
@@ -232,14 +232,15 @@ mh_summary_check (CamelLocalSummary *cls,
        /* keeps track of all uid's that have not been processed */
        left = g_hash_table_new (g_str_hash, g_str_equal);
        camel_folder_summary_prepare_fetch_all ((CamelFolderSummary *) cls, error);
-       count = camel_folder_summary_count ((CamelFolderSummary *) cls);
-       forceindex = count == 0;
-       for (i = 0; i < count; i++) {
-               info = camel_folder_summary_index ((CamelFolderSummary *) cls, i);
+       known_uids = camel_folder_summary_get_array ((CamelFolderSummary *) cls);
+       forceindex = !known_uids || known_uids->len == 0;
+       for (i = 0; known_uids && i < known_uids->len; i++) {
+               info = camel_folder_summary_get ((CamelFolderSummary *) cls, g_ptr_array_index (known_uids, i));
                if (info) {
                        g_hash_table_insert (left, (gchar *) camel_message_info_uid (info), info);
                }
        }
+       camel_folder_summary_free_array (known_uids);
 
        while ((d = readdir (dir))) {
                /* FIXME: also run stat to check for regular file */
@@ -249,7 +250,7 @@ mh_summary_check (CamelLocalSummary *cls,
                                break;
                }
                if (c == 0) {
-                       info = camel_folder_summary_uid ((CamelFolderSummary *) cls, d->d_name);
+                       info = camel_folder_summary_get ((CamelFolderSummary *) cls, d->d_name);
                        if (info == NULL || (cls->index && (!camel_index_has_name (cls->index, d->d_name)))) {
                                /* need to add this file to the summary */
                                if (info != NULL) {
@@ -290,7 +291,8 @@ mh_summary_sync (CamelLocalSummary *cls,
                  GError **error)
 {
        CamelLocalSummaryClass *local_summary_class;
-       gint count, i;
+       gint i;
+       GPtrArray *known_uids;
        CamelLocalMessageInfo *info;
        gchar *name;
        const gchar *uid;
@@ -305,9 +307,9 @@ mh_summary_sync (CamelLocalSummary *cls,
        /* FIXME: need to update/honour .mh_sequences or whatever it is */
 
        camel_folder_summary_prepare_fetch_all ((CamelFolderSummary *) cls, error);
-       count = camel_folder_summary_count ((CamelFolderSummary *) cls);
-       for (i = count - 1; i >= 0; i--) {
-               info = (CamelLocalMessageInfo *) camel_folder_summary_index ((CamelFolderSummary *) cls, i);
+       known_uids = camel_folder_summary_get_array ((CamelFolderSummary *) cls);
+       for (i = (known_uids ? known_uids->len : 0) - 1; i >= 0; i--) {
+               info = (CamelLocalMessageInfo *) camel_folder_summary_get ((CamelFolderSummary *) cls, g_ptr_array_index (known_uids, i));
                g_assert (info);
                if (expunge && (info->info.flags & CAMEL_MESSAGE_DELETED)) {
                        uid = camel_message_info_uid (info);
index 3d5f6ad..222a48d 100644 (file)
@@ -86,8 +86,7 @@ camel_spool_summary_new (CamelFolder *folder,
 {
        CamelSpoolSummary *new;
 
-       new = g_object_new (CAMEL_TYPE_SPOOL_SUMMARY, NULL);
-       ((CamelFolderSummary *) new)->folder = folder;
+       new = g_object_new (CAMEL_TYPE_SPOOL_SUMMARY, "folder", folder, NULL);
        if (folder) {
                CamelStore *parent_store;
 
@@ -310,9 +309,11 @@ spool_summary_check (CamelLocalSummary *cls,
                      GCancellable *cancellable,
                      GError **error)
 {
-       gint i, work, count;
+       gint i;
+       gboolean work;
        struct stat st;
        CamelFolderSummary *s = (CamelFolderSummary *) cls;
+       GPtrArray *known_uids;
 
        if (CAMEL_LOCAL_SUMMARY_CLASS (camel_spool_summary_parent_class)->check (cls, changeinfo, cancellable, error) == -1)
                return -1;
@@ -320,13 +321,14 @@ spool_summary_check (CamelLocalSummary *cls,
        /* check to see if we need to copy/update the file; missing xev headers prompt this */
        work = FALSE;
        camel_folder_summary_prepare_fetch_all (s, error);
-       count = camel_folder_summary_count (s);
-       for (i = 0; !work && i < count; i++) {
-               CamelMboxMessageInfo *info = (CamelMboxMessageInfo *) camel_folder_summary_index (s, i);
+       known_uids = camel_folder_summary_get_array (s);
+       for (i = 0; !work && known_uids && i < known_uids->len; i++) {
+               CamelMboxMessageInfo *info = (CamelMboxMessageInfo *) camel_folder_summary_get (s, g_ptr_array_index (known_uids, i));
                g_assert (info);
                work = (info->info.info.flags & (CAMEL_MESSAGE_FOLDER_NOXEV)) != 0;
                camel_message_info_free ((CamelMessageInfo *) info);
        }
+       camel_folder_summary_free_array (known_uids);
 
        /* if we do, then write out the headers using sync_full, etc */
        if (work) {
index 37bebfd..2881df4 100644 (file)
@@ -42,11 +42,19 @@ G_DEFINE_TYPE (CamelNNTPFolder, camel_nntp_folder, CAMEL_TYPE_DISCO_FOLDER)
 static void
 nntp_folder_dispose (GObject *object)
 {
+       CamelStore *parent_store;
        CamelNNTPFolder *nntp_folder = CAMEL_NNTP_FOLDER (object);
 
        camel_folder_summary_save_to_db (
                CAMEL_FOLDER (nntp_folder)->summary, NULL);
 
+       parent_store = camel_folder_get_parent_store (CAMEL_FOLDER (nntp_folder));
+       if (parent_store) {
+               camel_store_summary_disconnect_folder_summary (
+                       (CamelStoreSummary *) ((CamelNNTPStore *) parent_store)->summary,
+                       CAMEL_FOLDER (nntp_folder)->summary);
+       }
+
        /* Chain up to parent's dispose() method. */
        G_OBJECT_CLASS (camel_nntp_folder_parent_class)->dispose (object);
 }
@@ -140,7 +148,7 @@ unset_flagged_flag (const gchar *uid,
 {
        CamelMessageInfo *info;
 
-       info = camel_folder_summary_uid (summary, uid);
+       info = camel_folder_summary_get (summary, uid);
        if (info) {
                CamelMessageInfoBase *base = (CamelMessageInfoBase *) info;
 
@@ -738,5 +746,9 @@ camel_nntp_folder_new (CamelStore *parent,
                folder = NULL;
        }
 
+       camel_store_summary_connect_folder_summary (
+               (CamelStoreSummary *) ((CamelNNTPStore *) parent)->summary,
+               folder_name, folder->summary);
+
        return folder;
 }
index 105d47e..f8c02e3 100644 (file)
@@ -56,7 +56,7 @@ struct _CamelNNTPSummaryPrivate {
 static CamelMessageInfo * message_info_new_from_header (CamelFolderSummary *, struct _camel_header_raw *);
 static gint summary_header_load (CamelFolderSummary *, FILE *);
 static gint summary_header_save (CamelFolderSummary *, FILE *);
-static gint summary_header_from_db (CamelFolderSummary *s, CamelFIRecord *mir);
+static gboolean summary_header_from_db (CamelFolderSummary *s, CamelFIRecord *mir);
 static CamelFIRecord * summary_header_to_db (CamelFolderSummary *s, GError **error);
 
 G_DEFINE_TYPE (CamelNNTPSummary, camel_nntp_summary, CAMEL_TYPE_FOLDER_SUMMARY)
@@ -97,8 +97,7 @@ camel_nntp_summary_new (CamelFolder *folder,
 {
        CamelNNTPSummary *cns;
 
-       cns = g_object_new (CAMEL_TYPE_NNTP_SUMMARY, NULL);
-       ((CamelFolderSummary *) cns)->folder = folder;
+       cns = g_object_new (CAMEL_TYPE_NNTP_SUMMARY, "folder", folder, NULL);
 
        camel_folder_summary_set_filename ((CamelFolderSummary *) cns, path);
        camel_folder_summary_set_build_content ((CamelFolderSummary *) cns, FALSE);
@@ -128,15 +127,15 @@ message_info_new_from_header (CamelFolderSummary *s,
        return (CamelMessageInfo *) mi;
 }
 
-static gint
+static gboolean
 summary_header_from_db (CamelFolderSummary *s,
                         CamelFIRecord *mir)
 {
        CamelNNTPSummary *cns = CAMEL_NNTP_SUMMARY (s);
        gchar *part;
 
-       if (CAMEL_FOLDER_SUMMARY_CLASS (camel_nntp_summary_parent_class)->summary_header_from_db (s, mir) == -1)
-               return -1;
+       if (!CAMEL_FOLDER_SUMMARY_CLASS (camel_nntp_summary_parent_class)->summary_header_from_db (s, mir))
+               return FALSE;
 
        part = mir->bdata;
 
@@ -144,7 +143,7 @@ summary_header_from_db (CamelFolderSummary *s,
        cns->high = bdata_extract_digit (&part);
        cns->low = bdata_extract_digit (&part);
 
-       return 0;
+       return TRUE;
 }
 
 static gint
@@ -229,10 +228,8 @@ add_range_xover (CamelNNTPSummary *cns,
        gint ret;
        guint n, count, total, size;
        struct _xover_header *xover;
-       GHashTable *summary_table;
 
        s = (CamelFolderSummary *) cns;
-       summary_table = camel_folder_summary_get_hashtable (s);
 
        url = camel_service_get_camel_url (CAMEL_SERVICE (store));
 
@@ -301,7 +298,7 @@ add_range_xover (CamelNNTPSummary *cns,
 
                /* truncated line? ignore? */
                if (xover == NULL) {
-                       if (!GPOINTER_TO_INT (g_hash_table_lookup (summary_table, cns->priv->uid))) {
+                       if (!camel_folder_summary_check_uid (s, cns->priv->uid)) {
                                mi = (CamelMessageInfoBase *)
                                        camel_folder_summary_add_from_header (s, headers);
                                if (mi) {
@@ -322,8 +319,6 @@ add_range_xover (CamelNNTPSummary *cns,
 
        camel_operation_pop_message (cancellable);
 
-       camel_folder_summary_free_hashtable (summary_table);
-
        return ret;
 }
 
@@ -344,12 +339,9 @@ add_range_head (CamelNNTPSummary *cns,
        guint i, n, count, total;
        CamelMessageInfo *mi;
        CamelMimeParser *mp;
-       GHashTable *summary_table;
 
        s = (CamelFolderSummary *) cns;
 
-       summary_table = camel_folder_summary_get_hashtable (s);
-
        mp = camel_mime_parser_new ();
 
        url = camel_service_get_camel_url (CAMEL_SERVICE (store));
@@ -384,7 +376,7 @@ add_range_head (CamelNNTPSummary *cns,
                if ((msgid = strchr (line, '<')) && (line = strchr (msgid + 1, '>'))) {
                        line[1] = 0;
                        cns->priv->uid = g_strdup_printf ("%u,%s\n", n, msgid);
-                       if (!GPOINTER_TO_INT (g_hash_table_lookup (summary_table, cns->priv->uid))) {
+                       if (!camel_folder_summary_check_uid (s, cns->priv->uid)) {
                                if (camel_mime_parser_init_with_stream (mp, (CamelStream *) store->stream, error) == -1)
                                        goto error;
                                mi = camel_folder_summary_add_from_parser (s, mp);
@@ -429,8 +421,6 @@ ioerror:
 
        camel_operation_pop_message (cancellable);
 
-       camel_folder_summary_free_hashtable (summary_table);
-
        return ret;
 }
 
@@ -456,8 +446,8 @@ camel_nntp_summary_check (CamelNNTPSummary *cns,
 
        s = (CamelFolderSummary *) cns;
 
-       full_name = camel_folder_get_full_name (s->folder);
-       parent_store = camel_folder_get_parent_store (s->folder);
+       full_name = camel_folder_get_full_name (camel_folder_summary_get_folder (s));
+       parent_store = camel_folder_get_parent_store (camel_folder_summary_get_folder (s));
 
        line +=3;
        n = strtoul (line, &line, 10);
@@ -484,36 +474,37 @@ camel_nntp_summary_check (CamelNNTPSummary *cns,
 
        /* Check for messages no longer on the server */
        if (cns->low != f) {
-               count = camel_folder_summary_count (s);
-               for (i = 0; i < count; i++) {
-                       gchar *uid;
-                       const gchar *msgid;
-
-                       uid  = camel_folder_summary_uid_from_index (s, i);
-                       n = strtoul (uid, NULL, 10);
-
-                       if (n < f || n > l) {
-                               dd (printf ("nntp_summary: %u is lower/higher than lowest/highest article, removed\n", n));
-                               /* Since we use a global cache this could prematurely remove
-                                * a cached message that might be in another folder - not that important as
-                                * it is a true cache */
-                               msgid = strchr (uid, ',');
-                               if (msgid)
-                                       camel_data_cache_remove (store->cache, "cache", msgid+1, NULL);
-                               camel_folder_change_info_remove_uid (changes, uid);
-                               del = g_list_prepend (del, uid);
-                               camel_folder_summary_remove_uid_fast (s, uid);
-                               uid = NULL; /*Lets not free it */
-                               count--;
-                               i--;
+               GPtrArray *known_uids;
+
+               known_uids = camel_folder_summary_get_array (s);
+               if (known_uids) {
+                       for (i = 0; i < known_uids->len; i++) {
+                               const gchar *uid;
+                               const gchar *msgid;
+
+                               uid  = g_ptr_array_index (known_uids, i);
+                               n = strtoul (uid, NULL, 10);
+
+                               if (n < f || n > l) {
+                                       dd (printf ("nntp_summary: %u is lower/higher than lowest/highest article, removed\n", n));
+                                       /* Since we use a global cache this could prematurely remove
+                                        * a cached message that might be in another folder - not that important as
+                                        * it is a true cache */
+                                       msgid = strchr (uid, ',');
+                                       if (msgid)
+                                               camel_data_cache_remove (store->cache, "cache", msgid + 1, NULL);
+                                       camel_folder_change_info_remove_uid (changes, uid);
+                                       del = g_list_prepend (del, (gpointer) camel_pstring_strdup (uid));
+                                       camel_folder_summary_remove_uid (s, uid);
+                               }
                        }
-                       g_free (uid);
+                       camel_folder_summary_free_array (known_uids);
                }
                cns->low = f;
        }
 
        camel_db_delete_uids (parent_store->cdb_w, full_name, del, NULL);
-       g_list_foreach (del, (GFunc) g_free, NULL);
+       g_list_foreach (del, (GFunc) camel_pstring_free, NULL);
        g_list_free (del);
 
        if (cns->high < l) {