/* GLIB - Library of useful routines for C programming
 * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
 * Copyright (C) 1999 The Free Software Foundation
 *
 * 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.1 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, see <http://www.gnu.org/licenses/>.
 */

/*
 * 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/. 
 */

#undef G_DISABLE_ASSERT
#undef G_LOG_DOMAIN

#include <config.h>

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include <glib.h>



int array[10000];

static void
fill_hash_table_and_array (GHashTable *hash_table)
{
  int i;

  for (i = 0; i < 10000; i++)
    {
      array[i] = i;
      g_hash_table_insert (hash_table, &array[i], &array[i]);
    }
}

static void
init_result_array (int result_array[10000])
{
  int i;

  for (i = 0; i < 10000; i++)
    result_array[i] = -1;
}

static void
verify_result_array (int array[10000])
{
  int i;

  for (i = 0; i < 10000; i++)
    g_assert (array[i] == i);
}

static void
handle_pair (gpointer key, gpointer value, int result_array[10000])
{
  int n;

  g_assert (key == value);

  n = *((int *) value);

  g_assert (n >= 0 && n < 10000);
  g_assert (result_array[n] == -1);

  result_array[n] = n;
}

static gboolean
my_hash_callback_remove (gpointer key,
                         gpointer value,
                         gpointer user_data)
{
  int *d = value;

  if ((*d) % 2)
    return TRUE;

  return FALSE;
}

static void
my_hash_callback_remove_test (gpointer key,
                              gpointer value,
                              gpointer user_data)
{
  int *d = value;

  if ((*d) % 2)
    g_assert_not_reached ();
}

static void
my_hash_callback (gpointer key,
                  gpointer value,
                  gpointer user_data)
{
  handle_pair (key, value, user_data);
}

static guint
my_hash (gconstpointer key)
{
  return (guint) *((const gint*) key);
}

static gboolean
my_hash_equal (gconstpointer a,
               gconstpointer b)
{
  return *((const gint*) a) == *((const gint*) b);
}



/*
 * This is a simplified version of the pathalias hashing function.
 * Thanks to Steve Belovin and Peter Honeyman
 *
 * hash a string into a long int.  31 bit crc (from andrew appel).
 * the crc table is computed at run time by crcinit() -- we could
 * precompute, but it takes 1 clock tick on a 750.
 *
 * This fast table calculation works only if POLY is a prime polynomial
 * in the field of integers modulo 2.  Since the coefficients of a
 * 32-bit polynomial won't fit in a 32-bit word, the high-order bit is
 * implicit.  IT MUST ALSO BE THE CASE that the coefficients of orders
 * 31 down to 25 are zero.  Happily, we have candidates, from
 * E. J.  Watson, "Primitive Polynomials (Mod 2)", Math. Comp. 16 (1962):
 *      x^32 + x^7 + x^5 + x^3 + x^2 + x^1 + x^0
 *      x^31 + x^3 + x^0
 *
 * We reverse the bits to get:
 *      111101010000000000000000000000001 but drop the last 1
 *         f   5   0   0   0   0   0   0
 *      010010000000000000000000000000001 ditto, for 31-bit crc
 *         4   8   0   0   0   0   0   0
 */

#define POLY 0x48000000L        /* 31-bit polynomial (avoids sign problems) */

static guint CrcTable[128];

/*
 - crcinit - initialize tables for hash function
 */
static void crcinit(void)
{
  int i, j;
  guint sum;

  for (i = 0; i < 128; ++i)
    {
      sum = 0L;
      for (j = 7 - 1; j >= 0; --j)
        if (i & (1 << j))
          sum ^= POLY >> j;
      CrcTable[i] = sum;
    }
}

/*
 - hash - Honeyman's nice hashing function
 */
static guint
honeyman_hash (gconstpointer key)
{
  const gchar *name = (const gchar *) key;
  gint size;
  guint sum = 0;

  g_assert (name != NULL);
  g_assert (*name != 0);

  size = strlen (name);

  while (size--)
    sum = (sum >> 7) ^ CrcTable[(sum ^ (*name++)) & 0x7f];

  return sum;
}


static gboolean
second_hash_cmp (gconstpointer a, gconstpointer b)
{
  return strcmp (a, b) == 0;
}



static guint
one_hash (gconstpointer key)
{
  return 1;
}


static void
not_even_foreach (gpointer key,
                  gpointer value,
                  gpointer user_data)
{
  const char *_key = (const char *) key;
  const char *_value = (const char *) value;
  int i;
  char val [20];

  g_assert (_key != NULL);
  g_assert (*_key != 0);
  g_assert (_value != NULL);
  g_assert (*_value != 0);

  i = atoi (_key);

  sprintf (val, "%d value", i);
  g_assert (strcmp (_value, val) == 0);

  g_assert ((i % 2) != 0);
  g_assert (i != 3);
}

static gboolean
remove_even_foreach (gpointer key,
                     gpointer value,
                     gpointer user_data)
{
  const char *_key = (const char *) key;
  const char *_value = (const char *) value;
  int i;
  char val [20];

  g_assert (_key != NULL);
  g_assert (*_key != 0);
  g_assert (_value != NULL);
  g_assert (*_value != 0);

  i = atoi (_key);

  sprintf (val, "%d value", i);
  g_assert (strcmp (_value, val) == 0);

  return ((i % 2) == 0) ? TRUE : FALSE;
}




