1 /* GLIB - Library of useful routines for C programming
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
21 * Modified by the GLib Team and others 1997-2000. See the AUTHORS
22 * file for a list of people on the GLib Team. See the ChangeLog
23 * files for a list of changes. These files are distributed with
24 * GLib at ftp://ftp.gtk.org/pub/gtk/.
36 #include "gtestutils.h"
41 * @short_description: caches allow sharing of complex data structures
44 * A #GCache allows sharing of complex data structures, in order to
45 * save system resources.
47 * GTK+ uses caches for #GtkStyles and #GdkGCs. These consume a lot of
48 * resources, so a #GCache is used to see if a #GtkStyle or #GdkGC with
49 * the required properties already exists. If it does, then the
50 * existing object is used instead of creating a new one.
52 * #GCache uses keys and values. A #GCache key describes the properties
53 * of a particular resource. A #GCache value is the actual resource.
56 typedef struct _GCacheNode GCacheNode;
60 /* A reference counted node */
68 * The #GCache struct is an opaque data structure containing
69 * information about a #GCache. It should only be accessed via the
70 * following functions.
74 /* Called to create a value from a key */
75 GCacheNewFunc value_new_func;
77 /* Called to destroy a value */
78 GCacheDestroyFunc value_destroy_func;
80 /* Called to duplicate a key */
81 GCacheDupFunc key_dup_func;
83 /* Called to destroy a key */
84 GCacheDestroyFunc key_destroy_func;
86 /* Associates keys with nodes */
87 GHashTable *key_table;
89 /* Associates nodes with keys */
90 GHashTable *value_table;
93 static inline GCacheNode*
94 g_cache_node_new (gpointer value)
96 GCacheNode *node = g_slice_new (GCacheNode);
103 g_cache_node_destroy (GCacheNode *node)
105 g_slice_free (GCacheNode, node);
110 * @value_new_func: a function to create a new object given a key.
111 * This is called by g_cache_insert() if an object
112 * with the given key does not already exist.
113 * @value_destroy_func: a function to destroy an object. It is called
114 * by g_cache_remove() when the object is no
115 * longer needed (i.e. its reference count drops
117 * @key_dup_func: a function to copy a key. It is called by
118 * g_cache_insert() if the key does not already exist in
120 * @key_destroy_func: a function to destroy a key. It is called by
121 * g_cache_remove() when the object is no longer
122 * needed (i.e. its reference count drops to 0).
123 * @hash_key_func: a function to create a hash value from a key.
124 * @hash_value_func: a function to create a hash value from a value.
125 * @key_equal_func: a function to compare two keys. It should return
126 * %TRUE if the two keys are equivalent.
127 * @Returns: a new #GCache.
129 * Creates a new #GCache.
133 * @key: a #GCache key.
134 * @Returns: a new #GCache value corresponding to the key.
136 * Specifies the type of the @value_new_func function passed to
137 * g_cache_new(). It is passed a #GCache key and should create the
138 * value corresponding to the key.
142 * @value: the #GCache value to destroy.
144 * Specifies the type of the @value_destroy_func and @key_destroy_func
145 * functions passed to g_cache_new(). The functions are passed a
146 * pointer to the #GCache key or #GCache value and should free any
147 * memory and other resources associated with it.
151 * @value: the #GCache key to destroy (<emphasis>not</emphasis> a
152 * #GCache value as it seems).
153 * @Returns: a copy of the #GCache key.
155 * Specifies the type of the @key_dup_func function passed to
156 * g_cache_new(). The function is passed a key
157 * (<emphasis>not</emphasis> a value as the prototype implies) and
158 * should return a duplicate of the key.
161 g_cache_new (GCacheNewFunc value_new_func,
162 GCacheDestroyFunc value_destroy_func,
163 GCacheDupFunc key_dup_func,
164 GCacheDestroyFunc key_destroy_func,
165 GHashFunc hash_key_func,
166 GHashFunc hash_value_func,
167 GEqualFunc key_equal_func)
171 g_return_val_if_fail (value_new_func != NULL, NULL);
172 g_return_val_if_fail (value_destroy_func != NULL, NULL);
173 g_return_val_if_fail (key_dup_func != NULL, NULL);
174 g_return_val_if_fail (key_destroy_func != NULL, NULL);
175 g_return_val_if_fail (hash_key_func != NULL, NULL);
176 g_return_val_if_fail (hash_value_func != NULL, NULL);
177 g_return_val_if_fail (key_equal_func != NULL, NULL);
179 cache = g_slice_new (GCache);
180 cache->value_new_func = value_new_func;
181 cache->value_destroy_func = value_destroy_func;
182 cache->key_dup_func = key_dup_func;
183 cache->key_destroy_func = key_destroy_func;
184 cache->key_table = g_hash_table_new (hash_key_func, key_equal_func);
185 cache->value_table = g_hash_table_new (hash_value_func, NULL);
194 * Frees the memory allocated for the #GCache.
196 * Note that it does not destroy the keys and values which were
197 * contained in the #GCache.
200 g_cache_destroy (GCache *cache)
202 g_return_if_fail (cache != NULL);
204 g_hash_table_destroy (cache->key_table);
205 g_hash_table_destroy (cache->value_table);
206 g_slice_free (GCache, cache);
212 * @key: a key describing a #GCache object.
213 * @Returns: a pointer to a #GCache value.
215 * Gets the value corresponding to the given key, creating it if
216 * necessary. It first checks if the value already exists in the
217 * #GCache, by using the @key_equal_func function passed to
218 * g_cache_new(). If it does already exist it is returned, and its
219 * reference count is increased by one. If the value does not currently
220 * exist, if is created by calling the @value_new_func. The key is
221 * duplicated by calling @key_dup_func and the duplicated key and value
222 * are inserted into the #GCache.
225 g_cache_insert (GCache *cache,
231 g_return_val_if_fail (cache != NULL, NULL);
233 node = g_hash_table_lookup (cache->key_table, key);
236 node->ref_count += 1;
240 key = (* cache->key_dup_func) (key);
241 value = (* cache->value_new_func) (key);
242 node = g_cache_node_new (value);
244 g_hash_table_insert (cache->key_table, key, node);
245 g_hash_table_insert (cache->value_table, value, key);
253 * @value: the value to remove.
255 * Decreases the reference count of the given value. If it drops to 0
256 * then the value and its corresponding key are destroyed, using the
257 * @value_destroy_func and @key_destroy_func passed to g_cache_new().
260 g_cache_remove (GCache *cache,
266 g_return_if_fail (cache != NULL);
268 key = g_hash_table_lookup (cache->value_table, value);
269 node = g_hash_table_lookup (cache->key_table, key);
271 g_return_if_fail (node != NULL);
273 node->ref_count -= 1;
274 if (node->ref_count == 0)
276 g_hash_table_remove (cache->value_table, value);
277 g_hash_table_remove (cache->key_table, key);
279 (* cache->key_destroy_func) (key);
280 (* cache->value_destroy_func) (node->value);
281 g_cache_node_destroy (node);
286 * g_cache_key_foreach:
288 * @func: the function to call with each #GCache key.
289 * @user_data: user data to pass to the function.
291 * Calls the given function for each of the keys in the #GCache.
293 * NOTE @func is passed three parameters, the value and key of a cache
294 * entry and the @user_data. The order of value and key is different
295 * from the order in which g_hash_table_foreach() passes key-value
296 * pairs to its callback function !
299 g_cache_key_foreach (GCache *cache,
303 g_return_if_fail (cache != NULL);
304 g_return_if_fail (func != NULL);
306 g_hash_table_foreach (cache->value_table, func, user_data);
310 * g_cache_value_foreach:
312 * @func: the function to call with each #GCache value.
313 * @user_data: user data to pass to the function.
315 * Calls the given function for each of the values in the #GCache.
317 * Deprecated:2.10: The reason is that it passes pointers to internal
318 * data structures to @func; use g_cache_key_foreach()
322 g_cache_value_foreach (GCache *cache,
326 g_return_if_fail (cache != NULL);
327 g_return_if_fail (func != NULL);
329 g_hash_table_foreach (cache->key_table, func, user_data);