aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--camel/ChangeLog22
-rw-r--r--camel/camel-service.c10
-rw-r--r--camel/camel-service.h1
-rw-r--r--camel/camel-session.c62
-rw-r--r--camel/camel-session.h4
-rw-r--r--camel/camel-store.c14
-rw-r--r--camel/camel-url.c56
-rw-r--r--camel/camel-url.h4
-rw-r--r--camel/providers/mbox/camel-mbox-folder.c6
-rw-r--r--camel/providers/mbox/camel-mbox-summary.c2
10 files changed, 163 insertions, 18 deletions
diff --git a/camel/ChangeLog b/camel/ChangeLog
index f13b2c7c3a..f270abcad2 100644
--- a/camel/ChangeLog
+++ b/camel/ChangeLog
@@ -1,3 +1,25 @@
+2000-05-30 Not Zed <NotZed@HelixCode.com>
+
+ * providers/mbox/camel-mbox-folder.c (mbox_append_message): Init
+ filter_from to NULL, for exception case.
+ (mbox_get_message_by_uid): Cast off_t to long int for diagnostics.
+
+ * camel-url.c (camel_url_hash): Hash funciton for using camel
+ url's as hash keys.
+ (camel_url_equal): equal function for same.
+
+ * camel-session.c (camel_session_finalise): Free cached services.
+ (camel_session_init): Init service cache.
+ (service_cache_remove): destroy callback to remove a service from
+ the cache.
+
+ * camel-store.c (get_folder_internal): Remove the extra ref of the
+ folder. That seems the right behaviour ...?
+ (camel_store_get_type): Doh, actually call store init, so the
+ cache works.
+ (cache_folder): strdup the folder name! no wonder it never found
+ it again.
+
2000-05-30 Jeffrey Stedfast <fejj@helixcode.com>
* providers/imap/camel-imap-folder.c: Implemented a few more
diff --git a/camel/camel-service.c b/camel/camel-service.c
index 885c166a05..52a7581e9f 100644
--- a/camel/camel-service.c
+++ b/camel/camel-service.c
@@ -67,6 +67,13 @@ camel_service_class_init (CamelServiceClass *camel_service_class)
gtk_object_class->finalize = _finalize;
}
+static void
+camel_service_init (void *o, void *k)
+{
+/* CamelService *service = o;*/
+ return;
+}
+
GtkType
camel_service_get_type (void)
{
@@ -79,7 +86,7 @@ camel_service_get_type (void)
sizeof (CamelService),
sizeof (CamelServiceClass),
(GtkClassInitFunc) camel_service_class_init,
- (GtkObjectInitFunc) NULL,
+ (GtkObjectInitFunc) camel_service_init,
/* reserved_1 */ NULL,
/* reserved_2 */ NULL,
(GtkClassInitFunc) NULL,
@@ -92,7 +99,6 @@ camel_service_get_type (void)
return camel_service_type;
}
-
static void
_finalize (GtkObject *object)
{
diff --git a/camel/camel-service.h b/camel/camel-service.h
index c2f4f12020..7ebd6aa0e8 100644
--- a/camel/camel-service.h
+++ b/camel/camel-service.h
@@ -51,7 +51,6 @@ struct _CamelService {
gboolean connected;
CamelURL *url;
int url_flags;
-
};
diff --git a/camel/camel-session.c b/camel/camel-session.c
index 55a466e404..17d7e60ee0 100644
--- a/camel/camel-session.c
+++ b/camel/camel-session.c
@@ -34,12 +34,43 @@
#include "camel-url.h"
#include "hash-table-utils.h"
+static CamelObjectClass *parent_class;
+
static void
camel_session_init (CamelSession *session)
{
session->modules = camel_provider_init ();
- session->providers = g_hash_table_new (g_strcase_hash,
- g_strcase_equal);
+ session->providers =
+ g_hash_table_new (g_strcase_hash, g_strcase_equal);
+ session->service_cache =
+ g_hash_table_new (camel_url_hash, camel_url_equal);
+}
+
+static void
+hash_unref_service(void *key, void *value, void *data)
+{
+ gtk_object_unref((GtkObject *)value);
+}
+
+static void
+camel_session_finalise(GtkObject *o)
+{
+ CamelSession *session = (CamelSession *)o;
+
+ g_hash_table_foreach(session->service_cache, hash_unref_service, 0);
+ g_hash_table_destroy(session->service_cache);
+ g_hash_table_destroy(session->providers);
+
+ GTK_OBJECT_CLASS (parent_class)->finalize (o);
+}
+
+static void
+camel_session_class_init (CamelServiceClass *camel_service_class)
+{
+ GtkObjectClass *object_class = (GtkObjectClass *)camel_service_class;
+
+ parent_class = gtk_type_class (camel_object_get_type ());
+ object_class->finalize = camel_session_finalise;
}
GtkType
@@ -53,7 +84,7 @@ camel_session_get_type (void)
"CamelSession",
sizeof (CamelSession),
sizeof (CamelSessionClass),
- (GtkClassInitFunc) NULL,
+ (GtkClassInitFunc) camel_session_class_init,
(GtkObjectInitFunc) camel_session_init,
/* reserved_1 */ NULL,
/* reserved_2 */ NULL,
@@ -157,6 +188,11 @@ camel_session_list_providers (CamelSession *session, gboolean load)
return list;
}
+static void
+service_cache_remove(CamelService *service, CamelSession *session)
+{
+ g_hash_table_remove(session->service_cache, service->url);
+}
CamelService *
camel_session_get_service (CamelSession *session, const char *url_string,
@@ -164,11 +200,23 @@ camel_session_get_service (CamelSession *session, const char *url_string,
{
CamelURL *url;
const CamelProvider *provider;
+ CamelService *service;
url = camel_url_new (url_string, ex);
if (!url)
return NULL;
+ /* lookup in cache first */
+ printf("looking up service in cache: %s\n", url_string);
+ service = g_hash_table_lookup(session->service_cache, url);
+ if (service != NULL) {
+ printf("found!!\n");
+ camel_url_free(url);
+ gtk_object_ref((GtkObject *)service);
+ return service;
+ }
+ printf("not found, creating service\n");
+
provider = g_hash_table_lookup (session->providers, url->protocol);
if (!provider) {
/* See if there's one we can load. */
@@ -196,8 +244,12 @@ camel_session_get_service (CamelSession *session, const char *url_string,
return NULL;
}
- return camel_service_new (provider->object_types[type], session,
- url, ex);
+ service = camel_service_new (provider->object_types[type], session, url, ex);
+ if (service) {
+ g_hash_table_insert(session->service_cache, url, service);
+ gtk_signal_connect((GtkObject *)service, "destroy", service_cache_remove, session);
+ }
+ return service;
}
diff --git a/camel/camel-session.h b/camel/camel-session.h
index 81f8a3da85..e6a6b2ffc2 100644
--- a/camel/camel-session.h
+++ b/camel/camel-session.h
@@ -53,7 +53,9 @@ struct _CamelSession
CamelAuthCallback authenticator;
- GHashTable *providers, *modules;
+ GHashTable *providers,
+ *modules,
+ *service_cache;
};
typedef struct {
diff --git a/camel/camel-store.c b/camel/camel-store.c
index 87384a61d4..b4eae9975e 100644
--- a/camel/camel-store.c
+++ b/camel/camel-store.c
@@ -90,7 +90,7 @@ camel_store_get_type (void)
sizeof (CamelStore),
sizeof (CamelStoreClass),
(GtkClassInitFunc) camel_store_class_init,
- (GtkObjectInitFunc) NULL,
+ (GtkObjectInitFunc) camel_store_init,
/* reserved_1 */ NULL,
/* reserved_2 */ NULL,
(GtkClassInitFunc) NULL,
@@ -166,7 +166,7 @@ cache_folder (CamelStore *store, const char *folder_name, CamelFolder *folder)
g_warning ("Caching folder %s that already exists.",
folder_name);
}
- g_hash_table_insert (store->folders, (gpointer)folder_name, folder);
+ g_hash_table_insert (store->folders, (gpointer)g_strdup(folder_name), folder);
gtk_signal_connect_object (GTK_OBJECT (folder), "destroy",
GTK_SIGNAL_FUNC (CS_CLASS (store)->uncache_folder),
GTK_OBJECT (store));
@@ -175,6 +175,7 @@ cache_folder (CamelStore *store, const char *folder_name, CamelFolder *folder)
static void
uncache_folder (CamelStore *store, CamelFolder *folder)
{
+ /* FIXME: free name index */
g_hash_table_remove (store->folders,
camel_folder_get_full_name (folder));
}
@@ -186,18 +187,25 @@ get_folder_internal (CamelStore *store, const char *folder_name,
{
CamelFolder *folder = NULL;
+ printf("Getting folder %p '%s'\n", store, folder_name);
/* Try cache first. */
folder = CS_CLASS (store)->lookup_folder (store, folder_name);
+ if (folder) {
+ printf("Folder cached!\n");
+ } else {
+ printf("Folder not cached!\n");
+ }
+
if (!folder) {
folder = CS_CLASS (store)->get_folder (store, folder_name, ex);
if (!folder)
return NULL;
+ printf("storing folder in cache: %p '%s'\n", store, folder_name);
CS_CLASS (store)->cache_folder (store, folder_name, folder);
}
- gtk_object_ref (GTK_OBJECT (folder));
return folder;
}
diff --git a/camel/camel-url.c b/camel/camel-url.c
index 96721bda24..c0707dcbb1 100644
--- a/camel/camel-url.c
+++ b/camel/camel-url.c
@@ -43,8 +43,7 @@
*
* protocol://user;AUTH=mech:password@host:port/path
*
- * The protocol, followed by a ":" is required. If it is followed by
- * "//", there must be an "authority" containing at least a host,
+ * The protocol, followed by a ":" is required. If it is followed by * "//", there must be an "authority" containing at least a host,
* which ends at the end of the string or at the next "/". If there
* is an "@" in the authority, there must be a username before it,
* and the host comes after it. The authmech, password, and port are
@@ -292,3 +291,56 @@ camel_url_decode (char *part)
}
*d = '\0';
}
+
+static void
+add_hash(guint *hash, char *s)
+{
+ if (s)
+ *hash ^= g_str_hash(s);
+}
+
+guint camel_url_hash (const void *v)
+{
+ const CamelURL *u = v;
+ guint hash = 0;
+
+ add_hash(&hash, u->protocol);
+ add_hash(&hash, u->user);
+ add_hash(&hash, u->authmech);
+ add_hash(&hash, u->passwd);
+ add_hash(&hash, u->host);
+ add_hash(&hash, u->path);
+ hash ^= u->port;
+ return hash;
+}
+
+static int
+check_equal(char *s1, char *s2)
+{
+ if (s1 == NULL) {
+ if (s2 == NULL)
+ return TRUE;
+ else
+ return FALSE;
+ }
+ if (s2 == NULL) {
+ if (s1 == NULL)
+ return TRUE;
+ else
+ return FALSE;
+ }
+ return strcmp(s1, s2) == 0;
+}
+
+int camel_url_equal(const void *v, const void *v2)
+{
+ const CamelURL *u1 = v, *u2 = v2;
+
+ return check_equal(u1->protocol, u2->protocol)
+ && check_equal(u1->user, u2->user)
+ && check_equal(u1->authmech, u2->authmech)
+ && check_equal(u1->passwd, u2->passwd)
+ && check_equal(u1->host, u2->host)
+ && check_equal(u1->path, u2->path)
+ && u1->port == u2->port;
+}
diff --git a/camel/camel-url.h b/camel/camel-url.h
index f2a4c645f5..bea1c439b2 100644
--- a/camel/camel-url.h
+++ b/camel/camel-url.h
@@ -57,6 +57,10 @@ char *camel_url_encode (char *part, gboolean escape_unsafe,
char *escape_extra);
void camel_url_decode (char *part);
+/* for putting url's into hash tables */
+guint camel_url_hash (const void *v);
+int camel_url_equal(const void *v, const void *v2);
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/camel/providers/mbox/camel-mbox-folder.c b/camel/providers/mbox/camel-mbox-folder.c
index de7a7764ba..c663824301 100644
--- a/camel/providers/mbox/camel-mbox-folder.c
+++ b/camel/providers/mbox/camel-mbox-folder.c
@@ -593,7 +593,7 @@ mbox_append_message (CamelFolder *folder, CamelMimeMessage *message, CamelExcept
{
CamelMboxFolder *mbox_folder = CAMEL_MBOX_FOLDER (folder);
CamelStream *output_stream = NULL, *filter_stream = NULL;
- CamelMimeFilter *filter_from;
+ CamelMimeFilter *filter_from = NULL;
struct stat st;
off_t seek = -1;
char *xev;
@@ -779,8 +779,8 @@ mbox_get_message_by_uid (CamelFolder *folder, const gchar *uid, CamelException *
if (camel_mime_parser_tell_start_from(parser) != info->frompos) {
g_warning("Summary doesn't match the folder contents! eek!\n"
- " expecting offset %d got %d", info->frompos,
- camel_mime_parser_tell_start_from(parser));
+ " expecting offset %ld got %ld", (long int)info->frompos,
+ (long int)camel_mime_parser_tell_start_from(parser));
errno = EINVAL;
goto fail;
}
diff --git a/camel/providers/mbox/camel-mbox-summary.c b/camel/providers/mbox/camel-mbox-summary.c
index a5cd61b596..e78bede490 100644
--- a/camel/providers/mbox/camel-mbox-summary.c
+++ b/camel/providers/mbox/camel-mbox-summary.c
@@ -683,7 +683,7 @@ camel_mbox_summary_expunge(CamelMboxSummary *mbs)
goto error;
}
/* update from pos here? */
- /*info->frompos += offset;*/
+ info->frompos += offset;
} else {
d(printf("Nothing to do for this message\n"));
}