[kdbus] Add SipHash algorithm
[platform/upstream/glib.git] / glib / deprecated / gcache.c
1 /* GLIB - Library of useful routines for C programming
2  * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
3  *
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.
8  *
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.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
16  */
17
18 /*
19  * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
20  * file for a list of people on the GLib Team.  See the ChangeLog
21  * files for a list of changes.  These files are distributed with
22  * GLib at ftp://ftp.gtk.org/pub/gtk/.
23  */
24
25 /*
26  * MT safe
27  */
28
29 #include "config.h"
30
31 #include "gcache.h"
32
33 #include "gslice.h"
34 #include "ghash.h"
35 #include "gtestutils.h"
36
37 /**
38  * SECTION:caches
39  * @title: Caches
40  * @short_description: caches allow sharing of complex data structures
41  *                     to save resources
42  *
43  * A #GCache allows sharing of complex data structures, in order to
44  * save system resources.
45  *
46  * GCache uses keys and values. A GCache key describes the properties
47  * of a particular resource. A GCache value is the actual resource.
48  *
49  * GCache has been marked as deprecated, since this API is rarely
50  * used and not very actively maintained.
51  */
52
53 typedef struct _GCacheNode  GCacheNode;
54
55 struct _GCacheNode
56 {
57   /* A reference counted node */
58   gpointer value;
59   gint ref_count;
60 };
61
62 /**
63  * GCache:
64  *
65  * The #GCache struct is an opaque data structure containing
66  * information about a #GCache. It should only be accessed via the
67  * following functions.
68  *
69  * Deprecated:2.32: Use a #GHashTable instead
70  */
71 struct _GCache
72 {
73   /* Called to create a value from a key */
74   GCacheNewFunc value_new_func;
75
76   /* Called to destroy a value */
77   GCacheDestroyFunc value_destroy_func;
78
79   /* Called to duplicate a key */
80   GCacheDupFunc key_dup_func;
81
82   /* Called to destroy a key */
83   GCacheDestroyFunc key_destroy_func;
84
85   /* Associates keys with nodes */
86   GHashTable *key_table;
87
88   /* Associates nodes with keys */
89   GHashTable *value_table;
90 };
91
92 static inline GCacheNode*
93 g_cache_node_new (gpointer value)
94 {
95   GCacheNode *node = g_slice_new (GCacheNode);
96   node->value = value;
97   node->ref_count = 1;
98   return node;
99 }
100
101 static inline void
102 g_cache_node_destroy (GCacheNode *node)
103 {
104   g_slice_free (GCacheNode, node);
105 }
106
107 /**
108  * g_cache_new:
109  * @value_new_func: a function to create a new object given a key.
110  *                  This is called by g_cache_insert() if an object
111  *                  with the given key does not already exist
112  * @value_destroy_func: a function to destroy an object. It is called
113  *                      by g_cache_remove() when the object is no
114  *                      longer needed (i.e. its reference count drops
115  *                      to 0)
116  * @key_dup_func: a function to copy a key. It is called by
117  *                g_cache_insert() if the key does not already exist in
118  *                the #GCache
119  * @key_destroy_func: a function to destroy a key. It is called by
120  *                    g_cache_remove() when the object is no longer
121  *                    needed (i.e. its reference count drops to 0)
122  * @hash_key_func: a function to create a hash value from a key
123  * @hash_value_func: a function to create a hash value from a value
124  * @key_equal_func: a function to compare two keys. It should return
125  *                  %TRUE if the two keys are equivalent
126  *
127  * Creates a new #GCache.
128  *
129  * Returns: a new #GCache
130  *
131  * Deprecated:2.32: Use a #GHashTable instead
132  */
133
134 /**
135  * GCacheNewFunc:
136  * @key: a #GCache key
137  *
138  * Specifies the type of the @value_new_func function passed to
139  * g_cache_new(). It is passed a #GCache key and should create the
140  * value corresponding to the key.
141  *
142  * Returns: a new #GCache value corresponding to the key.
143  */
144
145 /**
146  * GCacheDestroyFunc:
147  * @value: the #GCache value to destroy
148  *
149  * Specifies the type of the @value_destroy_func and @key_destroy_func
150  * functions passed to g_cache_new(). The functions are passed a
151  * pointer to the #GCache key or #GCache value and should free any
152  * memory and other resources associated with it.
153  */
154
155 /**
156  * GCacheDupFunc:
157  * @value: the #GCache key to destroy (<emphasis>not</emphasis> a
158  *         #GCache value as it seems)
159  *
160  * Specifies the type of the @key_dup_func function passed to
161  * g_cache_new(). The function is passed a key
162  * (<emphasis>not</emphasis> a value as the prototype implies) and
163  * should return a duplicate of the key.
164  *
165  * Returns: a copy of the #GCache key
166  */
167 GCache*
168 g_cache_new (GCacheNewFunc      value_new_func,
169              GCacheDestroyFunc  value_destroy_func,
170              GCacheDupFunc      key_dup_func,
171              GCacheDestroyFunc  key_destroy_func,
172              GHashFunc          hash_key_func,
173              GHashFunc          hash_value_func,
174              GEqualFunc         key_equal_func)
175 {
176   GCache *cache;
177
178   g_return_val_if_fail (value_new_func != NULL, NULL);
179   g_return_val_if_fail (value_destroy_func != NULL, NULL);
180   g_return_val_if_fail (key_dup_func != NULL, NULL);
181   g_return_val_if_fail (key_destroy_func != NULL, NULL);
182   g_return_val_if_fail (hash_key_func != NULL, NULL);
183   g_return_val_if_fail (hash_value_func != NULL, NULL);
184   g_return_val_if_fail (key_equal_func != NULL, NULL);
185
186   cache = g_slice_new (GCache);
187   cache->value_new_func = value_new_func;
188   cache->value_destroy_func = value_destroy_func;
189   cache->key_dup_func = key_dup_func;
190   cache->key_destroy_func = key_destroy_func;
191   cache->key_table = g_hash_table_new (hash_key_func, key_equal_func);
192   cache->value_table = g_hash_table_new (hash_value_func, NULL);
193
194   return cache;
195 }
196
197 /**
198  * g_cache_destroy:
199  * @cache: a #GCache
200  *
201  * Frees the memory allocated for the #GCache.
202  *
203  * Note that it does not destroy the keys and values which were
204  * contained in the #GCache.
205  *
206  * Deprecated:2.32: Use a #GHashTable instead
207  */
208 void
209 g_cache_destroy (GCache *cache)
210 {
211   g_return_if_fail (cache != NULL);
212
213   g_hash_table_destroy (cache->key_table);
214   g_hash_table_destroy (cache->value_table);
215   g_slice_free (GCache, cache);
216 }
217
218 /**
219  * g_cache_insert:
220  * @cache: a #GCache
221  * @key: a key describing a #GCache object
222  *
223  * Gets the value corresponding to the given key, creating it if
224  * necessary. It first checks if the value already exists in the
225  * #GCache, by using the @key_equal_func function passed to
226  * g_cache_new(). If it does already exist it is returned, and its
227  * reference count is increased by one. If the value does not currently
228  * exist, if is created by calling the @value_new_func. The key is
229  * duplicated by calling @key_dup_func and the duplicated key and value
230  * are inserted into the #GCache.
231  *
232  * Returns: a pointer to a #GCache value
233  *
234  * Deprecated:2.32: Use a #GHashTable instead
235  */
236 gpointer
237 g_cache_insert (GCache   *cache,
238                 gpointer  key)
239 {
240   GCacheNode *node;
241   gpointer value;
242
243   g_return_val_if_fail (cache != NULL, NULL);
244
245   node = g_hash_table_lookup (cache->key_table, key);
246   if (node)
247     {
248       node->ref_count += 1;
249       return node->value;
250     }
251
252   key = (* cache->key_dup_func) (key);
253   value = (* cache->value_new_func) (key);
254   node = g_cache_node_new (value);
255
256   g_hash_table_insert (cache->key_table, key, node);
257   g_hash_table_insert (cache->value_table, value, key);
258
259   return node->value;
260 }
261
262 /**
263  * g_cache_remove:
264  * @cache: a #GCache
265  * @value: the value to remove
266  *
267  * Decreases the reference count of the given value. If it drops to 0
268  * then the value and its corresponding key are destroyed, using the
269  * @value_destroy_func and @key_destroy_func passed to g_cache_new().
270  *
271  * Deprecated:2.32: Use a #GHashTable instead
272  */
273 void
274 g_cache_remove (GCache        *cache,
275                 gconstpointer  value)
276 {
277   GCacheNode *node;
278   gpointer key;
279
280   g_return_if_fail (cache != NULL);
281
282   key = g_hash_table_lookup (cache->value_table, value);
283   node = g_hash_table_lookup (cache->key_table, key);
284
285   g_return_if_fail (node != NULL);
286
287   node->ref_count -= 1;
288   if (node->ref_count == 0)
289     {
290       g_hash_table_remove (cache->value_table, value);
291       g_hash_table_remove (cache->key_table, key);
292
293       (* cache->key_destroy_func) (key);
294       (* cache->value_destroy_func) (node->value);
295       g_cache_node_destroy (node);
296     }
297 }
298
299 /**
300  * g_cache_key_foreach:
301  * @cache: a #GCache
302  * @func: the function to call with each #GCache key
303  * @user_data: user data to pass to the function
304  *
305  * Calls the given function for each of the keys in the #GCache.
306  *
307  * NOTE @func is passed three parameters, the value and key of a cache
308  * entry and the @user_data. The order of value and key is different
309  * from the order in which g_hash_table_foreach() passes key-value
310  * pairs to its callback function !
311  *
312  * Deprecated:2.32: Use a #GHashTable instead
313  */
314 void
315 g_cache_key_foreach (GCache   *cache,
316                      GHFunc    func,
317                      gpointer  user_data)
318 {
319   g_return_if_fail (cache != NULL);
320   g_return_if_fail (func != NULL);
321
322   g_hash_table_foreach (cache->value_table, func, user_data);
323 }
324
325 /**
326  * g_cache_value_foreach:
327  * @cache: a #GCache
328  * @func: the function to call with each #GCache value
329  * @user_data: user data to pass to the function
330  *
331  * Calls the given function for each of the values in the #GCache.
332  *
333  * Deprecated:2.10: The reason is that it passes pointers to internal
334  *    data structures to @func; use g_cache_key_foreach() instead
335  */
336 void
337 g_cache_value_foreach (GCache   *cache,
338                        GHFunc    func,
339                        gpointer  user_data)
340 {
341   g_return_if_fail (cache != NULL);
342   g_return_if_fail (func != NULL);
343
344   g_hash_table_foreach (cache->key_table, func, user_data);
345 }