implemented generic FileData cache
authorVladimir Nadvornik <nadvornik@suse.cz>
Wed, 18 Jun 2008 22:26:52 +0000 (22:26 +0000)
committerVladimir Nadvornik <nadvornik@suse.cz>
Wed, 18 Jun 2008 22:26:52 +0000 (22:26 +0000)
use it for caching decoded exif data

14 files changed:
src/Makefile.am
src/bar_exif.c
src/bar_info.c
src/cache-loader.c
src/exif-common.c
src/exif.h
src/filecache.c [new file with mode: 0644]
src/filecache.h [new file with mode: 0644]
src/image-overlay.c
src/image.c
src/pan-view.c
src/thumb.c
src/thumb_standard.c
src/typedefs.h

index cfe02c5..1018e7e 100644 (file)
@@ -115,6 +115,8 @@ geeqie_SOURCES = \
        exif-int.h      \
        exif-common.c   \
        exiv2.cc        \
+       filecache.c     \
+       filecache.h     \
        filedata.c      \
        filedata.h      \
        filefilter.c    \
index 0a44997..bb47cd0 100644 (file)
@@ -300,7 +300,7 @@ static void bar_exif_update(ExifBar *eb)
                        }
                }
 
-       exif_free(exif);
+       exif_free_fd(eb->fd, exif);
 }
 
 static void bar_exif_clear(ExifBar *eb)
index 1a1891a..c94ae07 100644 (file)
@@ -355,7 +355,7 @@ static gint comment_xmp_read(FileData *fd, GList **keywords, gchar **comment)
                        }
                }
 
-       exif_free(exif);
+       exif_free_fd(fd, exif);
 
        return (comment && *comment) || (keywords && *keywords);
 }
@@ -401,7 +401,7 @@ static gint comment_xmp_write(FileData *fd, GList *keywords, const gchar *commen
 
        success = exif_write(exif);
 
-       exif_free(exif);
+       exif_free_fd(fd, exif);
 
        return success;
 }
index f990c32..3915f7d 100644 (file)
@@ -148,7 +148,7 @@ static gboolean cache_loader_process(CacheLoader *cl)
                                        }
                                g_free(text);
                                }
-                       exif_free(exif);
+                       exif_free_fd(cl->fd, exif);
                        }
 
                cl->cd->date = date;
index d0bcd6a..398bf6b 100644 (file)
@@ -37,6 +37,7 @@
 
 #include "filedata.h"
 #include "filefilter.h"
+#include "filecache.h"
 #include "format_raw.h"
 #include "ui_fileops.h"
 
@@ -520,11 +521,24 @@ gchar *exif_get_data_as_text(ExifData *exif, const gchar *key)
        return NULL;
 }
 
+
+static FileCacheData *exif_cache;
+
+void exif_release_cb(FileData *fd)
+{
+       exif_free(fd->exif);
+       fd->exif = NULL;
+}
+
 ExifData *exif_read_fd(FileData *fd)
 {
        gchar *sidecar_path = NULL;
 
        if (!fd) return NULL;
+       
+       if (!exif_cache) exif_cache = file_cache_new(exif_release_cb, 4);
+       
+       if (file_cache_get(exif_cache, fd)) return fd->exif;
 
        if (filter_file_class(fd->extension, FORMAT_CLASS_RAWIMAGE))
                {
@@ -544,11 +558,17 @@ ExifData *exif_read_fd(FileData *fd)
                }
 
 
-       // FIXME: some caching would be nice
-       return exif_read(fd->path, sidecar_path);
+       fd->exif = exif_read(fd->path, sidecar_path);
+       return fd->exif;
 }
 
-
+void exif_free_fd(FileData *fd, ExifData *exif)
+{
+       if (!fd) return;
+       g_assert(fd->exif == exif);
+       
+       file_cache_put(exif_cache, fd, 1);
+}
 
 /* embedded icc in jpeg */
 
