changeset 844:efed9a1520d6

implemented generic FileData cache use it for caching decoded exif data
author nadvornik
date Wed, 18 Jun 2008 22:26:52 +0000
parents add46f9c895c
children 06929cbcd796
files 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 src/filecache.h src/image-overlay.c src/image.c src/pan-view.c src/thumb.c src/thumb_standard.c src/typedefs.h
diffstat 14 files changed, 143 insertions(+), 16 deletions(-) [+]
line wrap: on
line diff
--- a/src/Makefile.am	Tue Jun 17 20:25:05 2008 +0000
+++ b/src/Makefile.am	Wed Jun 18 22:26:52 2008 +0000
@@ -115,6 +115,8 @@
 	exif-int.h	\
 	exif-common.c   \
 	exiv2.cc	\
+	filecache.c	\
+	filecache.h	\
 	filedata.c	\
 	filedata.h	\
 	filefilter.c	\
--- a/src/bar_exif.c	Tue Jun 17 20:25:05 2008 +0000
+++ b/src/bar_exif.c	Wed Jun 18 22:26:52 2008 +0000
@@ -300,7 +300,7 @@
 			}
 		}
 
-	exif_free(exif);
+	exif_free_fd(eb->fd, exif);
 }
 
 static void bar_exif_clear(ExifBar *eb)
--- a/src/bar_info.c	Tue Jun 17 20:25:05 2008 +0000
+++ b/src/bar_info.c	Wed Jun 18 22:26:52 2008 +0000
@@ -355,7 +355,7 @@
 			}
 		}
 
-	exif_free(exif);
+	exif_free_fd(fd, exif);
 
 	return (comment && *comment) || (keywords && *keywords);
 }
@@ -401,7 +401,7 @@
 
 	success = exif_write(exif);
 
-	exif_free(exif);
+	exif_free_fd(fd, exif);
 
 	return success;
 }
--- a/src/cache-loader.c	Tue Jun 17 20:25:05 2008 +0000
+++ b/src/cache-loader.c	Wed Jun 18 22:26:52 2008 +0000
@@ -148,7 +148,7 @@
 					}
 				g_free(text);
 				}
-			exif_free(exif);
+			exif_free_fd(cl->fd, exif);
 			}
 
 		cl->cd->date = date;
--- a/src/exif-common.c	Tue Jun 17 20:25:05 2008 +0000
+++ b/src/exif-common.c	Wed Jun 18 22:26:52 2008 +0000
@@ -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 @@
 	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 @@
 		}
 
 
-	// 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 */
 
--- a/src/exif.h	Tue Jun 17 20:25:05 2008 +0000
+++ b/src/exif.h	Wed Jun 18 22:26:52 2008 +0000
@@ -61,8 +61,6 @@
 
 typedef struct _ExifItem ExifItem;
 
-typedef struct _ExifData ExifData;
-
 typedef struct _ExifRational ExifRational;
 struct _ExifRational
 {
@@ -110,6 +108,7 @@
 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);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/filecache.c	Wed Jun 18 22:26:52 2008 +0000
@@ -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);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/filecache.h	Wed Jun 18 22:26:52 2008 +0000
@@ -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
--- a/src/image-overlay.c	Tue Jun 17 20:25:05 2008 +0000
+++ b/src/image-overlay.c	Wed Jun 18 22:26:52 2008 +0000
@@ -375,7 +375,7 @@
 		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')))
--- a/src/image.c	Tue Jun 17 20:25:05 2008 +0000
+++ b/src/image.c	Wed Jun 18 22:26:52 2008 +0000
@@ -535,7 +535,7 @@
 
 	if (!imd->cm) image_post_process_alter(imd, clamp);
 
-	exif_free(exif);
+	exif_free_fd(fd, exif);
 #endif
 }
 
@@ -731,7 +731,7 @@
 
 			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 @@
 			}
 		}
 
-	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) );
--- a/src/pan-view.c	Tue Jun 17 20:25:05 2008 +0000
+++ b/src/pan-view.c	Wed Jun 18 22:26:52 2008 +0000
@@ -1486,7 +1486,7 @@
 			}
 		}
 
-	exif_free(exif);
+	exif_free_fd(fd, exif);
 }
 
 static void pan_info_update(PanWindow *pw, PanItem *pi)
--- a/src/thumb.c	Tue Jun 17 20:25:05 2008 +0000
+++ b/src/thumb.c	Wed Jun 18 22:26:52 2008 +0000
@@ -172,7 +172,7 @@
 				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)
--- a/src/thumb_standard.c	Tue Jun 17 20:25:05 2008 +0000
+++ b/src/thumb_standard.c	Wed Jun 18 22:26:52 2008 +0000
@@ -414,7 +414,7 @@
 				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)
--- a/src/typedefs.h	Tue Jun 17 20:25:05 2008 +0000
+++ b/src/typedefs.h	Wed Jun 18 22:26:52 2008 +0000
@@ -177,6 +177,8 @@
 
 typedef struct _SecureSaveInfo SecureSaveInfo;
 
+typedef struct _ExifData ExifData;
+
 typedef struct _Editor Editor;
 struct _Editor {
 	gchar *name;
@@ -449,6 +451,8 @@
 	gint version; /* increased when any field in this structure is changed */
 	gint user_orientation;
 	gint exif_orientation;
+	
+	ExifData *exif;
 };
 
 struct _LayoutWindow