Init filter_from to NULL, for exception case. (mbox_get_message_by_uid):
authorNot Zed <NotZed@HelixCode.com>
Tue, 30 May 2000 22:35:40 +0000 (22:35 +0000)
committerMichael Zucci <zucchi@src.gnome.org>
Tue, 30 May 2000 22:35:40 +0000 (22:35 +0000)
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.

camel/ChangeLog
camel/camel-service.c
camel/camel-service.h
camel/camel-session.c
camel/camel-session.h
camel/camel-store.c
camel/camel-url.c
camel/camel-url.h
camel/providers/mbox/camel-mbox-folder.c

index f13b2c7..f270abc 100644 (file)
@@ -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
index 885c166..52a7581 100644 (file)
@@ -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)
 {
index c2f4f12..7ebd6aa 100644 (file)
@@ -51,7 +51,6 @@ struct _CamelService {
        gboolean connected;
        CamelURL *url;
        int url_flags;
-
 };
 
 
index 55a466e..17d7e60 100644 (file)
 #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;
 }
 
 
index 81f8a3d..e6a6b2f 100644 (file)
@@ -53,7 +53,9 @@ struct _CamelSession
 
        CamelAuthCallback authenticator;
 
-       GHashTable *providers, *modules;
+       GHashTable *providers,
+               *modules,
+               *service_cache;
 };
 
 typedef struct {
index 87384a6..b4eae99 100644 (file)
@@ -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;
 }
 
index 96721bd..c0707dc 100644 (file)
@@ -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;
+}
index f2a4c64..bea1c43 100644 (file)
@@ -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 */
index de7a776..c663824 100644 (file)
@@ -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;
        }