static void
second_hash_test (gconstpointer d)
{
  gboolean simple_hash = GPOINTER_TO_INT (d);

  int       i;
  char      key[20] = "", val[20]="", *v, *orig_key, *orig_val;
  GHashTable     *h;
  gboolean found;

  crcinit ();

  h = g_hash_table_new_full (simple_hash ? one_hash : honeyman_hash,
                             second_hash_cmp,
                             g_free, g_free);
  g_assert (h != NULL);
  for (i = 0; i < 20; i++)
    {
      sprintf (key, "%d", i);
      g_assert (atoi (key) == i);

      sprintf (val, "%d value", i);
      g_assert (atoi (val) == i);

      g_hash_table_insert (h, g_strdup (key), g_strdup (val));
    }

  g_assert (g_hash_table_size (h) == 20);

  for (i = 0; i < 20; i++)
    {
      sprintf (key, "%d", i);
      g_assert (atoi(key) == i);

      v = (char *) g_hash_table_lookup (h, key);

      g_assert (v != NULL);
      g_assert (*v != 0);
      g_assert (atoi (v) == i);
    }

  sprintf (key, "%d", 3);
  g_hash_table_remove (h, key);
  g_assert (g_hash_table_size (h) == 19);
  g_hash_table_foreach_remove (h, remove_even_foreach, NULL);
  g_assert (g_hash_table_size (h) == 9);
  g_hash_table_foreach (h, not_even_foreach, NULL);

  for (i = 0; i < 20; i++)
    {
      sprintf (key, "%d", i);
      g_assert (atoi(key) == i);

      sprintf (val, "%d value", i);
      g_assert (atoi (val) == i);

      orig_key = orig_val = NULL;
      found = g_hash_table_lookup_extended (h, key,
                                            (gpointer)&orig_key,
                                            (gpointer)&orig_val);
      if ((i % 2) == 0 || i == 3)
        {
          g_assert (!found);
          continue;
        }

      g_assert (found);

      g_assert (orig_key != NULL);
      g_assert (strcmp (key, orig_key) == 0);

      g_assert (orig_val != NULL);
      g_assert (strcmp (val, orig_val) == 0);
    }

  g_hash_table_destroy (h);
}

static gboolean
find_first (gpointer key,
            gpointer value,
            gpointer user_data)
{
  gint *v = value;
  gint *test = user_data;
  return (*v == *test);
}

static void
direct_hash_test (void)
{
  gint       i, rc;
  GHashTable     *h;

  h = g_hash_table_new (NULL, NULL);
  g_assert (h != NULL);
  for (i = 1; i <= 20; i++)
    g_hash_table_insert (h, GINT_TO_POINTER (i),
                         GINT_TO_POINTER (i + 42));

  g_assert (g_hash_table_size (h) == 20);

  for (i = 1; i <= 20; i++)
    {
      rc = GPOINTER_TO_INT (g_hash_table_lookup (h, GINT_TO_POINTER (i)));

      g_assert (rc != 0);
      g_assert ((rc - 42) == i);
    }

  g_hash_table_destroy (h);
}

static void
direct_hash_test2 (void)
{
  gint       i, rc;
  GHashTable     *h;

  h = g_hash_table_new (g_direct_hash, g_direct_equal);
  g_assert (h != NULL);
  for (i = 1; i <= 20; i++)
    g_hash_table_insert (h, GINT_TO_POINTER (i),
                         GINT_TO_POINTER (i + 42));

  g_assert (g_hash_table_size (h) == 20);

  for (i = 1; i <= 20; i++)
    {
      rc = GPOINTER_TO_INT (g_hash_table_lookup (h, GINT_TO_POINTER (i)));

      g_assert (rc != 0);
      g_assert ((rc - 42) == i);
    }

  g_hash_table_destroy (h);
}

static void
int_hash_test (void)
{
  gint       i, rc;
  GHashTable     *h;
  gint     values[20];
  gint key;

  h = g_hash_table_new (g_int_hash, g_int_equal);
  g_assert (h != NULL);
  for (i = 0; i < 20; i++)
    {
      values[i] = i + 42;
      g_hash_table_insert (h, &values[i], GINT_TO_POINTER (i + 42));
    }

  g_assert (g_hash_table_size (h) == 20);

  for (i = 0; i < 20; i++)
    {
      key = i + 42;
      rc = GPOINTER_TO_INT (g_hash_table_lookup (h, &key));

      g_assert_cmpint (rc, ==, i + 42);
    }

  g_hash_table_destroy (h);
}

static void
int64_hash_test (void)
{
  gint       i, rc;
  GHashTable     *h;
  gint64     values[20];
  gint64 key;

  h = g_hash_table_new (g_int64_hash, g_int64_equal);
  g_assert (h != NULL);
  for (i = 0; i < 20; i++)
    {
      values[i] = i + 42;
      g_hash_table_insert (h, &values[i], GINT_TO_POINTER (i + 42));
    }

  g_assert (g_hash_table_size (h) == 20);

  for (i = 0; i < 20; i++)
    {
      key = i + 42;
      rc = GPOINTER_TO_INT (g_hash_table_lookup (h, &key));

      g_assert_cmpint (rc, ==, i + 42);
    }

  g_hash_table_destroy (h);
}

