[Xfce4-commits] <tumbler:master> Optimize tumbler_service_get_supported() by not duplicating strings.

Jannis Pohlmann noreply at xfce.org
Thu Oct 8 16:42:02 CEST 2009


Updating branch refs/heads/master
         to 4bb5a7a70e138964f3a5bf3973efe2e57881a989 (commit)
       from 0368ed8b88ba63b440d4a370178868de63318e2a (commit)

commit 4bb5a7a70e138964f3a5bf3973efe2e57881a989
Author: Jannis Pohlmann <jannis at xfce.org>
Date:   Thu Oct 8 16:38:18 2009 +0200

    Optimize tumbler_service_get_supported() by not duplicating strings.
    
    Instead, we remember all strings used in the process of generating URI
    scheme / MIME type pairs. We don't free them immediately but leave them
    in memory for reuse in the hash table used to collect unique pairs and
    in the pair arrays returned by the GetSupported() D-Bus method. We free
    them at the very end of the function.

 tumblerd/tumbler-service.c |  110 ++++++++++++++++++++++++++------------------
 1 files changed, 65 insertions(+), 45 deletions(-)

diff --git a/tumblerd/tumbler-service.c b/tumblerd/tumbler-service.c
index eda23c4..72e38ae 100644
--- a/tumblerd/tumbler-service.c
+++ b/tumblerd/tumbler-service.c
@@ -533,28 +533,31 @@ tumbler_service_unqueue (TumblerService        *service,
 }
 
 
+
 void
 tumbler_service_get_supported (TumblerService        *service,
                                DBusGMethodInvocation *context)
 {
-  GHashTable    *types;
   GHashTableIter iter;
-  gpointer       key;
-  gpointer       value;
+  GHashTable    *unique_pairs;
+  GSList        *used_strings = NULL;
   GList         *thumbnailers;
   GList         *lp;
-  GStrv          supported_types;
-  GStrv          supported_schemes;
+  const gchar  **pair;
+  const gchar  **supported_types;
+  const gchar  **supported_schemes;
   GStrv          mime_types;
   GStrv          uri_schemes;
-  gint           n, u;
+  gchar         *pair_string;
+  gint           n;
+  gint           u;
 
   dbus_async_return_if_fail (TUMBLER_IS_SERVICE (service), context);
 
-  /* create a hash table to collect unique MIME types */
-  types = g_hash_table_new_full (g_str_hash, g_str_equal, 
-                                 (GDestroyNotify) g_free, 
-                                 (GDestroyNotify) g_strfreev);
+  /* 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);
 
@@ -569,64 +572,81 @@ tumbler_service_get_supported (TumblerService        *service,
       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 && mime_types[n] != NULL; ++n) 
+      for (n = 0; 
+           mime_types != NULL && uri_schemes != NULL && mime_types[n] != NULL; 
+           ++n)
         {
-         for (u = 0; uri_schemes != NULL && uri_schemes[u] != NULL; ++u)
-           {
-             GStrv registry = g_new0 (gchar *, 3);
-
-             registry[0] = g_strdup (uri_schemes[u]);
-             registry[1] = g_strdup (mime_types[n]);
-
-             g_hash_table_replace (types, 
-                                   g_strdup_printf ("%s-%s", uri_schemes[u],
-                                                    mime_types[n]),
-                                   registry);
-           }
+          /* 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 */
-      g_strfreev (mime_types);
-      g_strfreev (uri_schemes);
+      /* 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);
-  
-  g_mutex_unlock (service->mutex);
 
-  /* allocate a string array for them */
-  u =  g_hash_table_size (types) + 1;
-  supported_types = g_new0 (gchar *, u);
-  supported_schemes = g_new0 (gchar *, u);
+  g_mutex_unlock (service->mutex);
 
-  /* insert all MIME types & URI schemes into arrays */
+  /* 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, types);
-  while (g_hash_table_iter_next (&iter, &key, &value)) 
+  g_hash_table_iter_init (&iter, unique_pairs);
+  while (g_hash_table_iter_next (&iter, NULL, (gpointer) &pair)) 
     {
-      GStrv registry = value;
-
-      supported_schemes[n] = g_strdup (registry[0]);
-      supported_types[n] = g_strdup (registry[1]);
+      /* 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;
 
-  /* destroy the hash table we used */
-  g_hash_table_unref (types);
-
   dbus_g_method_return (context, supported_schemes, supported_types);
 
   /* free the supported types & schemes */
-  g_strfreev (supported_types);
-  g_strfreev (supported_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);
 }
 
 



More information about the Xfce4-commits mailing list