2 * Copyright (C) 2005 David Schleef <ds@schleef.org>
3 * 2007-2008 Benjamin Otte <otte@gnome.org>
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301 USA
25 #include "swfdec_cache.h"
26 #include "swfdec_debug.h"
29 G_DEFINE_TYPE (SwfdecCache
, swfdec_cache
, G_TYPE_OBJECT
)
37 /* NB: assumes that the cached was already removed from cache->list */
39 swfdec_cache_remove (SwfdecCache
*cache
, SwfdecCached
*cached
)
41 cache
->size
-= swfdec_cached_get_size (cached
);
42 g_signal_handlers_disconnect_matched (cached
,
43 G_SIGNAL_MATCH_DATA
, 0, 0, NULL
, NULL
, cache
);
44 g_object_unref (cached
);
48 swfdec_cache_dispose (GObject
*object
)
50 SwfdecCache
*cache
= SWFDEC_CACHE (object
);
54 while ((cached
= g_queue_pop_tail (cache
->queue
)))
55 swfdec_cache_remove (cache
, cached
);
56 g_queue_free (cache
->queue
);
58 g_assert (cache
->size
== 0);
60 G_OBJECT_CLASS (swfdec_cache_parent_class
)->dispose (object
);
64 swfdec_cache_get_property (GObject
*object
, guint param_id
, GValue
*value
,
67 SwfdecCache
*cache
= SWFDEC_CACHE (object
);
71 g_value_set_ulong (value
, cache
->size
);
73 case PROP_MAX_CACHE_SIZE
:
74 g_value_set_ulong (value
, cache
->max_size
);
77 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, param_id
, pspec
);
83 swfdec_cache_set_property (GObject
*object
, guint param_id
, const GValue
*value
,
86 SwfdecCache
*cache
= SWFDEC_CACHE (object
);
89 case PROP_MAX_CACHE_SIZE
:
90 swfdec_cache_set_max_cache_size (cache
, g_value_get_ulong (value
));
93 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, param_id
, pspec
);
99 swfdec_cache_class_init (SwfdecCacheClass
* g_class
)
101 GObjectClass
*object_class
= G_OBJECT_CLASS (g_class
);
103 object_class
->dispose
= swfdec_cache_dispose
;
104 object_class
->get_property
= swfdec_cache_get_property
;
105 object_class
->set_property
= swfdec_cache_set_property
;
107 /* FIXME: should be g_param_spec_size(), but no such thing exists */
108 g_object_class_install_property (object_class
, PROP_CACHE_SIZE
,
109 g_param_spec_ulong ("cache-size", "cache-size", "current size of cache",
110 0, G_MAXULONG
, 0, G_PARAM_READABLE
));
111 g_object_class_install_property (object_class
, PROP_MAX_CACHE_SIZE
,
112 g_param_spec_ulong ("max-cache-size", "max-cache-size", "maximum allowed size of cache",
113 0, G_MAXULONG
, 1024 * 1024, G_PARAM_READWRITE
| G_PARAM_CONSTRUCT
));
117 swfdec_cache_init (SwfdecCache
*cache
)
119 cache
->queue
= g_queue_new ();
123 swfdec_cache_new (gsize max_size
)
125 return g_object_new (SWFDEC_TYPE_CACHE
, "max-cache-size", max_size
, NULL
);
129 swfdec_cache_get_cache_size (SwfdecCache
*cache
)
131 g_return_val_if_fail (SWFDEC_IS_CACHE (cache
), 0);
137 swfdec_cache_get_max_cache_size (SwfdecCache
*cache
)
139 g_return_val_if_fail (SWFDEC_IS_CACHE (cache
), 0);
141 return cache
->max_size
;
145 swfdec_cache_set_max_cache_size (SwfdecCache
*cache
, gsize max_size
)
147 g_return_if_fail (SWFDEC_IS_CACHE (cache
));
149 cache
->max_size
= max_size
;
150 swfdec_cache_shrink (cache
, max_size
);
151 g_object_notify (G_OBJECT (cache
), "max-cache-size");
155 swfdec_cache_shrink (SwfdecCache
*cache
, gsize size
)
157 SwfdecCached
*cached
;
159 g_return_if_fail (SWFDEC_IS_CACHE (cache
));
161 if (size
>= cache
->size
)
165 cached
= g_queue_pop_tail (cache
->queue
);
167 swfdec_cache_remove (cache
, cached
);
168 } while (size
< cache
->size
);
169 g_object_notify (G_OBJECT (cache
), "cache-size");
173 swfdec_cache_use_cached (SwfdecCached
*cached
, SwfdecCache
*cache
)
175 /* move cached item to the front of the queue */
176 g_queue_remove (cache
->queue
, cached
);
177 g_queue_push_head (cache
->queue
, cached
);
181 swfdec_cache_unuse_cached (SwfdecCached
*cached
, SwfdecCache
*cache
)
183 /* move cached item to the front of the queue */
184 g_queue_remove (cache
->queue
, cached
);
185 swfdec_cache_remove (cache
, cached
);
189 swfdec_cache_add (SwfdecCache
*cache
, SwfdecCached
*cached
)
193 g_return_if_fail (SWFDEC_IS_CACHE (cache
));
194 g_return_if_fail (SWFDEC_IS_CACHED (cached
));
196 needed_size
= swfdec_cached_get_size (cached
);
197 if (needed_size
> cache
->max_size
)
200 g_object_ref (cached
);
201 swfdec_cache_shrink (cache
, cache
->max_size
- needed_size
);
202 cache
->size
+= needed_size
;
203 g_signal_connect (cached
, "use", G_CALLBACK (swfdec_cache_use_cached
), cache
);
204 g_signal_connect (cached
, "unuse", G_CALLBACK (swfdec_cache_unuse_cached
), cache
);
205 g_queue_push_head (cache
->queue
, cached
);