[Xfce4-commits] <tumbler:master> Cache supported URI schemes and MIME types in the registry.

Jannis Pohlmann noreply at xfce.org
Thu Oct 8 19:54:01 CEST 2009


Updating branch refs/heads/master
         to 82556ccd3d9d2a6c847dc1e211ea44e56bef8598 (commit)
       from 4bb5a7a70e138964f3a5bf3973efe2e57881a989 (commit)

commit 82556ccd3d9d2a6c847dc1e211ea44e56bef8598
Author: Jannis Pohlmann <jannis at xfce.org>
Date:   Thu Oct 8 19:52:15 2009 +0200

    Cache supported URI schemes and MIME types in the registry.
    
    This way, GetSupported() doesn't have to collect the same stuff over and
    over again. Determine all unique pairs of supported schemes/types is
    very expensive and should only be done when necessary.

 tumblerd/tumbler-registry.c |  271 ++++++++++++++++++++++++++++++++++++-------
 tumblerd/tumbler-service.c  |  109 +----------------
 2 files changed, 236 insertions(+), 144 deletions(-)

diff --git a/tumblerd/tumbler-registry.c b/tumblerd/tumbler-registry.c
index 57562ff..d2b76f9 100644
--- a/tumblerd/tumbler-registry.c
+++ b/tumblerd/tumbler-registry.c
@@ -40,25 +40,27 @@ enum
 
 
 
-static void         tumbler_registry_finalize     (GObject            *object);
-static void         tumbler_registry_get_property (GObject            *object,
-                                                   guint               prop_id,
-                                                   GValue             *value,
-                                                   GParamSpec         *pspec);
-static void         tumbler_registry_set_property (GObject            *object,
-                                                   guint               prop_id,
-                                                   const GValue       *value,
-                                                   GParamSpec         *pspec);
-static void         tumbler_registry_remove       (const gchar        *key,
-                                                   GList             **list,
-                                                   TumblerThumbnailer *thumbnailer);
-static void         tumbler_registry_unregister   (TumblerThumbnailer *thumbnailer,
-                                                   TumblerRegistry    *registry);
-static void         tumbler_registry_list_free    (gpointer            data);
-static gint         tumbler_registry_compare      (TumblerThumbnailer *a,
-                                                   TumblerThumbnailer *b);
-TumblerThumbnailer *tumbler_registry_lookup       (TumblerRegistry    *registry,
-                                                   const gchar        *hash_key);
+static void         tumbler_registry_finalize                  (GObject            *object);
+static void         tumbler_registry_get_property              (GObject            *object,
+                                                                guint               prop_id,
+                                                                GValue             *value,
+                                                                GParamSpec         *pspec);
+static void         tumbler_registry_set_property              (GObject            *object,
+                                                                guint               prop_id,
+                                                                const GValue       *value,
+                                                                GParamSpec         *pspec);
+static void         tumbler_registry_remove                    (const gchar        *key,
+                                                                GList             **list,
+                                                                TumblerThumbnailer *thumbnailer);
+static void         tumbler_registry_unregister                (TumblerThumbnailer *thumbnailer,
+                                                                TumblerRegistry    *registry);
+static void         tumbler_registry_list_free                 (gpointer            data);
+static void         tumbler_registry_update_supported_cache    (TumblerRegistry    *registry);
+static GList       *tumbler_registry_get_thumbnailers_internal (TumblerRegistry    *registry);
+static gint         tumbler_registry_compare                   (TumblerThumbnailer *a,
+                                                                TumblerThumbnailer *b);
+TumblerThumbnailer *tumbler_registry_lookup                    (TumblerRegistry    *registry,
+                                                                const gchar        *hash_key);
 
 
 
@@ -69,10 +71,13 @@ struct _TumblerRegistryClass
 
 struct _TumblerRegistry
 {
-  GObject __parent__;
+  GObject       __parent__;
 
-  GHashTable *thumbnailers;
-  GMutex     *mutex;
+  GHashTable   *thumbnailers;
+  GMutex       *mutex;
+
+  gchar       **uri_schemes;
+  gchar       **mime_types;
 };
 
 
