glib/libglib/src/ghash.c
branchRCL_3
changeset 57 2efc27d87e1c
parent 0 e4d67989cc36
equal deleted inserted replaced
56:acd3cd4aaceb 57:2efc27d87e1c
       
     1 /* GLIB - Library of useful routines for C programming
       
     2  * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
       
     3  * Portions copyright (c) 2006 Nokia Corporation.  All rights reserved.
       
     4  *
       
     5  * This library is free software; you can redistribute it and/or
       
     6  * modify it under the terms of the GNU Lesser General Public
       
     7  * License as published by the Free Software Foundation; either
       
     8  * version 2 of the License, or (at your option) any later version.
       
     9  *
       
    10  * This library is distributed in the hope that it will be useful,
       
    11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
       
    13  * Lesser General Public License for more details.
       
    14  *
       
    15  * You should have received a copy of the GNU Lesser General Public
       
    16  * License along with this library; if not, write to the
       
    17  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
       
    18  * Boston, MA 02111-1307, USA.
       
    19  */
       
    20 
       
    21 /*
       
    22  * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
       
    23  * file for a list of people on the GLib Team.  See the ChangeLog
       
    24  * files for a list of changes.  These files are distributed with
       
    25  * GLib at ftp://ftp.gtk.org/pub/gtk/. 
       
    26  */
       
    27 
       
    28 /* 
       
    29  * MT safe
       
    30  */
       
    31 
       
    32 #include "config.h"
       
    33 
       
    34 #include "glib.h"
       
    35 #include "galias.h"
       
    36 
       
    37 
       
    38 #define HASH_TABLE_MIN_SIZE 11
       
    39 #define HASH_TABLE_MAX_SIZE 13845163
       
    40 
       
    41 
       
    42 typedef struct _GHashNode      GHashNode;
       
    43 
       
    44 struct _GHashNode
       
    45 {
       
    46   gpointer   key;
       
    47   gpointer   value;
       
    48   GHashNode *next;
       
    49 };
       
    50 
       
    51 struct _GHashTable
       
    52 {
       
    53   gint             size;
       
    54   gint             nnodes;
       
    55   GHashNode      **nodes;
       
    56   GHashFunc        hash_func;
       
    57   GEqualFunc       key_equal_func;
       
    58   volatile guint   ref_count;
       
    59   GDestroyNotify   key_destroy_func;
       
    60   GDestroyNotify   value_destroy_func;
       
    61 };
       
    62 
       
    63 #define G_HASH_TABLE_RESIZE(hash_table)				\
       
    64    G_STMT_START {						\
       
    65      if ((hash_table->size >= 3 * hash_table->nnodes &&	        \
       
    66 	  hash_table->size > HASH_TABLE_MIN_SIZE) ||		\
       
    67 	 (3 * hash_table->size <= hash_table->nnodes &&	        \
       
    68 	  hash_table->size < HASH_TABLE_MAX_SIZE))		\
       
    69 	   g_hash_table_resize (hash_table);			\
       
    70    } G_STMT_END
       
    71 
       
    72 static void		g_hash_table_resize	  (GHashTable	  *hash_table);
       
    73 static GHashNode**	g_hash_table_lookup_node  (GHashTable     *hash_table,
       
    74                                                    gconstpointer   key);
       
    75 static GHashNode*	g_hash_node_new		  (gpointer	   key,
       
    76                                                    gpointer        value);
       
    77 static void		g_hash_node_destroy	  (GHashNode	  *hash_node,
       
    78                                                    GDestroyNotify  key_destroy_func,
       
    79                                                    GDestroyNotify  value_destroy_func);
       
    80 static void		g_hash_nodes_destroy	  (GHashNode	  *hash_node,
       
    81 						  GDestroyNotify   key_destroy_func,
       
    82 						  GDestroyNotify   value_destroy_func);
       
    83 static guint g_hash_table_foreach_remove_or_steal (GHashTable     *hash_table,
       
    84                                                    GHRFunc	   func,
       
    85                                                    gpointer	   user_data,
       
    86                                                    gboolean        notify);
       
    87 
       
    88 
       
    89 /**
       
    90  * g_hash_table_new:
       
    91  * @hash_func: a function to create a hash value from a key.
       
    92  *   Hash values are used to determine where keys are stored within the
       
    93  *   #GHashTable data structure. The g_direct_hash(), g_int_hash() and 
       
    94  *   g_str_hash() functions are provided for some common types of keys. 
       
    95  *   If hash_func is %NULL, g_direct_hash() is used.
       
    96  * @key_equal_func: a function to check two keys for equality.  This is
       
    97  *   used when looking up keys in the #GHashTable.  The g_direct_equal(),
       
    98  *   g_int_equal() and g_str_equal() functions are provided for the most
       
    99  *   common types of keys. If @key_equal_func is %NULL, keys are compared
       
   100  *   directly in a similar fashion to g_direct_equal(), but without the
       
   101  *   overhead of a function call.
       
   102  *
       
   103  * Creates a new #GHashTable with a reference count of 1.
       
   104  * 
       
   105  * Return value: a new #GHashTable.
       
   106  **/
       
   107 EXPORT_C GHashTable*
       
   108 g_hash_table_new (GHashFunc    hash_func,
       
   109 		  GEqualFunc   key_equal_func)
       
   110 {
       
   111   return g_hash_table_new_full (hash_func, key_equal_func, NULL, NULL);
       
   112 }
       
   113 
       
   114 
       
   115 /**
       
   116  * g_hash_table_new_full:
       
   117  * @hash_func: a function to create a hash value from a key.
       
   118  * @key_equal_func: a function to check two keys for equality.
       
   119  * @key_destroy_func: a function to free the memory allocated for the key 
       
   120  *   used when removing the entry from the #GHashTable or %NULL if you 
       
   121  *   don't want to supply such a function.
       
   122  * @value_destroy_func: a function to free the memory allocated for the 
       
   123  *   value used when removing the entry from the #GHashTable or %NULL if 
       
   124  *   you don't want to supply such a function.
       
   125  * 
       
   126  * Creates a new #GHashTable like g_hash_table_new() with a reference count
       
   127  * of 1 and allows to specify functions to free the memory allocated for the
       
   128  * key and value that get called when removing the entry from the #GHashTable.
       
   129  * 
       
   130  * Return value: a new #GHashTable.
       
   131  **/
       
   132 EXPORT_C GHashTable*
       
   133 g_hash_table_new_full (GHashFunc       hash_func,
       
   134 		       GEqualFunc      key_equal_func,
       
   135 		       GDestroyNotify  key_destroy_func,
       
   136 		       GDestroyNotify  value_destroy_func)
       
   137 {
       
   138   GHashTable *hash_table;
       
   139 
       
   140   hash_table = g_slice_new (GHashTable);
       
   141   hash_table->size               = HASH_TABLE_MIN_SIZE;
       
   142   hash_table->nnodes             = 0;
       
   143   hash_table->hash_func          = hash_func ? hash_func : g_direct_hash;
       
   144   hash_table->key_equal_func     = key_equal_func;
       
   145   hash_table->ref_count          = 1;
       
   146   hash_table->key_destroy_func   = key_destroy_func;
       
   147   hash_table->value_destroy_func = value_destroy_func;
       
   148   hash_table->nodes              = g_new0 (GHashNode*, hash_table->size);
       
   149   return hash_table;
       
   150 }
       
   151 
       
   152 
       
   153 /**
       
   154  * g_hash_table_ref:
       
   155  * @hash_table: a valid #GHashTable.
       
   156  * 
       
   157  * Atomically increments the reference count of @hash_table by one.
       
   158  * This function is MT-safe and may be called from any thread.
       
   159  * 
       
   160  * Return value: the passed in #GHashTable.
       
   161  * 
       
   162  * Since: 2.10
       
   163  **/
       
   164 EXPORT_C GHashTable*
       
   165 g_hash_table_ref (GHashTable *hash_table)
       
   166 {
       
   167   g_return_val_if_fail (hash_table != NULL, NULL);
       
   168   g_return_val_if_fail (hash_table->ref_count > 0, hash_table);
       
   169 
       
   170   g_atomic_int_add (FIX_CASTING(volatile int *)&hash_table->ref_count, 1);
       
   171   return hash_table;
       
   172 }
       
   173 
       
   174 /**
       
   175  * g_hash_table_unref:
       
   176  * @hash_table: a valid #GHashTable.
       
   177  * 
       
   178  * Atomically decrements the reference count of @hash_table by one.
       
   179  * If the reference count drops to 0, all keys and values will be
       
   180  * destroyed, and all memory allocated by the hash table is released.
       
   181  * This function is MT-safe and may be called from any thread.
       
   182  * 
       
   183  * Since: 2.10
       
   184  **/
       
   185 EXPORT_C void
       
   186 g_hash_table_unref (GHashTable *hash_table)
       
   187 {
       
   188   g_return_if_fail (hash_table != NULL);
       
   189   g_return_if_fail (hash_table->ref_count > 0);
       
   190 
       
   191   if (g_atomic_int_exchange_and_add (FIX_CASTING(volatile int *)&hash_table->ref_count, -1) - 1 == 0)
       
   192     {
       
   193       gint i;
       
   194 
       
   195       for (i = 0; i < hash_table->size; i++)
       
   196         g_hash_nodes_destroy (hash_table->nodes[i], 
       
   197                               hash_table->key_destroy_func,
       
   198                               hash_table->value_destroy_func);
       
   199       g_free (hash_table->nodes);
       
   200       g_slice_free (GHashTable, hash_table);
       
   201     }
       
   202 }
       
   203 
       
   204 /**
       
   205  * g_hash_table_destroy:
       
   206  * @hash_table: a #GHashTable.
       
   207  * 
       
   208  * Destroys all keys and values in the #GHashTable and decrements its
       
   209  * reference count by 1. If keys and/or values are dynamically allocated,
       
   210  * you should either free them first or create the #GHashTable with destroy
       
   211  * notifiers using g_hash_table_new_full(). In the latter case the destroy
       
   212  * functions you supplied will be called on all keys and values during the
       
   213  * destruction phase.
       
   214  **/
       
   215 EXPORT_C void
       
   216 g_hash_table_destroy (GHashTable *hash_table)
       
   217 {
       
   218   gint i;
       
   219   
       
   220   g_return_if_fail (hash_table != NULL);
       
   221   g_return_if_fail (hash_table->ref_count > 0);
       
   222   
       
   223   for (i = 0; i < hash_table->size; i++)
       
   224     {
       
   225       g_hash_nodes_destroy (hash_table->nodes[i], 
       
   226                             hash_table->key_destroy_func,
       
   227                             hash_table->value_destroy_func);
       
   228       hash_table->nodes[i] = NULL;
       
   229     }
       
   230   hash_table->nnodes = 0;
       
   231   hash_table->size = HASH_TABLE_MIN_SIZE;
       
   232 
       
   233   g_hash_table_unref (hash_table);
       
   234 }
       
   235 
       
   236 static inline GHashNode**
       
   237 g_hash_table_lookup_node (GHashTable	*hash_table,
       
   238 			  gconstpointer	 key)
       
   239 {
       
   240   GHashNode **node;
       
   241   
       
   242   node = &hash_table->nodes
       
   243     [(* hash_table->hash_func) (key) % hash_table->size];
       
   244   
       
   245   /* Hash table lookup needs to be fast.
       
   246    *  We therefore remove the extra conditional of testing
       
   247    *  whether to call the key_equal_func or not from
       
   248    *  the inner loop.
       
   249    */
       
   250   if (hash_table->key_equal_func)
       
   251     while (*node && !(*hash_table->key_equal_func) ((*node)->key, key))
       
   252       node = &(*node)->next;
       
   253   else
       
   254     while (*node && (*node)->key != key)
       
   255       node = &(*node)->next;
       
   256   
       
   257   return node;
       
   258 }
       
   259 
       
   260 /**
       
   261  * g_hash_table_lookup:
       
   262  * @hash_table: a #GHashTable.
       
   263  * @key: the key to look up.
       
   264  * 
       
   265  * Looks up a key in a #GHashTable. Note that this function cannot
       
   266  * distinguish between a key that is not present and one which is present
       
   267  * and has the value %NULL. If you need this distinction, use
       
   268  * g_hash_table_lookup_extended().
       
   269  * 
       
   270  * Return value: the associated value, or %NULL if the key is not found.
       
   271  **/
       
   272 EXPORT_C gpointer
       
   273 g_hash_table_lookup (GHashTable	  *hash_table,
       
   274 		     gconstpointer key)
       
   275 {
       
   276   GHashNode *node;
       
   277   
       
   278   g_return_val_if_fail (hash_table != NULL, NULL);
       
   279   
       
   280   node = *g_hash_table_lookup_node (hash_table, key);
       
   281   
       
   282   return node ? node->value : NULL;
       
   283 }
       
   284 
       
   285 /**
       
   286  * g_hash_table_lookup_extended:
       
   287  * @hash_table: a #GHashTable.
       
   288  * @lookup_key: the key to look up.
       
   289  * @orig_key: returns the original key.
       
   290  * @value: returns the value associated with the key.
       
   291  * 
       
   292  * Looks up a key in the #GHashTable, returning the original key and the
       
   293  * associated value and a #gboolean which is %TRUE if the key was found. This 
       
   294  * is useful if you need to free the memory allocated for the original key, 
       
   295  * for example before calling g_hash_table_remove().
       
   296  * 
       
   297  * Return value: %TRUE if the key was found in the #GHashTable.
       
   298  **/
       
   299 EXPORT_C gboolean
       
   300 g_hash_table_lookup_extended (GHashTable    *hash_table,
       
   301 			      gconstpointer  lookup_key,
       
   302 			      gpointer	    *orig_key,
       
   303 			      gpointer	    *value)
       
   304 {
       
   305   GHashNode *node;
       
   306   
       
   307   g_return_val_if_fail (hash_table != NULL, FALSE);
       
   308   
       
   309   node = *g_hash_table_lookup_node (hash_table, lookup_key);
       
   310   
       
   311   if (node)
       
   312     {
       
   313       if (orig_key)
       
   314 	*orig_key = node->key;
       
   315       if (value)
       
   316 	*value = node->value;
       
   317       return TRUE;
       
   318     }
       
   319   else
       
   320     return FALSE;
       
   321 }
       
   322 
       
   323 /**
       
   324  * g_hash_table_insert:
       
   325  * @hash_table: a #GHashTable.
       
   326  * @key: a key to insert.
       
   327  * @value: the value to associate with the key.
       
   328  * 
       
   329  * Inserts a new key and value into a #GHashTable.
       
   330  * 
       
   331  * If the key already exists in the #GHashTable its current value is replaced
       
   332  * with the new value. If you supplied a @value_destroy_func when creating the 
       
   333  * #GHashTable, the old value is freed using that function. If you supplied
       
   334  * a @key_destroy_func when creating the #GHashTable, the passed key is freed 
       
   335  * using that function.
       
   336  **/
       
   337 EXPORT_C void
       
   338 g_hash_table_insert (GHashTable *hash_table,
       
   339 		     gpointer	 key,
       
   340 		     gpointer	 value)
       
   341 {
       
   342   GHashNode **node;
       
   343   
       
   344   g_return_if_fail (hash_table != NULL);
       
   345   g_return_if_fail (hash_table->ref_count > 0);
       
   346   
       
   347   node = g_hash_table_lookup_node (hash_table, key);
       
   348   
       
   349   if (*node)
       
   350     {
       
   351       /* do not reset node->key in this place, keeping
       
   352        * the old key is the intended behaviour. 
       
   353        * g_hash_table_replace() can be used instead.
       
   354        */
       
   355 
       
   356       /* free the passed key */
       
   357       if (hash_table->key_destroy_func)
       
   358 	hash_table->key_destroy_func (key);
       
   359       
       
   360       if (hash_table->value_destroy_func)
       
   361 	hash_table->value_destroy_func ((*node)->value);
       
   362 
       
   363       (*node)->value = value;
       
   364     }
       
   365   else
       
   366     {
       
   367       *node = g_hash_node_new (key, value);
       
   368       hash_table->nnodes++;
       
   369       G_HASH_TABLE_RESIZE (hash_table);
       
   370     }
       
   371 }
       
   372 
       
   373 /**
       
   374  * g_hash_table_replace:
       
   375  * @hash_table: a #GHashTable.
       
   376  * @key: a key to insert.
       
   377  * @value: the value to associate with the key.
       
   378  * 
       
   379  * Inserts a new key and value into a #GHashTable similar to 
       
   380  * g_hash_table_insert(). The difference is that if the key already exists 
       
   381  * in the #GHashTable, it gets replaced by the new key. If you supplied a 
       
   382  * @value_destroy_func when creating the #GHashTable, the old value is freed 
       
   383  * using that function. If you supplied a @key_destroy_func when creating the 
       
   384  * #GHashTable, the old key is freed using that function. 
       
   385  **/
       
   386 EXPORT_C void
       
   387 g_hash_table_replace (GHashTable *hash_table,
       
   388 		      gpointer	  key,
       
   389 		      gpointer	  value)
       
   390 {
       
   391   GHashNode **node;
       
   392   
       
   393   g_return_if_fail (hash_table != NULL);
       
   394   g_return_if_fail (hash_table->ref_count > 0);
       
   395   
       
   396   node = g_hash_table_lookup_node (hash_table, key);
       
   397   
       
   398   if (*node)
       
   399     {
       
   400       if (hash_table->key_destroy_func)
       
   401 	hash_table->key_destroy_func ((*node)->key);
       
   402       
       
   403       if (hash_table->value_destroy_func)
       
   404 	hash_table->value_destroy_func ((*node)->value);
       
   405 
       
   406       (*node)->key   = key;
       
   407       (*node)->value = value;
       
   408     }
       
   409   else
       
   410     {
       
   411       *node = g_hash_node_new (key, value);
       
   412       hash_table->nnodes++;
       
   413       G_HASH_TABLE_RESIZE (hash_table);
       
   414     }
       
   415 }
       
   416 
       
   417 /**
       
   418  * g_hash_table_remove:
       
   419  * @hash_table: a #GHashTable.
       
   420  * @key: the key to remove.
       
   421  * 
       
   422  * Removes a key and its associated value from a #GHashTable.
       
   423  *
       
   424  * If the #GHashTable was created using g_hash_table_new_full(), the
       
   425  * key and value are freed using the supplied destroy functions, otherwise
       
   426  * you have to make sure that any dynamically allocated values are freed 
       
   427  * yourself.
       
   428  * 
       
   429  * Return value: %TRUE if the key was found and removed from the #GHashTable.
       
   430  **/
       
   431 EXPORT_C gboolean
       
   432 g_hash_table_remove (GHashTable	   *hash_table,
       
   433 		     gconstpointer  key)
       
   434 {
       
   435   GHashNode **node, *dest;
       
   436   
       
   437   g_return_val_if_fail (hash_table != NULL, FALSE);
       
   438   
       
   439   node = g_hash_table_lookup_node (hash_table, key);
       
   440   if (*node)
       
   441     {
       
   442       dest = *node;
       
   443       (*node) = dest->next;
       
   444       g_hash_node_destroy (dest, 
       
   445 			   hash_table->key_destroy_func,
       
   446 			   hash_table->value_destroy_func);
       
   447       hash_table->nnodes--;
       
   448   
       
   449       G_HASH_TABLE_RESIZE (hash_table);
       
   450 
       
   451       return TRUE;
       
   452     }
       
   453 
       
   454   return FALSE;
       
   455 }
       
   456 
       
   457 /**
       
   458  * g_hash_table_steal:
       
   459  * @hash_table: a #GHashTable.
       
   460  * @key: the key to remove.
       
   461  * 
       
   462  * Removes a key and its associated value from a #GHashTable without
       
   463  * calling the key and value destroy functions.
       
   464  *
       
   465  * Return value: %TRUE if the key was found and removed from the #GHashTable.
       
   466  **/
       
   467 EXPORT_C gboolean
       
   468 g_hash_table_steal (GHashTable    *hash_table,
       
   469                     gconstpointer  key)
       
   470 {
       
   471   GHashNode **node, *dest;
       
   472   
       
   473   g_return_val_if_fail (hash_table != NULL, FALSE);
       
   474   
       
   475   node = g_hash_table_lookup_node (hash_table, key);
       
   476   if (*node)
       
   477     {
       
   478       dest = *node;
       
   479       (*node) = dest->next;
       
   480       g_hash_node_destroy (dest, NULL, NULL);
       
   481       hash_table->nnodes--;
       
   482   
       
   483       G_HASH_TABLE_RESIZE (hash_table);
       
   484 
       
   485       return TRUE;
       
   486     }
       
   487 
       
   488   return FALSE;
       
   489 }
       
   490 
       
   491 /**
       
   492  * g_hash_table_foreach_remove:
       
   493  * @hash_table: a #GHashTable.
       
   494  * @func: the function to call for each key/value pair.
       
   495  * @user_data: user data to pass to the function.
       
   496  * 
       
   497  * Calls the given function for each key/value pair in the #GHashTable.
       
   498  * If the function returns %TRUE, then the key/value pair is removed from the
       
   499  * #GHashTable. If you supplied key or value destroy functions when creating
       
   500  * the #GHashTable, they are used to free the memory allocated for the removed
       
   501  * keys and values.
       
   502  * 
       
   503  * Return value: the number of key/value pairs removed.
       
   504  **/
       
   505 EXPORT_C guint
       
   506 g_hash_table_foreach_remove (GHashTable	*hash_table,
       
   507 			     GHRFunc	 func,
       
   508 			     gpointer	 user_data)
       
   509 {
       
   510   g_return_val_if_fail (hash_table != NULL, 0);
       
   511   g_return_val_if_fail (func != NULL, 0);
       
   512   
       
   513   return g_hash_table_foreach_remove_or_steal (hash_table, func, user_data, TRUE);
       
   514 }
       
   515 
       
   516 /**
       
   517  * g_hash_table_foreach_steal:
       
   518  * @hash_table: a #GHashTable.
       
   519  * @func: the function to call for each key/value pair.
       
   520  * @user_data: user data to pass to the function.
       
   521  * 
       
   522  * Calls the given function for each key/value pair in the #GHashTable.
       
   523  * If the function returns %TRUE, then the key/value pair is removed from the
       
   524  * #GHashTable, but no key or value destroy functions are called.
       
   525  * 
       
   526  * Return value: the number of key/value pairs removed.
       
   527  **/
       
   528 EXPORT_C guint
       
   529 g_hash_table_foreach_steal (GHashTable *hash_table,
       
   530                             GHRFunc	func,
       
   531                             gpointer	user_data)
       
   532 {
       
   533   g_return_val_if_fail (hash_table != NULL, 0);
       
   534   g_return_val_if_fail (func != NULL, 0);
       
   535   
       
   536   return g_hash_table_foreach_remove_or_steal (hash_table, func, user_data, FALSE);
       
   537 }
       
   538 
       
   539 static guint
       
   540 g_hash_table_foreach_remove_or_steal (GHashTable *hash_table,
       
   541                                       GHRFunc	  func,
       
   542                                       gpointer	  user_data,
       
   543                                       gboolean    notify)
       
   544 {
       
   545   GHashNode *node, *prev;
       
   546   gint i;
       
   547   guint deleted = 0;
       
   548   
       
   549   for (i = 0; i < hash_table->size; i++)
       
   550     {
       
   551     restart:
       
   552       
       
   553       prev = NULL;
       
   554       
       
   555       for (node = hash_table->nodes[i]; node; prev = node, node = node->next)
       
   556 	{
       
   557 	  if ((* func) (node->key, node->value, user_data))
       
   558 	    {
       
   559 	      deleted += 1;
       
   560 	      
       
   561 	      hash_table->nnodes -= 1;
       
   562 	      
       
   563 	      if (prev)
       
   564 		{
       
   565 		  prev->next = node->next;
       
   566 		  g_hash_node_destroy (node,
       
   567 				       notify ? hash_table->key_destroy_func : NULL,
       
   568 				       notify ? hash_table->value_destroy_func : NULL);
       
   569 		  node = prev;
       
   570 		}
       
   571 	      else
       
   572 		{
       
   573 		  hash_table->nodes[i] = node->next;
       
   574 		  g_hash_node_destroy (node,
       
   575 				       notify ? hash_table->key_destroy_func : NULL,
       
   576 				       notify ? hash_table->value_destroy_func : NULL);
       
   577 		  goto restart;
       
   578 		}
       
   579 	    }
       
   580 	}
       
   581     }
       
   582   
       
   583   G_HASH_TABLE_RESIZE (hash_table);
       
   584   
       
   585   return deleted;
       
   586 }
       
   587 
       
   588 /**
       
   589  * g_hash_table_foreach:
       
   590  * @hash_table: a #GHashTable.
       
   591  * @func: the function to call for each key/value pair.
       
   592  * @user_data: user data to pass to the function.
       
   593  * 
       
   594  * Calls the given function for each of the key/value pairs in the
       
   595  * #GHashTable.  The function is passed the key and value of each
       
   596  * pair, and the given @user_data parameter.  The hash table may not
       
   597  * be modified while iterating over it (you can't add/remove
       
   598  * items). To remove all items matching a predicate, use
       
   599  * g_hash_table_foreach_remove().
       
   600  **/
       
   601 EXPORT_C void
       
   602 g_hash_table_foreach (GHashTable *hash_table,
       
   603 		      GHFunc	  func,
       
   604 		      gpointer	  user_data)
       
   605 {
       
   606   GHashNode *node;
       
   607   gint i;
       
   608   
       
   609   g_return_if_fail (hash_table != NULL);
       
   610   g_return_if_fail (func != NULL);
       
   611   
       
   612   for (i = 0; i < hash_table->size; i++)
       
   613     for (node = hash_table->nodes[i]; node; node = node->next)
       
   614       (* func) (node->key, node->value, user_data);
       
   615 }
       
   616 
       
   617 /**
       
   618  * g_hash_table_find:
       
   619  * @hash_table: a #GHashTable.
       
   620  * @predicate:  function to test the key/value pairs for a certain property.
       
   621  * @user_data:  user data to pass to the function.
       
   622  * 
       
   623  * Calls the given function for key/value pairs in the #GHashTable until 
       
   624  * @predicate returns %TRUE.  The function is passed the key and value of 
       
   625  * each pair, and the given @user_data parameter. The hash table may not
       
   626  * be modified while iterating over it (you can't add/remove items). 
       
   627  *
       
   628  * Return value: The value of the first key/value pair is returned, for which 
       
   629  * func evaluates to %TRUE. If no pair with the requested property is found, 
       
   630  * %NULL is returned.
       
   631  *
       
   632  * Since: 2.4
       
   633  **/
       
   634 EXPORT_C gpointer
       
   635 g_hash_table_find (GHashTable	   *hash_table,
       
   636                    GHRFunc	    predicate,
       
   637                    gpointer	    user_data)
       
   638 {
       
   639   GHashNode *node;
       
   640   gint i;
       
   641   
       
   642   g_return_val_if_fail (hash_table != NULL, NULL);
       
   643   g_return_val_if_fail (predicate != NULL, NULL);
       
   644   
       
   645   for (i = 0; i < hash_table->size; i++)
       
   646     for (node = hash_table->nodes[i]; node; node = node->next)
       
   647       if (predicate (node->key, node->value, user_data))
       
   648         return node->value;       
       
   649   return NULL;
       
   650 }
       
   651 
       
   652 /**
       
   653  * g_hash_table_size:
       
   654  * @hash_table: a #GHashTable.
       
   655  * 
       
   656  * Returns the number of elements contained in the #GHashTable.
       
   657  * 
       
   658  * Return value: the number of key/value pairs in the #GHashTable.
       
   659  **/
       
   660 EXPORT_C guint
       
   661 g_hash_table_size (GHashTable *hash_table)
       
   662 {
       
   663   g_return_val_if_fail (hash_table != NULL, 0);
       
   664   
       
   665   return hash_table->nnodes;
       
   666 }
       
   667 
       
   668 static void
       
   669 g_hash_table_resize (GHashTable *hash_table)
       
   670 {
       
   671   GHashNode **new_nodes;
       
   672   GHashNode *node;
       
   673   GHashNode *next;
       
   674   guint hash_val;
       
   675   gint new_size;
       
   676   gint i;
       
   677 
       
   678   new_size = g_spaced_primes_closest (hash_table->nnodes);
       
   679   new_size = CLAMP (new_size, HASH_TABLE_MIN_SIZE, HASH_TABLE_MAX_SIZE);
       
   680   new_nodes = g_new0 (GHashNode*, new_size);
       
   681   
       
   682   for (i = 0; i < hash_table->size; i++)
       
   683     for (node = hash_table->nodes[i]; node; node = next)
       
   684       {
       
   685 	next = node->next;
       
   686 
       
   687 	hash_val = (* hash_table->hash_func) (node->key) % new_size;
       
   688 
       
   689 	node->next = new_nodes[hash_val];
       
   690 	new_nodes[hash_val] = node;
       
   691       }
       
   692   
       
   693   g_free (hash_table->nodes);
       
   694   hash_table->nodes = new_nodes;
       
   695   hash_table->size = new_size;
       
   696 }
       
   697 
       
   698 static GHashNode*
       
   699 g_hash_node_new (gpointer key,
       
   700 		 gpointer value)
       
   701 {
       
   702   GHashNode *hash_node = g_slice_new (GHashNode);
       
   703   
       
   704   hash_node->key = key;
       
   705   hash_node->value = value;
       
   706   hash_node->next = NULL;
       
   707   
       
   708   return hash_node;
       
   709 }
       
   710 
       
   711 static void
       
   712 g_hash_node_destroy (GHashNode      *hash_node,
       
   713 		     GDestroyNotify  key_destroy_func,
       
   714 		     GDestroyNotify  value_destroy_func)
       
   715 {
       
   716   if (key_destroy_func)
       
   717     key_destroy_func (hash_node->key);
       
   718   if (value_destroy_func)
       
   719     value_destroy_func (hash_node->value);
       
   720   g_slice_free (GHashNode, hash_node);
       
   721 }
       
   722 
       
   723 static void
       
   724 g_hash_nodes_destroy (GHashNode *hash_node,
       
   725 		      GFreeFunc  key_destroy_func,
       
   726 		      GFreeFunc  value_destroy_func)
       
   727 {
       
   728   while (hash_node)
       
   729     {
       
   730       GHashNode *next = hash_node->next;
       
   731       if (key_destroy_func)
       
   732 	key_destroy_func (hash_node->key);
       
   733       if (value_destroy_func)
       
   734 	value_destroy_func (hash_node->value);
       
   735       g_slice_free (GHashNode, hash_node);
       
   736       hash_node = next;
       
   737     }
       
   738 }
       
   739 
       
   740 
       
   741 #define __G_HASH_C__
       
   742 #include "galiasdef.c"