/* GLIB - Library of useful routines for C programming
 * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

/*
 * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
 * file for a list of people on the GLib Team.  See the ChangeLog
 * files for a list of changes.  These files are distributed with
 * GLib at ftp://ftp.gtk.org/pub/gtk/. 
 */

/* 
 * MT safe
 */

#include "config.h"

#include "glib.h"
#include "galias.h"


#define HASH_TABLE_MIN_SIZE 11
#define HASH_TABLE_MAX_SIZE 13845163


typedef struct _GHashNode      GHashNode;

struct _GHashNode
{
  gpointer   key;
  gpointer   value;
  GHashNode *next;
  guint      key_hash;
};

struct _GHashTable
{
  gint             size;
  gint             nnodes;
  GHashNode      **nodes;
  GHashFunc        hash_func;
  GEqualFunc       key_equal_func;
  volatile gint    ref_count;
  GDestroyNotify   key_destroy_func;
  GDestroyNotify   value_destroy_func;
};

#define G_HASH_TABLE_RESIZE(hash_table)				\
   G_STMT_START {						\
     if ((hash_table->size >= 3 * hash_table->nnodes &&	        \
	  hash_table->size > HASH_TABLE_MIN_SIZE) ||		\
	 (3 * hash_table->size <= hash_table->nnodes &&	        \
	  hash_table->size < HASH_TABLE_MAX_SIZE))		\
	   g_hash_table_resize (hash_table);			\
   } G_STMT_END

static void		g_hash_table_resize	  (GHashTable	  *hash_table);
static GHashNode**	g_hash_table_lookup_node  (GHashTable     *hash_table,
                                                   gconstpointer   key,
                                                   guint          *hash_return);
static GHashNode*	g_hash_node_new		  (gpointer	   key,
                                                   gpointer        value,
                                                   guint           key_hash);
static void		g_hash_node_destroy	  (GHashNode	  *hash_node,
                                                   GDestroyNotify  key_destroy_func,
                                                   GDestroyNotify  value_destroy_func);
static void		g_hash_nodes_destroy	  (GHashNode	  *hash_node,
						  GDestroyNotify   key_destroy_func,
						  GDestroyNotify   value_destroy_func);
static guint g_hash_table_foreach_remove_or_steal (GHashTable     *hash_table,
                                                   GHRFunc	   func,
                                                   gpointer	   user_data,
                                                   gboolean        notify);


/**
 * g_hash_table_new:
 * @hash_func: a function to create a hash value from a key.
 *   Hash values are used to determine where keys are stored within the
 *   #GHashTable data structure. The g_direct_hash(), g_int_hash() and 
 *   g_str_hash() functions are provided for some common types of keys. 
 *   If hash_func is %NULL, g_direct_hash() is used.
 * @key_equal_func: a function to check two keys for equality.  This is
 *   used when looking up keys in the #GHashTable.  The g_direct_equal(),
 *   g_int_equal() and g_str_equal() functions are provided for the most
 *   common types of keys. If @key_equal_func is %NULL, keys are compared
 *   directly in a similar fashion to g_direct_equal(), but without the
 *   overhead of a function call.
 *
 * Creates a new #GHashTable with a reference count of 1.
 * 
 * Return value: a new #GHashTable.
 **/
GHashTable*
g_hash_table_new (GHashFunc    hash_func,
		  GEqualFunc   key_equal_func)
{
  return g_hash_table_new_full (hash_func, key_equal_func, NULL, NULL);
}


/**
 * g_hash_table_new_full:
 * @hash_func: a function to create a hash value from a key.
 * @key_equal_func: a function to check two keys for equality.
 * @key_destroy_func: a function to free the memory allocated for the key 
 *   used when removing the entry from the #GHashTable or %NULL if you 
 *   don't want to supply such a function.
 * @value_destroy_func: a function to free the memory allocated for the 
 *   value used when removing the entry from the #GHashTable or %NULL if 
 *   you don't want to supply such a function.
 * 
 * Creates a new #GHashTable like g_hash_table_new() with a reference count
 * of 1 and allows to specify functions to free the memory allocated for the
 * key and value that get called when removing the entry from the #GHashTable.
 * 
 * Return value: a new #GHashTable.
 **/
