thumbnails: Use NautilusHashQueue

This commit is contained in:
Corey Berla 2024-01-07 18:57:35 -08:00 committed by Peter Eisenmann
parent 04884c759a
commit 722b219b8e
3 changed files with 80 additions and 59 deletions

View file

@ -109,3 +109,47 @@ nautilus_hash_queue_remove (NautilusHashQueue *queue,
g_queue_delete_link ((GQueue *) queue, link);
g_hash_table_remove (queue->item_to_link_map, key);
}
gpointer
nautilus_hash_queue_find_item (NautilusHashQueue *queue,
gconstpointer key)
{
GList *link = g_hash_table_lookup (queue->item_to_link_map, key);
if (link == NULL)
{
return NULL;
}
return link->data;
}
void
nautilus_hash_queue_move_existing_to_head (NautilusHashQueue *queue,
gconstpointer key)
{
GList *link = g_hash_table_lookup (queue->item_to_link_map, key);
if (link == NULL)
{
return;
}
g_queue_unlink ((GQueue *) queue, link);
g_queue_push_head_link ((GQueue *) queue, link);
}
void
nautilus_hash_queue_move_existing_to_tail (NautilusHashQueue *queue,
gconstpointer key)
{
GList *link = g_hash_table_lookup (queue->item_to_link_map, key);
if (link == NULL)
{
return;
}
g_queue_unlink ((GQueue *) queue, link);
g_queue_push_tail_link ((GQueue *) queue, link);
}

View file

@ -36,8 +36,16 @@ void nautilus_hash_queue_enqueue (NautilusHashQueue *queue,
gpointer item);
void nautilus_hash_queue_remove (NautilusHashQueue *queue,
gconstpointer key);
gpointer nautilus_hash_queue_find_item (NautilusHashQueue *queue,
gconstpointer key);
void nautilus_hash_queue_move_existing_to_head (NautilusHashQueue *queue,
gconstpointer key);
void nautilus_hash_queue_move_existing_to_tail (NautilusHashQueue *queue,
gconstpointer key);
/* Get the file at the head of the queue without removing or unrefing it. */
#define nautilus_hash_queue_peek_head(queue) (g_queue_peek_head ((GQueue *) (queue)))
#define nautilus_hash_queue_is_empty(queue) (g_queue_is_empty ((GQueue *) (queue)))
#define nautilus_hash_queue_get_length(queue) (g_queue_get_length ((GQueue *) (queue)))

View file

