acl  3.5.3.0
acl_binhash.h
浏览该文件的文档.
1 #ifndef ACL_BINHASH_INCLUDE_H
2 #define ACL_BINHASH_INCLUDE_H
3 
4 #ifdef __cplusplus
5 extern "C" {
6 #endif
7 
8 #include "acl_define.h"
9 #include "acl_hash.h" /* just for ACL_HASH_FN */
10 #include "acl_slice.h"
11 #include "acl_iterator.h"
12 
13 typedef struct ACL_BINHASH ACL_BINHASH;
15 
16 /**
17  * Structure of one hash table.
18  */
19 struct ACL_BINHASH {
20  int size; /**< length of entries array */
21  int used; /**< number of entries in table */
22  unsigned int flag; /**< the hash table's properties flag */
23  int status; /**< the hash tables' operation status */
24  ACL_BINHASH_INFO **data; /**< entries array, auto-resized */
25  ACL_SLICE *slice; /**< memory slice */
26  ACL_HASH_FN hash_fn; /**< hash function */
27 
28  /* for acl_iterator */
29 
30  /* 取迭代器头函数 */
31  void *(*iter_head)(ACL_ITER*, struct ACL_BINHASH*);
32  /* 取迭代器下一个函数 */
33  void *(*iter_next)(ACL_ITER*, struct ACL_BINHASH*);
34  /* 取迭代器尾函数 */
35  void *(*iter_tail)(ACL_ITER*, struct ACL_BINHASH*);
36  /* 取迭代器上一个函数 */
37  void *(*iter_prev)(ACL_ITER*, struct ACL_BINHASH*);
38  /* 取迭代器关联的当前容器成员结构对象 */
39  ACL_BINHASH_INFO *(*iter_info)(ACL_ITER*, struct ACL_BINHASH*);
40 };
41 
42 /**
43  * Structure of one hash table entry.
44  */
46  union {
47  void *key;
48  const void *c_key;
49  } key; /**
50  * 哈希键, 只所以如此声明,是因为当创建哈希表的标志位为
51  * ACL_BINHASH_FLAG_KEY_REUSE 时需要复用输入的键空间
52  */
53  int key_len; /**< 哈希键长度 */
54  void *value; /**< 哈希键所对应的用户数据 */
55  struct ACL_BINHASH_INFO *next; /**< colliding entry */
56  struct ACL_BINHASH_INFO *prev; /**< colliding entry */
57 };
58 
59 /**
60  * ACL_BINHASH 遍历用类型
61  */
62 typedef struct ACL_BINHASH_ITER {
63  /* public */
65 
66  /* private */
67  int i;
68  int size;
71 
72 /**
73  * 创建一个哈希表
74  * @param size {int} 哈希表的初始化大小
75  * @param flag {unsigned int} 哈希表属性标志位, ACL_BINHASH_FLAG_xxx
76  * @return {ACL_BINHASH*} 新创建的哈希表指针
77  */
78 ACL_API ACL_BINHASH *acl_binhash_create(int size, unsigned int flag);
79 #define ACL_BINHASH_FLAG_KEY_REUSE (1 << 0)
80 #define ACL_BINHASH_FLAG_SLICE_RTGC_OFF (1 << 1)
81 #define ACL_BINHASH_FLAG_SLICE1 (1 << 2)
82 #define ACL_BINHASH_FLAG_SLICE2 (1 << 3)
83 #define ACL_BINHASH_FLAG_SLICE3 (1 << 4)
84 
85 /**
86  * 向哈希表中添加对象
87  * @param table {ACL_BINHASH*} 哈希表指针
88  * @param key {const void*} 哈希键
89  * @param key_len {int} key 的长度
90  * @param value {void*} 键值
91  * @return {ACL_BINHASH_INFO*} 新创建的哈希条目指针
92  */
93 ACL_API ACL_BINHASH_INFO *acl_binhash_enter(ACL_BINHASH *table, const void *key, int key_len, void *value);
94 
95 /**
96  * 从哈希表中根据键名取得对应的哈希条目
97  * @param table {ACL_BINHASH*} 哈希表指针
98  * @param key {const void*} 哈希键
99  * @param key_len {int} key 的长度
100  * @return {ACL_BINHASH_INFO*} 哈希条目指针
101  */
102 ACL_API ACL_BINHASH_INFO *acl_binhash_locate(ACL_BINHASH *table, const void *key, int key_len);
103 
104 /**
105  * 查询某个哈希键的键值
106  * @param table {ACL_BINHASH*} 哈希表指针
107  * @param key {const void*} 哈希键
108  * @param key_len {int} key 的长度
109  * @return {void*} 哈希键值
110  */
111 ACL_API void *acl_binhash_find(ACL_BINHASH *table, const void *key, int key_len);
112 
113 /**
114  * 删除某个哈希项
115  * @param table {ACL_BINHASH*} 哈希表指针
116  * @param key {const void*} 哈希键
117  * @param key_len {int} key 的长度
118  * @param free_fn {void (*)(void*)} 用来释放哈希键值的函数指针,如果为空则不在内部释放键值
119  * @return {int} 0: ok, -1: error
120  */
121 ACL_API int acl_binhash_delete(ACL_BINHASH *table, const void *key, int key_len, void (*free_fn) (void *));
122 
123 /**
124  * 释放哈希表
125  * @param table {ACL_BINHASH*} 哈希表指针
126  * @param free_fn {void (*)(void*)} 如果不为空,则用此函数来释放哈希表内的所有键值
127  */
128 ACL_API void acl_binhash_free(ACL_BINHASH *table, void (*free_fn) (void *));
129 
130 /**
131  * 遍历整个哈希表,并用用户给出的回调函数操作哈希表中的键值
132  * @param table {ACL_BINHASH*} 哈希表指针
133  * @param walk_fn {void (*)(ACL_BINHASH_INFO*, void*)} 在遍历哈希表中的每个元素时的回调函数
134  * @param arg {void*} 用户传递的参数,作为参数在 walk_fn 中传递
135  */
136 ACL_API void acl_binhash_walk(ACL_BINHASH *table, void (*walk_fn) (ACL_BINHASH_INFO *, void *), void *arg);
137 
138 /**
139  * 列出当前哈希表中的所有元素数组列表
140  * @param table {ACL_BINHASH*} 哈希表指针
141  * @return {ACL_BINHASH_INFO*} 哈希表中所有元素组成的ACL_BINHASH_INFO数组,
142  * 该数组中的最后一个指针为 NULL
143  */
145 
146 /**
147  * 获得哈希表操作时的出错号
148  * @param table {ACL_BINHASH*} 哈希表指针
149  * @return {int} 错误号
150  */
151 ACL_API int acl_binhash_errno(ACL_BINHASH *table);
152 #define ACL_BINHASH_STAT_OK 0
153 #define ACL_BINHASH_STAT_INVAL 1
154 #define ACL_BINHASH_STAT_DUPLEX_KEY 2
155 #define ACL_BINHASH_STAT_NO_KEY 3
156 
157 /**
158  * 返回哈希表当前的容器空间大小
159  * @param table 哈希表指针
160  * @return 哈希表的容器空间大小
161  */
162 ACL_API int acl_binhash_size(const ACL_BINHASH *table);
163 
164 /**
165  * 当前哈希表中对象的个数
166  * @param table {ACL_BINHASH*} 哈希表指针
167  * @return {int}
168  */
169 ACL_API int acl_binhash_used(ACL_BINHASH *table);
170 
176 
177 /*-------------------- 一些方便快捷的宏操作 --------------------------------*/
178 
179 #define ACL_BINHASH_ITER_KEY(iter) ((iter).ptr->key.c_key)
180 #define acl_binhash_iter_key ACL_BINHASH_ITER_KEY
181 
182 #define ACL_BINHASH_ITER_VALUE(iter) ((iter).ptr->value)
183 #define acl_binhash_iter_value ACL_BINHASH_ITER_VALUE
184 
185 /**
186  * 遍历 ACL_BINHASH
187  * @param iter {ACL_BINHASH_ITER}
188  * @param table_ptr {ACL_BINHASH *}
189  * @example:
190  void test()
191  {
192  ACL_BINHASH *table = acl_binhash_create(10, 0);
193  ACL_BINHASH_ITER iter;
194  char *value, key[32];
195  int i;
196 
197  for (i = 0; i < 100; i++) {
198  value = (char*) acl_mystrdup("value");
199  snprintf(key, sizeof(key), "key:%d", i);
200  (void) acl_binhash_enter(table, key, strlen(key), value);
201  }
202 
203  acl_binhash_foreach(iter, table) {
204  printf("%s=%s\n", iter.ptr->key.c_key, iter.ptr->value);
205  if (i == 50)
206  break;
207  }
208 
209  acl_binhash_free(table, acl_myfree_fn);
210  }
211  */
212 #if 0
213 #define ACL_BINHASH_FOREACH(iter, table_ptr) \
214  if (table_ptr) \
215  for((iter).size = acl_binhash_size((table_ptr)), (iter).i = 0, \
216  (iter).h = acl_binhash_data((table_ptr)); (iter).i < (iter).size; (iter).i++) \
217  for ((iter).ptr = *(iter).h++; (iter).ptr; (iter).ptr = (iter).ptr->next)
218 #define ACL_BINHASH_FOREACH_REVERSE(iter, table_ptr) \
219  if (table_ptr) \
220  for((iter).size = acl_binhash_size((table_ptr)), (iter).i = (iter).size - 1, \
221  (iter).h = acl_binhash_data((table_ptr)) + (iter).i; (iter).i >= 0; (iter).i--) \
222  for ((iter).ptr = *(iter).h--; (iter).ptr; (iter).ptr = (iter).ptr->next)
223 #else
224 #define ACL_BINHASH_FOREACH(iter, table_ptr) \
225  if (table_ptr) \
226  for((void) acl_binhash_iter_head((table_ptr), &iter); \
227  (iter).ptr; \
228  (void) acl_binhash_iter_next(&iter))
229 #define ACL_BINHASH_FOREACH_REVERSE(iter, table_ptr) \
230  if (table_ptr) \
231  for((void) acl_binhash_iter_tail((table_ptr), &iter); \
232  (iter).ptr; \
233  (void) acl_binhash_iter_prev(&iter))
234 #endif
235 
236 #define acl_binhash_foreach ACL_BINHASH_FOREACH
237 #define acl_binhash_foreach_reverse ACL_BINHASH_FOREACH_REVERSE
238 
239 #ifdef __cplusplus
240 }
241 #endif
242 
243 #endif
244 
ACL_API const ACL_BINHASH_INFO * acl_binhash_iter_head(ACL_BINHASH *table, ACL_BINHASH_ITER *iter)
ACL_API void acl_binhash_walk(ACL_BINHASH *table, void(*walk_fn)(ACL_BINHASH_INFO *, void *), void *arg)
ACL_API ACL_BINHASH_INFO ** acl_binhash_data(ACL_BINHASH *table)
struct ACL_BINHASH_INFO * next
Definition: acl_binhash.h:55
ACL_HASH_FN hash_fn
Definition: acl_binhash.h:26
unsigned(* ACL_HASH_FN)(const void *buf, size_t len)
Definition: acl_hash.h:16
ACL_API int acl_binhash_size(const ACL_BINHASH *table)
const void * c_key
Definition: acl_binhash.h:48
ACL_API void acl_binhash_free(ACL_BINHASH *table, void(*free_fn)(void *))
ACL_API const ACL_BINHASH_INFO * acl_binhash_iter_tail(ACL_BINHASH *table, ACL_BINHASH_ITER *iter)
ACL_API int acl_binhash_used(ACL_BINHASH *table)
ACL_BINHASH_INFO ** data
Definition: acl_binhash.h:24
struct ACL_BINHASH_ITER ACL_BINHASH_ITER
ACL_API const ACL_BINHASH_INFO * acl_binhash_iter_next(ACL_BINHASH_ITER *iter)
ACL_API ACL_BINHASH_INFO * acl_binhash_locate(ACL_BINHASH *table, const void *key, int key_len)
ACL_API void * acl_binhash_find(ACL_BINHASH *table, const void *key, int key_len)
struct ACL_BINHASH_INFO * prev
Definition: acl_binhash.h:56
ACL_API int acl_binhash_errno(ACL_BINHASH *table)
ACL_SLICE * slice
Definition: acl_binhash.h:25
ACL_API ACL_BINHASH * acl_binhash_create(int size, unsigned int flag)
ACL_API ACL_BINHASH_INFO * acl_binhash_enter(ACL_BINHASH *table, const void *key, int key_len, void *value)
ACL_BINHASH_INFO ** h
Definition: acl_binhash.h:69
ACL_API int acl_binhash_delete(ACL_BINHASH *table, const void *key, int key_len, void(*free_fn)(void *))
ACL_API const ACL_BINHASH_INFO * acl_binhash_iter_prev(ACL_BINHASH_ITER *iter)
struct ACL_SLICE ACL_SLICE
Definition: acl_slice.h:33
unsigned int flag
Definition: acl_binhash.h:22
ACL_API ACL_BINHASH_INFO ** acl_binhash_list(ACL_BINHASH *table)
ACL_BINHASH_INFO * ptr
Definition: acl_binhash.h:64