GHashTable*
g_hash_table_new_full (GHashFunc       hash_func,
		       GEqualFunc      key_equal_func,
		       GDestroyNotify  key_destroy_func,
		       GDestroyNotify  value_destroy_func)
{
  GHashTable *hash_table;
  
  hash_table = g_slice_new (GHashTable);
  hash_table->size               = HASH_TABLE_MIN_SIZE;
  hash_table->nnodes             = 0;
  hash_table->hash_func          = hash_func ? hash_func : g_direct_hash;
  hash_table->key_equal_func     = key_equal_func;
  hash_table->ref_count          = 1;
  hash_table->key_destroy_func   = key_destroy_func;
  hash_table->value_destroy_func = value_destroy_func;
  hash_table->nodes              = g_new0 (GHashNode*, hash_table->size);
  
  return hash_table;
}


/**
 * g_hash_table_ref:
 * @hash_table: a valid #GHashTable.
 * 
 * Atomically increments the reference count of @hash_table by one.
 * This function is MT-safe and may be called from any thread.
 * 
 * Return value: the passed in #GHashTable.
 * 
 * Since: 2.10
 **/
GHashTable*
g_hash_table_ref (GHashTable *hash_table)
{
  g_return_val_if_fail (hash_table != NULL, NULL);
  g_return_val_if_fail (hash_table->ref_count > 0, hash_table);

  g_atomic_int_add (&hash_table->ref_count, 1);
  return hash_table;
}

/**
 * g_hash_table_unref:
 * @hash_table: a valid #GHashTable.
 * 
 * Atomically decrements the reference count of @hash_table by one.
 * If the reference count drops to 0, all keys and values will be
 * destroyed, and all memory allocated by the hash table is released.
 * This function is MT-safe and may be called from any thread.
 * 
 * Since: 2.10
 **/
void
g_hash_table_unref (GHashTable *hash_table)
{
  g_return_if_fail (hash_table != NULL);
  g_return_if_fail (hash_table->ref_count > 0);

  if (g_atomic_int_exchange_and_add (&hash_table->ref_count, -1) - 1 == 0)
    {
      gint i;

      for (i = 0; i < hash_table->size; i++)
        g_hash_nodes_destroy (hash_table->nodes[i], 
                              hash_table->key_destroy_func,
                              hash_table->value_destroy_func);
      g_free (hash_table->nodes);
      g_slice_free (GHashTable, hash_table);
    }
}

/**
 * g_hash_table_destroy:
 * @hash_table: a #GHashTable.
 * 
 * Destroys all keys and values in the #GHashTable and decrements its
 * reference count by 1. If keys and/or values are dynamically allocated,
 * you should either free them first or create the #GHashTable with destroy
 * notifiers using g_hash_table_new_full(). In the latter case the destroy
 * functions you supplied will be called on all keys and values during the
 * destruction phase.
 **/
void
g_hash_table_destroy (GHashTable *hash_table)
{
  g_return_if_fail (hash_table != NULL);
  g_return_if_fail (hash_table->ref_count > 0);
  
  g_hash_table_remove_all (hash_table);
  g_hash_table_unref (hash_table);
}

static inline GHashNode**
g_hash_table_lookup_node (GHashTable	*hash_table,
			  gconstpointer	 key,
			  guint		*hash_return)
{
  GHashNode **node;
  guint hash_value;

  hash_value = (* hash_table->hash_func) (key);
  node = &hash_table->nodes[hash_value % hash_table->size];
  
  if (hash_return)
    *hash_return = hash_value;
  
  /* Hash table lookup needs to be fast.
   *  We therefore remove the extra conditional of testing
   *  whether to call the key_equal_func or not from
   *  the inner loop.
   *
   *  Additional optimisation: first check if our full hash
   *  values are equal so we can avoid calling the full-blown
   *  key equality function in most cases.
   */
  if (hash_table->key_equal_func)
    while (*node && (((*node)->key_hash != hash_value) ||
                     !(*hash_table->key_equal_func) ((*node)->key, key)))
      node = &(*node)->next;
  else
    while (*node && (*node)->key != key)
      node = &(*node)->next;

  return node;
}

/**
 * g_hash_table_lookup:
 * @hash_table: a #GHashTable.
 * @key: the key to look up.
 * 
 * Looks up a key in a #GHashTable. Note that this function cannot
 * distinguish between a key that is not present and one which is present
 * and has the value %NULL. If you need this distinction, use
 * g_hash_table_lookup_extended().
 * 
 * Return value: the associated value, or %NULL if the key is not found.
 **/
