diff options
-rw-r--r-- | camel/ChangeLog | 18 | ||||
-rw-r--r-- | camel/camel-folder.c | 186 | ||||
-rw-r--r-- | camel/camel-folder.h | 2 | ||||
-rw-r--r-- | camel/providers/vee/camel-vee-folder.c | 52 |
4 files changed, 148 insertions, 110 deletions
diff --git a/camel/ChangeLog b/camel/ChangeLog index 26ed34e472..a8e84df589 100644 --- a/camel/ChangeLog +++ b/camel/ChangeLog @@ -1,3 +1,21 @@ +2001-02-22 Not Zed <NotZed@Ximian.com> + + * providers/vee/camel-vee-folder.c (vee_folder_build): Removed, + not used. + (camel_vee_folder_new): Removed call to build_folder. + (vee_get_message): Dont try and free the mi if we didn't get it. + + * camel-folder.c (camel_folder_change_info_new): Added a hash + table of what we have in the lists, plus moved private things into + private pointer. + (camel_folder_change_info_add_source): Fixed up private accesses. + (camel_folder_change_info_add_uid): Changed to use a hashtable to + see if we already have the uid, etc. + (camel_folder_change_info_remove_uid): Similar. + (change_info_remove): Likewise. + (camel_folder_change_info_clear): Fixes for privatisations. + (camel_folder_change_info_free): " + 2001-02-21 Dan Winship <danw@ximian.com> * providers/imap/camel-imap-folder.c (fetch_medium): Fixes for diff --git a/camel/camel-folder.c b/camel/camel-folder.c index 674094ce42..af9edcfe5d 100644 --- a/camel/camel-folder.c +++ b/camel/camel-folder.c @@ -1328,6 +1328,12 @@ camel_folder_free_deep (CamelFolder *folder, GPtrArray *array) g_ptr_array_free (array, TRUE); } +struct _CamelFolderChangeInfoPrivate { + GHashTable *uid_stored; /* what we have stored, which array they're in */ + GHashTable *uid_source; /* used to create unique lists */ + struct _EMemPool *uid_pool; /* pool used to store copies of uid strings */ +}; + /** * camel_folder_change_info_new: * @void: @@ -1348,38 +1354,14 @@ camel_folder_change_info_new(void) info->uid_added = g_ptr_array_new(); info->uid_removed = g_ptr_array_new(); info->uid_changed = g_ptr_array_new(); - info->uid_source = NULL; - info->uid_pool = e_mempool_new(512, 256, E_MEMPOOL_ALIGN_BYTE); + info->priv = g_malloc0(sizeof(*info->priv)); + info->priv->uid_stored = g_hash_table_new(g_str_hash, g_str_equal); + info->priv->uid_source = NULL; + info->priv->uid_pool = e_mempool_new(512, 256, E_MEMPOOL_ALIGN_BYTE); return info; } -static void -change_info_add_uid(CamelFolderChangeInfo *info, GPtrArray *uids, const char *uid, int copy) -{ - int i; - - /* TODO: Check that it is in the other arrays and remove it from them/etc? */ - for (i=0;i<uids->len;i++) { - if (!strcmp(uids->pdata[i], uid)) - return; - } - if (copy) - g_ptr_array_add(uids, e_mempool_strdup(info->uid_pool, uid)); - else - g_ptr_array_add(uids, (char *)uid); -} - -static void -change_info_cat(CamelFolderChangeInfo *info, GPtrArray *uids, GPtrArray *source) -{ - int i; - - for (i=0;i<source->len;i++) { - change_info_add_uid(info, uids, source->pdata[i], TRUE); - } -} - /** * camel_folder_change_info_add_source: * @info: @@ -1390,11 +1372,13 @@ change_info_cat(CamelFolderChangeInfo *info, GPtrArray *uids, GPtrArray *source) void camel_folder_change_info_add_source(CamelFolderChangeInfo *info, const char *uid) { - if (info->uid_source == NULL) - info->uid_source = g_hash_table_new(g_str_hash, g_str_equal); + struct _CamelFolderChangeInfoPrivate *p = info->priv; + + if (p->uid_source == NULL) + p->uid_source = g_hash_table_new(g_str_hash, g_str_equal); - if (g_hash_table_lookup(info->uid_source, uid) == NULL) - g_hash_table_insert(info->uid_source, e_mempool_strdup(info->uid_pool, uid), (void *)1); + if (g_hash_table_lookup(p->uid_source, uid) == NULL) + g_hash_table_insert(p->uid_source, e_mempool_strdup(p->uid_pool, uid), (void *)1); } /** @@ -1408,15 +1392,16 @@ void camel_folder_change_info_add_source_list(CamelFolderChangeInfo *info, const GPtrArray *list) { int i; + struct _CamelFolderChangeInfoPrivate *p = info->priv; - if (info->uid_source == NULL) - info->uid_source = g_hash_table_new(g_str_hash, g_str_equal); + if (p->uid_source == NULL) + p->uid_source = g_hash_table_new(g_str_hash, g_str_equal); for (i=0;i<list->len;i++) { char *uid = list->pdata[i]; - if (g_hash_table_lookup(info->uid_source, uid) == NULL) - g_hash_table_insert(info->uid_source, e_mempool_strdup(info->uid_pool, uid), (void *)1); + if (g_hash_table_lookup(p->uid_source, uid) == NULL) + g_hash_table_insert(p->uid_source, e_mempool_strdup(p->uid_pool, uid), (void *)1); } } @@ -1432,16 +1417,17 @@ camel_folder_change_info_add_update(CamelFolderChangeInfo *info, const char *uid { char *key; int value; + struct _CamelFolderChangeInfoPrivate *p = info->priv; - if (info->uid_source == NULL) { - change_info_add_uid(info, info->uid_added, uid, TRUE); + if (p->uid_source == NULL) { + camel_folder_change_info_add_uid(info, uid); return; } - if (g_hash_table_lookup_extended(info->uid_source, uid, (void **)&key, (void **)&value)) { - g_hash_table_remove(info->uid_source, key); + if (g_hash_table_lookup_extended(p->uid_source, uid, (void **)&key, (void **)&value)) { + g_hash_table_remove(p->uid_source, key); } else { - change_info_add_uid(info, info->uid_added, uid, TRUE); + camel_folder_change_info_add_uid(info, uid); } } @@ -1457,16 +1443,31 @@ camel_folder_change_info_add_update_list(CamelFolderChangeInfo *info, const GPtr { int i; - for (i=0;i<list->len;i++) { + for (i=0;i<list->len;i++) camel_folder_change_info_add_update(info, list->pdata[i]); - } } static void change_info_remove(char *key, void *value, CamelFolderChangeInfo *info) { + struct _CamelFolderChangeInfoPrivate *p = info->priv; + GPtrArray *olduids; + char *olduid; + + if (g_hash_table_lookup_extended(p->uid_stored, key, (void **)&olduid, (void **)&olduids)) { + /* if it was added/changed them removed, then remove it */ + if (olduids != info->uid_removed) { + g_ptr_array_remove_fast(olduids, olduid); + g_ptr_array_add(info->uid_removed, olduid); + g_hash_table_insert(p->uid_stored, olduid, info->uid_removed); + } + return; + } + + /* we dont need to copy this, as they've already been copied into our pool */ - change_info_add_uid(info, info->uid_removed, key, FALSE); + g_ptr_array_add(info->uid_removed, key); + g_hash_table_insert(p->uid_stored, key, info->uid_removed); } /** @@ -1479,13 +1480,24 @@ change_info_remove(char *key, void *value, CamelFolderChangeInfo *info) void camel_folder_change_info_build_diff(CamelFolderChangeInfo *info) { - if (info->uid_source) { - g_hash_table_foreach(info->uid_source, (GHFunc)change_info_remove, info); - g_hash_table_destroy(info->uid_source); - info->uid_source = NULL; + struct _CamelFolderChangeInfoPrivate *p = info->priv; + + if (p->uid_source) { + g_hash_table_foreach(p->uid_source, (GHFunc)change_info_remove, info); + g_hash_table_destroy(p->uid_source); + p->uid_source = NULL; } } +static void +change_info_cat(CamelFolderChangeInfo *info, GPtrArray *source, void (*add)(CamelFolderChangeInfo *info, const char *uid)) +{ + int i; + + for (i=0;i<source->len;i++) + add(info, source->pdata[i]); +} + /** * camel_folder_change_info_cat: * @info: @@ -1497,9 +1509,9 @@ camel_folder_change_info_build_diff(CamelFolderChangeInfo *info) void camel_folder_change_info_cat(CamelFolderChangeInfo *info, CamelFolderChangeInfo *source) { - change_info_cat(info, info->uid_added, source->uid_added); - change_info_cat(info, info->uid_removed, source->uid_removed); - change_info_cat(info, info->uid_changed, source->uid_changed); + change_info_cat(info, source->uid_added, camel_folder_change_info_add_uid); + change_info_cat(info, source->uid_removed, camel_folder_change_info_remove_uid); + change_info_cat(info, source->uid_changed, camel_folder_change_info_change_uid); } /** @@ -1512,7 +1524,24 @@ camel_folder_change_info_cat(CamelFolderChangeInfo *info, CamelFolderChangeInfo void camel_folder_change_info_add_uid(CamelFolderChangeInfo *info, const char *uid) { - change_info_add_uid(info, info->uid_added, uid, TRUE); + struct _CamelFolderChangeInfoPrivate *p = info->priv; + GPtrArray *olduids; + char *olduid; + + if (g_hash_table_lookup_extended(p->uid_stored, uid, (void **)&olduid, (void **)&olduids)) { + /* if it was removed then added, promote it to a changed */ + /* if it was changed then added, leave as changed */ + if (olduids == info->uid_removed) { + g_ptr_array_remove_fast(olduids, olduid); + g_ptr_array_add(info->uid_changed, olduid); + g_hash_table_insert(p->uid_stored, olduid, info->uid_changed); + } + return; + } + + olduid = e_mempool_strdup(p->uid_pool, uid); + g_ptr_array_add(info->uid_added, olduid); + g_hash_table_insert(p->uid_stored, olduid, info->uid_added); } /** @@ -1525,7 +1554,23 @@ camel_folder_change_info_add_uid(CamelFolderChangeInfo *info, const char *uid) void camel_folder_change_info_remove_uid(CamelFolderChangeInfo *info, const char *uid) { - change_info_add_uid(info, info->uid_removed, uid, TRUE); + struct _CamelFolderChangeInfoPrivate *p = info->priv; + GPtrArray *olduids; + char *olduid; + + if (g_hash_table_lookup_extended(p->uid_stored, uid, (void **)&olduid, (void **)&olduids)) { + /* if it was added/changed them removed, then remove it */ + if (olduids != info->uid_removed) { + g_ptr_array_remove_fast(olduids, olduid); + g_ptr_array_add(info->uid_removed, olduid); + g_hash_table_insert(p->uid_stored, olduid, info->uid_removed); + } + return; + } + + olduid = e_mempool_strdup(p->uid_pool, uid); + g_ptr_array_add(info->uid_removed, olduid); + g_hash_table_insert(p->uid_stored, olduid, info->uid_removed); } /** @@ -1538,7 +1583,18 @@ camel_folder_change_info_remove_uid(CamelFolderChangeInfo *info, const char *uid void camel_folder_change_info_change_uid(CamelFolderChangeInfo *info, const char *uid) { - change_info_add_uid(info, info->uid_changed, uid, TRUE); + struct _CamelFolderChangeInfoPrivate *p = info->priv; + GPtrArray *olduids; + char *olduid; + + if (g_hash_table_lookup_extended(p->uid_stored, uid, (void **)&olduid, (void **)&olduids)) { + /* if we have it already, leave it as that */ + return; + } + + olduid = e_mempool_strdup(p->uid_pool, uid); + g_ptr_array_add(info->uid_changed, olduid); + g_hash_table_insert(p->uid_stored, olduid, info->uid_changed); } /** @@ -1564,14 +1620,18 @@ camel_folder_change_info_changed(CamelFolderChangeInfo *info) void camel_folder_change_info_clear(CamelFolderChangeInfo *info) { + struct _CamelFolderChangeInfoPrivate *p = info->priv; + g_ptr_array_set_size(info->uid_added, 0); g_ptr_array_set_size(info->uid_removed, 0); g_ptr_array_set_size(info->uid_changed, 0); - if (info->uid_source) { - g_hash_table_destroy(info->uid_source); - info->uid_source = NULL; + if (p->uid_source) { + g_hash_table_destroy(p->uid_source); + p->uid_source = NULL; } - e_mempool_flush(info->uid_pool, TRUE); + g_hash_table_destroy(p->uid_stored); + p->uid_stored = g_hash_table_new(g_str_hash, g_str_equal); + e_mempool_flush(p->uid_pool, TRUE); } /** @@ -1583,10 +1643,14 @@ camel_folder_change_info_clear(CamelFolderChangeInfo *info) void camel_folder_change_info_free(CamelFolderChangeInfo *info) { - if (info->uid_source) - g_hash_table_destroy(info->uid_source); + struct _CamelFolderChangeInfoPrivate *p = info->priv; + + if (p->uid_source) + g_hash_table_destroy(p->uid_source); - e_mempool_destroy(info->uid_pool); + g_hash_table_destroy(p->uid_stored); + e_mempool_destroy(p->uid_pool); + g_free(p); g_ptr_array_free(info->uid_added, TRUE); g_ptr_array_free(info->uid_removed, TRUE); diff --git a/camel/camel-folder.h b/camel/camel-folder.h index 615ecb53a0..0f1c772346 100644 --- a/camel/camel-folder.h +++ b/camel/camel-folder.h @@ -47,8 +47,6 @@ struct _CamelFolderChangeInfo { GPtrArray *uid_removed; GPtrArray *uid_changed; - GHashTable *uid_source; /* used to create unique lists */ - struct _EMemPool *uid_pool; /* pool used to store copies of uid strings */ struct _CamelFolderChangeInfoPrivate *priv; }; diff --git a/camel/providers/vee/camel-vee-folder.c b/camel/providers/vee/camel-vee-folder.c index 617b67b162..18c1fe20c4 100644 --- a/camel/providers/vee/camel-vee-folder.c +++ b/camel/providers/vee/camel-vee-folder.c @@ -66,7 +66,6 @@ static void unmatched_finalise(CamelFolder *sub, gpointer type, CamelVeeFolder * static void folder_changed(CamelFolder *sub, gpointer type, CamelVeeFolder *vf); static void message_changed(CamelFolder *f, const char *uid, CamelVeeFolder *vf); -static void vee_folder_build(CamelVeeFolder *vf, CamelException *ex); static void vee_folder_build_folder(CamelVeeFolder *vf, CamelFolder *source, CamelException *ex); static CamelFolderClass *camel_vee_folder_parent; @@ -249,13 +248,6 @@ camel_vee_folder_new(CamelStore *parent_store, const char *name, guint32 flags, vf->expression = g_strdup(searchpart); vf->vname = namepart; - vee_folder_build(vf, ex); - if (camel_exception_is_set(ex)) { - printf("opening folder failed\n"); - camel_object_unref((CamelObject *)folder); - return NULL; - } - printf("opened normal folder folder %p %s with %d messages\n", folder, name, camel_folder_get_message_count(folder)); /* FIXME: should be moved to store */ @@ -796,13 +788,14 @@ static CamelMimeMessage *vee_get_message(CamelFolder *folder, const gchar *uid, CamelMimeMessage *msg = NULL; mi = (CamelVeeMessageInfo *)camel_folder_summary_uid(folder->summary, uid); - if (mi == NULL) + if (mi) { + msg = camel_folder_get_message(mi->folder, strchr(camel_message_info_uid(mi), ':') + 1, ex); + camel_folder_summary_info_free(folder->summary, (CamelMessageInfo *)mi); + } else { camel_exception_setv(ex, CAMEL_EXCEPTION_FOLDER_INVALID_UID, "No such message %s in %s", uid, folder->name); - else - msg = camel_folder_get_message(mi->folder, strchr(camel_message_info_uid(mi), ':') + 1, ex); - camel_folder_summary_info_free(folder->summary, (CamelMessageInfo *)mi); + } return msg; } @@ -881,41 +874,6 @@ vee_move_message_to(CamelFolder *folder, const char *uid, CamelFolder *dest, Cam } } -/* - need incremental update, based on folder. - Need to watch folders for changes and update accordingly. -*/ - -/* this does most of the vfolder magic */ -/* must have summary_lock held when calling */ -static void -vee_folder_build(CamelVeeFolder *vf, CamelException *ex) -{ - CamelFolder *folder = (CamelFolder *)vf; - struct _CamelVeeFolderPrivate *p = _PRIVATE(vf); - GList *node; - - camel_folder_summary_clear(folder->summary); - - CAMEL_VEE_FOLDER_LOCK(vf, subfolder_lock); - - node = p->folders; - while (node) { - GPtrArray *matches; - CamelFolder *f = node->data; - int i; - - matches = camel_folder_search_by_expression(f, vf->expression, ex); - for (i = 0; i < matches->len; i++) - vee_folder_add_uid(vf, f, matches->pdata[i]); - - camel_folder_search_free(f, matches); - node = g_list_next(node); - } - - CAMEL_VEE_FOLDER_UNLOCK(vf, subfolder_lock); -} - static void removed_uid(void *key, void *value, void *data) { |