static void
double_hash_test (void)
{
  gint       i, rc;
  GHashTable     *h;
  gdouble values[20];
  gdouble key;

  h = g_hash_table_new (g_double_hash, g_double_equal);
  g_assert (h != NULL);
  for (i = 0; i < 20; i++)
    {
      values[i] = i + 42.5;
      g_hash_table_insert (h, &values[i], GINT_TO_POINTER (i + 42));
    }

  g_assert (g_hash_table_size (h) == 20);

  for (i = 0; i < 20; i++)
    {
      key = i + 42.5;
      rc = GPOINTER_TO_INT (g_hash_table_lookup (h, &key));

      g_assert_cmpint (rc, ==, i + 42);
    }

  g_hash_table_destroy (h);
}

static void
string_free (gpointer data)
{
  GString *s = data;

  g_string_free (s, TRUE);
}

static void
string_hash_test (void)
{
  gint       i, rc;
  GHashTable     *h;
  GString *s;

  h = g_hash_table_new_full ((GHashFunc)g_string_hash, (GEqualFunc)g_string_equal, string_free, NULL);
  g_assert (h != NULL);
  for (i = 0; i < 20; i++)
    {
      s = g_string_new ("");
      g_string_append_printf (s, "%d", i + 42);
      g_string_append_c (s, '.');
      g_string_prepend_unichar (s, 0x2301);
      g_hash_table_insert (h, s, GINT_TO_POINTER (i + 42));
    }

  g_assert (g_hash_table_size (h) == 20);

  s = g_string_new ("");
  for (i = 0; i < 20; i++)
    {
      g_string_assign (s, "");
      g_string_append_printf (s, "%d", i + 42);
      g_string_append_c (s, '.');
      g_string_prepend_unichar (s, 0x2301);
      rc = GPOINTER_TO_INT (g_hash_table_lookup (h, s));

      g_assert_cmpint (rc, ==, i + 42);
    }

  g_string_free (s, TRUE);
  g_hash_table_destroy (h);
}

static void
set_check (gpointer key,
           gpointer value,
           gpointer user_data)
{
  int *pi = user_data;
  if (key != value)
    g_assert_not_reached ();

  g_assert_cmpint (atoi (key) % 7, ==, 2);

  (*pi)++;
}

static void
set_hash_test (void)
{
  GHashTable *hash_table =
    g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
  int i;

  for (i = 2; i < 5000; i += 7)
    {
      char *s = g_strdup_printf ("%d", i);
      g_assert (g_hash_table_add (hash_table, s));
    }

  g_assert (!g_hash_table_add (hash_table, g_strdup_printf ("%d", 2)));

  i = 0;
  g_hash_table_foreach (hash_table, set_check, &i);
  g_assert_cmpint (i, ==, g_hash_table_size (hash_table));

  g_assert (g_hash_table_contains (hash_table, "2"));
  g_assert (g_hash_table_contains (hash_table, "9"));
  g_assert (!g_hash_table_contains (hash_table, "a"));

  /* this will cause the hash table to loose set nature */
  g_assert (g_hash_table_insert (hash_table, g_strdup ("a"), "b"));
  g_assert (!g_hash_table_insert (hash_table, g_strdup ("a"), "b"));

  g_assert (g_hash_table_replace (hash_table, g_strdup ("c"), "d"));
  g_assert (!g_hash_table_replace (hash_table, g_strdup ("c"), "d"));

  g_assert_cmpstr (g_hash_table_lookup (hash_table, "2"), ==, "2");
  g_assert_cmpstr (g_hash_table_lookup (hash_table, "a"), ==, "b");

  g_hash_table_destroy (hash_table);
}


static void
test_hash_misc (void)
{
  GHashTable *hash_table;
  gint i;
  gint value = 120;
  gint *pvalue;
  GList *keys, *values;
  gint keys_len, values_len;
  GHashTableIter iter;
  gpointer ikey, ivalue;
  int result_array[10000];
  int n_array[1];

  hash_table = g_hash_table_new (my_hash, my_hash_equal);
  fill_hash_table_and_array (hash_table);
  pvalue = g_hash_table_find (hash_table, find_first, &value);
  if (!pvalue || *pvalue != value)
    g_assert_not_reached();

  keys = g_hash_table_get_keys (hash_table);
  if (!keys)
    g_assert_not_reached ();

  values = g_hash_table_get_values (hash_table);
  if (!values)
    g_assert_not_reached ();

  keys_len = g_list_length (keys);
  values_len = g_list_length (values);
  if (values_len != keys_len &&  keys_len != g_hash_table_size (hash_table))
    g_assert_not_reached ();

  g_list_free (keys);
  g_list_free (values);

  init_result_array (result_array);
  g_hash_table_iter_init (&iter, hash_table);
  for (i = 0; i < 10000; i++)
    {
      g_assert (g_hash_table_iter_next (&iter, &ikey, &ivalue));

      handle_pair (ikey, ivalue, result_array);

      if (i % 2)
        g_hash_table_iter_remove (&iter);
    }
  g_assert (! g_hash_table_iter_next (&iter, &ikey, &ivalue));
  g_assert (g_hash_table_size (hash_table) == 5000);
  verify_result_array (result_array);

  fill_hash_table_and_array (hash_table);

  init_result_array (result_array);
  g_hash_table_foreach (hash_table, my_hash_callback, result_array);
  verify_result_array (result_array);

  for (i = 0; i < 10000; i++)
    g_hash_table_remove (hash_table, &array[i]);

  fill_hash_table_and_array (hash_table);

  if (g_hash_table_foreach_remove (hash_table, my_hash_callback_remove, NULL) != 5000 ||
      g_hash_table_size (hash_table) != 5000)
    g_assert_not_reached();

  g_hash_table_foreach (hash_table, my_hash_callback_remove_test, NULL);
  g_hash_table_destroy (hash_table);

  hash_table = g_hash_table_new (my_hash, my_hash_equal);
  fill_hash_table_and_array (hash_table);

  n_array[0] = 1;

  g_hash_table_iter_init (&iter, hash_table);
  for (i = 0; i < 10000; i++)
    {
      g_assert (g_hash_table_iter_next (&iter, &ikey, &ivalue));
      g_hash_table_iter_replace (&iter, &n_array[0]);
    }

  g_hash_table_iter_init (&iter, hash_table);
  for (i = 0; i < 10000; i++)
    {
      g_assert (g_hash_table_iter_next (&iter, &ikey, &ivalue));

      g_assert (ivalue == &n_array[0]);
    }

  g_hash_table_destroy (hash_table);
}

