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 Library 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 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library 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.
22 typedef struct _GCacheNode GCacheNode;
23 typedef struct _GRealCache GRealCache;
27 /* A reference counted node */
34 /* Called to create a value from a key */
35 GCacheNewFunc value_new_func;
37 /* Called to destroy a value */
38 GCacheDestroyFunc value_destroy_func;
40 /* Called to duplicate a key */
41 GCacheDupFunc key_dup_func;
43 /* Called to destroy a key */
44 GCacheDestroyFunc key_destroy_func;
46 /* Associates keys with nodes */
47 GHashTable *key_table;
49 /* Associates nodes with keys */
50 GHashTable *value_table;
54 static GCacheNode* g_cache_node_new (gpointer value);
55 static void g_cache_node_destroy (GCacheNode *node);
58 static GMemChunk *node_mem_chunk = NULL;
62 g_cache_new (GCacheNewFunc value_new_func,
63 GCacheDestroyFunc value_destroy_func,
64 GCacheDupFunc key_dup_func,
65 GCacheDestroyFunc key_destroy_func,
66 GHashFunc hash_key_func,
67 GHashFunc hash_value_func,
68 GCompareFunc key_compare_func)
72 g_return_val_if_fail (value_new_func != NULL, NULL);
73 g_return_val_if_fail (value_destroy_func != NULL, NULL);
74 g_return_val_if_fail (key_dup_func != NULL, NULL);
75 g_return_val_if_fail (key_destroy_func != NULL, NULL);
76 g_return_val_if_fail (hash_key_func != NULL, NULL);
77 g_return_val_if_fail (hash_value_func != NULL, NULL);
78 g_return_val_if_fail (key_compare_func != NULL, NULL);
80 cache = g_new (GRealCache, 1);
81 cache->value_new_func = value_new_func;
82 cache->value_destroy_func = value_destroy_func;
83 cache->key_dup_func = key_dup_func;
84 cache->key_destroy_func = key_destroy_func;
85 cache->key_table = g_hash_table_new (hash_key_func, key_compare_func);
86 cache->value_table = g_hash_table_new (hash_value_func, NULL);
88 return (GCache*) cache;
92 g_cache_destroy (GCache *cache)
96 g_return_if_fail (cache != NULL);
98 rcache = (GRealCache*) cache;
99 g_hash_table_destroy (rcache->key_table);
100 g_hash_table_destroy (rcache->value_table);
105 g_cache_insert (GCache *cache,
112 g_return_val_if_fail (cache != NULL, NULL);
114 rcache = (GRealCache*) cache;
116 node = g_hash_table_lookup (rcache->key_table, key);
119 node->ref_count += 1;
123 key = (* rcache->key_dup_func) (key);
124 value = (* rcache->value_new_func) (key);
125 node = g_cache_node_new (value);
127 g_hash_table_insert (rcache->key_table, key, node);
128 g_hash_table_insert (rcache->value_table, value, key);
134 g_cache_remove (GCache *cache,
141 g_return_if_fail (cache != NULL);
143 rcache = (GRealCache*) cache;
145 key = g_hash_table_lookup (rcache->value_table, value);
146 node = g_hash_table_lookup (rcache->key_table, key);
148 node->ref_count -= 1;
149 if (node->ref_count == 0)
151 g_hash_table_remove (rcache->value_table, value);
152 g_hash_table_remove (rcache->key_table, key);
154 (* rcache->key_destroy_func) (key);
155 (* rcache->value_destroy_func) (node->value);
156 g_cache_node_destroy (node);
161 g_cache_key_foreach (GCache *cache,
167 g_return_if_fail (cache != NULL);
168 g_return_if_fail (func != NULL);
170 rcache = (GRealCache*) cache;
172 g_hash_table_foreach (rcache->value_table, func, user_data);
176 g_cache_value_foreach (GCache *cache,
182 g_return_if_fail (cache != NULL);
183 g_return_if_fail (func != NULL);
185 rcache = (GRealCache*) cache;
187 g_hash_table_foreach (rcache->key_table, func, user_data);
192 g_cache_node_new (gpointer value)
197 node_mem_chunk = g_mem_chunk_new ("cache node mem chunk", sizeof (GCacheNode),
198 1024, G_ALLOC_AND_FREE);
200 node = g_chunk_new (GCacheNode, node_mem_chunk);
209 g_cache_node_destroy (GCacheNode *node)
211 g_mem_chunk_free (node_mem_chunk, node);