]> err.no Git - mapper/commitdiff
Add a generic and simple pixbuf cache system.
authorKaj-Michael Lang <milang@tal.org>
Fri, 11 Apr 2008 10:23:30 +0000 (13:23 +0300)
committerKaj-Michael Lang <milang@tal.org>
Fri, 11 Apr 2008 10:23:30 +0000 (13:23 +0300)
src/Makefile.am
src/image-cache.c [new file with mode: 0644]
src/image-cache.h [new file with mode: 0644]

index f89aa567f2f77df1d2c5c5909abcbc5b7aa21767..074f53022d0242fc253ffe258ca43efe397fbeeb 100644 (file)
@@ -85,6 +85,8 @@ mapper_SOURCES = \
        mapper.h \
        path.c \
        path.h \
+       image-cache.c \
+       image-cache.h \
        poi-gui.c \
        poi-gui.h \
        poi.c \
diff --git a/src/image-cache.c b/src/image-cache.c
new file mode 100644 (file)
index 0000000..6549e2d
--- /dev/null
@@ -0,0 +1,129 @@
+#include "image-cache.h"
+
+ImageCache *
+image_cache_new(guint cache_max)
+{
+ImageCache *ic;
+ic=g_slice_new0(ImageCache);
+ic->cache=g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_object_unref);
+ic->cache_max=cache_max;
+return ic;
+}
+
+void
+image_cache_free(ImageCache *ic)
+{
+g_assert(ic);
+g_assert(ic->cache);
+image_cache_clear(ic);
+g_hash_table_destroy(ic->cache);
+g_slice_free(ImageCache, ic);
+}
+
+static void
+image_cache_stats(ImageCache *ic)
+{
+g_assert(ic);
+g_assert(ic->cache);
+
+g_debug("ICC: %u/%u (E: %u, GC: %u S: %d)", ic->hit, ic->miss, ic->error, ic->gc, g_hash_table_size(ic->cache));
+}
+
+void
+image_cache_clear(ImageCache *ic)
+{
+g_assert(ic);
+g_assert(ic->cache);
+
+#if (GLIB_CHECK_VERSION (2, 12, 0))
+g_hash_table_remove_all(ic->cache);
+#else
+g_hash_table_foreach_remove(ic->cache, gtk_true, NULL);
+#endif
+}
+
+void
+image_cache_invalidate(ImageCache *ic, const gchar *key)
+{
+g_assert(ic);
+g_assert(ic->cache);
+g_assert(key);
+g_hash_table_remove(ic->cache, key);
+}
+
+static gboolean
+image_cache_is_same(gchar *key, GdkPixbuf *cpixbuf, GdkPixbuf *pixbuf)
+{
+return (pixbuf==cpixbuf) ? TRUE : FALSE;
+}
+
+void
+image_cache_invalidate_by_image(ImageCache *ic, GdkPixbuf *pixbuf)
+{
+g_assert(ic);
+g_assert(ic->cache);
+g_return_if_fail(GDK_IS_PIXBUF(pixbuf));
+g_hash_table_foreach_remove(ic->cache, image_cache_is_same, pixbuf);
+}
+
+void
+image_cache_replace(ImageCache *ic, const gchar *key, GdkPixbuf *pixbuf)
+{
+
+}
+
+static gboolean
+image_cache_gc_check(gchar *key, GdkPixbuf *pixbuf, ImageCache *ic)
+{
+g_assert(ic);
+/* For now just remove everything when over limit */
+return TRUE;
+}
+
+void
+image_cache_gc(ImageCache *ic, gint max)
+{
+gint m;
+
+g_assert(ic);
+g_assert(ic->cache);
+
+m=(max>0) ? max : ic->cache_max;
+if (g_hash_table_size(ic->cache)>m) {
+       g_hash_table_foreach_remove(ic->cache,(GHRFunc *)image_cache_gc_check, ic);
+       ic->gc++;
+}
+}
+
+GdkPixbuf *
+image_cache_get(ImageCache *ic, const gchar *key, const gchar *image)
+{
+GdkPixbuf *pixbuf;
+GError *error=NULL;
+
+g_assert(ic);
+g_assert(ic->cache);
+g_assert(key);
+g_assert(image);
+
+image_cache_stats(ic);
+
+pixbuf=g_hash_table_lookup(ic->cache, key);
+if (pixbuf) {
+       ic->hit++;
+       return pixbuf;
+}
+
+pixbuf=gdk_pixbuf_new_from_file(image, &error);
+if (error || !pixbuf) {
+       ic->error++;
+       return NULL;
+}
+g_return_val_if_fail(GDK_IS_PIXBUF(pixbuf), NULL);
+
+image_cache_gc(ic, 0);
+
+ic->miss++;
+g_hash_table_insert(ic->cache, g_strdup(key), pixbuf);
+return pixbuf;
+}
diff --git a/src/image-cache.h b/src/image-cache.h
new file mode 100644 (file)
index 0000000..15ccd1f
--- /dev/null
@@ -0,0 +1,31 @@
+#ifndef _MAPPER_IMAGE_CACHE_H
+#define _MAPPER_IMAGE_CACHE_H
+
+#include <glib.h>
+#include <gtk/gtk.h>
+
+typedef struct _image_cache_item ImageCacheItem;
+struct _image_cache_item {
+       GdkPixbuf *pixbuf;
+       time_t last_hit;
+};
+
+typedef struct _image_cache ImageCache;
+struct _image_cache {
+       GHashTable *cache;
+       guint hit;
+       guint miss;
+       guint error;
+       guint cache_max;
+       guint gc;
+};
+
+ImageCache *image_cache_new(guint cache_max);
+void image_cache_free(ImageCache *ic);
+void image_cache_clear(ImageCache *ic);
+void image_cache_gc(ImageCache *ic, gint max);
+void image_cache_invalidate(ImageCache *ic, const gchar *key);
+void image_cache_invalidate_by_image(ImageCache *ic, GdkPixbuf *pixbuf);
+GdkPixbuf *image_cache_get(ImageCache *ic, const gchar *key, const gchar *icon);
+
+#endif