diff options
author | Not Zed <NotZed@Ximian.com> | 2002-12-09 08:28:06 +0800 |
---|---|---|
committer | Michael Zucci <zucchi@src.gnome.org> | 2002-12-09 08:28:06 +0800 |
commit | 24b06cb2a4030282763c8f60ba3b0b8b806d15d3 (patch) | |
tree | 44b57fbee23cb93c7b1e0d26aa2aac5eb360ee5f /camel/camel-vee-store.c | |
parent | c43c83145ab56f5422665f8a9c8468033064ce95 (diff) | |
download | gsoc2013-evolution-24b06cb2a4030282763c8f60ba3b0b8b806d15d3.tar gsoc2013-evolution-24b06cb2a4030282763c8f60ba3b0b8b806d15d3.tar.gz gsoc2013-evolution-24b06cb2a4030282763c8f60ba3b0b8b806d15d3.tar.bz2 gsoc2013-evolution-24b06cb2a4030282763c8f60ba3b0b8b806d15d3.tar.lz gsoc2013-evolution-24b06cb2a4030282763c8f60ba3b0b8b806d15d3.tar.xz gsoc2013-evolution-24b06cb2a4030282763c8f60ba3b0b8b806d15d3.tar.zst gsoc2013-evolution-24b06cb2a4030282763c8f60ba3b0b8b806d15d3.zip |
Use a bag instead of a hashtable to track the cache streams.
2002-12-07 Not Zed <NotZed@Ximian.com>
* camel-data-cache.c (data_cache_init): Use a bag instead of a
hashtable to track the cache streams.
(data_cache_finalise): Same.
(free_busy): No longer needed.
(data_cache_expire): use bag instead of hashtable.
(stream_finalised): No longer required.
(camel_data_cache_add): objectbagise
(camel_data_cache_get): "
(camel_data_cache_remove): "
(data_cache_path): Set the now expired date before running expiry,
so it plays better with multiple threads. Still a couple of
harmless races.
2002-12-06 Not Zed <NotZed@Ximian.com>
* providers/local/camel-spool-store.c (scan_dir): folders ->
object bag.
(get_folder_info_mbox): folders -> object bag.
* providers/local/camel-mh-store.c (folder_info_new): folders ->
object bag.
* providers/local/camel-maildir-store.c (scan_dir): folders ->
object bag.
* providers/local/camel-local-store.c (rename_folder): folders ->
object bag.
* camel-private.h (CamelStorePrivate): Remove 'cache' lock,
handled by the objectbag.
* providers/imap/camel-imap-store.c (copy_folder): Removed.
(imap_store_refresh_folders): folders -> object bag.
(get_folder_counts): folders -> object bag.
* camel-vee-store.c (vee_get_folder): changes for folders
objectbag.
(vee_get_folder_info): Change to use folders objectbag. Also,
dont refresh the base folder if we're in FAST mode.
(build_info): Removed, no longer needed.
(vee_rename_folder): Fixed for folders objectbag.
* camel-store.c (camel_store_init): init the folders objectbag.
(camel_store_finalize): Destroy the folders object bag.
(folder_matches):
(folder_finalize): Removed, now handled implicitly by the
objectbag.
(camel_store_get_folder): object bag changes.
(camel_store_delete_folder): "
(get_subfolders): Removed, now handled without a callback.
(camel_store_rename_folder): Changed to use object bag of folders.
(trash_add_folder): Removed.
(init_trash): use folders object bag.
(copy_folder_cache):
(sync_folder): Removed, no longer needed. Weird arsed code anyway.
(store_sync): Use folder object bag instead of hashtable.
(camel_store_unsubscribe_folder): "
(camel_store_init): remove cache_lock init, no longer used.
(camel_store_finalize): Same for cleanup.
2002-12-05 Not Zed <NotZed@Ximian.com>
* camel-store.h (struct _CamelStore): change folders from a
hashtable into a CamelObjectBag.
* camel-object.c (camel_object_ref): Use type_lock instead of
class lock for ref counting.
(camel_object_unref): Use type_lock instead of class lock for
unref.
(camel_object_unref): If the object is 'bagged', then also look
hooks, and remove it from any bags.
(camel_object_bag_new):
(camel_object_bag_destroy):
(camel_object_bag_add):
(camel_object_bag_get):
(camel_object_bag_remove_unlocked):
(camel_object_bag_list):
(camel_object_bag_abort):
(camel_object_bag_remove): New functions to implement a utility
object which can manage a 'bag' of weakly ref'd children in an
atomic & threadsafe way.
svn path=/trunk/; revision=19056
Diffstat (limited to 'camel/camel-vee-store.c')
-rw-r--r-- | camel/camel-vee-store.c | 154 |
1 files changed, 63 insertions, 91 deletions
diff --git a/camel/camel-vee-store.c b/camel/camel-vee-store.c index 4834ade7e1..9531d49fc0 100644 --- a/camel/camel-vee-store.c +++ b/camel/camel-vee-store.c @@ -74,7 +74,7 @@ camel_vee_store_class_init (CamelVeeStoreClass *klass) { CamelStoreClass *store_class = (CamelStoreClass *) klass; - camel_vee_store_parent = CAMEL_STORE_CLASS(camel_type_get_global_classfuncs (camel_store_get_type ())); + camel_vee_store_parent = (CamelStoreClass *)camel_store_get_type(); /* virtual method overload */ store_class->get_folder = vee_get_folder; @@ -146,7 +146,7 @@ change_folder(CamelStore *store, const char *name, guint32 flags, int count) fi->url = g_strdup_printf("vfolder:%s%s#%s", ((CamelService *)store)->url->path, (flags&CHANGE_NOSELECT)?";noselect=yes":"", name); fi->unread_message_count = count; camel_folder_info_build_path(fi, '/'); - camel_object_trigger_event(CAMEL_OBJECT(store), (flags&CHANGE_DELETE)?"folder_deleted":"folder_created", fi); + camel_object_trigger_event(store, (flags&CHANGE_DELETE)?"folder_deleted":"folder_created", fi); camel_folder_info_free(fi); } @@ -154,6 +154,7 @@ static CamelFolder * vee_get_folder (CamelStore *store, const char *folder_name, guint32 flags, CamelException *ex) { CamelVeeFolder *vf; + CamelFolder *folder; char *name, *p; int add; @@ -166,12 +167,11 @@ vee_get_folder (CamelStore *store, const char *folder_name, guint32 flags, Camel while ( (p = strchr(p, '/'))) { *p = 0; - CAMEL_STORE_LOCK(store, cache_lock); - add = g_hash_table_lookup (store->folders, name) == NULL; - CAMEL_STORE_UNLOCK(store, cache_lock); - - if (add) + folder = camel_object_bag_get(store->folders, name); + if (folder == NULL) change_folder(store, name, CHANGE_ADD|CHANGE_NOSELECT, -1); + else + camel_object_unref(folder); *p++='/'; } @@ -194,78 +194,55 @@ vee_get_trash (CamelStore *store, CamelException *ex) return NULL; } -struct _build_info { - const char *top; - guint32 flags; - GPtrArray *infos; - GPtrArray *folders; -}; - -static void -build_info(char *name, CamelVeeFolder *folder, struct _build_info *data) -{ - CamelFolderInfo *info; - - /* check we have to include this one */ - if (data->top) { - if (data->flags & CAMEL_STORE_FOLDER_INFO_RECURSIVE) { - int namelen = strlen(name); - int toplen = strlen(data->top); - - if (!((namelen == toplen && - strcmp(name, data->top) == 0) - || ((namelen > toplen) - && strncmp(name, data->top, toplen) == 0 - && name[toplen] == '/'))) - return; - } else { - if (strcmp(name, data->top)) - return; - } - } else { - if ((data->flags & CAMEL_STORE_FOLDER_INFO_RECURSIVE) == 0) { - if (strchr(name, '/')) - return; - } - } - - info = g_malloc0(sizeof(*info)); - info->url = g_strdup_printf("vfolder:%s#%s", ((CamelService *)((CamelFolder *)folder)->parent_store)->url->path, - ((CamelFolder *)folder)->full_name); - info->full_name = g_strdup(((CamelFolder *)folder)->full_name); - info->name = g_strdup(((CamelFolder *)folder)->name); - info->unread_message_count = -1; - g_ptr_array_add(data->infos, info); - camel_object_ref((CamelObject *)folder); - g_ptr_array_add(data->folders, folder); -} - static CamelFolderInfo * vee_get_folder_info(CamelStore *store, const char *top, guint32 flags, CamelException *ex) { - struct _build_info data; CamelFolderInfo *info; + GPtrArray *folders, *infos; int i; - /* first, build the info list */ - data.top = top; - data.flags = flags; - data.infos = g_ptr_array_new(); - data.folders = g_ptr_array_new(); - CAMEL_STORE_LOCK(store, cache_lock); - g_hash_table_foreach(store->folders, (GHFunc)build_info, &data); - CAMEL_STORE_UNLOCK(store, cache_lock); - - /* then make sure the unread counts are accurate */ - for (i=0;i<data.infos->len;i++) { - CamelFolderInfo *info = data.infos->pdata[i]; - CamelFolder *folder = data.folders->pdata[i]; - - camel_folder_refresh_info(folder, NULL); - info->unread_message_count = camel_folder_get_unread_message_count(folder); - camel_object_unref((CamelObject *)folder); + infos = g_ptr_array_new(); + folders = camel_object_bag_list(store->folders); + for (i=0;i<folders->len;i++) { + CamelVeeFolder *folder = folders->pdata[i]; + int add = FALSE; + char *name = ((CamelFolder *)folder)->full_name; + + /* check we have to include this one */ + if (top) { + if (flags & CAMEL_STORE_FOLDER_INFO_RECURSIVE) { + int namelen = strlen(name); + int toplen = strlen(top); + + add = ((namelen == toplen && + strcmp(name, top) == 0) + || ((namelen > toplen) + && strncmp(name, top, toplen) == 0 + && name[toplen] == '/')); + } else { + add = strcmp(name, top) == 0; + } + } else { + if ((flags & CAMEL_STORE_FOLDER_INFO_RECURSIVE) == 0) + add = strchr(name, '/') == NULL; + } + + if (add) { + /* ensures unread is correct */ + if ((flags & CAMEL_STORE_FOLDER_INFO_FAST) == 0) + camel_folder_refresh_info((CamelFolder *)folder, NULL); + + info = g_malloc0(sizeof(*info)); + info->url = g_strdup_printf("vfolder:%s#%s", ((CamelService *)((CamelFolder *)folder)->parent_store)->url->path, + ((CamelFolder *)folder)->full_name); + info->full_name = g_strdup(((CamelFolder *)folder)->full_name); + info->name = g_strdup(((CamelFolder *)folder)->name); + info->unread_message_count = camel_folder_get_unread_message_count((CamelFolder *)folder); + g_ptr_array_add(infos, info); + } + camel_object_unref(folder); } - g_ptr_array_free(data.folders, TRUE); + g_ptr_array_free(folders, TRUE); /* and always add UNMATCHED, if scanning from top/etc */ if (top == NULL || top[0] == 0 || strncmp(top, CAMEL_UNMATCHED_NAME, strlen(CAMEL_UNMATCHED_NAME)) == 0) { @@ -275,12 +252,12 @@ vee_get_folder_info(CamelStore *store, const char *top, guint32 flags, CamelExce info->name = g_strdup(CAMEL_UNMATCHED_NAME); info->unread_message_count = -1; camel_folder_info_build_path(info, '/'); - g_ptr_array_add(data.infos, info); + g_ptr_array_add(infos, info); } /* convert it into a tree */ - info = camel_folder_info_build(data.infos, (top&&top[0])?top:"", '/', TRUE); - g_ptr_array_free(data.infos, TRUE); + info = camel_folder_info_build(infos, (top&&top[0])?top:"", '/', TRUE); + g_ptr_array_free(infos, TRUE); return info; } @@ -289,7 +266,6 @@ static void vee_delete_folder(CamelStore *store, const char *folder_name, CamelException *ex) { CamelFolder *folder; - char *key; if (strcmp(folder_name, CAMEL_UNMATCHED_NAME) == 0) { camel_exception_setv(ex, CAMEL_EXCEPTION_STORE_NO_FOLDER, @@ -297,24 +273,20 @@ vee_delete_folder(CamelStore *store, const char *folder_name, CamelException *ex return; } - CAMEL_STORE_LOCK(store, cache_lock); - if (g_hash_table_lookup_extended(store->folders, folder_name, (void **)&key, (void **)&folder)) { - int update; + folder = camel_object_bag_get(store->folders, folder_name); + if (folder) { + camel_object_bag_remove(store->folders, folder); - update = (((CamelVeeFolder *)folder)->flags & CAMEL_STORE_FOLDER_PRIVATE) == 0; - g_hash_table_remove(store->folders, key); - CAMEL_STORE_UNLOCK(store, cache_lock); if (store->vtrash) camel_vee_folder_remove_folder((CamelVeeFolder *)store->vtrash, folder); - if (update) { + if ((((CamelVeeFolder *)folder)->flags & CAMEL_STORE_FOLDER_PRIVATE) == 0) { /* what about now-empty parents? ignore? */ - change_folder(store, key, CHANGE_DELETE, -1); + change_folder(store, folder_name, CHANGE_DELETE, -1); } - g_free(key); - } else { - CAMEL_STORE_UNLOCK(store, cache_lock); + camel_object_unref(folder); + } else { camel_exception_setv(ex, CAMEL_EXCEPTION_STORE_NO_FOLDER, _("Cannot delete folder: %s: No such folder"), folder_name); } @@ -334,11 +306,11 @@ vee_rename_folder(CamelStore *store, const char *old, const char *new, CamelExce } /* See if it exists, for vfolders, all folders are in the folders hash */ - CAMEL_STORE_LOCK(store, cache_lock); - if ((folder = g_hash_table_lookup(store->folders, old)) == NULL) { + folder = camel_object_bag_get(store->folders, old); + if (folder == NULL) { camel_exception_setv(ex, CAMEL_EXCEPTION_STORE_NO_FOLDER, _("Cannot rename folder: %s: No such folder"), old); + } else { + camel_object_unref(folder); } - - CAMEL_STORE_UNLOCK(store, cache_lock); } |