gpointer
g_hash_table_lookup (GHashTable	  *hash_table,
		     gconstpointer key)
{
  GHashNode *node;
  
  g_return_val_if_fail (hash_table != NULL, NULL);
  
  node = *g_hash_table_lookup_node (hash_table, key, NULL);
  
  return node ? node->value : NULL;
}

/**
 * g_hash_table_lookup_extended:
 * @hash_table: a #GHashTable.
 * @lookup_key: the key to look up.
 * @orig_key: returns the original key.
 * @value: returns the value associated with the key.
 * 
 * Looks up a key in the #GHashTable, returning the original key and the
 * associated value and a #gboolean which is %TRUE if the key was found. This 
 * is useful if you need to free the memory allocated for the original key, 
 * for example before calling g_hash_table_remove().
 * 
 * Return value: %TRUE if the key was found in the #GHashTable.
 **/
gboolean
g_hash_table_lookup_extended (GHashTable    *hash_table,
			      gconstpointer  lookup_key,
			      gpointer	    *orig_key,
			      gpointer	    *value)
{
  GHashNode *node;
  
  g_return_val_if_fail (hash_table != NULL, FALSE);
  
  node = *g_hash_table_lookup_node (hash_table, lookup_key, NULL);
  
  if (node)
    {
      if (orig_key)
	*orig_key = node->key;
      if (value)
	*value = node->value;
      return TRUE;
    }
  else
    return FALSE;
}

/**
 * g_hash_table_insert:
 * @hash_table: a #GHashTable.
 * @key: a key to insert.
 * @value: the value to associate with the key.
 * 
 * Inserts a new key and value into a #GHashTable.
 * 
 * If the key already exists in the #GHashTable its current value is replaced
 * with the new value. If you supplied a @value_destroy_func when creating the 
 * #GHashTable, the old value is freed using that function. If you supplied
 * a @key_destroy_func when creating the #GHashTable, the passed key is freed 
 * using that function.
 **/
void
g_hash_table_insert (GHashTable *hash_table,
		     gpointer	 key,
		     gpointer	 value)
{
  GHashNode **node;
  guint key_hash;
  
  g_return_if_fail (hash_table != NULL);
  g_return_if_fail (hash_table->ref_count > 0);
  
  node = g_hash_table_lookup_node (hash_table, key, &key_hash);
  
  if (*node)
    {
      /* do not reset node->key in this place, keeping
       * the old key is the intended behaviour. 
       * g_hash_table_replace() can be used instead.
       */

      /* free the passed key */
      if (hash_table->key_destroy_func)
	hash_table->key_destroy_func (key);
      
      if (hash_table->value_destroy_func)
	hash_table->value_destroy_func ((*node)->value);

      (*node)->value = value;
    }
  else
    {
      *node = g_hash_node_new (key, value, key_hash);
      hash_table->nnodes++;
      G_HASH_TABLE_RESIZE (hash_table);
    }
}

/**
 * g_hash_table_replace:
 * @hash_table: a #GHashTable.
 * @key: a key to insert.
 * @value: the value to associate with the key.
 * 
 * Inserts a new key and value into a #GHashTable similar to 
 * g_hash_table_insert(). The difference is that if the key already exists 
 * in the #GHashTable, it gets replaced by the new key. If you supplied a 
 * @value_destroy_func when creating the #GHashTable, the old value is freed 
 * using that function. If you supplied a @key_destroy_func when creating the 
 * #GHashTable, the old key is freed using that function. 
 **/
void
g_hash_table_replace (GHashTable *hash_table,
		      gpointer	  key,
		      gpointer	  value)
{
  GHashNode **node;
  guint key_hash;
  
  g_return_if_fail (hash_table != NULL);
  g_return_if_fail (hash_table->ref_count > 0);
  
  node = g_hash_table_lookup_node (hash_table, key, &key_hash);
  
  if (*node)
    {
      if (hash_table->key_destroy_func)
	hash_table->key_destroy_func ((*node)->key);
      
      if (hash_table->value_destroy_func)
	hash_table->value_destroy_func ((*node)->value);

      (*node)->key   = key;
      (*node)->value = value;
    }
  else
    {
      *node = g_hash_node_new (key, value, key_hash);
      hash_table->nnodes++;
      G_HASH_TABLE_RESIZE (hash_table);
    }
}