static gint destroy_counter;

static void
value_destroy (gpointer value)
{
  destroy_counter++;
}

static void
test_hash_ref (void)
{
  GHashTable *h;
  GHashTableIter iter;
  gchar *key, *value;
  gboolean abc_seen = FALSE;
  gboolean cde_seen = FALSE;
  gboolean xyz_seen = FALSE;

  h = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, value_destroy);
  g_hash_table_insert (h, "abc", "ABC");
  g_hash_table_insert (h, "cde", "CDE");
  g_hash_table_insert (h, "xyz", "XYZ");

  g_assert_cmpint (g_hash_table_size (h), == , 3);

  g_hash_table_iter_init (&iter, h);

  while (g_hash_table_iter_next (&iter, (gpointer*)&key, (gpointer*)&value))
    {
      if (strcmp (key, "abc") == 0)
        {
          g_assert_cmpstr (value, ==, "ABC");
          abc_seen = TRUE;
          g_hash_table_iter_steal (&iter);
        }
      else if (strcmp (key, "cde") == 0)
        {
          g_assert_cmpstr (value, ==, "CDE");
          cde_seen = TRUE;
        }
      else if (strcmp (key, "xyz") == 0)
        {
          g_assert_cmpstr (value, ==, "XYZ");
          xyz_seen = TRUE;
        }
    }
  g_assert_cmpint (destroy_counter, ==, 0);

  g_assert (g_hash_table_iter_get_hash_table (&iter) == h);
  g_assert (abc_seen && cde_seen && xyz_seen);
  g_assert_cmpint (g_hash_table_size (h), == , 2);

  g_hash_table_ref (h);
  g_hash_table_destroy (h);
  g_assert_cmpint (g_hash_table_size (h), == , 0);
  g_assert_cmpint (destroy_counter, ==, 2);
  g_hash_table_insert (h, "uvw", "UVW");
  g_hash_table_unref (h);
  g_assert_cmpint (destroy_counter, ==, 3);
}

static guint
null_safe_str_hash (gconstpointer key)
{
  if (key == NULL)
    return 0;
  else
    return g_str_hash (key);
}

static gboolean
null_safe_str_equal (gconstpointer a, gconstpointer b)
{
  return g_strcmp0 (a, b) == 0;
}

static void
test_lookup_null_key (void)
{
  GHashTable *h;
  gboolean res;
  gpointer key;
  gpointer value;

  g_test_bug ("642944");

  h = g_hash_table_new (null_safe_str_hash, null_safe_str_equal);
  g_hash_table_insert (h, "abc", "ABC");

  res = g_hash_table_lookup_extended (h, NULL, &key, &value);
  g_assert (!res);

  g_hash_table_insert (h, NULL, "NULL");

  res = g_hash_table_lookup_extended (h, NULL, &key, &value);
  g_assert (res);
  g_assert_cmpstr (value, ==, "NULL");

  g_hash_table_unref (h);
}

static gint destroy_key_counter;

static void
key_destroy (gpointer key)
{
  destroy_key_counter++;
}

static void
test_remove_all (void)
{
  GHashTable *h;
  gboolean res;

  h = g_hash_table_new_full (g_str_hash, g_str_equal, key_destroy, value_destroy);

  g_hash_table_insert (h, "abc", "cde");
  g_hash_table_insert (h, "cde", "xyz");
  g_hash_table_insert (h, "xyz", "abc");

  destroy_counter = 0;
  destroy_key_counter = 0;

  g_hash_table_steal_all (h);
  g_assert_cmpint (destroy_counter, ==, 0);
  g_assert_cmpint (destroy_key_counter, ==, 0);

  g_hash_table_insert (h, "abc", "ABC");
  g_hash_table_insert (h, "cde", "CDE");
  g_hash_table_insert (h, "xyz", "XYZ");

  res = g_hash_table_steal (h, "nosuchkey");
  g_assert (!res);
  g_assert_cmpint (destroy_counter, ==, 0);
  g_assert_cmpint (destroy_key_counter, ==, 0);

  res = g_hash_table_steal (h, "xyz");
  g_assert (res);
  g_assert_cmpint (destroy_counter, ==, 0);
  g_assert_cmpint (destroy_key_counter, ==, 0);

  g_hash_table_remove_all (h);
  g_assert_cmpint (destroy_counter, ==, 2);
  g_assert_cmpint (destroy_key_counter, ==, 2);

  g_hash_table_remove_all (h);
  g_assert_cmpint (destroy_counter, ==, 2);
  g_assert_cmpint (destroy_key_counter, ==, 2);

  g_hash_table_unref (h);
}

