X-Git-Url: https://erislabs.net/gitweb/?a=blobdiff_plain;f=tests%2Ftest-hash.c;h=b056d0a650f6afccc091e27c5f1f96102779625b;hb=9cedf3e1ac7dbdddefb7e172156e9000de7d80c2;hp=2266545cba495d07cf857fba1b35c43715378fa1;hpb=ae156c0bf8058d3c1568c1ed573a1319a451ac7e;p=gnulib.git diff --git a/tests/test-hash.c b/tests/test-hash.c index 2266545cb..b056d0a65 100644 --- a/tests/test-hash.c +++ b/tests/test-hash.c @@ -46,6 +46,7 @@ static bool hash_compare_strings (void const *x, void const *y) { + ASSERT (x != y); return STREQ (x, y) ? true : false; } @@ -77,14 +78,45 @@ walk (void *ent, void *data) return false; } +static int +get_seed (char const *str, unsigned int *seed) +{ + size_t len = strlen (str); + if (len == 0 || strspn (str, "0123456789") != len || 10 < len) + return 1; + + *seed = atoi (str); + return 0; +} + int -main (void) +main (int argc, char **argv) { unsigned int i; + unsigned int k; unsigned int table_size[] = {1, 2, 3, 4, 5, 23, 53}; Hash_table *ht; Hash_tuning tuning; + hash_reset_tuning (&tuning); + tuning.shrink_threshold = 0.3; + tuning.shrink_factor = 0.707; + tuning.growth_threshold = 1.5; + tuning.growth_factor = 2.0; + tuning.is_n_buckets = true; + + if (1 < argc) + { + unsigned int seed; + if (get_seed (argv[1], &seed) != 0) + { + fprintf (stderr, "invalid seed: %s\n", argv[1]); + exit (EXIT_FAILURE); + } + + srand (seed); + } + for (i = 0; i < ARRAY_CARDINALITY (table_size); i++) { size_t sz = table_size[i]; @@ -134,72 +166,20 @@ main (void) hash_clear (ht); ASSERT (hash_get_n_entries (ht) == 0); hash_free (ht); - } - - /* Now, each entry is malloc'd. */ - ht = hash_initialize (4651, NULL, hash_pjw, hash_compare_strings, hash_freer); - ASSERT (ht); - 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)); + /* Test pointer hashing. */ + ht = hash_initialize (sz, NULL, NULL, NULL, NULL); + ASSERT (ht); + { + char *str = xstrdup ("a"); + insert_new (ht, "a"); + insert_new (ht, str); + ASSERT (hash_lookup (ht, str) == str); + free (str); + } + hash_free (ht); } - hash_free (ht); - hash_reset_tuning (&tuning); tuning.shrink_threshold = 0.3; tuning.shrink_factor = 0.707; @@ -213,69 +193,77 @@ main (void) /* Alternate tuning. */ tuning.growth_threshold = 0.89; - ht = hash_initialize (4651, &tuning, hash_pjw, hash_compare_strings, - hash_freer); - ASSERT (ht); - for (i = 0; i < 10000; i++) + + /* Run with default tuning, then with custom tuning settings. */ + for (k = 0; k < 2; k++) { - unsigned int op = rand () % 10; - switch (op) + Hash_tuning const *tune = (k == 0 ? NULL : &tuning); + /* Now, each entry is malloc'd. */ + ht = hash_initialize (4651, tune, hash_pjw, + hash_compare_strings, hash_freer); + ASSERT (ht); + for (i = 0; i < 10000; i++) { - 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; + 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 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 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) + case 8: + case 9: { - size_t k = rand () % n; - void const *p; - void *v; - for (p = hash_get_first (ht); k; --k, p = hash_get_next (ht, p)) + /* Delete a random entry. */ + size_t n = hash_get_n_entries (ht); + if (n) { - /* empty */ + 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); } - ASSERT (p); - v = hash_delete (ht, p); - ASSERT (v); - free (v); + break; } - break; - } + } + ASSERT (hash_table_ok (ht)); } - ASSERT (hash_table_ok (ht)); - } - hash_free (ht); + hash_free (ht); + } return 0; }