/**
 * g_hash_table_remove:
 * @hash_table: a #GHashTable.
 * @key: the key to remove.
 * 
 * Removes a key and its associated value from a #GHashTable.
 *
 * If the #GHashTable was created using g_hash_table_new_full(), the
 * key and value are freed using the supplied destroy functions, otherwise
 * you have to make sure that any dynamically allocated values are freed 
 * yourself.
 * 
 * Return value: %TRUE if the key was found and removed from the #GHashTable.
 **/
gboolean
g_hash_table_remove (GHashTable	   *hash_table,
		     gconstpointer  key)
{
  GHashNode **node, *dest;
  
  g_return_val_if_fail (hash_table != NULL, FALSE);
  
  node = g_hash_table_lookup_node (hash_table, key, NULL);
  if (*node)
    {
      dest = *node;
      (*node) = dest->next;
      g_hash_node_destroy (dest, 
			   hash_table->key_destroy_func,
			   hash_table->value_destroy_func);
      hash_table->nnodes--;
  
      G_HASH_TABLE_RESIZE (hash_table);

      return TRUE;
    }

  return FALSE;
}

/**
 * g_hash_table_remove_all:
 * @hash_table: a #GHashTable
 *
 * Removes all keys and their associated values from a #GHashTable.
 *
 * If the #GHashTable was created using g_hash_table_new_full(), the keys
 * and values are freed using the supplied destroy functions, otherwise you
 * have to make sure that any dynamically allocated values are freed
 * yourself.
 *
 * Since: 2.12
 **/
void
g_hash_table_remove_all (GHashTable *hash_table)
{
  guint i;

  g_return_if_fail (hash_table != NULL);

  for (i = 0; i < hash_table->size; i++)
    {
      g_hash_nodes_destroy (hash_table->nodes[i],
                            hash_table->key_destroy_func,
                            hash_table->value_destroy_func);
      hash_table->nodes[i] = NULL;
    }
  hash_table->nnodes = 0;
  
  G_HASH_TABLE_RESIZE (hash_table);
}

/**
 * g_hash_table_steal:
 * @hash_table: a #GHashTable.
 * @key: the key to remove.
 * 
 * Removes a key and its associated value from a #GHashTable without
 * calling the key and value destroy functions.
 *
 * Return value: %TRUE if the key was found and removed from the #GHashTable.
 **/
gboolean
g_hash_table_steal (GHashTable    *hash_table,
                    gconstpointer  key)
{
  GHashNode **node, *dest;
  
  g_return_val_if_fail (hash_table != NULL, FALSE);
  
  node = g_hash_table_lookup_node (hash_table, key, NULL);
  if (*node)
    {
      dest = *node;
      (*node) = dest->next;
      g_hash_node_destroy (dest, NULL, NULL);
      hash_table->nnodes--;
  
      G_HASH_TABLE_RESIZE (hash_table);

      return TRUE;
    }

  return FALSE;
}

/**
 * g_hash_table_steal_all:
 * @hash_table: a #GHashTable.
 *
 * Removes all keys and their associated values from a #GHashTable 
 * without calling the key and value destroy functions.
 *
 * Since: 2.12
 **/
void
g_hash_table_steal_all (GHashTable *hash_table)
{
  guint i;

  g_return_if_fail (hash_table != NULL);

  for (i = 0; i < hash_table->size; i++)
    {
      g_hash_nodes_destroy (hash_table->nodes[i], NULL, NULL);
      hash_table->nodes[i] = NULL;
    }

  hash_table->nnodes = 0;

  G_HASH_TABLE_RESIZE (hash_table);
}

/**
 * g_hash_table_foreach_remove:
 * @hash_table: a #GHashTable.
 * @func: the function to call for each key/value pair.
 * @user_data: user data to pass to the function.
 * 
 * Calls the given function for each key/value pair in the #GHashTable.
 * If the function returns %TRUE, then the key/value pair is removed from the
 * #GHashTable. If you supplied key or value destroy functions when creating
 * the #GHashTable, they are used to free the memory allocated for the removed
 * keys and values.
 * 
 * Return value: the number of key/value pairs removed.
 **/
guint
g_hash_table_foreach_remove (GHashTable	*hash_table,
			     GHRFunc	 func,
			     gpointer	 user_data)
{
  g_return_val_if_fail (hash_table != NULL, 0);
  g_return_val_if_fail (func != NULL, 0);
  
  return g_hash_table_foreach_remove_or_steal (hash_table, func, user_data, TRUE);
}