GHashTable *recursive_destruction_table = NULL;
static void
recursive_value_destroy (gpointer value)
{
  destroy_counter++;

  if (recursive_destruction_table)
    g_hash_table_remove (recursive_destruction_table, value);
}

static void
test_recursive_remove_all_subprocess (void)
{
  GHashTable *h;

  h = g_hash_table_new_full (g_str_hash, g_str_equal, key_destroy, recursive_value_destroy);
  recursive_destruction_table = h;

  /* Add more items compared to test_remove_all, as it would not fail otherwise. */
  g_hash_table_insert (h, "abc", "cde");
  g_hash_table_insert (h, "cde", "fgh");
  g_hash_table_insert (h, "fgh", "ijk");
  g_hash_table_insert (h, "ijk", "lmn");
  g_hash_table_insert (h, "lmn", "opq");
  g_hash_table_insert (h, "opq", "rst");
  g_hash_table_insert (h, "rst", "uvw");
  g_hash_table_insert (h, "uvw", "xyz");
  g_hash_table_insert (h, "xyz", "abc");

  destroy_counter = 0;
  destroy_key_counter = 0;

  g_hash_table_remove_all (h);
  g_assert_cmpint (destroy_counter, ==, 9);
  g_assert_cmpint (destroy_key_counter, ==, 9);

  g_hash_table_unref (h);
}

static void
test_recursive_remove_all (void)
{
  g_test_trap_subprocess ("/hash/recursive-remove-all/subprocess", 1000000, 0);
  g_test_trap_assert_passed ();
}

typedef struct {
  gint ref_count;
  const gchar *key;
} RefCountedKey;

static guint
hash_func (gconstpointer key)
{
  const RefCountedKey *rkey = key;

  return g_str_hash (rkey->key);
}

static gboolean
eq_func (gconstpointer a, gconstpointer b)
{
  const RefCountedKey *aa = a;
  const RefCountedKey *bb = b;

  return g_strcmp0 (aa->key, bb->key) == 0;
}

static void
key_unref (gpointer data)
{
  RefCountedKey *key = data;

  g_assert (key->ref_count > 0);

  key->ref_count -= 1;

  if (key->ref_count == 0)
    g_free (key);
}

static RefCountedKey *
key_ref (RefCountedKey *key)
{
  key->ref_count += 1;

  return key;
}

static RefCountedKey *
key_new (const gchar *key)
{
  RefCountedKey *rkey;

  rkey = g_new (RefCountedKey, 1);

  rkey->ref_count = 1;
  rkey->key = key;

  return rkey;
}

static void
set_ref_hash_test (void)
{
  GHashTable *h;
  RefCountedKey *key1;
  RefCountedKey *key2;

  h = g_hash_table_new_full (hash_func, eq_func, key_unref, key_unref);

  key1 = key_new ("a");
  key2 = key_new ("a");

  g_assert_cmpint (key1->ref_count, ==, 1);
  g_assert_cmpint (key2->ref_count, ==, 1);

  g_hash_table_insert (h, key_ref (key1), key_ref (key1));

  g_assert_cmpint (key1->ref_count, ==, 3);
  g_assert_cmpint (key2->ref_count, ==, 1);

  g_hash_table_replace (h, key_ref (key2), key_ref (key2));

  g_assert_cmpint (key1->ref_count, ==, 1);
  g_assert_cmpint (key2->ref_count, ==, 3);

  g_hash_table_remove (h, key1);

  g_assert_cmpint (key1->ref_count, ==, 1);
  g_assert_cmpint (key2->ref_count, ==, 1);

  g_hash_table_unref (h);

  key_unref (key1);
  key_unref (key2);
}

GHashTable *h;

typedef struct {
    gchar *string;
    gboolean freed;
} FakeFreeData;

GPtrArray *fake_free_data;

static void
fake_free (gpointer dead)
{
  guint i;

  for (i = 0; i < fake_free_data->len; i++)
    {
      FakeFreeData *ffd = g_ptr_array_index (fake_free_data, i);

      if (ffd->string == (gchar *) dead)
        {
          g_assert (!ffd->freed);
          ffd->freed = TRUE;
          return;
        }
    }

  g_assert_not_reached ();
}

static void
value_destroy_insert (gpointer value)
{
  g_hash_table_remove_all (h);
}

static void
test_destroy_modify (void)
{
  FakeFreeData *ffd;
  guint i;

  g_test_bug ("650459");

  fake_free_data = g_ptr_array_new ();

  h = g_hash_table_new_full (g_str_hash, g_str_equal, fake_free, value_destroy_insert);

  ffd = g_new0 (FakeFreeData, 1);
  ffd->string = g_strdup ("a");
  g_ptr_array_add (fake_free_data, ffd);
  g_hash_table_insert (h, ffd->string, "b");

  ffd = g_new0 (FakeFreeData, 1);
  ffd->string = g_strdup ("c");
  g_ptr_array_add (fake_free_data, ffd);
  g_hash_table_insert (h, ffd->string, "d");

  ffd = g_new0 (FakeFreeData, 1);
  ffd->string = g_strdup ("e");
  g_ptr_array_add (fake_free_data, ffd);
  g_hash_table_insert (h, ffd->string, "f");

  ffd = g_new0 (FakeFreeData, 1);
  ffd->string = g_strdup ("g");
  g_ptr_array_add (fake_free_data, ffd);
  g_hash_table_insert (h, ffd->string, "h");

  ffd = g_new0 (FakeFreeData, 1);
  ffd->string = g_strdup ("h");
  g_ptr_array_add (fake_free_data, ffd);
  g_hash_table_insert (h, ffd->string, "k");

  ffd = g_new0 (FakeFreeData, 1);
  ffd->string = g_strdup ("a");
  g_ptr_array_add (fake_free_data, ffd);
  g_hash_table_insert (h, ffd->string, "c");

  g_hash_table_remove (h, "c");

  /* that removed everything... */
  for (i = 0; i < fake_free_data->len; i++)
    {
      FakeFreeData *ffd = g_ptr_array_index (fake_free_data, i);

      g_assert (ffd->freed);
      g_free (ffd->string);
      g_free (ffd);
    }

  g_ptr_array_unref (fake_free_data);

  /* ... so this is a no-op */
  g_hash_table_remove (h, "e");

  g_hash_table_unref (h);
}

