]> err.no Git - mapper/blob - src/image-cache.c
More map widget integration changes
[mapper] / src / image-cache.c
1 /*
2  * This file is part of mapper
3  *
4  * Copyright (C) 2008 Kaj-Michael Lang
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License along
17  * with this program; if not, write to the Free Software Foundation, Inc.,
18  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19  */
20
21 #include "image-cache.h"
22
23 ImageCache *
24 image_cache_new(guint cache_max)
25 {
26 ImageCache *ic;
27 ic=g_slice_new0(ImageCache);
28 ic->cache=g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_object_unref);
29 ic->cache_max=cache_max;
30 return ic;
31 }
32
33 void
34 image_cache_free(ImageCache *ic)
35 {
36 g_assert(ic);
37 g_assert(ic->cache);
38 image_cache_clear(ic);
39 g_hash_table_destroy(ic->cache);
40 g_slice_free(ImageCache, ic);
41 }
42
43 void
44 image_cache_set_size(ImageCache *ic, guint cache_size)
45 {
46 guint old;
47
48 old=ic->cache_max;
49 ic->cache_max=cache_size;
50 if (old>cache_size)
51         image_cache_gc(ic, cache_size);
52 }
53
54 static void
55 image_cache_stats(ImageCache *ic)
56 {
57 g_assert(ic);
58 g_assert(ic->cache);
59
60 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));
61 }
62
63 void
64 image_cache_clear(ImageCache *ic)
65 {
66 g_assert(ic);
67 g_assert(ic->cache);
68
69 #if (GLIB_CHECK_VERSION (2, 12, 0))
70 g_hash_table_remove_all(ic->cache);
71 #else
72 g_hash_table_foreach_remove(ic->cache, gtk_true, NULL);
73 #endif
74 }
75
76 void
77 image_cache_invalidate(ImageCache *ic, const gchar *key)
78 {
79 g_assert(ic);
80 g_assert(ic->cache);
81 g_assert(key);
82 g_hash_table_remove(ic->cache, key);
83 }
84
85 static gboolean
86 image_cache_is_same(gchar *key, GdkPixbuf *cpixbuf, GdkPixbuf *pixbuf)
87 {
88 return (pixbuf==cpixbuf) ? TRUE : FALSE;
89 }
90
91 void
92 image_cache_invalidate_by_image(ImageCache *ic, GdkPixbuf *pixbuf)
93 {
94 g_assert(ic);
95 g_assert(ic->cache);
96 g_return_if_fail(GDK_IS_PIXBUF(pixbuf));
97 g_hash_table_foreach_remove(ic->cache, image_cache_is_same, pixbuf);
98 }
99
100 void
101 image_cache_replace(ImageCache *ic, const gchar *key, GdkPixbuf *pixbuf)
102 {
103
104 }
105
106 static gboolean
107 image_cache_gc_check(gchar *key, GdkPixbuf *pixbuf, ImageCache *ic)
108 {
109 g_assert(ic);
110 /* For now just remove everything when over limit */
111 return TRUE;
112 }
113
114 void
115 image_cache_gc(ImageCache *ic, gint max)
116 {
117 gint m;
118
119 g_assert(ic);
120 g_assert(ic->cache);
121
122 m=(max>0) ? max : ic->cache_max;
123 if (g_hash_table_size(ic->cache)>m) {
124         g_hash_table_foreach_remove(ic->cache,(GHRFunc *)image_cache_gc_check, ic);
125         ic->gc++;
126 }
127 }
128
129 GdkPixbuf *
130 image_cache_get(ImageCache *ic, const gchar *key, const gchar *image)
131 {
132 GdkPixbuf *pixbuf;
133 GError *error=NULL;
134
135 g_assert(ic);
136 g_assert(ic->cache);
137 g_assert(key);
138 g_assert(image);
139
140 pixbuf=g_hash_table_lookup(ic->cache, key);
141 if (pixbuf) {
142         ic->hit++;
143         return pixbuf;
144 }
145
146 pixbuf=gdk_pixbuf_new_from_file(image, &error);
147 if (error || !pixbuf) {
148         ic->error++;
149         return NULL;
150 }
151 g_return_val_if_fail(GDK_IS_PIXBUF(pixbuf), NULL);
152
153 image_cache_gc(ic, 0);
154
155 ic->miss++;
156 g_hash_table_insert(ic->cache, g_strdup(key), pixbuf);
157 return pixbuf;
158 }