1 /*******************************************************************
2 uLan Utilities Library - C library of basic reusable constructions
4 ul_hastabcust.h - custom hash table implementation
6 (C) Copyright 2009 by Pavel Pisa - Originator
8 The uLan utilities library can be used, copied and modified under
10 - GPL - GNU General Public License
11 - LGPL - GNU Lesser General Public License
12 - MPL - Mozilla Public License
13 - and other licenses added by project originators
14 Code can be modified and re-distributed under any combination
15 of the above listed licenses. If contributor does not agree with
16 some of the licenses, he/she can delete appropriate line.
17 Warning, if you delete all lines, you are not allowed to
18 distribute source code and/or binaries utilizing code.
20 See files COPYING and README for details.
22 *******************************************************************/
24 #ifndef _UL_HASHTABCUST_H
25 #define _UL_HASHTABCUST_H
27 #include "ul_utdefs.h"
28 #include "ul_hashtab.h"
29 #include "ul_gavlcust.h"
35 #define UL_HASTAB_CUST_NODE_INT_IMP(cust_prefix, cust_table_t, cust_item_t, cust_key_t,\
36 cust_table_field, cust_item_node, cust_item_key, cust_cmp_fnc, cust_hash_fnc, \
37 cust_hash_get_fnc, cust_hash_prep_fnc, cust_sizestep) \
38 GAVL_CUST_NODE_INT_DEC_SCOPE(static, cust_prefix##_privtree, ul_hashtab_treeroot_t, cust_item_t, cust_key_t,\
39 treeroot, cust_item_node.treenode, cust_item_key, cust_cmp_fnc) \
40 GAVL_CUST_NODE_INT_IMP(cust_prefix##_privtree, ul_hashtab_treeroot_t, cust_item_t, cust_key_t,\
41 treeroot, cust_item_node.treenode, cust_item_key, cust_cmp_fnc) \
44 ul_hashtab_treeroot_t *cust_prefix##_privtree_tree4item(cust_table_t *table, const cust_item_t *item)\
46 return !table->cust_table_field.hashmask? &(table->cust_table_field.treeroots.treesingle):\
47 &(table->cust_table_field.treeroots.treetable[cust_hash_get_fnc(item)&table->cust_table_field.hashmask]);\
51 const ul_hashtab_treeroot_t *cust_prefix##_privtree_tree4key(const cust_table_t *table, cust_key_t const *key)\
53 return !table->cust_table_field.hashmask? &(table->cust_table_field.treeroots.treesingle):\
54 &(table->cust_table_field.treeroots.treetable[cust_hash_fnc(key)&table->cust_table_field.hashmask]);\
58 void cust_prefix##_privdummy(cust_table_t *table) \
59 {/*used to suppress warning about unused static function generated by GAVL*/\
60 cust3_privtree_init_root_field(&(table->cust_table_field.treeroots.treesingle));\
64 int cust_prefix##_privinternal_insert(cust_table_t *table, cust_item_t *item)\
66 return cust_prefix##_privtree_insert(cust_prefix##_privtree_tree4item(table, item), item);\
70 int cust_prefix##_privresize_insert(ul_hashtab_cust_table_field_t *table_field, gavl_node_t *treenode) UL_ATTR_REENTRANT\
72 return cust_prefix##_privinternal_insert(UL_CONTAINEROF(table_field, cust_table_t, cust_table_field),\
73 cust_prefix##_privtree_node2item(NULL,treenode));\
76 int cust_prefix##_resize_table(cust_table_t *table, ul_hashtab_hashval_t newsize)\
78 return ul_hashtab_resize_primitive(&table->cust_table_field, newsize, cust_prefix##_privresize_insert);\
81 int cust_prefix##_insert(cust_table_t *table, cust_item_t *item)\
84 if((cust_sizestep)!=ul_hashtab_sizestep_null) \
85 if((table->cust_table_field.sizestep<ul_hashtab_sizestep_max(cust_sizestep))&& \
86 (table->cust_table_field.count>=(cust_sizestep)[table->cust_table_field.sizestep].toexpand)) {\
87 table->cust_table_field.sizestep++; \
88 cust_prefix##_resize_table(table, (cust_sizestep)[table->cust_table_field.sizestep].size);\
90 cust_hash_prep_fnc(item);\
91 res=cust_prefix##_privinternal_insert(table, item);\
93 table->cust_table_field.count++; \
97 int cust_prefix##_delete(cust_table_t *table, cust_item_t *item)\
100 res=cust_prefix##_privtree_delete(cust_prefix##_privtree_tree4item(table, item), item);\
102 table->cust_table_field.count--; \
103 if(((cust_sizestep)!=ul_hashtab_sizestep_null)&&table->cust_table_field.sizestep) {\
104 if(table->cust_table_field.sizestep>ul_hashtab_sizestep_max(cust_sizestep)) \
105 table->cust_table_field.sizestep=ul_hashtab_sizestep_max(cust_sizestep); \
106 if(table->cust_table_field.count<=(cust_sizestep)[table->cust_table_field.sizestep].toshrink) {\
107 table->cust_table_field.sizestep--; \
108 cust_prefix##_resize_table(table, (cust_sizestep)[table->cust_table_field.sizestep].size);\
115 cust_item_t *cust_prefix##_delete_key(cust_table_t *table, cust_key_t const *key) \
118 const ul_hashtab_treeroot_t *treeroot; \
119 treeroot=cust_prefix##_privtree_tree4key(table, key); \
120 if(cust_prefix##_privtree_search_node(treeroot, key, &node)) \
122 cust_prefix##_privtree_delete_node((ul_hashtab_treeroot_t *)treeroot, node); \
123 table->cust_table_field.count--; \
124 return cust_prefix##_privtree_node2item(NULL,node); \
127 int cust_prefix##_search_node(const cust_table_t *table, cust_key_t const *key, typeof(((cust_item_t*)0)->cust_item_node) **nodep) \
130 if(cust_prefix##_privtree_search_node(cust_prefix##_privtree_tree4key(table, key), key, &node)) { \
134 *nodep=&(UL_CONTAINEROF(node, cust_item_t, cust_item_node.treenode)->cust_item_node); \
138 cust_item_t *cust_prefix##_find(const cust_table_t *table, cust_key_t const *key) \
140 return cust_prefix##_privtree_find(cust_prefix##_privtree_tree4key(table, key), key); \
143 int cust_prefix##_find_it(cust_table_t *container, cust_key_t const *key, cust_prefix##_it_t *it) \
145 it->container=container; \
146 it->ptreeroot=(ul_hashtab_treeroot_t*)cust_prefix##_privtree_tree4key(it->container, key); \
147 it->item=cust_prefix##_privtree_find(it->ptreeroot, key); \
148 return it->item!=NULL?1:0; \
151 void cust_prefix##_delete_it(cust_prefix##_it_t *it)\
154 ul_hashtab_treeroot_t *treeroot; \
155 if(!(item=it->item)) return;\
156 treeroot=it->ptreeroot; \
157 cust_prefix##_next_it(it);\
158 if(cust_prefix##_privtree_delete(treeroot,item)>=0)\
159 it->container->cust_table_field.count--; \
166 #endif /* _UL_HASHTABCUST_H */