int hi_remove_int16_t(hi_handle_t *hi_hndl, const int16_t key, void **data) { return hi_remove(hi_hndl, (void *)&key, sizeof(int16_t), data); }
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); }
/* concurrent_test do the following: * o It creates and removes randomly entries * whithin the hash table. At the end the count * must be equal to the expected */ static void concurrent_test(int num) { int i, ret; void *data; char *ptr_bucket[TEST_ITER_NO][2]; struct drand48_data seed_data; unsigned long seed; long int rand_res; seed = get_proper_seed(); /* init per thread seed */ srand48_r(seed, &seed_data); /* sleep for some amount of time */ lrand48_r(&seed_data, &rand_res); msleep(rand_res % 40000); /* max 4s */ fprintf(stderr, "+%d", num); for (i =0; i < TEST_ITER_NO; i++) { int sucess; char *key_ptr, *data_ptr; /* insert at least TEST_ITER_NO data * sets */ do { sucess = 1; random_string(KEYLEN, &key_ptr, &seed_data); random_string(DATALEN, &data_ptr, &seed_data); ptr_bucket[i][KEY] = key_ptr; ptr_bucket[i][DATA] = data_ptr; ret = hi_insert(hi_hndl, (void *) key_ptr, strlen(key_ptr), (void *) data_ptr); if (ret < 0) { fprintf(stderr, "# Key (%s) already in hash\n", key_ptr); fprintf(stderr, "Error %s\n", ret == HI_ERR_SYSTEM ? strerror(errno) : hi_strerror(ret)); sucess = 0; free(key_ptr); free(data_ptr); } } while (!sucess); } lrand48_r(&seed_data, &rand_res); msleep(rand_res % 4000); /* max 4s */ /* verify storage and cleanup */ for (i = 0; i < TEST_ITER_NO; i++) { ret = hi_remove(hi_hndl, ptr_bucket[i][KEY], strlen(ptr_bucket[i][KEY]), &data); if (ret == 0) { if (data != ptr_bucket[i][DATA]) { fprintf(stderr, "Failed: should %s - is %s\n", ptr_bucket[i][DATA], (char *) data); } free(ptr_bucket[i][KEY]); free(ptr_bucket[i][DATA]); } else { fprintf(stderr, "# already deleted\n"); } } fprintf(stderr, "-%d", num); }
int hi_remove_str(hi_handle_t *hi_hndl, const char *key, void **data) { return hi_remove(hi_hndl, (void *)key, strlen(key) + 1, data); }