/**
 * g_hash_table_foreach_steal:
 * @hash_table: a #GHashTable.
 * @func: the function to call for each key/value pair.
 * @user_data: user data to pass to the function.
 * 
 * Calls the given function for each key/value pair in the #GHashTable.
 * If the function returns %TRUE, then the key/value pair is removed from the
 * #GHashTable, but no key or value destroy functions are called.
 * 
 * Return value: the number of key/value pairs removed.
 **/
guint
g_hash_table_foreach_steal (GHashTable *hash_table,
                            GHRFunc	func,
                            gpointer	user_data)
{
  g_return_val_if_fail (hash_table != NULL, 0);
  g_return_val_if_fail (func != NULL, 0);
  
  return g_hash_table_foreach_remove_or_steal (hash_table, func, user_data, FALSE);
}

static guint
g_hash_table_foreach_remove_or_steal (GHashTable *hash_table,
                                      GHRFunc	  func,
                                      gpointer	  user_data,
                                      gboolean    notify)
{
  GHashNode *node, *prev;
  gint i;
  guint deleted = 0;
  
  for (i = 0; i < hash_table->size; i++)
    {
    restart:
      
      prev = NULL;
      
      for (node = hash_table->nodes[i]; node; prev = node, node = node->next)
	{
	  if ((* func) (node->key, node->value, user_data))
	    {
	      deleted += 1;
	      
	      hash_table->nnodes -= 1;
	      
	      if (prev)
		{
		  prev->next = node->next;
		  g_hash_node_destroy (node,
				       notify ? hash_table->key_destroy_func : NULL,
				       notify ? hash_table->value_destroy_func : NULL);
		  node = prev;
		}
	      else
		{
		  hash_table->nodes[i] = node->next;
		  g_hash_node_destroy (node,
				       notify ? hash_table->key_destroy_func : NULL,
				       notify ? hash_table->value_destroy_func : NULL);
		  goto restart;
		}
	    }
	}
    }
  
  G_HASH_TABLE_RESIZE (hash_table);
  
  return deleted;
}

/**
 * g_hash_table_foreach:
 * @hash_table: a #GHashTable.
 * @func: the function to call for each key/value pair.
 * @user_data: user data to pass to the function.
 * 
 * Calls the given function for each of the key/value pairs in the
 * #GHashTable.  The function is passed the key and value of each
 * pair, and the given @user_data parameter.  The hash table may not
 * be modified while iterating over it (you can't add/remove
 * items). To remove all items matching a predicate, use
 * g_hash_table_foreach_remove().
 *
 * See g_hash_table_find() for performance caveats for linear
 * order searches in contrast to g_hash_table_lookup().
 **/
void
g_hash_table_foreach (GHashTable *hash_table,
		      GHFunc	  func,
		      gpointer	  user_data)
{
  GHashNode *node;
  gint i;
  
  g_return_if_fail (hash_table != NULL);
  g_return_if_fail (func != NULL);
  
  for (i = 0; i < hash_table->size; i++)
    for (node = hash_table->nodes[i]; node; node = node->next)
      (* func) (node->key, node->value, user_data);
}

/**
 * g_hash_table_find:
 * @hash_table: a #GHashTable.
 * @predicate:  function to test the key/value pairs for a certain property.
 * @user_data:  user data to pass to the function.
 * 
 * Calls the given function for key/value pairs in the #GHashTable until 
 * @predicate returns %TRUE.  The function is passed the key and value of 
 * each pair, and the given @user_data parameter. The hash table may not
 * be modified while iterating over it (you can't add/remove items).
 *
 * Note, that hash tables are really only optimized for forward lookups,
 * i.e. g_hash_table_lookup().
 * So code that frequently issues g_hash_table_find() or
 * g_hash_table_foreach() (e.g. in the order of once per every entry in a
 * hash table) should probably be reworked to use additional or different
 * data structures for reverse lookups (keep in mind that an O(n) find/foreach
 * operation issued for all n values in a hash table ends up needing O(n*n)
 * operations).
 *
 * Return value: The value of the first key/value pair is returned, for which
 * func evaluates to %TRUE. If no pair with the requested property is found,
 * %NULL is returned.
 *
 * Since: 2.4
 **/
gpointer
g_hash_table_find (GHashTable	   *hash_table,
                   GHRFunc	    predicate,
                   gpointer	    user_data)
{
  GHashNode *node;
  gint i;
  
  g_return_val_if_fail (hash_table != NULL, NULL);
  g_return_val_if_fail (predicate != NULL, NULL);
  
  for (i = 0; i < hash_table->size; i++)
    for (node = hash_table->nodes[i]; node; node = node->next)
      if (predicate (node->key, node->value, user_data))
        return node->value;       
  return NULL;
}