@ -29,6 +29,7 @@
#include "nautilus-directory-notify.h"
#include "nautilus-global-preferences.h"
#include "nautilus-file-utilities.h"
#include "nautilus-hash-queue.h"
#include <math.h>
#include <gtk/gtk.h>
#include <errno.h>
@ -76,10 +77,7 @@ static guint thumbnail_thread_starter_id = 0;
/* The list of NautilusThumbnailInfo structs containing information about the
* thumbnails we are making. */
static GQueue thumbnails_to_make = G_QUEUE_INIT;
/* Quickly check if uri is in thumbnails_to_make list */
static GHashTable *thumbnails_to_make_hash = NULL;
static NautilusHashQueue *thumbnails_to_make = NULL;
/* The icons being currently thumbnailed. */
static GHashTable *currently_thumbnailing_hash = NULL;
@ -127,6 +125,13 @@ free_thumbnail_info (NautilusThumbnailInfo *info)
g_free (info);
}
static gpointer
create_info_key (gpointer item)
{
NautilusThumbnailInfo *info = item;
return info->image_uri;
}
static GnomeDesktopThumbnailFactory *
get_thumbnail_factory (void)
{
@ -168,22 +173,14 @@ get_thumbnail_factory (void)
void
nautilus_thumbnail_remove_from_queue (const char *file_uri)
{
GList *node;
NautilusThumbnailInfo *info;
if (G_UNLIKELY (thumbnails_to_make_hash == NULL))
if (G_UNLIKELY (thumbnails_to_make == NULL))
{
return;
}
node = g_hash_table_lookup (thumbnails_to_make_hash, file_uri);
if (node != NULL)
{
g_hash_table_remove (thumbnails_to_make_hash, file_uri);
free_thumbnail_info (node->data);
g_queue_delete_link (&thumbnails_to_make, node);
return;
}
nautilus_hash_queue_remove (thumbnails_to_make, file_uri);
info = g_hash_table_lookup (currently_thumbnailing_hash, file_uri);
if (info != NULL)
@ -195,39 +192,23 @@ nautilus_thumbnail_remove_from_queue (const char *file_uri)
void
nautilus_thumbnail_prioritize (const char *file_uri)
{
GList *node;
if (G_UNLIKELY (thumbnails_to_make_hash == NULL))
if (G_UNLIKELY (thumbnails_to_make == NULL))
{
return;
}
node = g_hash_table_lookup (thumbnails_to_make_hash, file_uri);
if (node != NULL)
{
g_queue_unlink (&thumbnails_to_make, node);
g_queue_push_head_link (&thumbnails_to_make, node);
}
nautilus_hash_queue_move_existing_to_head (thumbnails_to_make, file_uri);
}
void
nautilus_thumbnail_deprioritize (const char *file_uri)
{
GList *node;
if (G_UNLIKELY (thumbnails_to_make_hash == NULL))
if (G_UNLIKELY (thumbnails_to_make == NULL))
{
return;
}
node = g_hash_table_lookup (thumbnails_to_make_hash, file_uri);
if (node != NULL)
{
g_queue_unlink (&thumbnails_to_make, node);
g_queue_push_tail_link (&thumbnails_to_make, node);
}
nautilus_hash_queue_move_existing_to_tail (thumbnails_to_make, file_uri);
}
/***************************************************************************
@ -317,7 +298,7 @@ nautilus_create_thumbnail (NautilusFile *file)
time_t file_mtime = 0;
NautilusThumbnailInfo *info;
NautilusThumbnailInfo *existing_info;
GList *existing, *node;
NautilusThumbnailInfo *pending_info;
nautilus_file_set_is_thumbnailing (file, TRUE);
@ -342,29 +323,24 @@ nautilus_create_thumbnail (NautilusFile *file)
info->original_file_mtime = file_mtime;
info->updated_file_mtime = file_mtime;
if (G_UNLIKELY (thumbnails_to_make_hash == NULL))
if (G_UNLIKELY (thumbnails_to_make == NULL))
{
thumbnails_to_make_hash = g_hash_table_new (g_str_hash,
g_str_equal);
thumbnails_to_make = nautilus_hash_queue_new (g_str_hash, g_str_equal, create_info_key, NULL);
currently_thumbnailing_hash = g_hash_table_new (g_str_hash,
g_str_equal);
}
/* Check if it is already in the list of thumbnails to make or
* currently being made. */
existing = g_hash_table_lookup (thumbnails_to_make_hash, info->image_uri);
existing_info = g_hash_table_lookup (currently_thumbnailing_hash, info->image_uri);
pending_info = nautilus_hash_queue_find_item (thumbnails_to_make, info->image_uri);
if (existing == NULL && existing_info == NULL)
if (existing_info == NULL && pending_info == NULL)
{
/* Add the thumbnail to the list. */
g_debug ("(Main Thread) Adding thumbnail: %s",
info->image_uri);
g_queue_push_tail (&thumbnails_to_make, info);
node = g_queue_peek_tail_link (&thumbnails_to_make);
g_hash_table_insert (thumbnails_to_make_hash,
info->image_uri,
node);
nautilus_hash_queue_enqueue (thumbnails_to_make, info);
/* If we didn't schedule the thumbnail function to start on idle, do
* that now. We don't want to start it until all the other work is
@ -382,7 +358,7 @@ nautilus_create_thumbnail (NautilusFile *file)
/* The file in the queue might need a new original mtime */
if (existing_info == NULL)
{
existing_info = existing->data;
existing_info = pending_info;
}
existing_info->updated_file_mtime = info->original_file_mtime;
free_thumbnail_info (info);
@ -407,16 +383,12 @@ thumbnail_finalize (NautilusThumbnailInfo *info)
}
else
{
GList *node;
info->original_file_mtime = info->updated_file_mtime;
g_queue_push_tail (&thumbnails_to_make, info);
node = g_queue_peek_tail_link (&thumbnails_to_make);
g_hash_table_insert (thumbnails_to_make_hash, info->image_uri, node);
nautilus_hash_queue_enqueue (thumbnails_to_make, info);
}
if (g_queue_is_empty (&thumbnails_to_make))
if (nautilus_hash_queue_is_empty (thumbnails_to_make))
{
g_debug ("(Thumbnail Async Thread) Exiting");
}
@ -547,7 +519,6 @@ thumbnail_starter_cb (gpointer data)
time_t current_time;
guint backoff_time;
guint backoff_time_min = THUMBNAIL_CREATION_DELAY_SECS + 1;
GList *node;
g_debug ("(Main Thread) Creating thumbnails thread");
@ -560,11 +531,11 @@ thumbnail_starter_cb (gpointer data)
}
/* We loop until the queue is empty, or we reach the thread limit. */
while (ignored_thumbnails < g_queue_get_length (&thumbnails_to_make) &&
while (ignored_thumbnails < nautilus_hash_queue_get_length (thumbnails_to_make) &&
running_threads <= max_threads)
{
info = g_queue_pop_head (&thumbnails_to_make);
g_hash_table_remove (thumbnails_to_make_hash, info->image_uri);
info = nautilus_hash_queue_peek_head (thumbnails_to_make);
nautilus_hash_queue_remove (thumbnails_to_make, info->image_uri);
current_orig_mtime = info->updated_file_mtime;
time (&current_time);
@ -581,9 +552,7 @@ thumbnail_starter_cb (gpointer data)
backoff_time = THUMBNAIL_CREATION_DELAY_SECS - (current_time - current_orig_mtime);
backoff_time_min = MIN (backoff_time, backoff_time_min);
g_queue_push_tail (&thumbnails_to_make, info);
node = g_queue_peek_tail_link (&thumbnails_to_make);
g_hash_table_insert (thumbnails_to_make_hash, info->image_uri, node);
nautilus_hash_queue_enqueue (thumbnails_to_make, info);
ignored_thumbnails += 1;
continue;
}