diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-11-25 17:33:56 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-11-25 17:34:10 +0000 |
commit | 83ba6762cc43d9db581b979bb5e3445669e46cc2 (patch) | |
tree | 2e69833b43f791ed253a7a20318b767ebe56cdb8 /src/aclk/mqtt_websockets/c_rhash | |
parent | Releasing debian version 1.47.5-1. (diff) | |
download | netdata-83ba6762cc43d9db581b979bb5e3445669e46cc2.tar.xz netdata-83ba6762cc43d9db581b979bb5e3445669e46cc2.zip |
Merging upstream version 2.0.3+dfsg (Closes: #923993, #1042533, #1045145).
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/aclk/mqtt_websockets/c_rhash')
-rw-r--r-- | src/aclk/mqtt_websockets/c_rhash/c_rhash.c | 264 | ||||
-rw-r--r-- | src/aclk/mqtt_websockets/c_rhash/c_rhash.h | 61 | ||||
-rw-r--r-- | src/aclk/mqtt_websockets/c_rhash/c_rhash_internal.h | 19 | ||||
-rw-r--r-- | src/aclk/mqtt_websockets/c_rhash/tests.c | 273 |
4 files changed, 0 insertions, 617 deletions
diff --git a/src/aclk/mqtt_websockets/c_rhash/c_rhash.c b/src/aclk/mqtt_websockets/c_rhash/c_rhash.c deleted file mode 100644 index a71b500e2..000000000 --- a/src/aclk/mqtt_websockets/c_rhash/c_rhash.c +++ /dev/null @@ -1,264 +0,0 @@ -// Copyright: SPDX-License-Identifier: GPL-3.0-only - -#include "c_rhash_internal.h" - -#include <stdlib.h> -#include <string.h> - -#ifdef DEBUG_VERBOSE -#include <stdio.h> -#endif - -#define c_rmalloc(...) malloc(__VA_ARGS__) -#define c_rcalloc(...) calloc(__VA_ARGS__) -#define c_rfree(...) free(__VA_ARGS__) - -static inline uint32_t simple_hash(const char *name) { - unsigned char *s = (unsigned char *) name; - uint32_t hval = 0x811c9dc5; - while (*s) { - hval *= 16777619; - hval ^= (uint32_t) *s++; - } - return hval; -} - -c_rhash c_rhash_new(size_t bin_count) { - if (!bin_count) - bin_count = 1000; - - c_rhash hash = c_rcalloc(1, sizeof(struct c_rhash_s) + (bin_count * sizeof(struct bin_ll*)) ); - if (hash == NULL) - return NULL; - - hash->bin_count = bin_count; - hash->bins = (c_rhash_bin *)((char*)hash + sizeof(struct c_rhash_s)); - - return hash; -} - -static size_t get_itemtype_len(uint8_t item_type, const void* item_data) { - switch (item_type) { - case ITEMTYPE_STRING: - return strlen(item_data) + 1; - case ITEMTYPE_UINT64: - return sizeof(uint64_t); - case ITEMTYPE_UINT8: - return 1; - case ITEMTYPE_OPAQUE_PTR: - return sizeof(void*); - default: - return 0; - } -} - -static int compare_bin_item(struct bin_item *item, uint8_t key_type, const void *key) { - if (item->key_type != key_type) - return 1; - - size_t key_value_len = get_itemtype_len(key_type, key); - - if(key_type == ITEMTYPE_STRING) { - size_t new_key_value_len = get_itemtype_len(item->key_type, item->key); - if (new_key_value_len != key_value_len) - return 1; - } - - if(memcmp(item->key, key, key_value_len) == 0) { - return 0; - } - - return 1; -} - -static int insert_into_bin(c_rhash_bin *bin, uint8_t key_type, const void *key, uint8_t value_type, const void *value) { - struct bin_item *prev = NULL; - while (*bin != NULL) { - if (!compare_bin_item(*bin, key_type, key)) { -#ifdef DEBUG_VERBOSE - printf("Key already present! Updating value!\n"); -#endif -// TODO: optimize here if the new value is of different kind compared to the old one -// in case it is not crazily bigger we can reuse the memory and avoid malloc and free - c_rfree((*bin)->value); - (*bin)->value_type = value_type; - (*bin)->value = c_rmalloc(get_itemtype_len(value_type, value)); - if ((*bin)->value == NULL) - return 1; - memcpy((*bin)->value, value, get_itemtype_len(value_type, value)); - return 0; - } - prev = *bin; - bin = &(*bin)->next; - } - - if (*bin == NULL) - *bin = c_rcalloc(1, sizeof(struct bin_item)); - if (prev != NULL) - prev->next = *bin; - - (*bin)->key_type = key_type; - size_t len = get_itemtype_len(key_type, key); - (*bin)->key = c_rmalloc(len); - memcpy((*bin)->key, key, len); - - (*bin)->value_type = value_type; - len = get_itemtype_len(value_type, value); - (*bin)->value = c_rmalloc(len); - memcpy((*bin)->value, value, len); - return 0; -} - -static inline uint32_t get_bin_idx_str(c_rhash hash, const char *key) { - uint32_t nhash = simple_hash(key); - return nhash % hash->bin_count; -} - -static inline c_rhash_bin *get_binptr_by_str(c_rhash hash, const char *key) { - return &hash->bins[get_bin_idx_str(hash, key)]; -} - -int c_rhash_insert_str_ptr(c_rhash hash, const char *key, void *value) { - c_rhash_bin *bin = get_binptr_by_str(hash, key); - -#ifdef DEBUG_VERBOSE - if (bin != NULL) - printf("COLLISION. There will be more than one item in bin idx=%d\n", nhash); -#endif - - return insert_into_bin(bin, ITEMTYPE_STRING, key, ITEMTYPE_OPAQUE_PTR, &value); -} - -int c_rhash_insert_str_uint8(c_rhash hash, const char *key, uint8_t value) { - c_rhash_bin *bin = get_binptr_by_str(hash, key); - -#ifdef DEBUG_VERBOSE - if (bin != NULL) - printf("COLLISION. There will be more than one item in bin idx=%d\n", nhash); -#endif - - return insert_into_bin(bin, ITEMTYPE_STRING, key, ITEMTYPE_UINT8, &value); -} - -int c_rhash_insert_uint64_ptr(c_rhash hash, uint64_t key, void *value) { - c_rhash_bin *bin = &hash->bins[key % hash->bin_count]; - -#ifdef DEBUG_VERBOSE - if (bin != NULL) - printf("COLLISION. There will be more than one item in bin idx=%d\n", nhash); -#endif - - return insert_into_bin(bin, ITEMTYPE_UINT64, &key, ITEMTYPE_OPAQUE_PTR, &value); -} - -int c_rhash_get_uint8_by_str(c_rhash hash, const char *key, uint8_t *ret_val) { - uint32_t nhash = get_bin_idx_str(hash, key); - - struct bin_item *bin = hash->bins[nhash]; - - while (bin) { - if (bin->key_type == ITEMTYPE_STRING) { - if (!strcmp(bin->key, key)) { - *ret_val = *(uint8_t*)bin->value; - return 0; - } - } - bin = bin->next; - } - return 1; -} - -int c_rhash_get_ptr_by_str(c_rhash hash, const char *key, void **ret_val) { - uint32_t nhash = get_bin_idx_str(hash, key); - - struct bin_item *bin = hash->bins[nhash]; - - while (bin) { - if (bin->key_type == ITEMTYPE_STRING) { - if (!strcmp(bin->key, key)) { - *ret_val = *((void**)bin->value); - return 0; - } - } - bin = bin->next; - } - *ret_val = NULL; - return 1; -} - -int c_rhash_get_ptr_by_uint64(c_rhash hash, uint64_t key, void **ret_val) { - uint32_t nhash = key % hash->bin_count; - - struct bin_item *bin = hash->bins[nhash]; - - while (bin) { - if (bin->key_type == ITEMTYPE_UINT64) { - if (*((uint64_t *)bin->key) == key) { - *ret_val = *((void**)bin->value); - return 0; - } - } - bin = bin->next; - } - *ret_val = NULL; - return 1; -} - -static void c_rhash_destroy_bin(c_rhash_bin bin) { - struct bin_item *next; - do { - next = bin->next; - c_rfree(bin->key); - c_rfree(bin->value); - c_rfree(bin); - bin = next; - } while (bin != NULL); -} - -int c_rhash_iter_uint64_keys(c_rhash hash, c_rhash_iter_t *iter, uint64_t *key) { - while (iter->bin < hash->bin_count) { - if (iter->item != NULL) - iter->item = iter->item->next; - if (iter->item == NULL) { - if (iter->initialized) - iter->bin++; - else - iter->initialized = 1; - if (iter->bin < hash->bin_count) - iter->item = hash->bins[iter->bin]; - } - if (iter->item != NULL && iter->item->key_type == ITEMTYPE_UINT64) { - *key = *(uint64_t*)iter->item->key; - return 0; - } - } - return 1; -} - -int c_rhash_iter_str_keys(c_rhash hash, c_rhash_iter_t *iter, const char **key) { - while (iter->bin < hash->bin_count) { - if (iter->item != NULL) - iter->item = iter->item->next; - if (iter->item == NULL) { - if (iter->initialized) - iter->bin++; - else - iter->initialized = 1; - if (iter->bin < hash->bin_count) - iter->item = hash->bins[iter->bin]; - } - if (iter->item != NULL && iter->item->key_type == ITEMTYPE_STRING) { - *key = (const char*)iter->item->key; - return 0; - } - } - return 1; -} - -void c_rhash_destroy(c_rhash hash) { - for (size_t i = 0; i < hash->bin_count; i++) { - if (hash->bins[i] != NULL) - c_rhash_destroy_bin(hash->bins[i]); - } - c_rfree(hash); -} diff --git a/src/aclk/mqtt_websockets/c_rhash/c_rhash.h b/src/aclk/mqtt_websockets/c_rhash/c_rhash.h deleted file mode 100644 index 37addd161..000000000 --- a/src/aclk/mqtt_websockets/c_rhash/c_rhash.h +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright: SPDX-License-Identifier: GPL-3.0-only - -#include <sys/types.h> -#include <stdint.h> -#include <stddef.h> - -#ifndef DEFAULT_BIN_COUNT - #define DEFAULT_BIN_COUNT 1000 -#endif - -#define ITEMTYPE_UNSET (0x0) -#define ITEMTYPE_STRING (0x1) -#define ITEMTYPE_UINT8 (0x2) -#define ITEMTYPE_UINT64 (0x3) -#define ITEMTYPE_OPAQUE_PTR (0x4) - -typedef struct c_rhash_s *c_rhash; - -c_rhash c_rhash_new(size_t bin_count); - -void c_rhash_destroy(c_rhash hash); - -// # Insert -// ## Insert where key is string -int c_rhash_insert_str_ptr(c_rhash hash, const char *key, void *value); -int c_rhash_insert_str_uint8(c_rhash hash, const char *key, uint8_t value); -// ## Insert where key is uint64 -int c_rhash_insert_uint64_ptr(c_rhash hash, uint64_t key, void *value); - -// # Get -// ## Get where key is string -int c_rhash_get_ptr_by_str(c_rhash hash, const char *key, void **ret_val); -int c_rhash_get_uint8_by_str(c_rhash hash, const char *key, uint8_t *ret_val); -// ## Get where key is uint64 -int c_rhash_get_ptr_by_uint64(c_rhash hash, uint64_t key, void **ret_val); - -typedef struct { - size_t bin; - struct bin_item *item; - int initialized; -} c_rhash_iter_t; - -#define C_RHASH_ITER_T_INITIALIZER { .bin = 0, .item = NULL, .initialized = 0 } - -#define c_rhash_iter_t_initialize(p_iter) memset(p_iter, 0, sizeof(c_rhash_iter_t)) - -/* - * goes trough whole hash map and returns every - * type uint64 key present/stored - * - * it is not necessary to finish iterating and iterator can be reinitialized - * there are no guarantees on the order in which the keys will come - * behavior here is implementation dependent and can change any time - * - * returns: - * 0 for every key and stores the key in *key - * 1 on error or when all keys of this type has been already iterated over - */ -int c_rhash_iter_uint64_keys(c_rhash hash, c_rhash_iter_t *iter, uint64_t *key); - -int c_rhash_iter_str_keys(c_rhash hash, c_rhash_iter_t *iter, const char **key); diff --git a/src/aclk/mqtt_websockets/c_rhash/c_rhash_internal.h b/src/aclk/mqtt_websockets/c_rhash/c_rhash_internal.h deleted file mode 100644 index 20f741076..000000000 --- a/src/aclk/mqtt_websockets/c_rhash/c_rhash_internal.h +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright: SPDX-License-Identifier: GPL-3.0-only - -#include "c_rhash.h" - -struct bin_item { - uint8_t key_type:4; - void *key; - uint8_t value_type:4; - void *value; - - struct bin_item *next; -}; - -typedef struct bin_item *c_rhash_bin; - -struct c_rhash_s { - size_t bin_count; - c_rhash_bin *bins; -}; diff --git a/src/aclk/mqtt_websockets/c_rhash/tests.c b/src/aclk/mqtt_websockets/c_rhash/tests.c deleted file mode 100644 index 909c5562d..000000000 --- a/src/aclk/mqtt_websockets/c_rhash/tests.c +++ /dev/null @@ -1,273 +0,0 @@ -// Copyright: SPDX-License-Identifier: GPL-3.0-only - -#include <stdio.h> -#include <string.h> - -#include "c_rhash.h" - -// terminal color codes -#define KNRM "\x1B[0m" -#define KRED "\x1B[31m" -#define KGRN "\x1B[32m" -#define KYEL "\x1B[33m" -#define KBLU "\x1B[34m" -#define KMAG "\x1B[35m" -#define KCYN "\x1B[36m" -#define KWHT "\x1B[37m" - -#define KEY_1 "key1" -#define KEY_2 "keya" - -#define PRINT_ERR(str, ...) fprintf(stderr, "└─╼ ❌ " KRED str KNRM "\n" __VA_OPT__(,) __VA_ARGS__) - -#define ASSERT_RETVAL(fnc, comparator, expected_retval, ...) \ -{ int rval; \ -if(!((rval = fnc(__VA_ARGS__)) comparator expected_retval)) { \ - PRINT_ERR("Failed test. Value returned by \"%s\" in fnc:\"%s\",line:%d is not equal to expected value. Expected:%d, Got:%d", #fnc, __FUNCTION__, __LINE__, expected_retval, rval); \ - rc = 1; \ - goto test_cleanup; \ -} passed_subtest_count++;}; - -#define ASSERT_VAL_UINT8(returned, expected) \ -if(returned != expected) { \ - PRINT_ERR("Failed test. Value returned (%d) doesn't match expected (%d)! fnc:\"%s\",line:%d", returned, expected, __FUNCTION__, __LINE__); \ - rc = 1; \ - goto test_cleanup; \ -} passed_subtest_count++; - -#define ASSERT_VAL_PTR(returned, expected) \ -if((void*)returned != (void*)expected) { \ - PRINT_ERR("Failed test. Value returned(%p) doesn't match expected(%p)! fnc:\"%s\",line:%d", (void*)returned, (void*)expected, __FUNCTION__, __LINE__); \ - rc = 1; \ - goto test_cleanup; \ -} passed_subtest_count++; - -#define ALL_SUBTESTS_PASS() printf("└─╼ ✅" KGRN " Test \"%s\" DONE. All of %zu subtests PASS. (line:%d)\n" KNRM, __FUNCTION__, passed_subtest_count, __LINE__); - -#define TEST_START() size_t passed_subtest_count = 0; int rc = 0; printf("╒═ Starting test \"%s\"\n", __FUNCTION__); - -int test_str_uint8() { - c_rhash hash = c_rhash_new(100); - uint8_t val; - - TEST_START(); - // function should fail on empty hash - ASSERT_RETVAL(c_rhash_get_uint8_by_str, !=, 0, hash, KEY_1, &val); - - ASSERT_RETVAL(c_rhash_insert_str_uint8, ==, 0, hash, KEY_1, 5); - ASSERT_RETVAL(c_rhash_get_uint8_by_str, ==, 0, hash, KEY_1, &val); - ASSERT_VAL_UINT8(5, val); - - ASSERT_RETVAL(c_rhash_insert_str_uint8, ==, 0, hash, KEY_2, 8); - ASSERT_RETVAL(c_rhash_get_uint8_by_str, ==, 0, hash, KEY_1, &val); - ASSERT_VAL_UINT8(5, val); - ASSERT_RETVAL(c_rhash_get_uint8_by_str, ==, 0, hash, KEY_2, &val); - ASSERT_VAL_UINT8(8, val); - ASSERT_RETVAL(c_rhash_get_uint8_by_str, !=, 0, hash, "sndnskjdf", &val); - - // test update of key - ASSERT_RETVAL(c_rhash_insert_str_uint8, ==, 0, hash, KEY_1, 100); - ASSERT_RETVAL(c_rhash_get_uint8_by_str, ==, 0, hash, KEY_1, &val); - ASSERT_VAL_UINT8(100, val); - - ALL_SUBTESTS_PASS(); -test_cleanup: - c_rhash_destroy(hash); - return rc; -} - -int test_uint64_ptr() { - c_rhash hash = c_rhash_new(100); - void *val; - - TEST_START(); - - // function should fail on empty hash - ASSERT_RETVAL(c_rhash_get_ptr_by_uint64, !=, 0, hash, 0, &val); - - ASSERT_RETVAL(c_rhash_insert_uint64_ptr, ==, 0, hash, 0, &hash); - ASSERT_RETVAL(c_rhash_get_ptr_by_uint64, ==, 0, hash, 0, &val); - ASSERT_VAL_PTR(&hash, val); - - ASSERT_RETVAL(c_rhash_insert_uint64_ptr, ==, 0, hash, 1, &val); - ASSERT_RETVAL(c_rhash_get_ptr_by_uint64, ==, 0, hash, 0, &val); - ASSERT_VAL_PTR(&hash, val); - ASSERT_RETVAL(c_rhash_get_ptr_by_uint64, ==, 0, hash, 1, &val); - ASSERT_VAL_PTR(&val, val); - ASSERT_RETVAL(c_rhash_get_ptr_by_uint64, !=, 0, hash, 2, &val); - - ALL_SUBTESTS_PASS(); -test_cleanup: - c_rhash_destroy(hash); - return rc; -} - -#define UINT64_PTR_INC_ITERATION_COUNT 5000 -int test_uint64_ptr_incremental() { - c_rhash hash = c_rhash_new(100); - void *val; - - TEST_START(); - - char a = 0x20; - char *ptr = &a; - while(ptr < &a + UINT64_PTR_INC_ITERATION_COUNT) { - ASSERT_RETVAL(c_rhash_insert_uint64_ptr, ==, 0, hash, (ptr-&a), ptr); - ptr++; - } - - ptr = &a; - char *retptr; - for(int i = 0; i < UINT64_PTR_INC_ITERATION_COUNT; i++) { - ASSERT_RETVAL(c_rhash_get_ptr_by_uint64, ==, 0, hash, i, (void**)&retptr); - ASSERT_VAL_PTR(retptr, (&a+i)); - } - - ALL_SUBTESTS_PASS(); -test_cleanup: - c_rhash_destroy(hash); - return rc; -} - -struct test_string { - const char *str; - int counter; -}; - -struct test_string test_strings[] = { - { .str = "Cillum reprehenderit eiusmod elit nisi aliquip esse exercitation commodo Lorem voluptate esse.", .counter = 0 }, - { .str = "Ullamco eiusmod tempor occaecat ad.", .counter = 0 }, - { .str = "Esse aliquip tempor sint tempor ullamco duis aute incididunt ad.", .counter = 0 }, - { .str = "Cillum Lorem labore cupidatat commodo proident adipisicing.", .counter = 0 }, - { .str = "Quis ad cillum officia exercitation.", .counter = 0 }, - { .str = "Ipsum enim dolor ullamco amet sint nisi ut occaecat sint non.", .counter = 0 }, - { .str = "Id duis officia ipsum cupidatat velit fugiat.", .counter = 0 }, - { .str = "Aliqua non occaecat voluptate reprehenderit reprehenderit veniam minim exercitation ea aliquip enim aliqua deserunt qui.", .counter = 0 }, - { .str = "Ullamco elit tempor laboris reprehenderit quis deserunt duis quis tempor reprehenderit magna dolore reprehenderit exercitation.", .counter = 0 }, - { .str = "Culpa do dolor quis incididunt et labore in ex.", .counter = 0 }, - { .str = "Aliquip velit cupidatat qui incididunt ipsum nostrud eiusmod ut proident nisi magna fugiat excepteur.", .counter = 0 }, - { .str = "Aliqua qui dolore tempor id proident ullamco sunt magna.", .counter = 0 }, - { .str = "Labore eiusmod ut fugiat dolore reprehenderit mollit magna.", .counter = 0 }, - { .str = "Veniam aliquip dolor excepteur minim nulla esse cupidatat esse.", .counter = 0 }, - { .str = "Do quis dolor irure nostrud occaecat aute proident anim.", .counter = 0 }, - { .str = "Enim veniam non nulla ad quis sit amet.", .counter = 0 }, - { .str = "Cillum reprehenderit do enim esse do ullamco consectetur ea.", .counter = 0 }, - { .str = "Sit et duis sint anim qui ad anim labore exercitation sunt cupidatat.", .counter = 0 }, - { .str = "Dolor officia adipisicing sint pariatur in dolor occaecat officia reprehenderit magna.", .counter = 0 }, - { .str = "Aliquip dolore qui occaecat eiusmod sunt incididunt reprehenderit minim et.", .counter = 0 }, - { .str = "Aute fugiat laboris cillum tempor consequat tempor do non laboris culpa officia nisi.", .counter = 0 }, - { .str = "Et excepteur do aliquip fugiat nisi velit tempor officia enim quis elit incididunt.", .counter = 0 }, - { .str = "Eu officia adipisicing incididunt occaecat officia cupidatat enim sit sit officia.", .counter = 0 }, - { .str = "Do amet cillum duis pariatur commodo nulla cillum magna nulla Lorem veniam cupidatat.", .counter = 0 }, - { .str = "Dolor adipisicing voluptate laboris occaecat culpa aliquip ipsum ut consequat aliqua aliquip commodo sunt velit.", .counter = 0 }, - { .str = "Nulla proident ipsum quis nulla.", .counter = 0 }, - { .str = "Laborum adipisicing nulla do aute aliqua est quis sint culpa pariatur laborum voluptate qui.", .counter = 0 }, - { .str = "Proident eiusmod sunt et nulla elit pariatur dolore irure ex voluptate excepteur adipisicing consectetur.", .counter = 0 }, - { .str = "Consequat ex voluptate officia excepteur aute deserunt proident commodo et.", .counter = 0 }, - { .str = "Velit sit cupidatat dolor dolore.", .counter = 0 }, - { .str = "Sunt enim do non anim nostrud exercitation ullamco ex proident commodo.", .counter = 0 }, - { .str = "Id ex officia cillum ad.", .counter = 0 }, - { .str = "Laboris in sunt eiusmod veniam laboris nostrud.", .counter = 0 }, - { .str = "Ex magna occaecat ea ea incididunt aliquip.", .counter = 0 }, - { .str = "Sunt eiusmod ex nostrud eu pariatur sit cupidatat ea adipisicing cillum culpa esse consequat aliquip.", .counter = 0 }, - { .str = "Excepteur commodo qui incididunt enim culpa sunt non excepteur Lorem adipisicing.", .counter = 0 }, - { .str = "Quis officia est ullamco reprehenderit incididunt occaecat pariatur ex reprehenderit nisi.", .counter = 0 }, - { .str = "Culpa irure proident proident et eiusmod irure aliqua ipsum cupidatat minim sit.", .counter = 0 }, - { .str = "Qui cupidatat aliquip est velit magna veniam.", .counter = 0 }, - { .str = "Pariatur ad ad mollit nostrud non irure minim veniam anim aliquip quis eu.", .counter = 0 }, - { .str = "Nisi ex minim eu adipisicing tempor Lorem nisi do ad exercitation est non eu.", .counter = 0 }, - { .str = "Cupidatat do mollit ad commodo cupidatat ut.", .counter = 0 }, - { .str = "Est non excepteur eiusmod nostrud et eu.", .counter = 0 }, - { .str = "Cupidatat mollit nisi magna officia ut elit eiusmod.", .counter = 0 }, - { .str = "Est aliqua consectetur laboris ex consequat est ut dolor.", .counter = 0 }, - { .str = "Duis eu laboris laborum ut id Lorem nostrud qui ad velit proident fugiat minim ullamco.", .counter = 0 }, - { .str = "Pariatur esse excepteur anim amet excepteur irure sint quis esse ex cupidatat ut.", .counter = 0 }, - { .str = "Esse reprehenderit amet qui excepteur aliquip amet.", .counter = 0 }, - { .str = "Ullamco laboris elit labore adipisicing aute nulla qui laborum tempor officia ut dolor aute.", .counter = 0 }, - { .str = "Commodo sunt cillum velit minim laborum Lorem aliqua tempor ad id eu.", .counter = 0 }, - { .str = NULL, .counter = 0 } -}; - -uint32_t test_strings_contain_element(const char *str) { - struct test_string *str_desc = test_strings; - while(str_desc->str) { - if (!strcmp(str, str_desc->str)) - return str_desc - test_strings; - str_desc++; - } - return -1; -} - -#define TEST_INCREMENT_STR_KEYS_HASH_SIZE 20 -int test_increment_str_keys() { - c_rhash hash; - const char *key; - - TEST_START(); - - hash = c_rhash_new(TEST_INCREMENT_STR_KEYS_HASH_SIZE); // less than element count of test_strings - - c_rhash_iter_t iter = C_RHASH_ITER_T_INITIALIZER; - - // check iter on empty hash - ASSERT_RETVAL(c_rhash_iter_str_keys, !=, 0, hash, &iter, &key); - - int32_t element_count = 0; - while (test_strings[element_count].str) { - ASSERT_RETVAL(c_rhash_insert_str_ptr, ==, 0, hash, test_strings[element_count].str, NULL); - test_strings[element_count].counter++; // we want to test we got each key exactly once - element_count++; - } - - if (element_count <= TEST_INCREMENT_STR_KEYS_HASH_SIZE * 2) { - // verify we are actually test also iteration trough single bin (when 2 keys have same hash pointing them to same bin) - PRINT_ERR("For this test to properly test all the hash size needs to be much smaller than all test key count."); - rc = 1; - goto test_cleanup; - } - - // we insert another type of key as iterator should skip it - // in case is another type - ASSERT_RETVAL(c_rhash_insert_uint64_ptr, ==, 0, hash, 5, NULL); - - c_rhash_iter_t_initialize(&iter); - while(!c_rhash_iter_str_keys(hash, &iter, &key)) { - element_count--; - int i; - if ( (i = test_strings_contain_element(key)) < 0) { - PRINT_ERR("Key \"%s\" is not present in test_strings array! (Fnc: %s, Line: %d)", key, __FUNCTION__, __LINE__); - rc = 1; - goto test_cleanup; - } - passed_subtest_count++; - - test_strings[i].counter--; - } - ASSERT_VAL_UINT8(element_count, 0); // we added also same non string keys - - // check each key was present exactly once - struct test_string *str_desc = test_strings; - while (str_desc->str) { - ASSERT_VAL_UINT8(str_desc->counter, 0); - str_desc++; - } - - ALL_SUBTESTS_PASS(); -test_cleanup: - c_rhash_destroy(hash); - return rc; -} - -#define RUN_TEST(fnc) \ -if(fnc()) \ - return 1; - -int main(int argc, char *argv[]) { - RUN_TEST(test_str_uint8); - RUN_TEST(test_uint64_ptr); - RUN_TEST(test_uint64_ptr_incremental); - RUN_TEST(test_increment_str_keys); - // TODO hash with mixed key tests - // TODO iterator test - return 0; -} |