/** * This is the default initialize function for datatype int16_t. It takes * HI_HASH_DEFAULT as the default hash function, set the compare function for * int16_t and select as the collision engine the list (COLL_ENG_LIST) based * one. * * @arg hi_hndl this become out new hashish handle * @arg table_size dedicates the table size * @returns negativ error value or zero on success */ int hi_init_int16_t(hi_handle_t **hi_hndl, const uint32_t table_size) { struct hi_init_set hi_set; hi_set_zero(&hi_set); hi_set_bucket_size(&hi_set, table_size); hi_set_hash_alg(&hi_set, HI_HASH_DEFAULT); hi_set_coll_eng(&hi_set, COLL_ENG_LIST); hi_set_key_cmp_func(&hi_set, hi_cmp_int16_t); return hi_create(hi_hndl, &hi_set); }
static void check_hi_init_set(enum hash_alg hash_alg) { int ret; struct hi_init_set hi_set; fputs(" o struct set initialize tests ...", stdout); hi_set_zero(&hi_set); /* test if a hash table size of 100 * return the right values */ ret = hi_set_bucket_size(&hi_set, 100); assert(ret == 0); /* trigger a failure - hash table size of * 0 is invalid */ ret = hi_set_bucket_size(&hi_set, 0); assert(ret == HI_ERR_RANGE); /* test for standard hashing algorithm - must pass */ ret = hi_set_hash_alg(&hi_set, hash_alg); assert(ret == 0); ret = hi_set_hash_func(&hi_set, dumb_hash_func); assert(ret == 0); /* hash algorithm not supported test - must fail */ ret = hi_set_hash_alg(&hi_set, (unsigned int) -1); assert(ret == HI_ERR_NOFUNC); /* test for standard collision engine - must pass */ ret = hi_set_coll_eng(&hi_set, COLL_ENG_LIST); assert(ret == 0); /* collision engine not supported test - must fail */ ret = hi_set_coll_eng(&hi_set, (unsigned int) -1); assert(ret == HI_ERR_NOFUNC); /* test compare functions - must pass */ ret = hi_set_key_cmp_func(&hi_set, hi_cmp_str); assert(ret == 0); /* test compare functions - must fail */ ret = hi_set_key_cmp_func(&hi_set, NULL); assert(ret == HI_ERR_NODATA); puts(" passed"); }
static int test_hashtable(enum coll_eng collision_engine) { int ret = 0, i; pthread_t thread_id[MAXTHREAD]; struct hi_init_set hi_set; fputs("# concurrent test\n", stderr); /* create one hash */ hi_set_zero(&hi_set); hi_set_bucket_size(&hi_set, 100); hi_set_hash_alg(&hi_set, HI_HASH_ELF); hi_set_coll_eng(&hi_set, collision_engine); hi_set_key_cmp_func(&hi_set, hi_cmp_str); ret = hi_create(&hi_hndl, &hi_set); if (ret != 0) { fprintf(stderr, "Error %s\n", ret == HI_ERR_SYSTEM ? strerror(errno) : hi_strerror(ret)); return ret; } for (i = 0; i < MAXTHREAD; i++) { int *num = malloc(sizeof(int *)); if (!num) { perror("malloc"); exit(1); } *num = i; ret = pthread_create(&thread_id[i], NULL, thread_main, num); if (ret) { fprintf(stderr, "pthread_create failed: %s\n", strerror(ret)); free(num); return ret; } } fputs("# + -> thread startup; - -> thread shutdown\n", stderr); for(i = 0; i < MAXTHREAD; i++) { pthread_join(thread_id[i], NULL); } hi_fini(hi_hndl); fprintf(stderr, " passed\n"); return ret; }
static void check_iterator(enum coll_eng engine, enum hash_alg hash_alg) { int ret, i; hi_handle_t *hi_hndl; struct hi_init_set hi_set; hi_iterator_t *iterator; void *data_ptr = (void *) 0xdeadbeef; void *key; uint32_t keylen; hi_set_zero(&hi_set); ret = hi_set_bucket_size(&hi_set, 100); assert(ret == 0); ret = hi_set_hash_alg(&hi_set, hash_alg); assert(ret == 0); ret = hi_set_coll_eng(&hi_set, engine); assert(ret == 0); ret = hi_set_key_cmp_func(&hi_set, hi_cmp_str); assert(ret == 0); /* we need aditional arguments for ARRAY based engines */ switch (engine) { case COLL_ENG_ARRAY: case COLL_ENG_ARRAY_HASH: case COLL_ENG_ARRAY_DYN: case COLL_ENG_ARRAY_DYN_HASH: ret = hi_set_coll_eng_array_size(&hi_set, 20); assert(ret == 0); break; default: break; }; ret = hi_create(&hi_hndl, &hi_set); if (ret != 0) print_error(ret); assert(ret == 0); ret = hi_insert(hi_hndl, (void *) "key", sizeof("key"), "data"); assert(ret == 0); ret = hi_insert(hi_hndl, (void *) "key1", sizeof("key1"), "data1"); assert(ret == 0); ret = hi_insert(hi_hndl, (void *) "key2", sizeof("key2"), "data2"); assert(ret == 0); ret = hi_iterator_create(hi_hndl, &iterator); if (ret != 0) return; for (i = 0; i < 2; i++) { bool got_key[] = { 0, 0, 0 }; unsigned int j; for (j = 0 ; j < 3 ; j++) { data_ptr = NULL; ret = hi_iterator_getnext(iterator, &data_ptr, &key, &keylen); assert(ret == 0); assert(data_ptr); if (strcmp(data_ptr, "data") == 0) { assert(!got_key[0]); got_key[0] = true; continue; } if (strcmp(data_ptr, "data1") == 0) { assert(!got_key[1]); got_key[1] = true; continue; } assert (strcmp(data_ptr, "data2") == 0); assert(!got_key[2]); got_key[2] = true; } ret = hi_iterator_getnext(iterator, &data_ptr, &key, &keylen); assert (ret == HI_ERR_NODATA); ret = hi_iterator_reset(iterator); assert(ret == 0); } hi_iterator_fini(iterator); ret = hi_remove(hi_hndl, (void *) "key", sizeof("key"), &data_ptr); assert(ret == 0); ret = hi_remove(hi_hndl, (void *) "key1", sizeof("key1"), &data_ptr); assert(ret == 0); ret = hi_remove(hi_hndl, (void *) "key2", sizeof("key2"), &data_ptr); assert(ret == 0); ret = hi_fini(hi_hndl); assert(ret == 0); fputs("passed\n", stdout); }
static void check_insert(enum coll_eng engine, enum hash_alg hash_alg) { int ret; hi_handle_t *hi_hndl; struct hi_init_set hi_set; void *data_ptr = (void *) 0xdeadbeef; hi_set_zero(&hi_set); ret = hi_set_bucket_size(&hi_set, 100); assert(ret == 0); ret = hi_set_hash_alg(&hi_set, hash_alg); assert(ret == 0); ret = hi_set_coll_eng(&hi_set, engine); assert(ret == 0); ret = hi_set_key_cmp_func(&hi_set, hi_cmp_str); assert(ret == 0); /* we need aditional arguments for ARRAY based engines */ switch (engine) { case COLL_ENG_ARRAY: case COLL_ENG_ARRAY_HASH: case COLL_ENG_ARRAY_DYN: case COLL_ENG_ARRAY_DYN_HASH: ret = hi_set_coll_eng_array_size(&hi_set, 20); assert(ret == 0); break; default: break; }; ret = hi_create(&hi_hndl, &hi_set); if (ret != 0) print_error(ret); assert(ret == 0); ret = hi_insert(hi_hndl, (void *) "key", sizeof("key"), "XX"); assert(ret == 0); /* same key -> must fail */ ret = hi_insert(hi_hndl, (void *) "key", sizeof("key"), "XX"); assert(ret == HI_ERR_DUPKEY); /* key already in data structure -> must return 0 (SUCCESS) */ ret = hi_get(hi_hndl, (void *) "key", sizeof("key"), &data_ptr); assert(ret == 0); //assert(data_ptr == NULL); ret = hi_remove(hi_hndl, (void *) "key", sizeof("key"), &data_ptr); assert(ret == 0); ret = hi_get(hi_hndl, (void *) "key", sizeof("key"), &data_ptr); assert(ret == HI_ERR_NOKEY); ret = hi_fini(hi_hndl); assert(ret == 0); fputs("passed\n", stdout); }
static void check_get_remove(enum coll_eng engine, enum hash_alg hash_alg) { int ret; hi_handle_t *hi_hndl; struct hi_init_set hi_set; void *data_ret; hi_set_zero(&hi_set); ret = hi_set_bucket_size(&hi_set, 100); assert(ret == 0); ret = hi_set_hash_alg(&hi_set, hash_alg); assert(ret == 0); ret = hi_set_coll_eng(&hi_set, engine); assert(ret == 0); ret = hi_set_key_cmp_func(&hi_set, hi_cmp_str); assert(ret == 0); /* we need aditional arguments for ARRAY based engines */ switch (engine) { case COLL_ENG_ARRAY: case COLL_ENG_ARRAY_HASH: case COLL_ENG_ARRAY_DYN: case COLL_ENG_ARRAY_DYN_HASH: ret = hi_set_coll_eng_array_size(&hi_set, 20); assert(ret == 0); break; default: break; }; ret = hi_create(&hi_hndl, &hi_set); if (ret != 0) print_error(ret); assert(ret == 0); assert(hi_hndl->no_objects == 0); ret = hi_insert(hi_hndl, (void *) "key", sizeof("key"), "DATA"); assert(ret == 0); assert(hi_hndl->no_objects == 1); ret = hi_insert(hi_hndl, (void *) "key2", sizeof("key2"), "DATAX"); assert(ret == 0); assert(hi_hndl->no_objects == 2); ret = hi_insert(hi_hndl, (void *) "key3", sizeof("key3"), "DATAX"); assert(ret == 0); assert(hi_hndl->no_objects == 3); /* key already in data structure -> must return 0 (SUCCESS) */ ret = hi_get(hi_hndl, (void *) "key", sizeof("key"), &data_ret); if (ret != 0) print_error(ret); check_data(data_ret, "DATA"); assert(hi_hndl->no_objects == 3); ret = hi_get(hi_hndl, (void *) "key3", sizeof("key3"), &data_ret); if (ret != 0) print_error(ret); check_data(data_ret, "DATAX"); assert(hi_hndl->no_objects == 3); data_ret = NULL; ret = hi_remove(hi_hndl, (void *) "key", sizeof("key"), &data_ret); assert(ret == 0); assert(hi_hndl->no_objects == 2); check_data(data_ret, "DATA"); data_ret = NULL; ret = hi_remove(hi_hndl, (void *) "key2", sizeof("key2"), &data_ret); assert(ret == 0); assert(hi_hndl->no_objects == 1); ret = hi_remove(hi_hndl, (void *) "key3", sizeof("key3"), &data_ret); assert(ret == 0); assert(hi_hndl->no_objects == 0); check_data(data_ret, "DATAX"); ret = hi_fini(hi_hndl); assert(ret == 0); fputs("passed\n", stdout); }