aboutsummaryrefslogtreecommitdiffstats
path: root/camel/camel-vee-store.c
diff options
context:
space:
mode:
authorNot Zed <NotZed@Ximian.com>2002-12-09 08:28:06 +0800
committerMichael Zucci <zucchi@src.gnome.org>2002-12-09 08:28:06 +0800
commit24b06cb2a4030282763c8f60ba3b0b8b806d15d3 (patch)
tree44b57fbee23cb93c7b1e0d26aa2aac5eb360ee5f /camel/camel-vee-store.c
parentc43c83145ab56f5422665f8a9c8468033064ce95 (diff)
downloadgsoc2013-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.c154
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);
}