[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