Nilorea Library
C utilities for networking, threading, graphics
Loading...
Searching...
No Matches
ex_hash.c

Nilorea Library hash table api test.

Nilorea Library hash table api test

Author
Castagnier Mickael
Version
1.0
Date
26/05/2015
/*
* Nilorea Library
* Copyright (C) 2005-2026 Castagnier Mickael
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
* implied. See the License for the specific language governing
* permissions and limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "nilorea/n_str.h"
#include "nilorea/n_log.h"
#include "nilorea/n_list.h"
#include "nilorea/n_hash.h"
#define NB_HASH_ELEMENTS 24
typedef struct DATA {
int value;
} DATA;
void destroy_data(void* ptr) {
DATA* data = (DATA*)ptr;
free_nstr(&data->rnd_str);
Free(data);
}
int main(void) {
DATA* data = NULL;
char* str = NULL;
n_log(LOG_INFO, "Filling HashTable with %d random elements", NB_HASH_ELEMENTS);
for (int it = 0; it < NB_HASH_ELEMENTS; it++) {
N_STR* nkey = NULL;
int randomizator = rand() % 4;
nstrprintf(nkey, "key%d_%d", it, randomizator);
switch (randomizator) {
default:
case 0:
ht_put_int(htable, _nstr(nkey), 666);
n_log(LOG_INFO, "Put int 666 with key %s", _nstr(nkey));
break;
case 1:
ht_put_double(htable, _nstr(nkey), 3.14);
n_log(LOG_INFO, "Put double 3.14 with key %s", _nstr(nkey));
break;
case 2:
Malloc(data, DATA, 1);
data->rnd_str = NULL;
nstrprintf(data->rnd_str, "%s%d", _nstr(nkey), rand() % 10);
data->value = 7;
ht_put_ptr(htable, _nstr(nkey), data, &destroy_data, NULL);
n_log(LOG_INFO, "Put ptr rnd_str %s value %d with key %s", _nstr(data->rnd_str), data->value, _nstr(nkey));
break;
case 3:
Malloc(str, char, 64);
snprintf(str, 64, "%s%d", _nstr(nkey), rand() % 10);
ht_put_string(htable, _nstr(nkey), str);
n_log(LOG_INFO, "Put string %s key %s", str, _nstr(nkey));
Free(str);
break;
}
/* asving key for ulterior use */
list_push(keys_list, nkey, free_nstr_ptr);
}
n_log(LOG_INFO, "Reading hash table with ht_foreach");
HT_FOREACH(node, htable,
{
n_log(LOG_INFO, "HT_FOREACH hash: %u, key:%s", node->hash_value, _str(node->key));
});
HT_FOREACH_R(node, htable, hash_iterator,
{
n_log(LOG_INFO, "HT_FOREACH_R hash: %u, key:%s", node->hash_value, _str(node->key));
});
size_t optimal_size = ht_get_optimal_size(htable);
n_log(LOG_INFO, "########");
n_log(LOG_INFO, "collisions: %d %%", ht_get_table_collision_percentage(htable));
n_log(LOG_INFO, "table size: %zu , table optimal size: %zu", htable->size, optimal_size);
n_log(LOG_INFO, "resizing to %zu returned %d", optimal_size, ht_resize(&htable, optimal_size));
n_log(LOG_INFO, "collisions after resize: %d %%", ht_get_table_collision_percentage(htable));
n_log(LOG_INFO, "########");
if (ht_optimize(&htable) == FALSE) {
n_log(LOG_ERR, "Error when optimizing table %p", htable);
}
n_log(LOG_INFO, "collisions after ht_optimize: %d %%", ht_get_table_collision_percentage(htable));
n_log(LOG_INFO, "########");
LIST* results = ht_get_completion_list(htable, "key", NB_HASH_ELEMENTS);
if (results) {
list_foreach(node, results) {
n_log(LOG_INFO, "completion result: %s", (char*)node->ptr);
}
list_destroy(&results);
}
int matching_nodes(HASH_NODE * node) {
if (strncasecmp("key", node->key, 3) == 0)
return TRUE;
return FALSE;
}
results = ht_search(htable, &matching_nodes);
list_foreach(node, results) {
n_log(LOG_INFO, "htsearch: key: %s", (char*)node->ptr);
}
list_destroy(&results);
/* test ht_get_ptr */
Malloc(data, DATA, 1);
if (data) {
data->rnd_str = NULL;
nstrprintf(data->rnd_str, "ptr_test_value");
data->value = 42;
ht_put_ptr(htable, "ptr_test_key", data, &destroy_data, NULL);
void* retrieved = NULL;
ht_get_ptr(htable, "ptr_test_key", &retrieved);
if (retrieved) {
DATA* rd = (DATA*)retrieved;
n_log(LOG_INFO, "ht_get_ptr: value=%d str=%s", rd->value, _nstr(rd->rnd_str));
}
}
/* test ht_remove */
ht_put_int(htable, "remove_me", 999);
n_log(LOG_INFO, "Before ht_remove, table has entries");
ht_remove(htable, "remove_me");
n_log(LOG_INFO, "After ht_remove(\"remove_me\")");
{
HASH_INT_TYPE check_val = -1;
if (ht_get_int(htable, "remove_me", &check_val) == FALSE) {
n_log(LOG_INFO, "ht_remove confirmed: key no longer found");
}
}
/* test ht_duplicate */
HASH_TABLE* htable_copy = ht_duplicate(htable);
if (htable_copy) {
n_log(LOG_INFO, "ht_duplicate: created copy with size %ld", htable_copy->size);
destroy_ht(&htable_copy);
}
list_destroy(&keys_list);
destroy_ht(&htable);
/* testing empty destroy */
htable = new_ht(1024);
empty_ht(htable);
destroy_ht(&htable);
htable = new_ht_trie(256, 32);
ht_put_int(htable, "TestInt", 1);
ht_put_double(htable, "TestDouble", 2.0);
ht_put_string(htable, "TestString", "MyString");
HASH_INT_TYPE ival = -1;
double fval = -1.0;
ht_get_int(htable, "TestInt", &ival);
ht_get_double(htable, "TestDouble", &fval);
char* string = NULL;
ht_get_string(htable, "TestString", &string);
n_log(LOG_INFO, "Trie:%ld %f %s", (long)ival, fval, string);
results = ht_get_completion_list(htable, "Test", 10);
if (results) {
list_foreach(node, results) {
n_log(LOG_INFO, "completion result: %s", (char*)node->ptr);
}
list_destroy(&results);
}
destroy_ht(&htable);
exit(0);
} /* END_OF_MAIN */
int main(void)
int value
int value
Definition ex_hash.c:40
void destroy_data(void *ptr)
destroy a DATA struct
Definition ex_hash.c:47
#define NB_HASH_ELEMENTS
Definition ex_hash.c:33
N_STR * rnd_str
string holder
Definition ex_hash.c:38
string and int holder
Definition ex_hash.c:36
#define Malloc(__ptr, __struct, __size)
Malloc Handler to get errors and set to 0.
Definition n_common.h:204
#define _str(__PTR)
define true
Definition n_common.h:193
#define Free(__ptr)
Free Handler to get errors.
Definition n_common.h:263
#define _nstr(__PTR)
N_STR or "NULL" string for logging purposes.
Definition n_common.h:199
char * key
string key of the node if any, else NULL
Definition n_hash.h:114
size_t size
size of the hash table
Definition n_hash.h:140
int ht_get_ptr(HASH_TABLE *table, const char *key, void **val)
get pointer at 'key' from 'table'
Definition n_hash.c:2110
LIST * ht_search(HASH_TABLE *table, int(*node_is_matching)(HASH_NODE *node))
seach table for matching nodes
Definition n_hash.c:2224
HASH_TABLE * ht_duplicate(HASH_TABLE *table)
duplicate a hash table (all pointers should have a duplicator func set)
Definition n_hash.c:2652
int destroy_ht(HASH_TABLE **table)
empty a table and destroy it
Definition n_hash.c:2244
#define HT_FOREACH_R(__ITEM_, __HASH_, __ITERATOR,...)
ForEach macro helper.
Definition n_hash.h:262
int ht_remove(HASH_TABLE *table, const char *key)
remove and delete node at key in table
Definition n_hash.c:2202
HASH_TABLE * new_ht(size_t size)
Create a hash table with the given size.
Definition n_hash.c:2011
int ht_get_table_collision_percentage(HASH_TABLE *table)
get table collision percentage (HASH_CLASSIC mode only)
Definition n_hash.c:2487
int ht_get_double(HASH_TABLE *table, const char *key, double *val)
get double at 'key' from 'table'
Definition n_hash.c:2084
int empty_ht(HASH_TABLE *table)
empty a table
Definition n_hash.c:2234
LIST * ht_get_completion_list(HASH_TABLE *table, const char *keybud, size_t max_results)
get next matching keys in table tree
Definition n_hash.c:2401
int ht_put_double(HASH_TABLE *table, const char *key, double value)
put a double value with given key in the targeted hash table
Definition n_hash.c:2136
size_t ht_get_optimal_size(HASH_TABLE *table)
get optimal array size based on nb=(number_of_key*1.3) && if( !isprime(nb) )nb=nextprime(nb) (HASH_CL...
Definition n_hash.c:2511
int ht_put_ptr(HASH_TABLE *table, const char *key, void *ptr, void(*destructor)(void *ptr), void *(*duplicator)(void *ptr))
put an arbitrary pointer value with given key in the targeted hash table
Definition n_hash.c:2164
int ht_get_string(HASH_TABLE *table, const char *key, char **val)
get string at 'key' from 'table'
Definition n_hash.c:2123
#define HASH_INT_TYPE
type of a HASH_INT in 64 bits
Definition n_hash.h:93
int ht_put_string(HASH_TABLE *table, const char *key, char *string)
put a string value (copy/dup) with given key in the targeted hash table
Definition n_hash.c:2177
int ht_resize(HASH_TABLE **table, size_t size)
rehash table according to size (HASH_CLASSIC mode only)
Definition n_hash.c:2530
int ht_get_int(HASH_TABLE *table, const char *key, int64_t *val)
get node at 'key' from 'table'
Definition n_hash.c:2097
HASH_TABLE * new_ht_trie(size_t alphabet_length, size_t alphabet_offset)
create a TRIE hash table with the alphabet_size, each key value beeing decreased by alphabet_offset
Definition n_hash.c:1965
int ht_put_int(HASH_TABLE *table, const char *key, int64_t value)
put an integral value with given key in the targeted hash table
Definition n_hash.c:2149
int ht_optimize(HASH_TABLE **table)
try an automatic optimization of the table (HASH_CLASSIC mode only)
Definition n_hash.c:2618
#define HT_FOREACH(__ITEM_, __HASH_,...)
ForEach macro helper.
Definition n_hash.h:216
structure of a hash table node
Definition n_hash.h:112
structure of a hash table
Definition n_hash.h:138
int list_push(LIST *list, void *ptr, void(*destructor)(void *ptr))
Add a pointer to the end of the list.
Definition n_list.c:228
#define list_foreach(__ITEM_, __LIST_)
ForEach macro helper, safe for node removal during iteration.
Definition n_list.h:89
int list_destroy(LIST **list)
Empty and Free a list container.
Definition n_list.c:548
LIST * new_generic_list(size_t max_items)
Initialiaze a generic list container to max_items pointers.
Definition n_list.c:37
Structure of a generic LIST container.
Definition n_list.h:59
#define n_log(__LEVEL__,...)
Logging function wrapper to get line and func.
Definition n_log.h:89
#define LOG_DEBUG
debug-level messages
Definition n_log.h:84
#define LOG_ERR
error conditions
Definition n_log.h:76
void set_log_level(const int log_level)
Set the global log level value ( static int LOG_LEVEL )
Definition n_log.c:121
#define LOG_INFO
informational
Definition n_log.h:82
void free_nstr_ptr(void *ptr)
Free a N_STR pointer structure.
Definition n_str.c:70
#define free_nstr(__ptr)
free a N_STR structure and set the pointer to NULL
Definition n_str.h:203
#define nstrprintf(__nstr_var, __format,...)
Macro to quickly allocate and sprintf to N_STR.
Definition n_str.h:117
A box including a string and his lenght.
Definition n_str.h:61
Hash functions and table.
List structures and definitions.
Generic log system.
N_STR and string function declaration.