Cleanup openssl.ec
[openssl.git] / include / openssl / lhash.h
1 /*
2  * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the OpenSSL license (the "License").  You may not use
5  * this file except in compliance with the License.  You can obtain a copy
6  * in the file LICENSE in the source distribution or at
7  * https://www.openssl.org/source/license.html
8  */
9
10 /*
11  * Header for dynamic hash table routines Author - Eric Young
12  */
13
14 #ifndef HEADER_LHASH_H
15 # define HEADER_LHASH_H
16
17 # include <openssl/e_os2.h>
18 # include <openssl/bio.h>
19
20 #ifdef  __cplusplus
21 extern "C" {
22 #endif
23
24 typedef struct lhash_node_st {
25     void *data;
26     struct lhash_node_st *next;
27     unsigned long hash;
28 } LHASH_NODE;
29
30 typedef int (*LHASH_COMP_FN_TYPE) (const void *, const void *);
31 typedef unsigned long (*LHASH_HASH_FN_TYPE) (const void *);
32 typedef void (*LHASH_DOALL_FN_TYPE) (void *);
33 typedef void (*LHASH_DOALL_ARG_FN_TYPE) (void *, void *);
34
35 /*
36  * Macros for declaring and implementing type-safe wrappers for LHASH
37  * callbacks. This way, callbacks can be provided to LHASH structures without
38  * function pointer casting and the macro-defined callbacks provide
39  * per-variable casting before deferring to the underlying type-specific
40  * callbacks. NB: It is possible to place a "static" in front of both the
41  * DECLARE and IMPLEMENT macros if the functions are strictly internal.
42  */
43
44 /* First: "hash" functions */
45 # define DECLARE_LHASH_HASH_FN(name, o_type) \
46         unsigned long name##_LHASH_HASH(const void *);
47 # define IMPLEMENT_LHASH_HASH_FN(name, o_type) \
48         unsigned long name##_LHASH_HASH(const void *arg) { \
49                 const o_type *a = arg; \
50                 return name##_hash(a); }
51 # define LHASH_HASH_FN(name) name##_LHASH_HASH
52
53 /* Second: "compare" functions */
54 # define DECLARE_LHASH_COMP_FN(name, o_type) \
55         int name##_LHASH_COMP(const void *, const void *);
56 # define IMPLEMENT_LHASH_COMP_FN(name, o_type) \
57         int name##_LHASH_COMP(const void *arg1, const void *arg2) { \
58                 const o_type *a = arg1;             \
59                 const o_type *b = arg2; \
60                 return name##_cmp(a,b); }
61 # define LHASH_COMP_FN(name) name##_LHASH_COMP
62
63 /* Fourth: "doall_arg" functions */
64 # define DECLARE_LHASH_DOALL_ARG_FN(name, o_type, a_type) \
65         void name##_LHASH_DOALL_ARG(void *, void *);
66 # define IMPLEMENT_LHASH_DOALL_ARG_FN(name, o_type, a_type) \
67         void name##_LHASH_DOALL_ARG(void *arg1, void *arg2) { \
68                 o_type *a = arg1; \
69                 a_type *b = arg2; \
70                 name##_doall_arg(a, b); }
71 # define LHASH_DOALL_ARG_FN(name) name##_LHASH_DOALL_ARG
72
73 typedef struct lhash_st {
74     LHASH_NODE **b;
75     LHASH_COMP_FN_TYPE comp;
76     LHASH_HASH_FN_TYPE hash;
77     unsigned int num_nodes;
78     unsigned int num_alloc_nodes;
79     unsigned int p;
80     unsigned int pmax;
81     unsigned long up_load;      /* load times 256 */
82     unsigned long down_load;    /* load times 256 */
83     unsigned long num_items;
84     unsigned long num_expands;
85     unsigned long num_expand_reallocs;
86     unsigned long num_contracts;
87     unsigned long num_contract_reallocs;
88     unsigned long num_hash_calls;
89     unsigned long num_comp_calls;
90     unsigned long num_insert;
91     unsigned long num_replace;
92     unsigned long num_delete;
93     unsigned long num_no_delete;
94     unsigned long num_retrieve;
95     unsigned long num_retrieve_miss;
96     unsigned long num_hash_comps;
97     int error;
98 } _LHASH;                       /* Do not use _LHASH directly, use LHASH_OF
99                                  * and friends */
100
101 # define LH_LOAD_MULT    256
102
103 /*
104  * Indicates a malloc() error in the last call, this is only bad in
105  * lh_insert().
106  */
107 int lh_error(_LHASH *lh);
108
109 _LHASH *lh_new(LHASH_HASH_FN_TYPE h, LHASH_COMP_FN_TYPE c);
110 void lh_free(_LHASH *lh);
111 void *lh_insert(_LHASH *lh, void *data);
112 void *lh_delete(_LHASH *lh, const void *data);
113 void *lh_retrieve(_LHASH *lh, const void *data);
114 void lh_doall(_LHASH *lh, LHASH_DOALL_FN_TYPE func);
115 void lh_doall_arg(_LHASH *lh, LHASH_DOALL_ARG_FN_TYPE func, void *arg);
116 unsigned long lh_strhash(const char *c);
117 unsigned long lh_num_items(const _LHASH *lh);
118 unsigned long lh_get_down_load(const _LHASH *lh);
119 void lh_set_down_load(_LHASH *lh, unsigned long down_load);
120
121 # ifndef OPENSSL_NO_STDIO
122 void lh_stats(const _LHASH *lh, FILE *fp);
123 void lh_node_stats(const _LHASH *lh, FILE *fp);
124 void lh_node_usage_stats(const _LHASH *lh, FILE *fp);
125 # endif
126 void lh_stats_bio(const _LHASH *lh, BIO *out);
127 void lh_node_stats_bio(const _LHASH *lh, BIO *out);
128 void lh_node_usage_stats_bio(const _LHASH *lh, BIO *out);
129
130 /* Type checking... */
131
132 # define LHASH_OF(type) struct lhash_st_##type
133
134 # define DEFINE_LHASH_OF(type) \
135     LHASH_OF(type) { union lh_##type##_dummy { void* d1; unsigned long d2; int d3; } dummy; }; \
136     static ossl_inline LHASH_OF(type) * \
137         lh_##type##_new(unsigned long (*hfn)(const type *), \
138                         int (*cfn)(const type *, const type *)) \
139     { \
140         return (LHASH_OF(type) *) \
141             lh_new((LHASH_HASH_FN_TYPE) hfn, (LHASH_COMP_FN_TYPE)cfn); \
142     } \
143     static ossl_inline void lh_##type##_free(LHASH_OF(type) *lh) \
144     { \
145         lh_free((_LHASH *)lh); \
146     } \
147     static ossl_inline type *lh_##type##_insert(LHASH_OF(type) *lh, type *d) \
148     { \
149         return (type *)lh_insert((_LHASH *)lh, d); \
150     } \
151     static ossl_inline type *lh_##type##_delete(LHASH_OF(type) *lh, const type *d) \
152     { \
153         return (type *)lh_delete((_LHASH *)lh, d); \
154     } \
155     static ossl_inline type *lh_##type##_retrieve(LHASH_OF(type) *lh, const type *d) \
156     { \
157         return (type *)lh_retrieve((_LHASH *)lh, d); \
158     } \
159     static ossl_inline int lh_##type##_error(LHASH_OF(type) *lh) \
160     { \
161         return lh_error((_LHASH *)lh); \
162     } \
163     static ossl_inline unsigned long lh_##type##_num_items(LHASH_OF(type) *lh) \
164     { \
165         return lh_num_items((_LHASH *)lh); \
166     } \
167     static ossl_inline void lh_##type##_node_stats_bio(const LHASH_OF(type) *lh, BIO *out) \
168     { \
169         lh_node_stats_bio((_LHASH *)lh, out); \
170     } \
171     static ossl_inline void lh_##type##_node_usage_stats_bio(const LHASH_OF(type) *lh, BIO *out) \
172     { \
173         lh_node_usage_stats_bio((_LHASH *)lh, out); \
174     } \
175     static ossl_inline void lh_##type##_stats_bio(const LHASH_OF(type) *lh, BIO *out) \
176     { \
177         lh_stats_bio((_LHASH *)lh, out); \
178     } \
179     static ossl_inline unsigned long lh_##type##_get_down_load(LHASH_OF(type) *lh) \
180     { \
181         return lh_get_down_load((_LHASH *)lh); \
182     } \
183     static ossl_inline void lh_##type##_set_down_load(LHASH_OF(type) *lh, unsigned long dl) \
184     { \
185         lh_set_down_load((_LHASH *)lh, dl); \
186     } \
187     static ossl_inline void lh_##type##_doall(LHASH_OF(type) *lh, \
188                                          void (*doall)(type *)) \
189     { \
190         lh_doall((_LHASH *)lh, (LHASH_DOALL_FN_TYPE)doall); \
191     } \
192     LHASH_OF(type)
193
194 #define IMPLEMENT_LHASH_DOALL_ARG_CONST(type, argtype) \
195     int_implement_lhash_doall(type, argtype, const type)
196
197 #define IMPLEMENT_LHASH_DOALL_ARG(type, argtype) \
198     int_implement_lhash_doall(type, argtype, type)
199
200 #define int_implement_lhash_doall(type, argtype, cbargtype) \
201     static ossl_inline void \
202         lh_##type##_doall_##argtype(LHASH_OF(type) *lh, \
203                                    void (*fn)(cbargtype *, argtype *), \
204                                    argtype *arg) \
205     { \
206         lh_doall_arg((_LHASH *)lh, (LHASH_DOALL_ARG_FN_TYPE)fn, (void *)arg); \
207     } \
208     LHASH_OF(type)
209
210 # define CHECKED_LHASH_OF(type,lh) \
211   ((_LHASH *)CHECKED_PTR_OF(LHASH_OF(type),lh))
212
213 /* Define wrapper functions. */
214 # define LHM_lh_doall_arg(type, lh, fn, arg_type, arg) \
215   lh_doall_arg(CHECKED_LHASH_OF(type, lh), fn, CHECKED_PTR_OF(arg_type, arg))
216
217 DEFINE_LHASH_OF(OPENSSL_STRING);
218 DEFINE_LHASH_OF(OPENSSL_CSTRING);
219
220 #ifdef  __cplusplus
221 }
222 #endif
223
224 #endif