@@ -109,7 +114,14 @@ tumbler_registry_finalize (GObject *object)
 {
   TumblerRegistry *registry = TUMBLER_REGISTRY (object);
 
+  /* release all thumbnailers */
   g_hash_table_unref (registry->thumbnailers);
+
+  /* free the cached URI schemes and MIME types */
+  g_strfreev (registry->uri_schemes);
+  g_strfreev (registry->mime_types);
+
+  /* destroy the mutex */
   g_mutex_free (registry->mutex);
 
   (*G_OBJECT_CLASS (tumbler_registry_parent_class)->finalize) (object);
@@ -182,10 +194,14 @@ tumbler_registry_unregister (TumblerThumbnailer *thumbnailer,
 
   g_mutex_lock (registry->mutex);
 
-  g_hash_table_foreach (registry->thumbnailers, (GHFunc) tumbler_registry_remove, 
+  /* remove the thumbnailer from all hash key lists */
+  g_hash_table_foreach (registry->thumbnailers, (GHFunc) tumbler_registry_remove,
                         thumbnailer);
 
   g_mutex_unlock (registry->mutex);
+
+  /* update the cache of supported URI schemes and MIME types */
+  tumbler_registry_update_supported_cache (registry);
 }
 
 
@@ -265,6 +281,172 @@ static void tumbler_registry_list_free (gpointer data)
 
 
 
+static void
+free_pair (gpointer data)
+{
+  g_slice_free1 (2 * sizeof (const gchar *), data);
+}
+
+
+
+static void
+tumbler_registry_update_supported_cache (TumblerRegistry *registry)
+{
+  GHashTableIter iter;
+  GHashTable    *unique_pairs;
+  GSList        *used_strings = NULL;
+  GList         *thumbnailers;
+  GList         *lp;
+  const gchar  **pair;
+  GString       *pair_string;
+  GStrv          mime_types;
+  GStrv          uri_schemes;
+  gint           n;
+  gint           u;
+
+  g_return_if_fail (TUMBLER_IS_REGISTRY (registry));
+
+  g_mutex_lock (registry->mutex);
+
+  /* free the old cache */
+  g_strfreev (registry->uri_schemes);
+  registry->uri_schemes = NULL;
+  g_strfreev (registry->mime_types);
+  registry->mime_types = NULL;
+
+  /* get a list of all active thumbnailers */
+  thumbnailers = tumbler_registry_get_thumbnailers_internal (registry);
+
+  g_mutex_unlock (registry->mutex);
+
+  /* abort if there are no thumbnailers */
+  if (thumbnailers == NULL)
+    return;
+
+  /* create a hash table to collect unique URI scheme / MIME type pairs */
+  unique_pairs = g_hash_table_new_full (g_str_hash, g_str_equal, 
+                                        (GDestroyNotify) g_free, 
+                                        (GDestroyNotify) free_pair);
+
+  /* iterate over all of them */
+  for (lp = thumbnailers; lp != NULL; lp = lp->next)
+    {
+      /* determine the MIME types & URI schemes supported by the current thumbnailer */
+      mime_types = tumbler_thumbnailer_get_mime_types (lp->data);
+      uri_schemes = tumbler_thumbnailer_get_uri_schemes (lp->data);
+
+      /* insert all MIME types & URI schemes into the hash table */
+      for (n = 0; 
+           mime_types != NULL && uri_schemes != NULL && mime_types[n] != NULL; 
+           ++n)
+        {
+          /* remember the MIME type so that we can later reuse it without copying */
+          used_strings = g_slist_prepend (used_strings, mime_types[n]);
+
+          for (u = 0; uri_schemes[u] != NULL; ++u)
+            {
+              /* remember the URI scheme for this pair so that we can later reuse it 
+               * without copying. Only remember it once (n==0) to avoid segmentation 
+               * faults when freeing the list */
+              if (n == 0)
+                used_strings = g_slist_prepend (used_strings, uri_schemes[u]);
+
+              /* allocate a pair with the current URI scheme and MIME type */
+              pair = g_slice_alloc (2 * sizeof (const gchar *));
+
+              /* we can now reuse the strings */
+              pair[0] = uri_schemes[u];
+              pair[1] = mime_types[n];
+
+              /* combine the two to a unique pair identifier */
+              pair_string = g_string_new (pair[0]);
+              g_string_append_c (pair_string, '-');
+              g_string_append (pair_string, pair[1]);
+
+              /* remember the pair in the hash table */
+              g_hash_table_insert (unique_pairs, pair_string->str, pair);
+
+              /* free the pair string */
+              g_string_free (pair_string, FALSE);
+            }
+        }
+
+      /* free MIME types & URI schemes array. Their contents are stored in
+       * used_strings and are freed later */
+      g_free (mime_types);
+      g_free (uri_schemes);
+    }
+
+  /* relase the thumbnailer list */
+  g_list_foreach (thumbnailers, (GFunc) g_object_unref, NULL);
+  g_list_free (thumbnailers);
+
+  n = g_hash_table_size (unique_pairs);
+
+  g_mutex_lock (registry->mutex);
+
+  /* allocate a string array for the URI scheme / MIME type pairs */
+  registry->uri_schemes = g_new0 (gchar *, n+1);
+  registry->mime_types = g_new0 (gchar *, n+1);
+
+  /* insert all unique URI scheme / MIME type pairs into string arrays */
+  n = 0;
+  g_hash_table_iter_init (&iter, unique_pairs);
+  while (g_hash_table_iter_next (&iter, NULL, (gpointer) &pair)) 
+    {
+      /* fill the cache arrays with copied values */
+      registry->uri_schemes[n] = g_strdup (pair[0]);
+      registry->mime_types[n] = g_strdup (pair[1]);
+
+      ++n;
+    }
+
+  /* NULL-terminate the arrays */
+  registry->uri_schemes[n] = NULL;
+  registry->mime_types[n] = NULL;
+
+  g_mutex_unlock (registry->mutex);
+
+  /* destroy the hash table we used */
+  g_hash_table_unref (unique_pairs);
+
+  /* free all strings we used but haven't freed yet */
+  g_slist_foreach (used_strings, (GFunc) g_free, NULL);
+  g_slist_free (used_strings);
+}
+
+
+
+static GList *
+tumbler_registry_get_thumbnailers_internal (TumblerRegistry *registry)
+{
+  GList **list;
+  GList  *thumbnailers = NULL;
+  GList  *lists;
+  GList  *lp;
+
+  g_return_val_if_fail (TUMBLER_IS_REGISTRY (registry), NULL);
+
+  /* get the thumbnailer lists */
+  lists = g_hash_table_get_values (registry->thumbnailers);
+
+  for (lp = lists; lp != NULL; lp = lp->next)
+    {
+      list = lp->data;
+
+      /* add the first thumbnailer of each list to the output list */
+      if (list != NULL && *list != NULL)
+        thumbnailers = g_list_prepend (thumbnailers, g_object_ref ((*list)->data));
+    }
+
+  /* release the thumbnailer list */
+  g_list_free (lists);
+
+  return thumbnailers;
+}
+
+
+
 TumblerThumbnailer *
 tumbler_registry_lookup (TumblerRegistry *registry,
                          const gchar     *hash_key)
@@ -363,6 +545,9 @@ tumbler_registry_add (TumblerRegistry    *registry,
   g_strfreev (hash_keys);
 
   g_mutex_unlock (registry->mutex);
+
+  /* update the cached URI schemes / MIME types */
+  tumbler_registry_update_supported_cache (registry);
 }
 
 
@@ -370,29 +555,13 @@ tumbler_registry_add (TumblerRegistry    *registry,
 GList *
 tumbler_registry_get_thumbnailers (TumblerRegistry *registry)
 {
-  GList **list;
-  GList  *thumbnailers = NULL;
-  GList  *lists;
-  GList  *lp;
+  GList *thumbnailers;
 
   g_return_val_if_fail (TUMBLER_IS_REGISTRY (registry), NULL);
 
   g_mutex_lock (registry->mutex);
 
-  /* get the thumbnailer lists */
-  lists = g_hash_table_get_values (registry->thumbnailers);
-
-  for (lp = lists; lp != NULL; lp = lp->next)
-    {
-      list = lp->data;
-
-      /* add the first thumbnailer of each list to the output list */
-      if (list != NULL && *list != NULL)
-        thumbnailers = g_list_prepend (thumbnailers, (*list)->data);
-    }
-
-  /* release the thumbnailer list */
-  g_list_free (lists);
+  thumbnailers = tumbler_registry_get_thumbnailers_internal (registry);
 
   g_mutex_unlock (registry->mutex);
 
@@ -456,3 +625,23 @@ tumbler_registry_get_thumbnailer_array (TumblerRegistry *registry,
 
   return thumbnailers;
 }
+
+
+
+void
+tumbler_registry_get_supported (TumblerRegistry     *registry,
+                                const gchar *const **uri_schemes,
+                                const gchar *const **mime_types)
+{
+  g_return_if_fail (TUMBLER_IS_REGISTRY (registry));
+
+  g_mutex_lock (registry->mutex);
+  
+  if (uri_schemes != NULL)
+    *uri_schemes = (const gchar *const *)registry->uri_schemes;
+
+  if (mime_types != NULL)
+    *mime_types = (const gchar *const *)registry->mime_types;
+
+  g_mutex_unlock (registry->mutex);
+}
diff --git a/tumblerd/tumbler-service.c b/tumblerd/tumbler-service.c
index 72e38ae..2754460 100644
--- a/tumblerd/tumbler-service.c
+++ b/tumblerd/tumbler-service.c
@@ -538,115 +538,18 @@ void
 tumbler_service_get_supported (TumblerService        *service,
                                DBusGMethodInvocation *context)
 {
-  GHashTableIter iter;
-  GHashTable    *unique_pairs;
-  GSList        *used_strings = NULL;
-  GList         *thumbnailers;
-  GList         *lp;
-  const gchar  **pair;
-  const gchar  **supported_types;
-  const gchar  **supported_schemes;
-  GStrv          mime_types;
-  GStrv          uri_schemes;
-  gchar         *pair_string;
-  gint           n;
-  gint           u;
+  const gchar *const *uri_schemes;
+  const gchar *const *mime_types;
 
   dbus_async_return_if_fail (TUMBLER_IS_SERVICE (service), context);
 
-  /* create a hash table to collect unique URI scheme / MIME type pairs */
-  unique_pairs = g_hash_table_new_full (g_str_hash, g_str_equal, 
-                                        (GDestroyNotify) g_free, 
-                                        (GDestroyNotify) g_free);
-
   g_mutex_lock (service->mutex);
 
-  /* get a list of all active thumbnailers */
-  thumbnailers = tumbler_registry_get_thumbnailers (service->registry);
-
-  /* iterate over all of them */
-  for (lp = thumbnailers; lp != NULL; lp = lp->next)
-    {
-      /* determine the MIME types & URI schemes supported by the current thumbnailer */
-      mime_types = tumbler_thumbnailer_get_mime_types (lp->data);
-      uri_schemes = tumbler_thumbnailer_get_uri_schemes (lp->data);
-
-      /* insert all MIME types & URI schemes into the hash table */
-      for (n = 0; 
-           mime_types != NULL && uri_schemes != NULL && mime_types[n] != NULL; 
-           ++n)
-        {
-          /* remember the MIME type so that we can later reuse it without copying */
-          used_strings = g_slist_prepend (used_strings, mime_types[n]);
-
-          for (u = 0; uri_schemes[u] != NULL; ++u)
-            {
-              /* remember the URI scheme for this pair so that we can later reuse it 
-               * without copying. Only remember it once (n==0) to avoid segmentation 
-               * faults when freeing the list */
-              if (n == 0)
-                used_strings = g_slist_prepend (used_strings, uri_schemes[u]);
-
-              /* allocate a pair with the current URI scheme and MIME type */
-              pair = g_new0 (const gchar *, 3);
-
-              /* we can now reuse the strings */
-              pair[0] = uri_schemes[u];
-              pair[1] = mime_types[n];
-              pair[2] = NULL;
-
-              /* combine the two to a unique pair identifier */
-              pair_string = g_strdup_printf ("%s-%s", pair[0], pair[1]);
-
-              /* remember the pair in the hash table */
-              g_hash_table_insert (unique_pairs, pair_string, pair);
-            }
-        }
-
-      /* free MIME types & URI schemes array. Their contents are stored in
-       * used_strings and are freed later */
-      g_free (mime_types);
-      g_free (uri_schemes);
-    }
-
-  /* relase the thumbnailer list */
-  g_list_free (thumbnailers);
+  tumbler_registry_get_supported (service->registry, &uri_schemes, &mime_types);
 
   g_mutex_unlock (service->mutex);
 
-  /* allocate a string array for the URI scheme / MIME type pairs */
-  n =  g_hash_table_size (unique_pairs) + 1;
-  supported_types = g_new0 (const gchar *, n);
-  supported_schemes = g_new0 (const gchar *, n);
-
-  /* insert all unique URI scheme / MIME type pairs into string arrays */
-  n = 0;
-  g_hash_table_iter_init (&iter, unique_pairs);
-  while (g_hash_table_iter_next (&iter, NULL, (gpointer) &pair)) 
-    {
-      /* reuse the strings from the hash table without copying */
-      supported_schemes[n] = pair[0];
-      supported_types[n] = pair[1];
-
-      ++n;
-    }
-
-  /* NULL-terminate the arrays */
-  supported_types[n] = NULL;
-  supported_schemes[n] = NULL;
-
-  dbus_g_method_return (context, supported_schemes, supported_types);
-
-  /* free the supported types & schemes */
-  g_free (supported_types);
-  g_free (supported_schemes);
-
-  /* destroy the hash table we used */
-  g_hash_table_unref (unique_pairs);
-
-  /* free all strings we used but haven't freed yet */
-  g_slist_foreach (used_strings, (GFunc) g_free, NULL);
-  g_slist_free (used_strings);
+  dbus_g_method_return (context, uri_schemes, mime_types);
 }
 
 
@@ -654,9 +557,9 @@ void
 tumbler_service_get_schedulers (TumblerService        *service,
                                 DBusGMethodInvocation *context)
 {
-  GStrv supported_schedulers;
+  GStrv  supported_schedulers;
   GList *iter;
-  guint n = 0;
+  guint  n = 0;
 
   dbus_async_return_if_fail (TUMBLER_IS_SERVICE (service), context);
 



More information about the Xfce4-commits mailing list