index e315e26..4c39fc0 100644 (file)
@@ -61,8 +61,6 @@ typedef enum {
 
 typedef struct _ExifItem ExifItem;
 
-typedef struct _ExifData ExifData;
-
 typedef struct _ExifRational ExifRational;
 struct _ExifRational
 {
@@ -110,6 +108,7 @@ struct _ExifFormattedText
 ExifData *exif_read(gchar *path, gchar *sidecar_path);
 
 ExifData *exif_read_fd(FileData *fd);
+void exif_free_fd(FileData *fd, ExifData *exif);
 
 
 int exif_write(ExifData *exif);
diff --git a/src/filecache.c b/src/filecache.c
new file mode 100644 (file)
index 0000000..3d2d8cc
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * Geeqie
+ * Copyright (C) 2008 The Geeqie Team
+ *
+ * Author: Vladimir Nadvornik
+ *
+ * This software is released under the GNU General Public License (GNU GPL).
+ * Please read the included file COPYING for more information.
+ * This software comes with no warranty of any kind, use at your own risk!
+ */
+
+
+#include "main.h"
+#include "filecache.h"
+
+/* this implements a simple LRU algorithm */
+
+struct _FileCacheData {
+       FileCacheReleaseFunc release;
+       GList *list;
+       gulong max_size;
+       gulong size;
+       };
+
+
+FileCacheData *file_cache_new(FileCacheReleaseFunc release, gulong max_size)
+{
+       FileCacheData *fc = g_new(FileCacheData, 1);
+       fc->release = release;
+       fc->list = NULL;
+       fc->max_size = max_size;
+       fc->size = 0;
+       return fc;
+}
+
+gint file_cache_get(FileCacheData *fc, FileData *fd)
+{
+       GList *work;
+       if ((work = g_list_find(fc->list, fd)))
+               {
+               fc->list = g_list_remove_link(fc->list, work);
+               fc->list = g_list_concat(work, fc->list);
+               DEBUG_1("cache hit: %s", fd->path);
+               return TRUE;
+               }
+       DEBUG_1("cache miss: %s", fd->path);
+       return FALSE;
+}
+
+void file_cache_put(FileCacheData *fc, FileData *fd, gulong size)
+{
+       GList *work;
+       FileData *last_fd;
+       if ((work = g_list_find(fc->list, fd)))
+               { 
+               /* entry already exists, move it to the beginning */
+               fc->list = g_list_remove_link(fc->list, work);
+               fc->list = g_list_concat(work, fc->list);
+               return;
+               }
+       
+       DEBUG_1("cache add: %s", fd->path);
+       file_data_ref(fd);
+       fc->list = g_list_prepend(fc->list, fd);
+       fc->size++; /* FIXME: use size */
+       
+       if (fc->size < fc->max_size) return;
+       
+       fc->size--;
+       work = g_list_last(fc->list);
+       last_fd = work->data;
+       fc->list = g_list_delete_link(fc->list, work);
+       DEBUG_1("cache remove: %s", last_fd->path);
+       fc->release(last_fd);
+       file_data_unref(last_fd);
+}
diff --git a/src/filecache.h b/src/filecache.h
new file mode 100644 (file)
index 0000000..36a7eb8
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * Geeqie
+ * Copyright (C) 2008 The Geeqie Team
+ *
+ * Author: Vladimir Nadvornik
+ *
+ * This software is released under the GNU General Public License (GNU GPL).
+ * Please read the included file COPYING for more information.
+ * This software comes with no warranty of any kind, use at your own risk!
+ */
+
+#ifndef FILECACHE_H
+#define FILECACHE_H
+
+#include "main.h"
+#include "filedata.h"
+
+typedef struct _FileCacheData FileCacheData;
+typedef void (*FileCacheReleaseFunc)(FileData *fd);
+
+
+FileCacheData *file_cache_new(FileCacheReleaseFunc release, gulong max_size);
+gint file_cache_get(FileCacheData *fc, FileData *fd);
+void file_cache_put(FileCacheData *fc, FileData *fd, gulong size);
+
+#endif
index 975c9f4..28add8d 100644 (file)
@@ -375,7 +375,7 @@ static gchar *image_osd_mkinfo(const gchar *str, ImageWindow *imd, GHashTable *v
                g_free(data);
                }
 
-       exif_free(exif);
+       exif_free_fd(imd->image_fd, exif);
        /* search and destroy empty lines */
        end = new->str;
        while ((start = strchr(end, '\n')))
index 5a2d6c5..006c646 100644 (file)
@@ -535,7 +535,7 @@ static void image_post_process(ImageWindow *imd, gint clamp)
 
        if (!imd->cm) image_post_process_alter(imd, clamp);
 
-       exif_free(exif);
+       exif_free_fd(fd, exif);
 #endif
 }
 
@@ -731,7 +731,7 @@ static gint image_post_buffer_get(ImageWindow *imd)
 
                        if (imd->color_profile_use_image) exif = exif_read_fd(imd->image_fd);
 //                     image_post_process_color(imd, imd->prev_color_row, exif, TRUE);
-                       exif_free(exif);
+                       exif_free_fd(imd->image_fd, exif);
                        }
                success = TRUE;
                }