static gboolean
find_str (gpointer key, gpointer value, gpointer data)
{
  return g_str_equal (key, data);
}

static void
test_find (void)
{
  GHashTable *hash;
  const gchar *value;

  hash = g_hash_table_new (g_str_hash, g_str_equal);

  g_hash_table_insert (hash, "a", "A");
  g_hash_table_insert (hash, "b", "B");
  g_hash_table_insert (hash, "c", "C");
  g_hash_table_insert (hash, "d", "D");
  g_hash_table_insert (hash, "e", "E");
  g_hash_table_insert (hash, "f", "F");

  value = g_hash_table_find (hash, find_str, "a");
  g_assert_cmpstr (value, ==, "A");

  value = g_hash_table_find (hash, find_str, "b");
  g_assert_cmpstr (value, ==, "B");

  value = g_hash_table_find (hash, find_str, "c");
  g_assert_cmpstr (value, ==, "C");

  value = g_hash_table_find (hash, find_str, "d");
  g_assert_cmpstr (value, ==, "D");

  value = g_hash_table_find (hash, find_str, "e");
  g_assert_cmpstr (value, ==, "E");

  value = g_hash_table_find (hash, find_str, "f");
  g_assert_cmpstr (value, ==, "F");

  value = g_hash_table_find (hash, find_str, "0");
  g_assert (value == NULL);

  g_hash_table_unref (hash);
}

gboolean seen_key[6];

static void
foreach_func (gpointer key, gpointer value, gpointer data)
{
  seen_key[((char*)key)[0] - 'a'] = TRUE;
}

static void
test_foreach (void)
{
  GHashTable *hash;
  gint i;

  hash = g_hash_table_new (g_str_hash, g_str_equal);

  g_hash_table_insert (hash, "a", "A");
  g_hash_table_insert (hash, "b", "B");
  g_hash_table_insert (hash, "c", "C");
  g_hash_table_insert (hash, "d", "D");
  g_hash_table_insert (hash, "e", "E");
  g_hash_table_insert (hash, "f", "F");

  for (i = 0; i < 6; i++)
    seen_key[i] = FALSE;

  g_hash_table_foreach (hash, foreach_func, NULL);

  for (i = 0; i < 6; i++)
    g_assert (seen_key[i]);

  g_hash_table_unref (hash);
}

static gboolean
foreach_steal_func (gpointer key, gpointer value, gpointer data)
{
  GHashTable *hash2 = data;

  if (strstr ("ace", (gchar*)key))
    {
      g_hash_table_insert (hash2, key, value);
      return TRUE;
    }

  return FALSE;
}


static void
test_foreach_steal (void)
{
  GHashTable *hash;
  GHashTable *hash2;

  hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
  hash2 = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);

  g_hash_table_insert (hash, g_strdup ("a"), g_strdup ("A"));
  g_hash_table_insert (hash, g_strdup ("b"), g_strdup ("B"));
  g_hash_table_insert (hash, g_strdup ("c"), g_strdup ("C"));
  g_hash_table_insert (hash, g_strdup ("d"), g_strdup ("D"));
  g_hash_table_insert (hash, g_strdup ("e"), g_strdup ("E"));
  g_hash_table_insert (hash, g_strdup ("f"), g_strdup ("F"));

  g_hash_table_foreach_steal (hash, foreach_steal_func, hash2);

  g_assert_cmpint (g_hash_table_size (hash), ==, 3);
  g_assert_cmpint (g_hash_table_size (hash2), ==, 3);

  g_assert_cmpstr (g_hash_table_lookup (hash2, "a"), ==, "A");
  g_assert_cmpstr (g_hash_table_lookup (hash, "b"), ==, "B");
  g_assert_cmpstr (g_hash_table_lookup (hash2, "c"), ==, "C");
  g_assert_cmpstr (g_hash_table_lookup (hash, "d"), ==, "D");
  g_assert_cmpstr (g_hash_table_lookup (hash2, "e"), ==, "E");
  g_assert_cmpstr (g_hash_table_lookup (hash, "f"), ==, "F");

  g_hash_table_unref (hash);
  g_hash_table_unref (hash2);
}

/* Test g_hash_table_steal_extended() works properly with existing and
 * non-existing keys. */
