Slight improvement. This adds a key assertion at the end of the loop. >From 59ebc6425b73267ab588cfc1856891736fe3e062 Mon Sep 17 00:00:00 2001 From: Jim Meyering <meyer...@redhat.com> Date: Mon, 8 Jun 2009 16:11:44 +0200 Subject: [PATCH] hash-tests: new module.
* modules/hash-tests: New file. * tests/test-hash.c: New file. --- modules/hash-tests | 14 +++++ tests/test-hash.c | 161 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 175 insertions(+), 0 deletions(-) create mode 100644 modules/hash-tests create mode 100644 tests/test-hash.c diff --git a/modules/hash-tests b/modules/hash-tests new file mode 100644 index 0000000..fab9c88 --- /dev/null +++ b/modules/hash-tests @@ -0,0 +1,14 @@ +Files: +tests/test-hash.c + +Depends-on: +hash-pjw +inttostr +stdbool +xalloc + +configure.ac: + +Makefile.am: +TESTS += test-hash +check_PROGRAMS += test-hash diff --git a/tests/test-hash.c b/tests/test-hash.c new file mode 100644 index 0000000..a09d6d1 --- /dev/null +++ b/tests/test-hash.c @@ -0,0 +1,161 @@ +/* + * Copyright (C) 2009 Free Software Foundation + * Written by Jim Meyering + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include <config.h> + +#include "hash.h" +#include "hash-pjw.h" +#include "inttostr.h" +#include "xalloc.h" + +#include <stdio.h> +#include <stdlib.h> +#include <stdbool.h> +#include <string.h> +#include <unistd.h> + +#define STREQ(a, b) (strcmp (a, b) == 0) + +#define ASSERT(expr) \ + do \ + { \ + if (!(expr)) \ + { \ + fprintf (stderr, "%s:%d: assertion failed\n", __FILE__, __LINE__); \ + fflush (stderr); \ + abort (); \ + } \ + } \ + while (0) + +static bool +hash_compare_strings (void const *x, void const *y) +{ + return STREQ (x, y) ? true : false; +} + +static void +hash_freer (void *x) +{ + free (x); +} + +static void +insert_new (Hash_table *ht, void *ent) +{ + void *e = hash_insert (ht, ent); + ASSERT (e == ent); +} + +int +main (void) +{ + unsigned int i; + Hash_table *ht = hash_initialize (53, NULL, hash_pjw, + hash_compare_strings, NULL); + ASSERT (ht); + insert_new (ht, "a"); + insert_new (ht, "b"); + insert_new (ht, "c"); + ASSERT (hash_delete (ht, "a")); + ASSERT (hash_delete (ht, "a") == NULL); + ASSERT (hash_delete (ht, "b")); + ASSERT (hash_delete (ht, "c")); + + ASSERT (hash_rehash (ht, 47)); + ASSERT (hash_rehash (ht, 467)); + + /* Free an empty table. */ + hash_free (ht); + + ht = hash_initialize (53, NULL, hash_pjw, hash_compare_strings, NULL); + ASSERT (ht); + + insert_new (ht, "z"); + insert_new (ht, "y"); + insert_new (ht, "x"); + insert_new (ht, "w"); + insert_new (ht, "v"); + insert_new (ht, "u"); + + hash_free (ht); + + /* Now, each entry is malloc'd. */ + ht = hash_initialize (4651, NULL, hash_pjw, hash_compare_strings, hash_freer); + for (i = 0; i < 10000; i++) + { + unsigned int op = rand () % 10; + switch (op) + { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + { + char buf[50]; + char const *p = uinttostr (i, buf); + insert_new (ht, xstrdup (p)); + } + break; + + case 6: + { + size_t n = hash_get_n_entries (ht); + ASSERT (hash_rehash (ht, n + rand () % 20)); + } + break; + + case 7: + { + size_t n = hash_get_n_entries (ht); + size_t delta = rand () % 20; + if (delta < n) + ASSERT (hash_rehash (ht, n - delta)); + } + break; + + case 8: + case 9: + { + /* Delete a random entry. */ + size_t n = hash_get_n_entries (ht); + if (n) + { + size_t k = rand () % n; + void const *p; + void *v; + for (p = hash_get_first (ht); k; --k, p = hash_get_next (ht, p)) + { + /* empty */ + } + ASSERT (p); + v = hash_delete (ht, p); + ASSERT (v); + free (v); + } + break; + } + } + ASSERT (hash_table_ok (ht)); + } + + hash_free (ht); + + return 0; +} -- 1.6.3.2.406.gd6a466