Coverage Report

Created: 2026-08-25 07:00

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