static void
test_steal_extended (void)
{
  GHashTable *hash;
  gchar *stolen_key = NULL, *stolen_value = NULL;

  hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);

  g_hash_table_insert (hash, g_strdup ("a"), g_strdup ("A"));
  g_hash_table_insert (hash, g_strdup ("b"), g_strdup ("B"));
  g_hash_table_insert (hash, g_strdup ("c"), g_strdup ("C"));
  g_hash_table_insert (hash, g_strdup ("d"), g_strdup ("D"));
  g_hash_table_insert (hash, g_strdup ("e"), g_strdup ("E"));
  g_hash_table_insert (hash, g_strdup ("f"), g_strdup ("F"));

  g_assert_true (g_hash_table_steal_extended (hash, "a",
                                              (gpointer *) &stolen_key,
                                              (gpointer *) &stolen_value));
  g_assert_cmpstr (stolen_key, ==, "a");
  g_assert_cmpstr (stolen_value, ==, "A");
  g_clear_pointer (&stolen_key, g_free);
  g_clear_pointer (&stolen_value, g_free);

  g_assert_cmpuint (g_hash_table_size (hash), ==, 5);

  g_assert_false (g_hash_table_steal_extended (hash, "a",
                                               (gpointer *) &stolen_key,
                                               (gpointer *) &stolen_value));
  g_assert_null (stolen_key);
  g_assert_null (stolen_value);

  g_assert_false (g_hash_table_steal_extended (hash, "never a key",
                                               (gpointer *) &stolen_key,
                                               (gpointer *) &stolen_value));
  g_assert_null (stolen_key);
  g_assert_null (stolen_value);

  g_assert_cmpuint (g_hash_table_size (hash), ==, 5);

  g_hash_table_unref (hash);
}

struct _GHashTable
{
  gint             size;
  gint             mod;
  guint            mask;
  gint             nnodes;
  gint             noccupied;  /* nnodes + tombstones */

  gpointer        *keys;
  guint           *hashes;
  gpointer        *values;

  GHashFunc        hash_func;
  GEqualFunc       key_equal_func;
  volatile gint    ref_count;

#ifndef G_DISABLE_ASSERT
  int              version;
#endif
  GDestroyNotify   key_destroy_func;
  GDestroyNotify   value_destroy_func;
};

static void
count_keys (GHashTable *h, gint *unused, gint *occupied, gint *tombstones)
{
  gint i;

  *unused = 0;
  *occupied = 0;
  *tombstones = 0;
  for (i = 0; i < h->size; i++)
    {
      if (h->hashes[i] == 0)
        (*unused)++;
      else if (h->hashes[i] == 1)
        (*tombstones)++;
      else
        (*occupied)++;
    }
}

static void
check_data (GHashTable *h)
{
  gint i;

  for (i = 0; i < h->size; i++)
    {
      if (h->hashes[i] < 2)
        {
          g_assert (h->keys[i] == NULL);
          g_assert (h->values[i] == NULL);
        }
      else
        {
          g_assert_cmpint (h->hashes[i], ==, h->hash_func (h->keys[i]));
        }
    }
}

static void
check_consistency (GHashTable *h)
{
  gint unused;
  gint occupied;
  gint tombstones;

  count_keys (h, &unused, &occupied, &tombstones);

  g_assert_cmpint (occupied, ==, h->nnodes);
  g_assert_cmpint (occupied + tombstones, ==, h->noccupied);
  g_assert_cmpint (occupied + tombstones + unused, ==, h->size);

  check_data (h);
}

static void
check_counts (GHashTable *h, gint occupied, gint tombstones)
{
  g_assert_cmpint (occupied, ==, h->nnodes);
  g_assert_cmpint (occupied + tombstones, ==, h->noccupied);
}

static void
trivial_key_destroy (gpointer key)
{
}

static void
test_internal_consistency (void)
{
  GHashTable *h;

  h = g_hash_table_new_full (g_str_hash, g_str_equal, trivial_key_destroy, NULL);

  check_counts (h, 0, 0);
  check_consistency (h);

  g_hash_table_insert (h, "a", "A");
  g_hash_table_insert (h, "b", "B");
  g_hash_table_insert (h, "c", "C");
  g_hash_table_insert (h, "d", "D");
  g_hash_table_insert (h, "e", "E");
  g_hash_table_insert (h, "f", "F");

  check_counts (h, 6, 0);
  check_consistency (h);

  g_hash_table_remove (h, "a");
  check_counts (h, 5, 1);
  check_consistency (h);

  g_hash_table_remove (h, "b");
  check_counts (h, 4, 2);
  check_consistency (h);

  g_hash_table_insert (h, "c", "c");
  check_counts (h, 4, 2);
  check_consistency (h);

  g_hash_table_insert (h, "a", "A");
  check_counts (h, 5, 1);
  check_consistency (h);

  g_hash_table_remove_all (h);
  check_counts (h, 0, 0);
  check_consistency (h);

  g_hash_table_unref (h);
}

static void
my_key_free (gpointer v)
{
  gchar *s = v;
  g_assert (s[0] != 'x');
  s[0] = 'x';
  g_free (v);
}

static void
my_value_free (gpointer v)
{
  gchar *s = v;
  g_assert (s[0] != 'y');
  s[0] = 'y';
  g_free (v);
}

static void
test_iter_replace (void)
{
  GHashTable *h;
  GHashTableIter iter;
  gpointer k, v;
  gchar *s;

  g_test_bug ("662544");

  h = g_hash_table_new_full (g_str_hash, g_str_equal, my_key_free, my_value_free);

  g_hash_table_insert (h, g_strdup ("A"), g_strdup ("a"));
  g_hash_table_insert (h, g_strdup ("B"), g_strdup ("b"));
  g_hash_table_insert (h, g_strdup ("C"), g_strdup ("c"));

  g_hash_table_iter_init (&iter, h);

  while (g_hash_table_iter_next (&iter, &k, &v))
    {
       s = (gchar*)v;
       g_assert (g_ascii_islower (s[0]));
       g_hash_table_iter_replace (&iter, g_strdup (k));
    }

  g_hash_table_unref (h);
}