/**
 * g_hash_table_size:
 * @hash_table: a #GHashTable.
 * 
 * Returns the number of elements contained in the #GHashTable.
 * 
 * Return value: the number of key/value pairs in the #GHashTable.
 **/
guint
g_hash_table_size (GHashTable *hash_table)
{
  g_return_val_if_fail (hash_table != NULL, 0);
  
  return hash_table->nnodes;
}

/**
 * g_hash_table_get_keys:
 * @hash_table: a #GHashTable
 *
 * Retrieves every key inside @hash_table. The returned data is valid
 * until @hash_table is modified.
 *
 * Return value: a #GList containing all the keys inside the hash
 *   table. The content of the list is owned by the hash table and
 *   should not be modified or freed. Use g_list_free() when done
 *   using the list.
 *
 * Since: 2.14
 */
GList *
g_hash_table_get_keys (GHashTable *hash_table)
{
  GHashNode *node;
  gint i;
  GList *retval;
  
  g_return_val_if_fail (hash_table != NULL, NULL);
  
  retval = NULL;
  for (i = 0; i < hash_table->size; i++)
    for (node = hash_table->nodes[i]; node; node = node->next)
      retval = g_list_prepend (retval, node->key);
  
  return retval;
}

/**
 * g_hash_table_get_values:
 * @hash_table: a #GHashTable
 *
 * Retrieves every value inside @hash_table. The returned data is
 * valid until @hash_table is modified.
 *
 * Return value: a #GList containing all the values inside the hash
 *   table. The content of the list is owned by the hash table and
 *   should not be modified or freed. Use g_list_free() when done
 *   using the list.
 *
 * Since: 2.14
 */
GList *
g_hash_table_get_values (GHashTable *hash_table)
{
  GHashNode *node;
  gint i;
  GList *retval;
  
  g_return_val_if_fail (hash_table != NULL, NULL);
  
  retval = NULL;
  for (i = 0; i < hash_table->size; i++)
    for (node = hash_table->nodes[i]; node; node = node->next)
      retval = g_list_prepend (retval, node->value);
  
  return retval;
}

static void
g_hash_table_resize (GHashTable *hash_table)
{
  GHashNode **new_nodes;
  GHashNode *node;
  GHashNode *next;
  guint hash_val;
  gint new_size;
  gint i;

  new_size = g_spaced_primes_closest (hash_table->nnodes);
  new_size = CLAMP (new_size, HASH_TABLE_MIN_SIZE, HASH_TABLE_MAX_SIZE);
 
  new_nodes = g_new0 (GHashNode*, new_size);
  
  for (i = 0; i < hash_table->size; i++)
    for (node = hash_table->nodes[i]; node; node = next)
      {
	next = node->next;

	hash_val = node->key_hash % new_size;

	node->next = new_nodes[hash_val];
	new_nodes[hash_val] = node;
      }
  
  g_free (hash_table->nodes);
  hash_table->nodes = new_nodes;
  hash_table->size = new_size;
}

static GHashNode*
g_hash_node_new (gpointer key,
		 gpointer value,
		 guint key_hash)
{
  GHashNode *hash_node = g_slice_new (GHashNode);
  
  hash_node->key = key;
  hash_node->value = value;
  hash_node->key_hash = key_hash;
  hash_node->next = NULL;
  
  return hash_node;
}

static void
g_hash_node_destroy (GHashNode      *hash_node,
		     GDestroyNotify  key_destroy_func,
		     GDestroyNotify  value_destroy_func)
{
  if (key_destroy_func)
    key_destroy_func (hash_node->key);
  if (value_destroy_func)
    value_destroy_func (hash_node->value);
  g_slice_free (GHashNode, hash_node);
}

static void
g_hash_nodes_destroy (GHashNode *hash_node,
		      GFreeFunc  key_destroy_func,
		      GFreeFunc  value_destroy_func)
{
  while (hash_node)
    {
      GHashNode *next = hash_node->next;
      if (key_destroy_func)
	key_destroy_func (hash_node->key);
      if (value_destroy_func)
	value_destroy_func (hash_node->value);
      g_slice_free (GHashNode, hash_node);
      hash_node = next;
    }
}


#define __G_HASH_C__
#include "galiasdef.c"
