Author: abrander
Date: 2009-08-10 19:06:02 +0200 (Mon, 10 Aug 2009)
New Revision: 2616
Modified:
trunk/src/gtk-interface.c
trunk/src/rs-photo.c
trunk/src/rs-preload.c
trunk/src/rs-preload.h
trunk/src/rs-store.c
Log:
Changed preloader to only cache binary file data (using the OS cache) and
removed preloader checkbox from preferences.
Modified: trunk/src/gtk-interface.c
===================================================================
--- trunk/src/gtk-interface.c 2009-08-09 17:28:54 UTC (rev 2615)
+++ trunk/src/gtk-interface.c 2009-08-10 17:06:02 UTC (rev 2616)
@@ -37,7 +37,6 @@
#include "filename.h"
#include "rs-store.h"
#include "rs-preview-widget.h"
-#include "rs-preload.h"
#include "rs-photo.h"
#include "rs-external-editor.h"
#include "rs-actions.h"
@@ -353,17 +352,6 @@
}
}
-static void
-gui_preference_preload_changed(GtkToggleButton *togglebutton, gpointer
user_data)
-{
- if (togglebutton->active)
- rs_preload_set_maximum_memory(200*1024*1024);
- else
- rs_preload_set_maximum_memory(0);
-
- return;
-}
-
typedef struct {
GtkWidget *example_label;
GtkWidget *event;
@@ -563,7 +551,6 @@
GtkWidget *local_cache_check;
GtkWidget *system_theme_check;
GtkWidget *load_gdk_check;
- GtkWidget *preload_check;
GtkWidget *show_filenames;
/*
@@ -640,11 +627,6 @@
load_gdk_check = checkbox_from_conf(CONF_LOAD_GDK, _("Load 8 bit photos
(jpeg, png, etc)"), FALSE);
gtk_box_pack_start (GTK_BOX (preview_page), load_gdk_check, FALSE,
TRUE, 0);
- preload_check = checkbox_from_conf(CONF_PRELOAD, _("Preload photos"),
FALSE);
- gtk_box_pack_start (GTK_BOX (preview_page), preload_check, FALSE, TRUE,
0);
- g_signal_connect ((gpointer) preload_check, "toggled",
- G_CALLBACK (gui_preference_preload_changed), rs);
-
/*
batch_page = gtk_vbox_new(FALSE, 4);
gtk_container_set_border_width (GTK_CONTAINER (batch_page), 6);
@@ -1138,15 +1120,6 @@
gtk_widget_show_all (rs->window);
- {
- gboolean preload = FALSE;
- rs_conf_get_boolean(CONF_PRELOAD, &preload);
- if (preload)
- rs_preload_set_maximum_memory(200*1024*1024);
- else
- rs_preload_set_maximum_memory(0);
- }
-
if (argc > 1)
{
gchar *path;
Modified: trunk/src/rs-photo.c
===================================================================
--- trunk/src/rs-photo.c 2009-08-09 17:28:54 UTC (rev 2615)
+++ trunk/src/rs-photo.c 2009-08-10 17:06:02 UTC (rev 2616)
@@ -20,7 +20,6 @@
#include <rawstudio.h>
#include "rs-photo.h"
#include "rs-cache.h"
-#include "rs-preload.h"
static void rs_photo_class_init (RS_PHOTOClass *klass);
@@ -516,25 +515,16 @@
RSSettingsMask mask;
gint i;
- /* Try preloaded first! */
- photo = rs_get_preloaded(filename);
- if (photo)
- return photo;
-
- /* If photo not found in cache, try to load it */
- if (!photo)
+ image = rs_filetype_load(filename);
+ if (image)
{
- image = rs_filetype_load(filename);
- if (image)
- {
- photo = rs_photo_new();
+ photo = rs_photo_new();
- /* Set filename */
- photo->filename = g_strdup(filename);
+ /* Set filename */
+ photo->filename = g_strdup(filename);
- /* Set input image */
- photo->input = image;
- }
+ /* Set input image */
+ photo->input = image;
}
/* If photo available, read & process metadata */
Modified: trunk/src/rs-preload.c
===================================================================
--- trunk/src/rs-preload.c 2009-08-09 17:28:54 UTC (rev 2615)
+++ trunk/src/rs-preload.c 2009-08-10 17:06:02 UTC (rev 2616)
@@ -16,286 +16,89 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
USA.
*/
-
-#include <gtk/gtk.h>
-#include <glib.h>
+#if __gnu_linux__
+#define _GNU_SOURCE
+#include <fcntl.h>
+#endif /* __gnu_linux__ */
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
#include "rs-preload.h"
-#include "rs-photo.h"
-#define PRELOAD_DEBUG if (0) printf
+static GAsyncQueue *queue = NULL;
-static void rs_preload(const gchar *filename);
-
-static GThreadPool *pool = NULL;
-
-/* Which images are "near" the current image */
-static GStaticMutex near_lock = G_STATIC_MUTEX_INIT;
-static GList *near = NULL;
-
-/* The queue - to be processed */
-static GStaticMutex queue_lock = G_STATIC_MUTEX_INIT;
-static GList *queue = NULL;
-
-/* Which images are currently preloaded */
-static GStaticMutex preloaded_lock = G_STATIC_MUTEX_INIT;
-
-static GList *preloaded = NULL; /* RS_PRELOADED * */
-static size_t preloaded_memory_in_use = 0;
-
-/* The queue - to be processed */
-static GStaticMutex average_size_lock = G_STATIC_MUTEX_INIT;
-static size_t average_size = 0;
-
-/* The maximum amount of memory to use in bytes */
-static size_t max_memory = 0; /* The maximum memory to use for preload cache */
-
-/**
- * Searches in a GList of strings
- */
-static gint
-g_list_str_equal(gconstpointer a, gconstpointer b)
+static gpointer
+worker(gpointer data)
{
- if (!(a&&b)) return -1;
- return !g_str_equal(a, b);
-}
+ gchar *filename;
+ gint fd;
+ struct stat st;
-/**
- * Searches for a specific filename in a GList of RS_PRELOADED *
- */
-static gint
-g_list_find_filename(gconstpointer a, gconstpointer b)
-{
- if (!(a&&b)) return -1;
- return !g_str_equal((RS_PHOTO(a))->filename, b);
-}
+ while (1)
+ {
+ data = g_async_queue_pop(queue);
+ if (data == NULL)
+ continue;
-/**
- * Removes exactly one image from preload-cache, trying to keep images that
are "near"
- */
-static void
-_remove_one_image()
-{
- gint len, pos;
- RS_PHOTO *photo = NULL;
- GList *remove = NULL;
- GList *l;
+ filename = data;
+ fd = open(filename, O_RDONLY);
- len = g_list_length(preloaded);
- pos = len-1;
-
- /* Try to find the last cached - NOT in near list */
- while (pos >= 0)
- {
- l = g_list_nth(preloaded, pos);
- photo = l->data;
- if(!(g_list_find_custom(near, photo->filename,
g_list_str_equal)))
+ if (fd > 0)
{
- PRELOAD_DEBUG("\033[34m[NOT NEAR] ");
- remove = l;
- break;
- }
- pos--;
- }
-
- /* If all are near, pick the one farest away */
- if (!remove)
- {
- len = g_list_length(near);
- pos = len-1;
- while(pos >= 0)
- {
- if((l = g_list_find_custom(preloaded,
g_list_nth_data(near, pos), g_list_find_filename)))
+ stat(filename, &st);
+ if (st.st_size > 0)
{
- PRELOAD_DEBUG("\033[34m[NEAR] ");
- remove = l;
- break;
+#if __gnu_linux__
+ readahead(fd, 0, st.st_size);
+#else
+ gint bytes_read = 0;
+ gchar *tmp = g_new(gchar, st.st_size);
+ while(bytes_read < st.st_size)
+ bytes_read += read(fd, tmp,
st.st_size-bytes_read);
+ g_free(tmp);
+#endif /* __gnu_linux__ */
}
- pos--;
+ close(fd);
}
- }
- if (remove)
- {
- photo = remove->data;
- PRELOAD_DEBUG("Removed %s\033[0m\n", photo->filename);
-
- preloaded_memory_in_use -=
rs_image16_get_footprint(photo->input);
-
- g_object_unref(photo);
-
- preloaded = g_list_remove_link(preloaded, remove);
- g_list_free(remove);
+ g_free(data);
}
+ return NULL;
}
static void
-worker_thread(gpointer data, gpointer bogus)
+init()
{
- gchar *filename = (gchar *) data;
- RS_PHOTO *photo = NULL;
+ static GStaticMutex lock = G_STATIC_MUTEX_INIT;
- photo = rs_photo_load_from_file(filename);
- if (photo)
+ g_static_mutex_lock(&lock);
+ if (queue == NULL)
{
- GList *q = NULL;
- size_t footprint = rs_image16_get_footprint(photo->input);
- PRELOAD_DEBUG("\033[34mPreloading %s\033[0m\n", filename);
-
- g_static_mutex_lock(&queue_lock);
- g_static_mutex_lock(&preloaded_lock);
-
- while((preloaded_memory_in_use + footprint) > max_memory)
- _remove_one_image();
- preloaded_memory_in_use += footprint;
-
- /* Move from queue to preloaded */
- if ((q = g_list_find_custom(queue, filename, g_list_str_equal)))
- queue = g_list_remove_link(queue, q);
- preloaded = g_list_prepend(preloaded, photo);
-
- g_static_mutex_unlock(&preloaded_lock);
- g_static_mutex_unlock(&queue_lock);
-
- /* Calculate average image size */
- g_static_mutex_lock(&average_size_lock);
- if (average_size == 0)
- average_size = footprint;
- else
- average_size = (average_size+footprint+1)/2;
- g_static_mutex_unlock(&average_size_lock);
+ queue = g_async_queue_new_full(g_free);
+ g_thread_create_full(worker, NULL, 0, FALSE, FALSE,
G_THREAD_PRIORITY_LOW, NULL);
}
- PRELOAD_DEBUG("\033[33m[%zd/%zdMB used] [%d tasks unprocessed] [%zdMB
avg]\033[0m\n", preloaded_memory_in_use/(1024*1024), max_memory/(1024*1024),
g_thread_pool_unprocessed(pool), average_size/(1024*1024));
+ g_static_mutex_unlock(&lock);
}
/**
- * Remove all images from near list, this should be called before populating
near
+ * Empty the current queue
*/
-void
-rs_preload_near_remove_all()
+extern void
+rs_preload_cancel_all()
{
- /* Clear the "near" array, will be filled by rs_preload_near_add() */
- g_static_mutex_lock(&near_lock);
- if (near)
- {
- g_list_foreach(near, (GFunc) g_free, NULL);
- g_list_free(near);
- near = NULL;
- }
- g_static_mutex_unlock(&near_lock);
-}
+ init();
-/**
- * Add a near image, near images will be free'ed last,
- * rs_preload_near_remove_all() should be called first, to empty the list
- */
-void
-rs_preload_near_add(const gchar *filename)
-{
- if (max_memory == 0) return;
- g_static_mutex_lock(&near_lock);
- near = g_list_prepend(near, g_strdup(filename));
- g_static_mutex_unlock(&near_lock);
- rs_preload(filename);
+ while(g_async_queue_try_pop(queue));
}
/**
- * Preload a file
- * @param filename The file to preload
+ * Preloads a file - this will add file content to the OS cache
+ * @param filename A filename to preload
*/
-static void
+void
rs_preload(const gchar *filename)
{
- if (max_memory == 0) return;
+ init();
- g_static_mutex_lock(&queue_lock);
- g_static_mutex_lock(&preloaded_lock);
- if ((!g_list_find_custom(queue, filename, g_list_str_equal))
- && (!g_list_find_custom(preloaded, filename,
g_list_find_filename)))
- {
- queue = g_list_prepend(queue, g_strdup(filename));
- g_thread_pool_push(pool, g_strdup(filename), NULL);
- }
- g_static_mutex_unlock(&preloaded_lock);
- g_static_mutex_unlock(&queue_lock);
+ g_async_queue_push(queue, g_strdup(filename));
}
-
-/**
- * Get a preloaded photo
- * @param filename A filename
- * @return The new RS_PHOTO or NULL if not preloaded
- */
-RS_PHOTO *
-rs_get_preloaded(const gchar *filename)
-{
- RS_PHOTO *photo = NULL;
-
- if (max_memory == 0) return NULL;
-
- if (filename)
- {
- GList *l;
- g_static_mutex_lock(&preloaded_lock);
- if ((l = g_list_find_custom(preloaded, filename,
g_list_find_filename)))
- {
- PRELOAD_DEBUG("\033[32m%s preloaded\033[0m\n",
filename);
- photo = g_object_ref(l->data);
- }
- else
- PRELOAD_DEBUG("\033[31m%s NOT preloaded\033[0m\n",
filename);
- g_static_mutex_unlock(&preloaded_lock);
- }
-
- return photo;
-}
-
-/**
- * Get a qualified guess about how many photos we would like to have marked as
- * near
- * @return A number of photos to mark as near
- */
-gint
-rs_preload_get_near_count()
-{
- /* Defaults to 2, this should not saturate anyone */
- gint near = 2;
-
- if (max_memory == 0) return 0;
-
- g_static_mutex_lock(&average_size_lock);
- if (average_size > 0)
- near = ((max_memory*2)/3)/average_size-1;
- g_static_mutex_unlock(&average_size_lock);
-
- /* Bigger is not always better! */
- if (near > 3)
- near = 3;
-
- PRELOAD_DEBUG("near: %d\n", near);
-
- return near;
-}
-
-/**
- * Set the maximum amount of memory to be used for preload buffer
- * @param max A value in bytes, everything below 100MB will be interpreted as 0
- */
-void
-rs_preload_set_maximum_memory(size_t max)
-{
- if (max < (100*1024*1024))
- max = 0;
- max_memory = max;
-
- /* Initialize thread pool */
- if ((max_memory > 0) && (!pool))
- pool = g_thread_pool_new(worker_thread, NULL, 2, TRUE, NULL);
-
- g_static_mutex_lock(&queue_lock);
- g_static_mutex_lock(&preloaded_lock);
-
- while(preloaded_memory_in_use > max_memory)
- _remove_one_image();
-
- g_static_mutex_unlock(&preloaded_lock);
- g_static_mutex_unlock(&queue_lock);
-}
Modified: trunk/src/rs-preload.h
===================================================================
--- trunk/src/rs-preload.h 2009-08-09 17:28:54 UTC (rev 2615)
+++ trunk/src/rs-preload.h 2009-08-10 17:06:02 UTC (rev 2616)
@@ -19,44 +19,19 @@
#ifndef RS_PRELOAD_H
#define RS_PRELOAD_H
-#include "application.h"
+#include <glib.h>
/**
- * Empty the near list
+ * Empty the current queue
*/
extern void
-rs_preload_near_remove_all();
+rs_preload_cancel_all();
/**
- * Add a filename to the near list, the near list is a previous or following
- * number of photos, given by rs_preload_get_near_count() from the currently
- * selected image
- * @param filename A filename
+ * Preloads a file - this will add file content to the OS cache
+ * @param filename A filename to preload
*/
extern void
-rs_preload_near_add(const gchar *filename);
+rs_preload(const gchar *filename);
-/**
- * Get a preloaded photo
- * @param filename A filename
- * @return The new RS_PHOTO or NULL if not preloaded
- */
-extern RS_PHOTO *
-rs_get_preloaded(const gchar *filename);
-
-/**
- * Get a qualified guess about how many photos we would like to have marked as
- * near
- * @return A number of photos to mark as near
- */
-extern gint
-rs_preload_get_near_count();
-
-/**
- * Set the maximum amount of memory to be used for preload buffer
- * @param max A value in bytes, everything below 100MB will be interpreted as 0
- */
-void
-rs_preload_set_maximum_memory(size_t max);
-
#endif /* RS_PRELOAD_H */
Modified: trunk/src/rs-store.c
===================================================================
--- trunk/src/rs-store.c 2009-08-09 17:28:54 UTC (rev 2615)
+++ trunk/src/rs-store.c 2009-08-10 17:06:02 UTC (rev 2616)
@@ -358,22 +358,20 @@
gchar *filename;
gtk_tree_model_get(model, iter, FULLNAME_COLUMN, &filename, -1);
- rs_preload_near_add(filename);
+ rs_preload(filename);
}
static void
predict_preload(RSStore *store, gboolean initial)
{
GList *selected = NULL;
- gint n, near;
+ gint n, near = 5;
GtkTreeIter iter;
GtkIconView *iconview = GTK_ICON_VIEW(store->current_iconview);
GtkTreePath *path, *next, *prev;
GtkTreeModel *model = gtk_icon_view_get_model (iconview);
- near = rs_preload_get_near_count();
- if (near < 1) return;
- rs_preload_near_remove_all();
+ rs_preload_cancel_all();
/* Get a list of selected icons */
selected = gtk_icon_view_get_selected_items(iconview);
_______________________________________________
Rawstudio-commit mailing list
[email protected]
http://rawstudio.org/cgi-bin/mailman/listinfo/rawstudio-commit