static void
replace_first_character (gchar *string)
{
  string[0] = 'b';
}

static void
test_set_insert_corruption (void)
{
  GHashTable *hash_table =
    g_hash_table_new_full (g_str_hash, g_str_equal,
        (GDestroyNotify) replace_first_character, NULL);
  GHashTableIter iter;
  gchar a[] = "foo";
  gchar b[] = "foo";
  gpointer key, value;

  g_test_bug ("692815");

  g_hash_table_insert (hash_table, a, a);
  g_assert (g_hash_table_contains (hash_table, "foo"));

  g_hash_table_insert (hash_table, b, b);

  g_assert_cmpuint (g_hash_table_size (hash_table), ==, 1);
  g_hash_table_iter_init (&iter, hash_table);
  if (!g_hash_table_iter_next (&iter, &key, &value))
    g_assert_not_reached();

  /* per the documentation to g_hash_table_insert(), 'b' has now been freed,
   * and the sole key in 'hash_table' should be 'a'.
   */
  g_assert (key != b);
  g_assert (key == a);

  g_assert_cmpstr (b, ==, "boo");

  /* g_hash_table_insert() also says that the value should now be 'b',
   * which is probably not what the caller intended but is precisely what they
   * asked for.
   */
  g_assert (value == b);

  /* even though the hash has now been de-set-ified: */
  g_assert (g_hash_table_contains (hash_table, "foo"));

  g_hash_table_unref (hash_table);
}

static void
test_set_to_strv (void)
{
  GHashTable *set;
  gchar **strv;
  guint n;

  set = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
  g_hash_table_add (set, g_strdup ("xyz"));
  g_hash_table_add (set, g_strdup ("xyz"));
  g_hash_table_add (set, g_strdup ("abc"));
  strv = (gchar **) g_hash_table_get_keys_as_array (set, &n);
  g_hash_table_steal_all (set);
  g_hash_table_unref (set);
  g_assert_cmpint (n, ==, 2);
  n = g_strv_length (strv);
  g_assert_cmpint (n, ==, 2);
  if (g_str_equal (strv[0], "abc"))
    g_assert_cmpstr (strv[1], ==, "xyz");
  else
    {
    g_assert_cmpstr (strv[0], ==, "xyz");
    g_assert_cmpstr (strv[1], ==, "abc");
    }
  g_strfreev (strv);
}

static gboolean
is_prime (guint p)
{
  guint i;

  if (p % 2 == 0)
    return FALSE;

  i = 3;
  while (TRUE)
    {
      if (i * i > p)
        return TRUE;

      if (p % i == 0)
        return FALSE;

      i += 2;       
    }
}

static void
test_primes (void)
{
  guint p, q;
  gdouble r, min, max;

  max = 1.0;
  min = 10.0;
  q = 1;
  while (1) {
    p = q;
    q = g_spaced_primes_closest (p);
    g_assert (is_prime (q));
    if (p == 1) continue;
    if (q == p) break;
    r = q / (gdouble) p;
    min = MIN (min, r);
    max = MAX (max, r);
  };

  g_assert_cmpfloat (1.3, <, min);
  g_assert_cmpfloat (max, <, 2.0);
}

int
main (int argc, char *argv[])
{
  g_test_init (&argc, &argv, NULL);

  g_test_bug_base ("http://bugzilla.gnome.org/");

  g_test_add_func ("/hash/misc", test_hash_misc);
  g_test_add_data_func ("/hash/one", GINT_TO_POINTER (TRUE), second_hash_test);
  g_test_add_data_func ("/hash/honeyman", GINT_TO_POINTER (FALSE), second_hash_test);
  g_test_add_func ("/hash/direct", direct_hash_test);
  g_test_add_func ("/hash/direct2", direct_hash_test2);
  g_test_add_func ("/hash/int", int_hash_test);
  g_test_add_func ("/hash/int64", int64_hash_test);
  g_test_add_func ("/hash/double", double_hash_test);
  g_test_add_func ("/hash/string", string_hash_test);
  g_test_add_func ("/hash/set", set_hash_test);
  g_test_add_func ("/hash/set-ref", set_ref_hash_test);
  g_test_add_func ("/hash/ref", test_hash_ref);
  g_test_add_func ("/hash/remove-all", test_remove_all);
  g_test_add_func ("/hash/recursive-remove-all", test_recursive_remove_all);
  g_test_add_func ("/hash/recursive-remove-all/subprocess", test_recursive_remove_all_subprocess);
  g_test_add_func ("/hash/find", test_find);
  g_test_add_func ("/hash/foreach", test_foreach);
  g_test_add_func ("/hash/foreach-steal", test_foreach_steal);
  g_test_add_func ("/hash/steal-extended", test_steal_extended);

  /* tests for individual bugs */
  g_test_add_func ("/hash/lookup-null-key", test_lookup_null_key);
  g_test_add_func ("/hash/destroy-modify", test_destroy_modify);
  g_test_add_func ("/hash/consistency", test_internal_consistency);
  g_test_add_func ("/hash/iter-replace", test_iter_replace);
  g_test_add_func ("/hash/set-insert-corruption", test_set_insert_corruption);
  g_test_add_func ("/hash/set-to-strv", test_set_to_strv);
  g_test_add_func ("/hash/primes", test_primes);

  return g_test_run ();

}
