ghash.c revision 8079eb3456914a03618b92b48f75a71b25331acb
12e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor/* GLIB - Library of useful routines for C programming
22e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
32e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor *
42e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor * This library is free software; you can redistribute it and/or
5c9bd7542e1a28ba9de60048361c0a97d251833e7Tim Janik * modify it under the terms of the GNU Lesser General Public
62e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor * License as published by the Free Software Foundation; either
72e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor * version 2 of the License, or (at your option) any later version.
82e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor *
92e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor * This library is distributed in the hope that it will be useful,
102e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor * but WITHOUT ANY WARRANTY; without even the implied warranty of
112d68cbbb7d37d3f265bf1087e6ddedcc58bc62beTim Janik * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
12c9bd7542e1a28ba9de60048361c0a97d251833e7Tim Janik * Lesser General Public License for more details.
132e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor *
14c9bd7542e1a28ba9de60048361c0a97d251833e7Tim Janik * You should have received a copy of the GNU Lesser General Public
152e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor * License along with this library; if not, write to the
162e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
172e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor * Boston, MA 02111-1307, USA.
182e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor */
19931ea952650b013b834041b91b0c37a748ffd449Owen Taylor
20b9ef2b41db975061960e2217220668c2a5d563daCST/*
21c9bd7542e1a28ba9de60048361c0a97d251833e7Tim Janik * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
22b9ef2b41db975061960e2217220668c2a5d563daCST * file for a list of people on the GLib Team.  See the ChangeLog
23b9ef2b41db975061960e2217220668c2a5d563daCST * files for a list of changes.  These files are distributed with
24b9ef2b41db975061960e2217220668c2a5d563daCST * GLib at ftp://ftp.gtk.org/pub/gtk/.
25b9ef2b41db975061960e2217220668c2a5d563daCST */
26b9ef2b41db975061960e2217220668c2a5d563daCST
27931ea952650b013b834041b91b0c37a748ffd449Owen Taylor/*
28931ea952650b013b834041b91b0c37a748ffd449Owen Taylor * MT safe
29931ea952650b013b834041b91b0c37a748ffd449Owen Taylor */
30931ea952650b013b834041b91b0c37a748ffd449Owen Taylor
312fb47703e2929d300a3f804268a36d50543b4a2cSebastian Wilhelmi#ifdef HAVE_CONFIG_H
322fb47703e2929d300a3f804268a36d50543b4a2cSebastian Wilhelmi#include <config.h>
332fb47703e2929d300a3f804268a36d50543b4a2cSebastian Wilhelmi#endif
342fb47703e2929d300a3f804268a36d50543b4a2cSebastian Wilhelmi
352e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor#include "glib.h"
362e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor
372e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor
382e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor#define HASH_TABLE_MIN_SIZE 11
392e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor#define HASH_TABLE_MAX_SIZE 13845163
402e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor
412e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor
422e0320d57e417f7d1c838d729a99545db2228e9Owen Taylortypedef struct _GHashNode      GHashNode;
432e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor
442e0320d57e417f7d1c838d729a99545db2228e9Owen Taylorstruct _GHashNode
452e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor{
46a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann  gpointer   key;
47a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann  gpointer   value;
482e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor  GHashNode *next;
492e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor};
502e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor
517519c2338ae484135b44bbb7eb49719aea8c4ca3Lauri Alankostruct _GHashTable
522e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor{
53a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann  gint             size;
54a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann  gint             nnodes;
55a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann  GHashNode      **nodes;
56a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann  GHashFunc        hash_func;
57a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann  GEqualFunc       key_equal_func;
58a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann  GDestroyNotify   key_destroy_func;
59a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann  GDestroyNotify   value_destroy_func;
602e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor};
612e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor
628079eb3456914a03618b92b48f75a71b25331acbOwen Taylor#define G_HASH_TABLE_RESIZE(hash_table)				\
638079eb3456914a03618b92b48f75a71b25331acbOwen Taylor   G_STMT_START {						\
648079eb3456914a03618b92b48f75a71b25331acbOwen Taylor     if ((hash_table->size >= 3 * hash_table->nnodes &&	        \
658079eb3456914a03618b92b48f75a71b25331acbOwen Taylor	  hash_table->size > HASH_TABLE_MIN_SIZE) ||		\
668079eb3456914a03618b92b48f75a71b25331acbOwen Taylor	 (3 * hash_table->size <= hash_table->nnodes &&	        \
678079eb3456914a03618b92b48f75a71b25331acbOwen Taylor	  hash_table->size < HASH_TABLE_MAX_SIZE))		\
688079eb3456914a03618b92b48f75a71b25331acbOwen Taylor	   g_hash_table_resize (hash_table);			\
698079eb3456914a03618b92b48f75a71b25331acbOwen Taylor   } G_STMT_END
702e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor
71a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumannstatic void		g_hash_table_resize	  (GHashTable	  *hash_table);
72a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumannstatic GHashNode**	g_hash_table_lookup_node  (GHashTable     *hash_table,
73a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann                                                   gconstpointer   key);
74a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumannstatic GHashNode*	g_hash_node_new		  (gpointer	   key,
75a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann                                                   gpointer        value);
76a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumannstatic void		g_hash_node_destroy	  (GHashNode	  *hash_node,
77a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann                                                   GDestroyNotify  key_destroy_func,
78a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann                                                   GDestroyNotify  value_destroy_func);
79a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumannstatic void		g_hash_nodes_destroy	  (GHashNode	  *hash_node,
80a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann						  GDestroyNotify   key_destroy_func,
81a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann						  GDestroyNotify   value_destroy_func);
82a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumannstatic guint g_hash_table_foreach_remove_or_steal (GHashTable     *hash_table,
83a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann                                                   GHRFunc	   func,
84a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann                                                   gpointer	   user_data,
85a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann                                                   gboolean        notify);
862e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor
872e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor
88b37e032581c44135b480dc74ae0355e72eef1372Sebastian WilhelmiG_LOCK_DEFINE_STATIC (g_hash_global);
89931ea952650b013b834041b91b0c37a748ffd449Owen Taylor
902e0320d57e417f7d1c838d729a99545db2228e9Owen Taylorstatic GMemChunk *node_mem_chunk = NULL;
912e0320d57e417f7d1c838d729a99545db2228e9Owen Taylorstatic GHashNode *node_free_list = NULL;
922e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor
93a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann/**
94a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * g_hash_table_new:
95a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * @hash_func: a function to create a hash value from a key.
96a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann *   Hash values are used to determine where keys are stored within the
97a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann *   #GHashTable data structure. The g_direct_hash(), g_int_hash() and
98a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann *   g_str_hash() functions are provided for some common types of keys.
99a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann *   If hash_func is NULL, g_direct_hash() is used.
100a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * @key_equal_func: a function to check two keys for equality.  This is
101a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann *   used when looking up keys in the #GHashTable.  The g_direct_equal(),
102a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann *   g_int_equal() and g_str_equal() functions are provided for the most
103a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann *   common types of keys. If @key_equal_func is NULL, keys are compared
104a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann *   directly in a similar fashion to g_direct_equal(), but without the
105a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann *   overhead of a function call.
106a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann *
107a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * Creates a new #GHashTable.
108a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann *
109a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * Return value: a new #GHashTable.
110a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann **/
1112e0320d57e417f7d1c838d729a99545db2228e9Owen TaylorGHashTable*
1122e0320d57e417f7d1c838d729a99545db2228e9Owen Taylorg_hash_table_new (GHashFunc    hash_func,
113267b6813703e24ef60d0e8ba42557c414f9dd52eSebastian Wilhelmi		  GEqualFunc   key_equal_func)
1142e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor{
115a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann  return g_hash_table_new_full (hash_func, key_equal_func, NULL, NULL);
116a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann}
117a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann
118a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann
119a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann/**
120a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * g_hash_table_new_full:
121a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * @hash_func: a function to create a hash value from a key.
122a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * @key_equal_func: a function to check two keys for equality.
123a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * @key_destroy_func: a function to free the memory allocated for the key
124a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann *   used when removing the entry from the #GHashTable or #NULL if you
125d18b364dd774087555f036fec2c6ec9fe838368fSven Neumann *   don't want to supply such a function.
126a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * @value_destroy_func: a function to free the memory allocated for the
127a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann *   value used when removing the entry from the #GHashTable or #NULL if
128a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann *   you don't want to supply such a function.
129a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann *
130a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * Creates a new #GHashTable like g_hash_table_new() and allows to specify
131a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * functions to free the memory allocated for the key and value that get
132a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * called when removing the entry from the #GHashTable.
133a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann *
134a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * Return value: a new #GHashTable.
135a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann **/
136a2b269bae3315a2ea772b741fb62f683c1db5770Sven NeumannGHashTable*
137a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumanng_hash_table_new_full (GHashFunc       hash_func,
138a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann		       GEqualFunc      key_equal_func,
139a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann		       GDestroyNotify  key_destroy_func,
140a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann		       GDestroyNotify  value_destroy_func)
141a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann{
1427519c2338ae484135b44bbb7eb49719aea8c4ca3Lauri Alanko  GHashTable *hash_table;
1432d68cbbb7d37d3f265bf1087e6ddedcc58bc62beTim Janik  guint i;
1442d68cbbb7d37d3f265bf1087e6ddedcc58bc62beTim Janik
1457519c2338ae484135b44bbb7eb49719aea8c4ca3Lauri Alanko  hash_table = g_new (GHashTable, 1);
146a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann  hash_table->size               = HASH_TABLE_MIN_SIZE;
147a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann  hash_table->nnodes             = 0;
148a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann  hash_table->hash_func          = hash_func ? hash_func : g_direct_hash;
149a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann  hash_table->key_equal_func     = key_equal_func;
150a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann  hash_table->key_destroy_func   = key_destroy_func;
151a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann  hash_table->value_destroy_func = value_destroy_func;
152a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann  hash_table->nodes              = g_new (GHashNode*, hash_table->size);
1532d68cbbb7d37d3f265bf1087e6ddedcc58bc62beTim Janik
1547519c2338ae484135b44bbb7eb49719aea8c4ca3Lauri Alanko  for (i = 0; i < hash_table->size; i++)
1557519c2338ae484135b44bbb7eb49719aea8c4ca3Lauri Alanko    hash_table->nodes[i] = NULL;
1562d68cbbb7d37d3f265bf1087e6ddedcc58bc62beTim Janik
1577519c2338ae484135b44bbb7eb49719aea8c4ca3Lauri Alanko  return hash_table;
1582e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor}
1592e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor
160a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann/**
161a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * g_hash_table_destroy:
162a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * @hash_table: a #GHashTable.
163a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann *
164a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * Destroys the #GHashTable. If keys and/or values are dynamically
165a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * allocated, you should either free them first or create the #GHashTable
166a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * using g_hash_table_new_full(). In the latter case the destroy functions
167a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * you supplied will be called on all keys and values before destroying
168a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * the #GHashTable.
169a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann **/
1702e0320d57e417f7d1c838d729a99545db2228e9Owen Taylorvoid
1712e0320d57e417f7d1c838d729a99545db2228e9Owen Taylorg_hash_table_destroy (GHashTable *hash_table)
1722e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor{
1732d68cbbb7d37d3f265bf1087e6ddedcc58bc62beTim Janik  guint i;
1742d68cbbb7d37d3f265bf1087e6ddedcc58bc62beTim Janik
1752d68cbbb7d37d3f265bf1087e6ddedcc58bc62beTim Janik  g_return_if_fail (hash_table != NULL);
1762d68cbbb7d37d3f265bf1087e6ddedcc58bc62beTim Janik
1777519c2338ae484135b44bbb7eb49719aea8c4ca3Lauri Alanko  for (i = 0; i < hash_table->size; i++)
178a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann    g_hash_nodes_destroy (hash_table->nodes[i],
179a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann			  hash_table->key_destroy_func,
180a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann			  hash_table->value_destroy_func);
1812d68cbbb7d37d3f265bf1087e6ddedcc58bc62beTim Janik
1827519c2338ae484135b44bbb7eb49719aea8c4ca3Lauri Alanko  g_free (hash_table->nodes);
1837519c2338ae484135b44bbb7eb49719aea8c4ca3Lauri Alanko  g_free (hash_table);
1842e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor}
1852e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor
186d5492a983cfa048658af8b03f833ddb3c0cf355eESTstatic inline GHashNode**
187d5492a983cfa048658af8b03f833ddb3c0cf355eESTg_hash_table_lookup_node (GHashTable	*hash_table,
188d5492a983cfa048658af8b03f833ddb3c0cf355eEST			  gconstpointer	 key)
1892e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor{
190d5492a983cfa048658af8b03f833ddb3c0cf355eEST  GHashNode **node;
1912d68cbbb7d37d3f265bf1087e6ddedcc58bc62beTim Janik
192d5492a983cfa048658af8b03f833ddb3c0cf355eEST  node = &hash_table->nodes
193d5492a983cfa048658af8b03f833ddb3c0cf355eEST    [(* hash_table->hash_func) (key) % hash_table->size];
1942d68cbbb7d37d3f265bf1087e6ddedcc58bc62beTim Janik
1952d68cbbb7d37d3f265bf1087e6ddedcc58bc62beTim Janik  /* Hash table lookup needs to be fast.
1962d68cbbb7d37d3f265bf1087e6ddedcc58bc62beTim Janik   *  We therefore remove the extra conditional of testing
197267b6813703e24ef60d0e8ba42557c414f9dd52eSebastian Wilhelmi   *  whether to call the key_equal_func or not from
1982d68cbbb7d37d3f265bf1087e6ddedcc58bc62beTim Janik   *  the inner loop.
1992d68cbbb7d37d3f265bf1087e6ddedcc58bc62beTim Janik   */
200267b6813703e24ef60d0e8ba42557c414f9dd52eSebastian Wilhelmi  if (hash_table->key_equal_func)
201267b6813703e24ef60d0e8ba42557c414f9dd52eSebastian Wilhelmi    while (*node && !(*hash_table->key_equal_func) ((*node)->key, key))
202d5492a983cfa048658af8b03f833ddb3c0cf355eEST      node = &(*node)->next;
2032d68cbbb7d37d3f265bf1087e6ddedcc58bc62beTim Janik  else
204d5492a983cfa048658af8b03f833ddb3c0cf355eEST    while (*node && (*node)->key != key)
205d5492a983cfa048658af8b03f833ddb3c0cf355eEST      node = &(*node)->next;
2062d68cbbb7d37d3f265bf1087e6ddedcc58bc62beTim Janik
2072d68cbbb7d37d3f265bf1087e6ddedcc58bc62beTim Janik  return node;
2082d68cbbb7d37d3f265bf1087e6ddedcc58bc62beTim Janik}
2092e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor
210a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann/**
211a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * g_hash_table_lookup:
212a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * @hash_table: a #GHashTable.
213a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * @key: the key to look up.
214a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann *
215a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * Looks up a key in a #GHashTable.
216a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann *
217a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * Return value: the associated value, or NULL if the key is not found.
218a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann **/
2192d68cbbb7d37d3f265bf1087e6ddedcc58bc62beTim Janikgpointer
2202d68cbbb7d37d3f265bf1087e6ddedcc58bc62beTim Janikg_hash_table_lookup (GHashTable	  *hash_table,
2212d68cbbb7d37d3f265bf1087e6ddedcc58bc62beTim Janik		     gconstpointer key)
2222d68cbbb7d37d3f265bf1087e6ddedcc58bc62beTim Janik{
2232d68cbbb7d37d3f265bf1087e6ddedcc58bc62beTim Janik  GHashNode *node;
2242d68cbbb7d37d3f265bf1087e6ddedcc58bc62beTim Janik
2252d68cbbb7d37d3f265bf1087e6ddedcc58bc62beTim Janik  g_return_val_if_fail (hash_table != NULL, NULL);
2262d68cbbb7d37d3f265bf1087e6ddedcc58bc62beTim Janik
227d5492a983cfa048658af8b03f833ddb3c0cf355eEST  node = *g_hash_table_lookup_node (hash_table, key);
2282d68cbbb7d37d3f265bf1087e6ddedcc58bc62beTim Janik
2292d68cbbb7d37d3f265bf1087e6ddedcc58bc62beTim Janik  return node ? node->value : NULL;
2302d68cbbb7d37d3f265bf1087e6ddedcc58bc62beTim Janik}
2317401460a60504dad7b77219d0ba3d93112e12444Manish Singh
232a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann/**
233a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * g_hash_table_lookup_extended:
234a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * @hash_table: a #GHashTable.
235a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * @lookup_key: the key to look up.
236a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * @orig_key: returns the original key.
237a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * @value: returns the value associated with the key.
238a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann *
239a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * Looks up a key in the #GHashTable, returning the original key and the
240a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * associated value and a gboolean which is TRUE if the key was found. This
241a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * is useful if you need to free the memory allocated for the original key,
242a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * for example before calling g_hash_table_remove().
243a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann *
244a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * Return value: #TRUE if the key was found in the #GHashTable.
245a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann **/
246a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumanngboolean
247a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumanng_hash_table_lookup_extended (GHashTable    *hash_table,
248a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann			      gconstpointer  lookup_key,
249a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann			      gpointer	    *orig_key,
250a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann			      gpointer	    *value)
251a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann{
252a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann  GHashNode *node;
253a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann
254a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann  g_return_val_if_fail (hash_table != NULL, FALSE);
255a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann
256a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann  node = *g_hash_table_lookup_node (hash_table, lookup_key);
257a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann
258a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann  if (node)
259a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann    {
260a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann      if (orig_key)
261a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann	*orig_key = node->key;
262a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann      if (value)
263a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann	*value = node->value;
264a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann      return TRUE;
265a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann    }
266a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann  else
267a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann    return FALSE;
268a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann}
269a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann
270a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann/**
271a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * g_hash_table_insert:
272a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * @hash_table: a #GHashTable.
273a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * @key: a key to insert.
274a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * @value: the value to associate with the key.
275a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann *
276a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * Inserts a new key and value into a #GHashTable.
277a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann *
278a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * If the key already exists in the #GHashTable its current value is replaced
279a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * with the new value. If you supplied a value_destroy_func when creating the
280a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * #GHashTable, the old value is freed using that function. If you supplied
281a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * a key_destroy_func when creating the #GHashTable, the passed key is freed
282a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * using that function.
283a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann **/
2842d68cbbb7d37d3f265bf1087e6ddedcc58bc62beTim Janikvoid
2852d68cbbb7d37d3f265bf1087e6ddedcc58bc62beTim Janikg_hash_table_insert (GHashTable *hash_table,
2862d68cbbb7d37d3f265bf1087e6ddedcc58bc62beTim Janik		     gpointer	 key,
2872d68cbbb7d37d3f265bf1087e6ddedcc58bc62beTim Janik		     gpointer	 value)
2882d68cbbb7d37d3f265bf1087e6ddedcc58bc62beTim Janik{
289d5492a983cfa048658af8b03f833ddb3c0cf355eEST  GHashNode **node;
2902d68cbbb7d37d3f265bf1087e6ddedcc58bc62beTim Janik
2912d68cbbb7d37d3f265bf1087e6ddedcc58bc62beTim Janik  g_return_if_fail (hash_table != NULL);
2922d68cbbb7d37d3f265bf1087e6ddedcc58bc62beTim Janik
293d5492a983cfa048658af8b03f833ddb3c0cf355eEST  node = g_hash_table_lookup_node (hash_table, key);
294d5492a983cfa048658af8b03f833ddb3c0cf355eEST
295d5492a983cfa048658af8b03f833ddb3c0cf355eEST  if (*node)
2967519c2338ae484135b44bbb7eb49719aea8c4ca3Lauri Alanko    {
2977519c2338ae484135b44bbb7eb49719aea8c4ca3Lauri Alanko      /* do not reset node->key in this place, keeping
298a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann       * the old key is the intended behaviour.
299a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann       * g_hash_table_replace() can be used instead.
300a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann       */
301a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann
302a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann      /* free the passed key */
303a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann      if (hash_table->key_destroy_func)
304a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann	hash_table->key_destroy_func (key);
305a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann
306a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann      if (hash_table->value_destroy_func)
307a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann	hash_table->value_destroy_func ((*node)->value);
308a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann
309a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann      (*node)->value = value;
310a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann    }
311a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann  else
312a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann    {
313a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann      *node = g_hash_node_new (key, value);
314a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann      hash_table->nnodes++;
3158079eb3456914a03618b92b48f75a71b25331acbOwen Taylor      G_HASH_TABLE_RESIZE (hash_table);
316a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann    }
317a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann}
318a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann
319a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann/**
320a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * g_hash_table_replace:
321a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * @hash_table: a #GHashTable.
322a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * @key: a key to insert.
323a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * @value: the value to associate with the key.
324a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann *
325a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * Inserts a new key and value into a #GHashTable similar to
326a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * g_hash_table_insert(). The difference is that if the key already exists
327a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * in the #GHashTable, it gets replaced by the new key. If you supplied a
328a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * value_destroy_func when creating the #GHashTable, the old value is freed
329a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * using that function. If you supplied a key_destroy_func when creating the
330a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * #GHashTable, the old key is freed using that function.
331a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann **/
332a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumannvoid
333a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumanng_hash_table_replace (GHashTable *hash_table,
334a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann		      gpointer	  key,
335a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann		      gpointer	  value)
336a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann{
337a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann  GHashNode **node;
338a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann
339a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann  g_return_if_fail (hash_table != NULL);
340a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann
341a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann  node = g_hash_table_lookup_node (hash_table, key);
342a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann
343a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann  if (*node)
344a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann    {
345a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann      if (hash_table->key_destroy_func)
346a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann	hash_table->key_destroy_func ((*node)->key);
347a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann
348a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann      if (hash_table->value_destroy_func)
349a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann	hash_table->value_destroy_func ((*node)->value);
350a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann
351a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann      (*node)->key   = key;
352d5492a983cfa048658af8b03f833ddb3c0cf355eEST      (*node)->value = value;
353d5492a983cfa048658af8b03f833ddb3c0cf355eEST    }
354d5492a983cfa048658af8b03f833ddb3c0cf355eEST  else
355d5492a983cfa048658af8b03f833ddb3c0cf355eEST    {
356d5492a983cfa048658af8b03f833ddb3c0cf355eEST      *node = g_hash_node_new (key, value);
357d5492a983cfa048658af8b03f833ddb3c0cf355eEST      hash_table->nnodes++;
3588079eb3456914a03618b92b48f75a71b25331acbOwen Taylor      G_HASH_TABLE_RESIZE (hash_table);
3592e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor    }
3602e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor}
3612e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor
362a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann/**
363a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * g_hash_table_remove:
364a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * @hash_table: a #GHashTable.
365a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * @key: the key to remove.
366a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann *
367a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * Removes a key and its associated value from a #GHashTable.
368a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann *
369a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * If the #GHashTable was created using g_hash_table_new_full(), the
370a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * key and value are freed using the supplied destroy_functions, otherwise
371a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * you have to make sure that any dynamically allocated values are freed
372a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * yourself.
373a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann *
374a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * Return value: #TRUE if the key was found and removed from the #GHashTable.
375a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann **/
3769a8c33db5cc37bc3c6bd4794a03f4b99a847ff4aTim Janikgboolean
377a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumanng_hash_table_remove (GHashTable	   *hash_table,
378a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann		     gconstpointer  key)
3792e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor{
380d5492a983cfa048658af8b03f833ddb3c0cf355eEST  GHashNode **node, *dest;
3812d68cbbb7d37d3f265bf1087e6ddedcc58bc62beTim Janik
3829a8c33db5cc37bc3c6bd4794a03f4b99a847ff4aTim Janik  g_return_val_if_fail (hash_table != NULL, FALSE);
3832d68cbbb7d37d3f265bf1087e6ddedcc58bc62beTim Janik
384d5492a983cfa048658af8b03f833ddb3c0cf355eEST  node = g_hash_table_lookup_node (hash_table, key);
385d5492a983cfa048658af8b03f833ddb3c0cf355eEST  if (*node)
3862e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor    {
387d5492a983cfa048658af8b03f833ddb3c0cf355eEST      dest = *node;
388d5492a983cfa048658af8b03f833ddb3c0cf355eEST      (*node) = dest->next;
389a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann      g_hash_node_destroy (dest,
390a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann			   hash_table->key_destroy_func,
391a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann			   hash_table->value_destroy_func);
3927519c2338ae484135b44bbb7eb49719aea8c4ca3Lauri Alanko      hash_table->nnodes--;
3932d68cbbb7d37d3f265bf1087e6ddedcc58bc62beTim Janik
3948079eb3456914a03618b92b48f75a71b25331acbOwen Taylor      G_HASH_TABLE_RESIZE (hash_table);
3959a8c33db5cc37bc3c6bd4794a03f4b99a847ff4aTim Janik
3969a8c33db5cc37bc3c6bd4794a03f4b99a847ff4aTim Janik      return TRUE;
397448e792b0a9b092f9593eaa51e16acd8abe54c76Jeff Garzik    }
3989a8c33db5cc37bc3c6bd4794a03f4b99a847ff4aTim Janik
3999a8c33db5cc37bc3c6bd4794a03f4b99a847ff4aTim Janik  return FALSE;
4002e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor}
4012e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor
402a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann/**
403a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * g_hash_table_steal:
404a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * @hash_table: a #GHashTable.
405a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * @key: the key to remove.
406a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann *
407a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * Removes a key and its associated value from a #GHashTable without
408a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * calling the key and value destroy functions.
409a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann *
410a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * Return value: #TRUE if the key was found and removed from the #GHashTable.
411a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann **/
4127519c2338ae484135b44bbb7eb49719aea8c4ca3Lauri Alankogboolean
413a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumanng_hash_table_steal (GHashTable    *hash_table,
414a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann                    gconstpointer  key)
4157519c2338ae484135b44bbb7eb49719aea8c4ca3Lauri Alanko{
416a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann  GHashNode **node, *dest;
4172d68cbbb7d37d3f265bf1087e6ddedcc58bc62beTim Janik
4182d68cbbb7d37d3f265bf1087e6ddedcc58bc62beTim Janik  g_return_val_if_fail (hash_table != NULL, FALSE);
4192d68cbbb7d37d3f265bf1087e6ddedcc58bc62beTim Janik
420a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann  node = g_hash_table_lookup_node (hash_table, key);
421a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann  if (*node)
4222e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor    {
423a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann      dest = *node;
424a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann      (*node) = dest->next;
425a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann      g_hash_node_destroy (dest, NULL, NULL);
426a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann      hash_table->nnodes--;
427a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann
4288079eb3456914a03618b92b48f75a71b25331acbOwen Taylor      G_HASH_TABLE_RESIZE (hash_table);
429a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann
4307519c2338ae484135b44bbb7eb49719aea8c4ca3Lauri Alanko      return TRUE;
4312e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor    }
432a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann
433a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann  return FALSE;
4342e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor}
4352e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor
436a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann/**
437a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * g_hash_table_foreach_remove:
438a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * @hash_table: a #GHashTable.
439a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * @func: the function to call for each key/value pair.
440a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * @user_data: user data to pass to the function.
441a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann *
442a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * Calls the given function for each key/value pair in the #GHashTable.
443a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * If the function returns TRUE, then the key/value pair is removed from the
444a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * #GHashTable. If you supplied key or value destroy functions when creating
445a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * the #GHashTable, they are used to free the memory allocated for the removed
446a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * keys and values.
447a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann *
448a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * Return value: the number of key/value pairs removed.
449a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann **/
450a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumannguint
451a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumanng_hash_table_foreach_remove (GHashTable	*hash_table,
452a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann			     GHRFunc	 func,
453a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann			     gpointer	 user_data)
4542e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor{
455a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann  g_return_val_if_fail (hash_table != NULL, 0);
456a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann  g_return_val_if_fail (func != NULL, 0);
457a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann
458a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann  return g_hash_table_foreach_remove_or_steal (hash_table, func, user_data, TRUE);
4592e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor}
4602e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor
461a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann/**
462a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * g_hash_table_foreach_steal:
463a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * @hash_table: a #GHashTable.
464a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * @func: the function to call for each key/value pair.
465a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * @user_data: user data to pass to the function.
466a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann *
467a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * Calls the given function for each key/value pair in the #GHashTable.
468a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * If the function returns TRUE, then the key/value pair is removed from the
469a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * #GHashTable, but no key or value destroy functions are called.
470a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann *
471a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * Return value: the number of key/value pairs removed.
472a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann **/
473a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumannguint
474a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumanng_hash_table_foreach_steal (GHashTable *hash_table,
475a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann                            GHRFunc	func,
476a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann                            gpointer	user_data)
4772e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor{
478a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann  g_return_val_if_fail (hash_table != NULL, 0);
479a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann  g_return_val_if_fail (func != NULL, 0);
480a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann
481a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann  return g_hash_table_foreach_remove_or_steal (hash_table, func, user_data, FALSE);
4822e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor}
4832e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor
484a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumannstatic guint
485a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumanng_hash_table_foreach_remove_or_steal (GHashTable *hash_table,
486a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann                                      GHRFunc	  func,
487a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann                                      gpointer	  user_data,
488a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann                                      gboolean    notify)
489034e7c0339f64d4d52a53f2324daa2fca0332addManish Singh{
490034e7c0339f64d4d52a53f2324daa2fca0332addManish Singh  GHashNode *node, *prev;
4912d68cbbb7d37d3f265bf1087e6ddedcc58bc62beTim Janik  guint i;
492d31ba84c8ea40b6f0199318e43cc2bb2e816c586Tim Janik  guint deleted = 0;
4932d68cbbb7d37d3f265bf1087e6ddedcc58bc62beTim Janik
494034e7c0339f64d4d52a53f2324daa2fca0332addManish Singh  for (i = 0; i < hash_table->size; i++)
495034e7c0339f64d4d52a53f2324daa2fca0332addManish Singh    {
496034e7c0339f64d4d52a53f2324daa2fca0332addManish Singh    restart:
4972d68cbbb7d37d3f265bf1087e6ddedcc58bc62beTim Janik
498034e7c0339f64d4d52a53f2324daa2fca0332addManish Singh      prev = NULL;
4992d68cbbb7d37d3f265bf1087e6ddedcc58bc62beTim Janik
500034e7c0339f64d4d52a53f2324daa2fca0332addManish Singh      for (node = hash_table->nodes[i]; node; prev = node, node = node->next)
501034e7c0339f64d4d52a53f2324daa2fca0332addManish Singh	{
502034e7c0339f64d4d52a53f2324daa2fca0332addManish Singh	  if ((* func) (node->key, node->value, user_data))
503034e7c0339f64d4d52a53f2324daa2fca0332addManish Singh	    {
504034e7c0339f64d4d52a53f2324daa2fca0332addManish Singh	      deleted += 1;
5052d68cbbb7d37d3f265bf1087e6ddedcc58bc62beTim Janik
506034e7c0339f64d4d52a53f2324daa2fca0332addManish Singh	      hash_table->nnodes -= 1;
5072d68cbbb7d37d3f265bf1087e6ddedcc58bc62beTim Janik
508034e7c0339f64d4d52a53f2324daa2fca0332addManish Singh	      if (prev)
509034e7c0339f64d4d52a53f2324daa2fca0332addManish Singh		{
510034e7c0339f64d4d52a53f2324daa2fca0332addManish Singh		  prev->next = node->next;
511a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann		  g_hash_node_destroy (node,
512a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann				       notify ? hash_table->value_destroy_func : NULL,
513a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann				       notify ? hash_table->key_destroy_func : NULL);
514034e7c0339f64d4d52a53f2324daa2fca0332addManish Singh		  node = prev;
515034e7c0339f64d4d52a53f2324daa2fca0332addManish Singh		}
516034e7c0339f64d4d52a53f2324daa2fca0332addManish Singh	      else
517034e7c0339f64d4d52a53f2324daa2fca0332addManish Singh		{
518034e7c0339f64d4d52a53f2324daa2fca0332addManish Singh		  hash_table->nodes[i] = node->next;
519a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann		  g_hash_node_destroy (node,
520a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann				       notify ? hash_table->value_destroy_func : NULL,
521a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann				       notify ? hash_table->key_destroy_func : NULL);
522034e7c0339f64d4d52a53f2324daa2fca0332addManish Singh		  goto restart;
523034e7c0339f64d4d52a53f2324daa2fca0332addManish Singh		}
524034e7c0339f64d4d52a53f2324daa2fca0332addManish Singh	    }
525034e7c0339f64d4d52a53f2324daa2fca0332addManish Singh	}
526034e7c0339f64d4d52a53f2324daa2fca0332addManish Singh    }
5272d68cbbb7d37d3f265bf1087e6ddedcc58bc62beTim Janik
5288079eb3456914a03618b92b48f75a71b25331acbOwen Taylor  G_HASH_TABLE_RESIZE (hash_table);
5292d68cbbb7d37d3f265bf1087e6ddedcc58bc62beTim Janik
530034e7c0339f64d4d52a53f2324daa2fca0332addManish Singh  return deleted;
531034e7c0339f64d4d52a53f2324daa2fca0332addManish Singh}
532034e7c0339f64d4d52a53f2324daa2fca0332addManish Singh
533a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann/**
534a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * g_hash_table_foreach:
535a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * @hash_table: a #GHashTable.
536a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * @func: the function to call for each key/value pair.
537a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * @user_data: user data to pass to the function.
538a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann *
539a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * Calls the given function for each of the key/value pairs in the #GHashTable.
540a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * The function is passed the key and value of each pair, and the given
541a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * @user_data parameter.
542a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann **/
5432e0320d57e417f7d1c838d729a99545db2228e9Owen Taylorvoid
5442e0320d57e417f7d1c838d729a99545db2228e9Owen Taylorg_hash_table_foreach (GHashTable *hash_table,
5452d68cbbb7d37d3f265bf1087e6ddedcc58bc62beTim Janik		      GHFunc	  func,
5462d68cbbb7d37d3f265bf1087e6ddedcc58bc62beTim Janik		      gpointer	  user_data)
5472e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor{
5482e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor  GHashNode *node;
5492e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor  gint i;
5502d68cbbb7d37d3f265bf1087e6ddedcc58bc62beTim Janik
5512d68cbbb7d37d3f265bf1087e6ddedcc58bc62beTim Janik  g_return_if_fail (hash_table != NULL);
5522d68cbbb7d37d3f265bf1087e6ddedcc58bc62beTim Janik  g_return_if_fail (func != NULL);
5532d68cbbb7d37d3f265bf1087e6ddedcc58bc62beTim Janik
5547519c2338ae484135b44bbb7eb49719aea8c4ca3Lauri Alanko  for (i = 0; i < hash_table->size; i++)
5557519c2338ae484135b44bbb7eb49719aea8c4ca3Lauri Alanko    for (node = hash_table->nodes[i]; node; node = node->next)
5567519c2338ae484135b44bbb7eb49719aea8c4ca3Lauri Alanko      (* func) (node->key, node->value, user_data);
5572e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor}
5582e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor
559a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann/**
560a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * g_hash_table_size:
561a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * @hash_table: a #GHashTable.
562a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann *
563a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * Returns the number of elements contained in the #GHashTable.
564a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann *
565a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann * Return value: the number of key/value pairs in the #GHashTable.
566a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann **/
567d31ba84c8ea40b6f0199318e43cc2bb2e816c586Tim Janikguint
5682d68cbbb7d37d3f265bf1087e6ddedcc58bc62beTim Janikg_hash_table_size (GHashTable *hash_table)
5697519c2338ae484135b44bbb7eb49719aea8c4ca3Lauri Alanko{
5702d68cbbb7d37d3f265bf1087e6ddedcc58bc62beTim Janik  g_return_val_if_fail (hash_table != NULL, 0);
5712d68cbbb7d37d3f265bf1087e6ddedcc58bc62beTim Janik
5727519c2338ae484135b44bbb7eb49719aea8c4ca3Lauri Alanko  return hash_table->nnodes;
5737519c2338ae484135b44bbb7eb49719aea8c4ca3Lauri Alanko}
5742e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor
5752e0320d57e417f7d1c838d729a99545db2228e9Owen Taylorstatic void
5762e0320d57e417f7d1c838d729a99545db2228e9Owen Taylorg_hash_table_resize (GHashTable *hash_table)
5772e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor{
5782e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor  GHashNode **new_nodes;
5792e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor  GHashNode *node;
5802e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor  GHashNode *next;
5812e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor  guint hash_val;
5822e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor  gint new_size;
5832e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor  gint i;
5848079eb3456914a03618b92b48f75a71b25331acbOwen Taylor
5857401460a60504dad7b77219d0ba3d93112e12444Manish Singh  new_size = CLAMP(g_spaced_primes_closest (hash_table->nnodes),
5867519c2338ae484135b44bbb7eb49719aea8c4ca3Lauri Alanko		   HASH_TABLE_MIN_SIZE,
5877519c2338ae484135b44bbb7eb49719aea8c4ca3Lauri Alanko		   HASH_TABLE_MAX_SIZE);
588448e792b0a9b092f9593eaa51e16acd8abe54c76Jeff Garzik  new_nodes = g_new0 (GHashNode*, new_size);
5892d68cbbb7d37d3f265bf1087e6ddedcc58bc62beTim Janik
5907519c2338ae484135b44bbb7eb49719aea8c4ca3Lauri Alanko  for (i = 0; i < hash_table->size; i++)
5917519c2338ae484135b44bbb7eb49719aea8c4ca3Lauri Alanko    for (node = hash_table->nodes[i]; node; node = next)
5927519c2338ae484135b44bbb7eb49719aea8c4ca3Lauri Alanko      {
5937519c2338ae484135b44bbb7eb49719aea8c4ca3Lauri Alanko	next = node->next;
594448e792b0a9b092f9593eaa51e16acd8abe54c76Jeff Garzik
5957519c2338ae484135b44bbb7eb49719aea8c4ca3Lauri Alanko	hash_val = (* hash_table->hash_func) (node->key) % new_size;
596448e792b0a9b092f9593eaa51e16acd8abe54c76Jeff Garzik
5977519c2338ae484135b44bbb7eb49719aea8c4ca3Lauri Alanko	node->next = new_nodes[hash_val];
5987519c2338ae484135b44bbb7eb49719aea8c4ca3Lauri Alanko	new_nodes[hash_val] = node;
5997519c2338ae484135b44bbb7eb49719aea8c4ca3Lauri Alanko      }
6002d68cbbb7d37d3f265bf1087e6ddedcc58bc62beTim Janik
6017519c2338ae484135b44bbb7eb49719aea8c4ca3Lauri Alanko  g_free (hash_table->nodes);
6027519c2338ae484135b44bbb7eb49719aea8c4ca3Lauri Alanko  hash_table->nodes = new_nodes;
6037519c2338ae484135b44bbb7eb49719aea8c4ca3Lauri Alanko  hash_table->size = new_size;
6047519c2338ae484135b44bbb7eb49719aea8c4ca3Lauri Alanko}
6057519c2338ae484135b44bbb7eb49719aea8c4ca3Lauri Alanko
6062e0320d57e417f7d1c838d729a99545db2228e9Owen Taylorstatic GHashNode*
6072e0320d57e417f7d1c838d729a99545db2228e9Owen Taylorg_hash_node_new (gpointer key,
6082e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor		 gpointer value)
6092e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor{
6102e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor  GHashNode *hash_node;
6112d68cbbb7d37d3f265bf1087e6ddedcc58bc62beTim Janik
612b2e318ff3ecc50d72121a4e8561442a6d79a7a84Tim Janik  G_LOCK (g_hash_global);
6132e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor  if (node_free_list)
6142e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor    {
6152e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor      hash_node = node_free_list;
6162e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor      node_free_list = node_free_list->next;
6172e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor    }
6182e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor  else
6192e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor    {
6202e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor      if (!node_mem_chunk)
6212e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor	node_mem_chunk = g_mem_chunk_new ("hash node mem chunk",
6222e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor					  sizeof (GHashNode),
6232e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor					  1024, G_ALLOC_ONLY);
6242d68cbbb7d37d3f265bf1087e6ddedcc58bc62beTim Janik
6252e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor      hash_node = g_chunk_new (GHashNode, node_mem_chunk);
6262e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor    }
627b2e318ff3ecc50d72121a4e8561442a6d79a7a84Tim Janik  G_UNLOCK (g_hash_global);
6282d68cbbb7d37d3f265bf1087e6ddedcc58bc62beTim Janik
6292e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor  hash_node->key = key;
6302e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor  hash_node->value = value;
6312e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor  hash_node->next = NULL;
6322d68cbbb7d37d3f265bf1087e6ddedcc58bc62beTim Janik
6332e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor  return hash_node;
6342e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor}
6352e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor
6362e0320d57e417f7d1c838d729a99545db2228e9Owen Taylorstatic void
637a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumanng_hash_node_destroy (GHashNode      *hash_node,
638a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann		     GDestroyNotify  key_destroy_func,
639a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann		     GDestroyNotify  value_destroy_func)
6402e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor{
641a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann  if (key_destroy_func)
642a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann    key_destroy_func (hash_node->key);
643a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann  if (value_destroy_func)
644a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann    value_destroy_func (hash_node->value);
645a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann
6468c90d7766b1708a8bcb3cb96988b6b7fc92c2e59Sebastian Wilhelmi#ifdef ENABLE_GC_FRIENDLY
6478c90d7766b1708a8bcb3cb96988b6b7fc92c2e59Sebastian Wilhelmi  hash_node->key = NULL;
6488c90d7766b1708a8bcb3cb96988b6b7fc92c2e59Sebastian Wilhelmi  hash_node->value = NULL;
6498c90d7766b1708a8bcb3cb96988b6b7fc92c2e59Sebastian Wilhelmi#endif /* ENABLE_GC_FRIENDLY */
6508c90d7766b1708a8bcb3cb96988b6b7fc92c2e59Sebastian Wilhelmi
651b2e318ff3ecc50d72121a4e8561442a6d79a7a84Tim Janik  G_LOCK (g_hash_global);
6527519c2338ae484135b44bbb7eb49719aea8c4ca3Lauri Alanko  hash_node->next = node_free_list;
6537519c2338ae484135b44bbb7eb49719aea8c4ca3Lauri Alanko  node_free_list = hash_node;
654b2e318ff3ecc50d72121a4e8561442a6d79a7a84Tim Janik  G_UNLOCK (g_hash_global);
6552e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor}
6562e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor
6572e0320d57e417f7d1c838d729a99545db2228e9Owen Taylorstatic void
658a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumanng_hash_nodes_destroy (GHashNode *hash_node,
659a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann		      GFreeFunc  key_destroy_func,
660a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann		      GFreeFunc  value_destroy_func)
6612e0320d57e417f7d1c838d729a99545db2228e9Owen Taylor{
662448e792b0a9b092f9593eaa51e16acd8abe54c76Jeff Garzik  if (hash_node)
663448e792b0a9b092f9593eaa51e16acd8abe54c76Jeff Garzik    {
664448e792b0a9b092f9593eaa51e16acd8abe54c76Jeff Garzik      GHashNode *node = hash_node;
6652d68cbbb7d37d3f265bf1087e6ddedcc58bc62beTim Janik
666448e792b0a9b092f9593eaa51e16acd8abe54c76Jeff Garzik      while (node->next)
6678c90d7766b1708a8bcb3cb96988b6b7fc92c2e59Sebastian Wilhelmi	{
668a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann	  if (key_destroy_func)
669a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann	    key_destroy_func (node->key);
670a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann	  if (value_destroy_func)
671a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann	    value_destroy_func (node->value);
672a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann
6738c90d7766b1708a8bcb3cb96988b6b7fc92c2e59Sebastian Wilhelmi#ifdef ENABLE_GC_FRIENDLY
6748c90d7766b1708a8bcb3cb96988b6b7fc92c2e59Sebastian Wilhelmi	  node->key = NULL;
6758c90d7766b1708a8bcb3cb96988b6b7fc92c2e59Sebastian Wilhelmi	  node->value = NULL;
6768c90d7766b1708a8bcb3cb96988b6b7fc92c2e59Sebastian Wilhelmi#endif /* ENABLE_GC_FRIENDLY */
677a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann
6788c90d7766b1708a8bcb3cb96988b6b7fc92c2e59Sebastian Wilhelmi	  node = node->next;
6798c90d7766b1708a8bcb3cb96988b6b7fc92c2e59Sebastian Wilhelmi	}
6808c90d7766b1708a8bcb3cb96988b6b7fc92c2e59Sebastian Wilhelmi
681a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann  if (key_destroy_func)
682a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann    key_destroy_func (node->key);
683a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann  if (value_destroy_func)
684a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann    value_destroy_func (node->value);
685a2b269bae3315a2ea772b741fb62f683c1db5770Sven Neumann
6868c90d7766b1708a8bcb3cb96988b6b7fc92c2e59Sebastian Wilhelmi#ifdef ENABLE_GC_FRIENDLY
6878c90d7766b1708a8bcb3cb96988b6b7fc92c2e59Sebastian Wilhelmi      node->key = NULL;
6888c90d7766b1708a8bcb3cb96988b6b7fc92c2e59Sebastian Wilhelmi      node->value = NULL;
6898c90d7766b1708a8bcb3cb96988b6b7fc92c2e59Sebastian Wilhelmi#endif /* ENABLE_GC_FRIENDLY */
6908c90d7766b1708a8bcb3cb96988b6b7fc92c2e59Sebastian Wilhelmi
691448e792b0a9b092f9593eaa51e16acd8abe54c76Jeff Garzik      G_LOCK (g_hash_global);
692448e792b0a9b092f9593eaa51e16acd8abe54c76Jeff Garzik      node->next = node_free_list;
693448e792b0a9b092f9593eaa51e16acd8abe54c76Jeff Garzik      node_free_list = hash_node;
694448e792b0a9b092f9593eaa51e16acd8abe54c76Jeff Garzik      G_UNLOCK (g_hash_global);
695448e792b0a9b092f9593eaa51e16acd8abe54c76Jeff Garzik    }
696df9a49ec3cbb19e58be929548cfba12452c55d83Josh MacDonald}
697