@@ -1328,7 +1328,7 @@ void image_change_pixbuf(ImageWindow *imd, GdkPixbuf *pixbuf, gdouble zoom)
                        }
                }
 
-       exif_free(exif);
+       exif_free_fd(imd->image_fd, exif);
 
        if (imd->cm || imd->desaturate)
                pixbuf_renderer_set_post_process_func((PixbufRenderer *)imd->pr, image_post_process_tile_color_cb, (gpointer) imd, (imd->cm != NULL) );
index a770553..d29c472 100644 (file)
@@ -1486,7 +1486,7 @@ static void pan_info_add_exif(PanTextAlignment *ta, FileData *fd)
                        }
                }
 
-       exif_free(exif);
+       exif_free_fd(fd, exif);
 }
 
 static void pan_info_update(PanWindow *pw, PanItem *pi)
index 05c64a9..4247ae4 100644 (file)
@@ -172,7 +172,7 @@ static void thumb_loader_done_cb(ImageLoader *il, gpointer data)
                                tl->fd->exif_orientation = orientation;
                        else
                                tl->fd->exif_orientation = EXIF_ORIENTATION_TOP_LEFT;
-                       exif_free(exif);
+                       exif_free_fd(tl->fd, exif);
                        }
                
                if (tl->fd->exif_orientation != EXIF_ORIENTATION_TOP_LEFT)
index 5dbc421..4967ef8 100644 (file)
@@ -414,7 +414,7 @@ static GdkPixbuf *thumb_loader_std_finish(ThumbLoaderStd *tl, GdkPixbuf *pixbuf,
                                tl->fd->exif_orientation = orientation;
                        else
                                tl->fd->exif_orientation = EXIF_ORIENTATION_TOP_LEFT;
-                       exif_free(exif);
+                       exif_free_fd(tl->fd, exif);
                        }
                
                if (tl->fd->exif_orientation != EXIF_ORIENTATION_TOP_LEFT)
index d5c9c82..51befa6 100644 (file)
@@ -177,6 +177,8 @@ typedef struct _Histogram Histogram;
 
 typedef struct _SecureSaveInfo SecureSaveInfo;
 
+typedef struct _ExifData ExifData;
+
 typedef struct _Editor Editor;
 struct _Editor {
        gchar *name;
@@ -449,6 +451,8 @@ struct _FileData {
        gint version; /* increased when any field in this structure is changed */
        gint user_orientation;
        gint exif_orientation;
+       
+       ExifData *exif;
 };
 
 struct _LayoutWindow