[Xfce4-commits] <thunar:jannis/thumbnailer-improvements> Add thunar_thumbnail_cache_delete_file(). Use queues for processing.
Jannis Pohlmann
noreply at xfce.org
Mon Feb 7 21:26:01 CET 2011
Updating branch refs/heads/jannis/thumbnailer-improvements
to 133d32f0fcc2c37f5c581d647ae5fd02014244f3 (commit)
from 57cee92472be55feb9cb3549725190dfc035c314 (commit)
commit 133d32f0fcc2c37f5c581d647ae5fd02014244f3
Author: Jannis Pohlmann <jannis at xfce.org>
Date: Mon Feb 7 21:21:58 2011 +0100
Add thunar_thumbnail_cache_delete_file(). Use queues for processing.
We again use something like the wait queue in the old ThunarThumbnailer
here for grouping Move() and Delete() calls. The same will be done for
Copy(). It performs really well, moving 200 images from one folder to
another only generates a single Move() request with all images. At least
on my fast machine.
The actual calls to thunar_thumbnail_cache_move_file() and
thunar_thumbnail_cache_delete_file() in the transfer and I/O jobs still
have to be added.
thunar/thunar-thumbnail-cache.c | 236 ++++++++++++++++++++++++++++++++++++---
thunar/thunar-thumbnail-cache.h | 12 +-
2 files changed, 226 insertions(+), 22 deletions(-)
diff --git a/thunar/thunar-thumbnail-cache.c b/thunar/thunar-thumbnail-cache.c
index c71c672..22d9eaf 100644
--- a/thunar/thunar-thumbnail-cache.c
+++ b/thunar/thunar-thumbnail-cache.c
@@ -53,6 +53,13 @@ struct _ThunarThumbnailCache
#ifdef HAVE_DBUS
DBusGProxy *cache_proxy;
+
+ GList *move_source_queue;
+ GList *move_target_queue;
+ guint move_queue_idle_id;
+
+ GList *delete_queue;
+ guint delete_queue_idle_id;
GMutex *lock;
#endif
@@ -115,6 +122,20 @@ thunar_thumbnail_cache_finalize (GObject *object)
/* acquire a cache lock */
g_mutex_lock (cache->lock);
+ /* drop the move queue idle and all queued files */
+ if (cache->move_queue_idle_id > 0)
+ g_source_remove (cache->move_queue_idle_id);
+ g_list_foreach (cache->move_source_queue, (GFunc) g_object_unref, NULL);
+ g_list_foreach (cache->move_target_queue, (GFunc) g_object_unref, NULL);
+ g_list_free (cache->move_source_queue);
+ g_list_free (cache->move_target_queue);
+
+ /* drop the delete queue idle and all queued files */
+ if (cache->delete_queue_idle_id > 0)
+ g_source_remove (cache->delete_queue_idle_id);
+ g_list_foreach (cache->delete_queue, (GFunc) g_object_unref, NULL);
+ g_list_free (cache->delete_queue);
+
/* check if we have a valid cache proxy */
if (cache->cache_proxy != NULL)
{
@@ -160,6 +181,150 @@ thunar_thumbnail_cache_move_async (ThunarThumbnailCache *cache,
thunar_thumbnail_cache_move_async_reply,
NULL);
}
+
+
+
+static void
+thunar_thumbnail_cache_delete_async_reply (DBusGProxy *proxy,
+ GError *error,
+ gpointer user_data)
+{
+ _thunar_return_if_fail (DBUS_IS_G_PROXY (proxy));
+}
+
+
+
+static void
+thunar_thumbnail_cache_delete_async (ThunarThumbnailCache *cache,
+ const gchar **uris)
+{
+ _thunar_return_if_fail (THUNAR_IS_THUMBNAIL_CACHE (cache));
+ _thunar_return_if_fail (uris != NULL);
+
+ /* request a thumbnail cache update asynchronously */
+ thunar_thumbnail_cache_proxy_delete_async (cache->cache_proxy, uris,
+ thunar_thumbnail_cache_delete_async_reply,
+ NULL);
+}
+
+
+
+static gboolean
+thunar_thumbnail_cache_process_move_queue (ThunarThumbnailCache *cache)
+{
+ GList *sp;
+ GList *tp;
+ gchar **source_uris;
+ gchar **target_uris;
+ guint n_uris;
+ guint n;
+
+ _thunar_return_val_if_fail (THUNAR_IS_THUMBNAIL_CACHE (cache), FALSE);
+
+ /* acquire a cache lock */
+ g_mutex_lock (cache->lock);
+
+ /* compute how many URIs there are */
+ n_uris = g_list_length (cache->move_source_queue);
+
+ /* allocate a string array for the URIs */
+ source_uris = g_new0 (gchar *, n_uris + 1);
+ target_uris = g_new0 (gchar *, n_uris + 1);
+
+ /* fill URI array with file URIs from the move queue */
+ for (n = 0,
+ sp = g_list_last (cache->move_source_queue),
+ tp = g_list_last (cache->move_target_queue);
+ sp != NULL && tp != NULL;
+ sp = sp->prev, tp = tp->prev, ++n)
+ {
+ source_uris[n] = g_file_get_uri (sp->data);
+ target_uris[n] = g_file_get_uri (tp->data);
+
+ /* release the file objects */
+ g_object_unref (sp->data);
+ g_object_unref (tp->data);
+ }
+
+ /* NULL-terminate the URI arrays */
+ source_uris[n] = NULL;
+ target_uris[n] = NULL;
+
+ /* asynchronously move the thumbnails */
+ thunar_thumbnail_cache_move_async (cache,
+ (const gchar **)source_uris,
+ (const gchar **)target_uris);
+
+ /* free the URI arrays */
+ g_free (source_uris);
+ g_free (target_uris);
+
+ /* release the move queue lists */
+ g_list_free (cache->move_source_queue);
+ g_list_free (cache->move_target_queue);
+ cache->move_source_queue = NULL;
+ cache->move_target_queue = NULL;
+
+ /* reset the move queue idle ID */
+ cache->move_queue_idle_id = 0;
+
+ /* release the cache lock */
+ g_mutex_unlock (cache->lock);
+
+ return FALSE;
+}
+
+
+
+static gboolean
+thunar_thumbnail_cache_process_delete_queue (ThunarThumbnailCache *cache)
+{
+ GList *lp;
+ gchar **uris;
+ guint n_uris;
+ guint n;
+
+ _thunar_return_val_if_fail (THUNAR_IS_THUMBNAIL_CACHE (cache), FALSE);
+
+ /* acquire a cache lock */
+ g_mutex_lock (cache->lock);
+
+ /* compute how many URIs there are */
+ n_uris = g_list_length (cache->delete_queue);
+
+ /* allocate a string array for the URIs */
+ uris = g_new0 (gchar *, n_uris + 1);
+
+ /* fill URI array with file URIs from the delete queue */
+ for (lp = g_list_last (cache->delete_queue), n = 0; lp != NULL; lp = lp->prev, ++n)
+ {
+ uris[n] = g_file_get_uri (lp->data);
+
+ /* release the file object */
+ g_object_unref (lp->data);
+ }
+
+ /* NULL-terminate the URI array */
+ uris[n] = NULL;
+
+ /* asynchronously delete the thumbnails */
+ thunar_thumbnail_cache_delete_async (cache, (const gchar **)uris);
+
+ /* free the URI array */
+ g_free (uris);
+
+ /* release the delete queue list */
+ g_list_free (cache->delete_queue);
+ cache->delete_queue = NULL;
+
+ /* reset the delete queue idle ID */
+ cache->delete_queue_idle_id = 0;
+
+ /* release the cache lock */
+ g_mutex_unlock (cache->lock);
+
+ return FALSE;
+}
#endif /* HAVE_DBUS */
@@ -177,9 +342,6 @@ thunar_thumbnail_cache_move_file (ThunarThumbnailCache *cache,
GFile *source_file,
GFile *target_file)
{
- gchar *source_uris[2] = { NULL, NULL };
- gchar *target_uris[2] = { NULL, NULL };
-
_thunar_return_if_fail (THUNAR_IS_THUMBNAIL_CACHE (cache));
_thunar_return_if_fail (G_IS_FILE (source_file));
_thunar_return_if_fail (G_IS_FILE (target_file));
@@ -191,20 +353,60 @@ thunar_thumbnail_cache_move_file (ThunarThumbnailCache *cache,
/* check if we have a valid proxy for the cache service */
if (cache->cache_proxy != NULL)
{
- /* build the source and target URI arrays */
- source_uris[0] = g_file_get_uri (source_file);
- target_uris[0] = g_file_get_uri (target_file);
-
- /* notify the thumbnail cache of the move operation. the cache
- * can thereby copy the thumbnail and we avoid regenerating it
- * just because the file name changed */
- thunar_thumbnail_cache_move_async (cache,
- (const gchar **)source_uris,
- (const gchar **)target_uris);
-
- /* release the source and target URI */
- g_free (source_uris[0]);
- g_free (target_uris[0]);
+ /* cancel any pending timeout to process the move queue */
+ if (cache->move_queue_idle_id > 0)
+ {
+ g_source_remove (cache->move_queue_idle_id);
+ cache->move_queue_idle_id = 0;
+ }
+
+ /* add the files to the move queues */
+ cache->move_source_queue = g_list_prepend (cache->move_source_queue,
+ g_object_ref (source_file));
+ cache->move_target_queue = g_list_prepend (cache->move_target_queue,
+ g_object_ref (target_file));
+
+ /* process the move queue in a 250ms timeout */
+ cache->move_queue_idle_id =
+ g_timeout_add (250, (GSourceFunc) thunar_thumbnail_cache_process_move_queue,
+ cache);
+ }
+
+ /* release the cache lock */
+ g_mutex_unlock (cache->lock);
+#endif
+}
+
+
+
+void
+thunar_thumbnail_cache_delete_file (ThunarThumbnailCache *cache,
+ GFile *file)
+{
+ _thunar_return_if_fail (THUNAR_IS_THUMBNAIL_CACHE (cache));
+ _thunar_return_if_fail (G_IS_FILE (file));
+
+#ifdef HAVE_DBUS
+ /* acquire a cache lock */
+ g_mutex_lock (cache->lock);
+
+ /* check if we have a valid proxy for the cache service */
+ if (cache->cache_proxy)
+ {
+ /* cancel any pending timeout to process the delete queue */
+ if (cache->delete_queue_idle_id > 0)
+ {
+ g_source_remove (cache->delete_queue_idle_id);
+ cache->delete_queue_idle_id = 0;
+ }
+
+ /* add the file to the delete queue */
+ cache->delete_queue = g_list_prepend (cache->delete_queue, g_object_ref (file));
+
+ /* process the delete queue in a 250ms timeout */
+ cache->delete_queue_idle_id =
+ g_timeout_add (250, (GSourceFunc) thunar_thumbnail_cache_process_delete_queue,
+ cache);
}
/* release the cache lock */
diff --git a/thunar/thunar-thumbnail-cache.h b/thunar/thunar-thumbnail-cache.h
index 848d707..adc023c 100644
--- a/thunar/thunar-thumbnail-cache.h
+++ b/thunar/thunar-thumbnail-cache.h
@@ -36,13 +36,15 @@ typedef struct _ThunarThumbnailCachePrivate ThunarThumbnailCachePrivate;
typedef struct _ThunarThumbnailCacheClass ThunarThumbnailCacheClass;
typedef struct _ThunarThumbnailCache ThunarThumbnailCache;
-GType thunar_thumbnail_cache_get_type (void) G_GNUC_CONST;
+GType thunar_thumbnail_cache_get_type (void) G_GNUC_CONST;
-ThunarThumbnailCache *thunar_thumbnail_cache_new (void) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
+ThunarThumbnailCache *thunar_thumbnail_cache_new (void) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
-void thunar_thumbnail_cache_move_file (ThunarThumbnailCache *cache,
- GFile *source_file,
- GFile *target_file);
+void thunar_thumbnail_cache_move_file (ThunarThumbnailCache *cache,
+ GFile *source_file,
+ GFile *target_file);
+void thunar_thumbnail_cache_delete_file (ThunarThumbnailCache *cache,
+ GFile *file);
G_END_DECLS
More information about the Xfce4-commits
mailing list