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.
27 typedef struct _GCacheNode GCacheNode;
28 typedef struct _GRealCache GRealCache;
32 /* A reference counted node */
39 /* Called to create a value from a key */
40 GCacheNewFunc value_new_func;
42 /* Called to destroy a value */
43 GCacheDestroyFunc value_destroy_func;
45 /* Called to duplicate a key */
46 GCacheDupFunc key_dup_func;
48 /* Called to destroy a key */
49 GCacheDestroyFunc key_destroy_func;
51 /* Associates keys with nodes */
52 GHashTable *key_table;
54 /* Associates nodes with keys */
55 GHashTable *value_table;
59 static GCacheNode* g_cache_node_new (gpointer value);
60 static void g_cache_node_destroy (GCacheNode *node);
63 static GMemChunk *node_mem_chunk = NULL;
64 static G_LOCK_DEFINE(node_mem_chunk);
67 g_cache_new (GCacheNewFunc value_new_func,
68 GCacheDestroyFunc value_destroy_func,
69 GCacheDupFunc key_dup_func,
70 GCacheDestroyFunc key_destroy_func,
71 GHashFunc hash_key_func,
72 GHashFunc hash_value_func,
73 GCompareFunc key_compare_func)
77 g_return_val_if_fail (value_new_func != NULL, NULL);
78 g_return_val_if_fail (value_destroy_func != NULL, NULL);
79 g_return_val_if_fail (key_dup_func != NULL, NULL);
80 g_return_val_if_fail (key_destroy_func != NULL, NULL);
81 g_return_val_if_fail (hash_key_func != NULL, NULL);
82 g_return_val_if_fail (hash_value_func != NULL, NULL);
83 g_return_val_if_fail (key_compare_func != NULL, NULL);
85 cache = g_new (GRealCache, 1);
86 cache->value_new_func = value_new_func;
87 cache->value_destroy_func = value_destroy_func;
88 cache->key_dup_func = key_dup_func;
89 cache->key_destroy_func = key_destroy_func;
90 cache->key_table = g_hash_table_new (hash_key_func, key_compare_func);
91 cache->value_table = g_hash_table_new (hash_value_func, NULL);
93 return (GCache*) cache;
97 g_cache_destroy (GCache *cache)
101 g_return_if_fail (cache != NULL);
103 rcache = (GRealCache*) cache;
104 g_hash_table_destroy (rcache->key_table);
105 g_hash_table_destroy (rcache->value_table);
110 g_cache_insert (GCache *cache,
117 g_return_val_if_fail (cache != NULL, NULL);
119 rcache = (GRealCache*) cache;
121 node = g_hash_table_lookup (rcache->key_table, key);
124 node->ref_count += 1;
128 key = (* rcache->key_dup_func) (key);
129 value = (* rcache->value_new_func) (key);
130 node = g_cache_node_new (value);
132 g_hash_table_insert (rcache->key_table, key, node);
133 g_hash_table_insert (rcache->value_table, value, key);
139 g_cache_remove (GCache *cache,
146 g_return_if_fail (cache != NULL);
148 rcache = (GRealCache*) cache;
150 key = g_hash_table_lookup (rcache->value_table, value);
151 node = g_hash_table_lookup (rcache->key_table, key);
153 node->ref_count -= 1;
154 if (node->ref_count == 0)
156 g_hash_table_remove (rcache->value_table, value);
157 g_hash_table_remove (rcache->key_table, key);
159 (* rcache->key_destroy_func) (key);
160 (* rcache->value_destroy_func) (node->value);
161 g_cache_node_destroy (node);
166 g_cache_key_foreach (GCache *cache,
172 g_return_if_fail (cache != NULL);
173 g_return_if_fail (func != NULL);
175 rcache = (GRealCache*) cache;
177 g_hash_table_foreach (rcache->value_table, func, user_data);
181 g_cache_value_foreach (GCache *cache,
187 g_return_if_fail (cache != NULL);
188 g_return_if_fail (func != NULL);
190 rcache = (GRealCache*) cache;
192 g_hash_table_foreach (rcache->key_table, func, user_data);
197 g_cache_node_new (gpointer value)
201 g_lock (node_mem_chunk);
203 node_mem_chunk = g_mem_chunk_new ("cache node mem chunk", sizeof (GCacheNode),
204 1024, G_ALLOC_AND_FREE);
206 node = g_chunk_new (GCacheNode, node_mem_chunk);
207 g_unlock (node_mem_chunk);
216 g_cache_node_destroy (GCacheNode *node)
218 g_lock (node_mem_chunk);
219 g_mem_chunk_free (node_mem_chunk, node);
220 g_unlock (node_mem_chunk);