summaryrefslogtreecommitdiffstats
path: root/test/hash_test.c
diff options
context:
space:
mode:
Diffstat (limited to 'test/hash_test.c')
-rw-r--r--test/hash_test.c308
1 files changed, 153 insertions, 155 deletions
diff --git a/test/hash_test.c b/test/hash_test.c
index bfddc49..b55820c 100644
--- a/test/hash_test.c
+++ b/test/hash_test.c
@@ -29,34 +29,34 @@
static bool expect_failure = false;
static const char* strings[] = {
- "one", "two", "three", "four", "five", "six", "seven", "eight",
- "2one", "2two", "2three", "2four", "2five", "2six", "2seven", "2eight",
- "3one", "3two", "3three", "3four", "3five", "3six", "3seven", "3eight",
- "4one", "4two", "4three", "4four", "4five", "4six", "4seven", "4eight",
- "5one", "5two", "5three", "5four", "5five", "5six", "5seven", "5eight",
- "6one", "6two", "6three", "6four", "6five", "6six", "6seven", "6eight",
- "7one", "7two", "7three", "7four", "7five", "7six", "7seven", "7eight",
- "8one", "8two", "8three", "8four", "8five", "8six", "8seven", "8eight",
- "9one", "9two", "9three", "9four", "9five", "9six", "9seven", "9eight",
- "Aone", "Atwo", "Athree", "Afour", "Afive", "Asix", "Aseven", "Aeight",
- "Bone", "Btwo", "Bthree", "Bfour", "Bfive", "Bsix", "Bseven", "Beight",
- "Cone", "Ctwo", "Cthree", "Cfour", "Cfive", "Csix", "Cseven", "Ceight",
- "Done", "Dtwo", "Dthree", "Dfour", "Dfive", "Dsix", "Dseven", "Deight",
+ "one", "two", "three", "four", "five", "six", "seven", "eight",
+ "2one", "2two", "2three", "2four", "2five", "2six", "2seven", "2eight",
+ "3one", "3two", "3three", "3four", "3five", "3six", "3seven", "3eight",
+ "4one", "4two", "4three", "4four", "4five", "4six", "4seven", "4eight",
+ "5one", "5two", "5three", "5four", "5five", "5six", "5seven", "5eight",
+ "6one", "6two", "6three", "6four", "6five", "6six", "6seven", "6eight",
+ "7one", "7two", "7three", "7four", "7five", "7six", "7seven", "7eight",
+ "8one", "8two", "8three", "8four", "8five", "8six", "8seven", "8eight",
+ "9one", "9two", "9three", "9four", "9five", "9six", "9seven", "9eight",
+ "Aone", "Atwo", "Athree", "Afour", "Afive", "Asix", "Aseven", "Aeight",
+ "Bone", "Btwo", "Bthree", "Bfour", "Bfive", "Bsix", "Bseven", "Beight",
+ "Cone", "Ctwo", "Cthree", "Cfour", "Cfive", "Csix", "Cseven", "Ceight",
+ "Done", "Dtwo", "Dthree", "Dfour", "Dfive", "Dsix", "Dseven", "Deight",
};
ZIX_LOG_FUNC(1, 2)
static int
test_fail(const char* fmt, ...)
{
- if (expect_failure) {
- return 0;
- }
- va_list args;
- va_start(args, fmt);
- fprintf(stderr, "error: ");
- vfprintf(stderr, fmt, args);
- va_end(args);
- return 1;
+ if (expect_failure) {
+ return 0;
+ }
+ va_list args;
+ va_start(args, fmt);
+ fprintf(stderr, "error: ");
+ vfprintf(stderr, fmt, args);
+ va_end(args);
+ return 1;
}
static unsigned n_checked = 0;
@@ -64,163 +64,161 @@ static unsigned n_checked = 0;
static void
check(void* value, void* ZIX_UNUSED(user_data))
{
- if (strlen(*(const char*const*)value) >= 3) {
- ++n_checked;
- } else {
- fprintf(stderr, "ERROR: %s\n", (const char*)value);
- }
+ if (strlen(*(const char* const*)value) >= 3) {
+ ++n_checked;
+ } else {
+ fprintf(stderr, "ERROR: %s\n", (const char*)value);
+ }
}
static uint32_t
string_ptr_hash(const void* value)
{
- const char* const str = *(const char* const*)value;
+ const char* const str = *(const char* const*)value;
- return zix_digest_add(zix_digest_start(), str, strlen(str));
+ return zix_digest_add(zix_digest_start(), str, strlen(str));
}
static bool
string_ptr_equal(const void* a, const void* b)
{
- return !strcmp(*(const char*const*)a, *(const char*const*)b);
+ return !strcmp(*(const char* const*)a, *(const char* const*)b);
}
static int
stress(void)
{
- ZixHash* hash = zix_hash_new(
- string_ptr_hash, string_ptr_equal, sizeof(const char*));
- if (!hash) {
- return test_fail("Failed to allocate hash\n");
- }
-
- const size_t n_strings = sizeof(strings) / sizeof(const char*);
-
- // Insert each string
- for (size_t i = 0; i < n_strings; ++i) {
- void* inserted = NULL;
- ZixStatus st = zix_hash_insert(hash, &strings[i], &inserted);
- if (st) {
- return test_fail("Failed to insert `%s'\n", strings[i]);
- }
-
- if (*(const void*const*)inserted != strings[i]) {
- return test_fail("Corrupt insertion %s != %s\n",
- strings[i], *(const char*const*)inserted);
- }
- }
-
- // Ensure hash size is correct
- if (zix_hash_size(hash) != n_strings) {
- return test_fail("Hash size %zu != %zu\n",
- zix_hash_size(hash), n_strings);
- }
-
- //zix_hash_print_dot(hash, stdout);
-
- // Attempt to insert each string again
- for (size_t i = 0; i < n_strings; ++i) {
- void* inserted = NULL;
- ZixStatus st = zix_hash_insert(hash, &strings[i], &inserted);
- if (st != ZIX_STATUS_EXISTS) {
- return test_fail("Double inserted `%s'\n", strings[i]);
- }
- }
-
- // Search for each string
- for (size_t i = 0; i < n_strings; ++i) {
- const char*const* match = (const char*const*)zix_hash_find(
- hash, &strings[i]);
- if (!match) {
- return test_fail("Failed to find `%s'\n", strings[i]);
- }
- if (*match != strings[i]) {
- return test_fail("Bad match for `%s': `%s'\n", strings[i], *match);
- }
- }
-
- // Try some false matches
- const char* not_indexed[] = {
- "ftp://example.org/not-there-at-all",
- "http://example.org/foobar",
- "http://",
- "http://otherdomain.com"
- };
- const size_t n_not_indexed = sizeof(not_indexed) / sizeof(char*);
- for (size_t i = 0; i < n_not_indexed; ++i) {
- const char*const* match = (const char*const*)zix_hash_find(
- hash, &not_indexed[i]);
- if (match) {
- return test_fail("Unexpectedly found `%s'\n", not_indexed[i]);
- }
- }
-
- // Remove strings
- for (size_t i = 0; i < n_strings; ++i) {
- // Remove string
- ZixStatus st = zix_hash_remove(hash, &strings[i]);
- if (st) {
- return test_fail("Failed to remove `%s'\n", strings[i]);
- }
-
- // Ensure second removal fails
- st = zix_hash_remove(hash, &strings[i]);
- if (st != ZIX_STATUS_NOT_FOUND) {
- return test_fail("Unexpectedly removed `%s' twice\n", strings[i]);
- }
-
- // Check to ensure remaining strings are still present
- for (size_t j = i + 1; j < n_strings; ++j) {
- const char*const* match = (const char*const*)zix_hash_find(
- hash, &strings[j]);
- if (!match) {
- return test_fail("Failed to find `%s' after remove\n", strings[j]);
- }
- if (*match != strings[j]) {
- return test_fail("Bad match for `%s' after remove\n", strings[j]);
- }
- }
- }
-
- // Insert each string again (to check non-empty destruction)
- for (size_t i = 0; i < n_strings; ++i) {
- ZixStatus st = zix_hash_insert(hash, &strings[i], NULL);
- if (st) {
- return test_fail("Failed to insert `%s'\n", strings[i]);
- }
- }
-
- // Check key == value (and test zix_hash_foreach)
- zix_hash_foreach(hash, check, NULL);
- if (n_checked != n_strings) {
- return test_fail("Check failed\n");
- }
-
- zix_hash_free(hash);
-
- return 0;
+ ZixHash* hash =
+ zix_hash_new(string_ptr_hash, string_ptr_equal, sizeof(const char*));
+ if (!hash) {
+ return test_fail("Failed to allocate hash\n");
+ }
+
+ const size_t n_strings = sizeof(strings) / sizeof(const char*);
+
+ // Insert each string
+ for (size_t i = 0; i < n_strings; ++i) {
+ void* inserted = NULL;
+ ZixStatus st = zix_hash_insert(hash, &strings[i], &inserted);
+ if (st) {
+ return test_fail("Failed to insert `%s'\n", strings[i]);
+ }
+
+ if (*(const void* const*)inserted != strings[i]) {
+ return test_fail("Corrupt insertion %s != %s\n",
+ strings[i],
+ *(const char* const*)inserted);
+ }
+ }
+
+ // Ensure hash size is correct
+ if (zix_hash_size(hash) != n_strings) {
+ return test_fail("Hash size %zu != %zu\n", zix_hash_size(hash), n_strings);
+ }
+
+ // zix_hash_print_dot(hash, stdout);
+
+ // Attempt to insert each string again
+ for (size_t i = 0; i < n_strings; ++i) {
+ void* inserted = NULL;
+ ZixStatus st = zix_hash_insert(hash, &strings[i], &inserted);
+ if (st != ZIX_STATUS_EXISTS) {
+ return test_fail("Double inserted `%s'\n", strings[i]);
+ }
+ }
+
+ // Search for each string
+ for (size_t i = 0; i < n_strings; ++i) {
+ const char* const* match =
+ (const char* const*)zix_hash_find(hash, &strings[i]);
+ if (!match) {
+ return test_fail("Failed to find `%s'\n", strings[i]);
+ }
+ if (*match != strings[i]) {
+ return test_fail("Bad match for `%s': `%s'\n", strings[i], *match);
+ }
+ }
+
+ // Try some false matches
+ const char* not_indexed[] = {"ftp://example.org/not-there-at-all",
+ "http://example.org/foobar",
+ "http://",
+ "http://otherdomain.com"};
+ const size_t n_not_indexed = sizeof(not_indexed) / sizeof(char*);
+ for (size_t i = 0; i < n_not_indexed; ++i) {
+ const char* const* match =
+ (const char* const*)zix_hash_find(hash, &not_indexed[i]);
+ if (match) {
+ return test_fail("Unexpectedly found `%s'\n", not_indexed[i]);
+ }
+ }
+
+ // Remove strings
+ for (size_t i = 0; i < n_strings; ++i) {
+ // Remove string
+ ZixStatus st = zix_hash_remove(hash, &strings[i]);
+ if (st) {
+ return test_fail("Failed to remove `%s'\n", strings[i]);
+ }
+
+ // Ensure second removal fails
+ st = zix_hash_remove(hash, &strings[i]);
+ if (st != ZIX_STATUS_NOT_FOUND) {
+ return test_fail("Unexpectedly removed `%s' twice\n", strings[i]);
+ }
+
+ // Check to ensure remaining strings are still present
+ for (size_t j = i + 1; j < n_strings; ++j) {
+ const char* const* match =
+ (const char* const*)zix_hash_find(hash, &strings[j]);
+ if (!match) {
+ return test_fail("Failed to find `%s' after remove\n", strings[j]);
+ }
+ if (*match != strings[j]) {
+ return test_fail("Bad match for `%s' after remove\n", strings[j]);
+ }
+ }
+ }
+
+ // Insert each string again (to check non-empty destruction)
+ for (size_t i = 0; i < n_strings; ++i) {
+ ZixStatus st = zix_hash_insert(hash, &strings[i], NULL);
+ if (st) {
+ return test_fail("Failed to insert `%s'\n", strings[i]);
+ }
+ }
+
+ // Check key == value (and test zix_hash_foreach)
+ zix_hash_foreach(hash, check, NULL);
+ if (n_checked != n_strings) {
+ return test_fail("Check failed\n");
+ }
+
+ zix_hash_free(hash);
+
+ return 0;
}
int
main(void)
{
- zix_hash_free(NULL);
+ zix_hash_free(NULL);
- if (stress()) {
- return 1;
- }
+ if (stress()) {
+ return 1;
+ }
#ifdef ZIX_WITH_TEST_MALLOC
- const size_t total_n_allocs = test_malloc_get_n_allocs();
- printf("Testing 0 ... %zu failed allocations\n", total_n_allocs);
- expect_failure = true;
- for (size_t i = 0; i < total_n_allocs; ++i) {
- test_malloc_reset(i);
- stress();
- }
-
- test_malloc_reset((size_t)-1);
+ const size_t total_n_allocs = test_malloc_get_n_allocs();
+ printf("Testing 0 ... %zu failed allocations\n", total_n_allocs);
+ expect_failure = true;
+ for (size_t i = 0; i < total_n_allocs; ++i) {
+ test_malloc_reset(i);
+ stress();
+ }
+
+ test_malloc_reset((size_t)-1);
#endif
- return 0;
+ return 0;
}