Skip to content

Commit

Permalink
implement c_rhash_iter_str_keys + tests
Browse files Browse the repository at this point in the history
  • Loading branch information
underhood committed Dec 15, 2022
1 parent 98bc3c8 commit f6c2183
Show file tree
Hide file tree
Showing 3 changed files with 162 additions and 3 deletions.
5 changes: 5 additions & 0 deletions include/c_rhash.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include <sys/types.h>
#include <stdint.h>
#include <stddef.h>

#ifndef DEFAULT_BIN_COUNT
#define DEFAULT_BIN_COUNT 1000
Expand Down Expand Up @@ -39,6 +40,8 @@ typedef struct {

#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
Expand All @@ -52,3 +55,5 @@ typedef struct {
* 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);
20 changes: 20 additions & 0 deletions src/c_rhash.c
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,26 @@ int c_rhash_iter_uint64_keys(c_rhash hash, c_rhash_iter_t *iter, uint64_t *key)
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)
Expand Down
140 changes: 137 additions & 3 deletions src/tests.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include <stdio.h>
#include <string.h>

#include "c_rhash.h"

Expand All @@ -21,18 +22,21 @@
{ 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++;
} passed_subtest_count++;};

#define ASSERT_VAL_UINT8(returned, expected) \
if(returned != expected) { \
PRINT_ERR("Failed test. Value returned (%d) from hash doesn't match expected (%d)! fnc:\"%s\",line:%d", returned, expected, __FUNCTION__, __LINE__); \
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) from hash doesn't match expected(%p)! fnc:\"%s\",line:%d", (void*)returned, (void*)expected, __FUNCTION__, __LINE__); \
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++;

Expand Down Expand Up @@ -123,6 +127,135 @@ int test_uint64_ptr_incremental() {
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;
Expand All @@ -131,6 +264,7 @@ 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;
Expand Down

0 comments on commit f6c2183

Please sign in to comment.