summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/lhash/lhash.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/lhash/lhash.c')
-rw-r--r--src/lib/libcrypto/lhash/lhash.c459
1 files changed, 224 insertions, 235 deletions
diff --git a/src/lib/libcrypto/lhash/lhash.c b/src/lib/libcrypto/lhash/lhash.c
index 78ba26db83..ad24a7726b 100644
--- a/src/lib/libcrypto/lhash/lhash.c
+++ b/src/lib/libcrypto/lhash/lhash.c
@@ -5,21 +5,21 @@
5 * This package is an SSL implementation written 5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com). 6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL. 7 * The implementation was written so as to conform with Netscapes SSL.
8 * 8 *
9 * This library is free for commercial and non-commercial use as long as 9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions 10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA, 11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation 12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms 13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com). 14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 * 15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in 16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed. 17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution 18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used. 19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or 20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package. 21 * in documentation (online or textual) provided with the package.
22 * 22 *
23 * Redistribution and use in source and binary forms, with or without 23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions 24 * modification, are permitted provided that the following conditions
25 * are met: 25 * are met:
@@ -34,10 +34,10 @@
34 * Eric Young (eay@cryptsoft.com)" 34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library 35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-). 36 * being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from 37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 * the apps directory (application code) you must include an acknowledgement: 38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 * 40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@@ -49,7 +49,7 @@
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE. 51 * SUCH DAMAGE.
52 * 52 *
53 * The licence and distribution terms for any publically available version or 53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be 54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence 55 * copied and put under another distribution licence
@@ -100,9 +100,9 @@
100#include <openssl/crypto.h> 100#include <openssl/crypto.h>
101#include <openssl/lhash.h> 101#include <openssl/lhash.h>
102 102
103const char lh_version[]="lhash" OPENSSL_VERSION_PTEXT; 103const char lh_version[] = "lhash" OPENSSL_VERSION_PTEXT;
104 104
105#undef MIN_NODES 105#undef MIN_NODES
106#define MIN_NODES 16 106#define MIN_NODES 16
107#define UP_LOAD (2*LH_LOAD_MULT) /* load times 256 (default 2) */ 107#define UP_LOAD (2*LH_LOAD_MULT) /* load times 256 (default 2) */
108#define DOWN_LOAD (LH_LOAD_MULT) /* load times 256 (default 1) */ 108#define DOWN_LOAD (LH_LOAD_MULT) /* load times 256 (default 1) */
@@ -111,365 +111,354 @@ static void expand(_LHASH *lh);
111static void contract(_LHASH *lh); 111static void contract(_LHASH *lh);
112static LHASH_NODE **getrn(_LHASH *lh, const void *data, unsigned long *rhash); 112static LHASH_NODE **getrn(_LHASH *lh, const void *data, unsigned long *rhash);
113 113
114_LHASH *lh_new(LHASH_HASH_FN_TYPE h, LHASH_COMP_FN_TYPE c) 114_LHASH *
115 { 115lh_new(LHASH_HASH_FN_TYPE h, LHASH_COMP_FN_TYPE c)
116{
116 _LHASH *ret; 117 _LHASH *ret;
117 int i; 118 int i;
118 119
119 if ((ret=malloc(sizeof(_LHASH))) == NULL) 120 if ((ret = malloc(sizeof(_LHASH))) == NULL)
120 goto err0; 121 goto err0;
121 if ((ret->b=malloc(sizeof(LHASH_NODE *)*MIN_NODES)) == NULL) 122 if ((ret->b = malloc(sizeof(LHASH_NODE *) * MIN_NODES)) == NULL)
122 goto err1; 123 goto err1;
123 for (i=0; i<MIN_NODES; i++) 124 for (i = 0; i < MIN_NODES; i++)
124 ret->b[i]=NULL; 125 ret->b[i] = NULL;
125 ret->comp=((c == NULL)?(LHASH_COMP_FN_TYPE)strcmp:c); 126 ret->comp = ((c == NULL) ? (LHASH_COMP_FN_TYPE)strcmp : c);
126 ret->hash=((h == NULL)?(LHASH_HASH_FN_TYPE)lh_strhash:h); 127 ret->hash = ((h == NULL) ? (LHASH_HASH_FN_TYPE)lh_strhash : h);
127 ret->num_nodes=MIN_NODES/2; 128 ret->num_nodes = MIN_NODES / 2;
128 ret->num_alloc_nodes=MIN_NODES; 129 ret->num_alloc_nodes = MIN_NODES;
129 ret->p=0; 130 ret->p = 0;
130 ret->pmax=MIN_NODES/2; 131 ret->pmax = MIN_NODES / 2;
131 ret->up_load=UP_LOAD; 132 ret->up_load = UP_LOAD;
132 ret->down_load=DOWN_LOAD; 133 ret->down_load = DOWN_LOAD;
133 ret->num_items=0; 134 ret->num_items = 0;
134 135
135 ret->num_expands=0; 136 ret->num_expands = 0;
136 ret->num_expand_reallocs=0; 137 ret->num_expand_reallocs = 0;
137 ret->num_contracts=0; 138 ret->num_contracts = 0;
138 ret->num_contract_reallocs=0; 139 ret->num_contract_reallocs = 0;
139 ret->num_hash_calls=0; 140 ret->num_hash_calls = 0;
140 ret->num_comp_calls=0; 141 ret->num_comp_calls = 0;
141 ret->num_insert=0; 142 ret->num_insert = 0;
142 ret->num_replace=0; 143 ret->num_replace = 0;
143 ret->num_delete=0; 144 ret->num_delete = 0;
144 ret->num_no_delete=0; 145 ret->num_no_delete = 0;
145 ret->num_retrieve=0; 146 ret->num_retrieve = 0;
146 ret->num_retrieve_miss=0; 147 ret->num_retrieve_miss = 0;
147 ret->num_hash_comps=0; 148 ret->num_hash_comps = 0;
148 149
149 ret->error=0; 150 ret->error = 0;
150 return(ret); 151 return (ret);
152
151err1: 153err1:
152 free(ret); 154 free(ret);
153err0: 155err0:
154 return(NULL); 156 return (NULL);
155 } 157}
156 158
157void lh_free(_LHASH *lh) 159void
158 { 160lh_free(_LHASH *lh)
161{
159 unsigned int i; 162 unsigned int i;
160 LHASH_NODE *n,*nn; 163 LHASH_NODE *n, *nn;
161 164
162 if (lh == NULL) 165 if (lh == NULL)
163 return; 166 return;
164 167
165 for (i=0; i<lh->num_nodes; i++) 168 for (i = 0; i < lh->num_nodes; i++) {
166 { 169 n = lh->b[i];
167 n=lh->b[i]; 170 while (n != NULL) {
168 while (n != NULL) 171 nn = n->next;
169 {
170 nn=n->next;
171 free(n); 172 free(n);
172 n=nn; 173 n = nn;
173 }
174 } 174 }
175 }
175 free(lh->b); 176 free(lh->b);
176 free(lh); 177 free(lh);
177 } 178}
178 179
179void *lh_insert(_LHASH *lh, void *data) 180void *
180 { 181lh_insert(_LHASH *lh, void *data)
182{
181 unsigned long hash; 183 unsigned long hash;
182 LHASH_NODE *nn,**rn; 184 LHASH_NODE *nn, **rn;
183 void *ret; 185 void *ret;
184 186
185 lh->error=0; 187 lh->error = 0;
186 if (lh->up_load <= (lh->num_items*LH_LOAD_MULT/lh->num_nodes)) 188 if (lh->up_load <= (lh->num_items * LH_LOAD_MULT / lh->num_nodes))
187 expand(lh); 189 expand(lh);
188 190
189 rn=getrn(lh,data,&hash); 191 rn = getrn(lh, data, &hash);
190 192
191 if (*rn == NULL) 193 if (*rn == NULL) {
192 { 194 if ((nn = (LHASH_NODE *)malloc(sizeof(LHASH_NODE))) == NULL) {
193 if ((nn=(LHASH_NODE *)malloc(sizeof(LHASH_NODE))) == NULL)
194 {
195 lh->error++; 195 lh->error++;
196 return(NULL); 196 return (NULL);
197 } 197 }
198 nn->data=data; 198 nn->data = data;
199 nn->next=NULL; 199 nn->next = NULL;
200#ifndef OPENSSL_NO_HASH_COMP 200#ifndef OPENSSL_NO_HASH_COMP
201 nn->hash=hash; 201 nn->hash = hash;
202#endif 202#endif
203 *rn=nn; 203 *rn = nn;
204 ret=NULL; 204 ret = NULL;
205 lh->num_insert++; 205 lh->num_insert++;
206 lh->num_items++; 206 lh->num_items++;
207 } 207 }
208 else /* replace same key */ 208 else /* replace same key */
209 { 209 {
210 ret= (*rn)->data; 210 ret = (*rn)->data;
211 (*rn)->data=data; 211 (*rn)->data = data;
212 lh->num_replace++; 212 lh->num_replace++;
213 }
214 return(ret);
215 } 213 }
214 return (ret);
215}
216 216
217void *lh_delete(_LHASH *lh, const void *data) 217void *
218 { 218lh_delete(_LHASH *lh, const void *data)
219{
219 unsigned long hash; 220 unsigned long hash;
220 LHASH_NODE *nn,**rn; 221 LHASH_NODE *nn, **rn;
221 void *ret; 222 void *ret;
222 223
223 lh->error=0; 224 lh->error = 0;
224 rn=getrn(lh,data,&hash); 225 rn = getrn(lh, data, &hash);
225 226
226 if (*rn == NULL) 227 if (*rn == NULL) {
227 {
228 lh->num_no_delete++; 228 lh->num_no_delete++;
229 return(NULL); 229 return (NULL);
230 } 230 } else {
231 else
232 {
233 nn= *rn; 231 nn= *rn;
234 *rn=nn->next; 232 *rn = nn->next;
235 ret=nn->data; 233 ret = nn->data;
236 free(nn); 234 free(nn);
237 lh->num_delete++; 235 lh->num_delete++;
238 } 236 }
239 237
240 lh->num_items--; 238 lh->num_items--;
241 if ((lh->num_nodes > MIN_NODES) && 239 if ((lh->num_nodes > MIN_NODES) &&
242 (lh->down_load >= (lh->num_items*LH_LOAD_MULT/lh->num_nodes))) 240 (lh->down_load >= (lh->num_items * LH_LOAD_MULT / lh->num_nodes)))
243 contract(lh); 241 contract(lh);
244 242
245 return(ret); 243 return (ret);
246 } 244}
247 245
248void *lh_retrieve(_LHASH *lh, const void *data) 246void *
249 { 247lh_retrieve(_LHASH *lh, const void *data)
248{
250 unsigned long hash; 249 unsigned long hash;
251 LHASH_NODE **rn; 250 LHASH_NODE **rn;
252 void *ret; 251 void *ret;
253 252
254 lh->error=0; 253 lh->error = 0;
255 rn=getrn(lh,data,&hash); 254 rn = getrn(lh, data, &hash);
256 255
257 if (*rn == NULL) 256 if (*rn == NULL) {
258 {
259 lh->num_retrieve_miss++; 257 lh->num_retrieve_miss++;
260 return(NULL); 258 return (NULL);
261 } 259 } else {
262 else 260 ret = (*rn)->data;
263 {
264 ret= (*rn)->data;
265 lh->num_retrieve++; 261 lh->num_retrieve++;
266 }
267 return(ret);
268 } 262 }
263 return (ret);
264}
269 265
270static void doall_util_fn(_LHASH *lh, int use_arg, LHASH_DOALL_FN_TYPE func, 266static void
271 LHASH_DOALL_ARG_FN_TYPE func_arg, void *arg) 267doall_util_fn(_LHASH *lh, int use_arg, LHASH_DOALL_FN_TYPE func,
272 { 268 LHASH_DOALL_ARG_FN_TYPE func_arg, void *arg)
269{
273 int i; 270 int i;
274 LHASH_NODE *a,*n; 271 LHASH_NODE *a, *n;
275 272
276 if (lh == NULL) 273 if (lh == NULL)
277 return; 274 return;
278 275
279 /* reverse the order so we search from 'top to bottom' 276 /* reverse the order so we search from 'top to bottom'
280 * We were having memory leaks otherwise */ 277 * We were having memory leaks otherwise */
281 for (i=lh->num_nodes-1; i>=0; i--) 278 for (i = lh->num_nodes - 1; i >= 0; i--) {
282 { 279 a = lh->b[i];
283 a=lh->b[i]; 280 while (a != NULL) {
284 while (a != NULL)
285 {
286 /* 28/05/91 - eay - n added so items can be deleted 281 /* 28/05/91 - eay - n added so items can be deleted
287 * via lh_doall */ 282 * via lh_doall */
288 /* 22/05/08 - ben - eh? since a is not passed, 283 /* 22/05/08 - ben - eh? since a is not passed,
289 * this should not be needed */ 284 * this should not be needed */
290 n=a->next; 285 n = a->next;
291 if(use_arg) 286 if (use_arg)
292 func_arg(a->data,arg); 287 func_arg(a->data, arg);
293 else 288 else
294 func(a->data); 289 func(a->data);
295 a=n; 290 a = n;
296 }
297 } 291 }
298 } 292 }
293}
299 294
300void lh_doall(_LHASH *lh, LHASH_DOALL_FN_TYPE func) 295void
301 { 296lh_doall(_LHASH *lh, LHASH_DOALL_FN_TYPE func)
297{
302 doall_util_fn(lh, 0, func, (LHASH_DOALL_ARG_FN_TYPE)0, NULL); 298 doall_util_fn(lh, 0, func, (LHASH_DOALL_ARG_FN_TYPE)0, NULL);
303 } 299}
304 300
305void lh_doall_arg(_LHASH *lh, LHASH_DOALL_ARG_FN_TYPE func, void *arg) 301void
306 { 302lh_doall_arg(_LHASH *lh, LHASH_DOALL_ARG_FN_TYPE func, void *arg)
303{
307 doall_util_fn(lh, 1, (LHASH_DOALL_FN_TYPE)0, func, arg); 304 doall_util_fn(lh, 1, (LHASH_DOALL_FN_TYPE)0, func, arg);
308 } 305}
309 306
310static void expand(_LHASH *lh) 307static void
311 { 308expand(_LHASH *lh)
312 LHASH_NODE **n,**n1,**n2,*np; 309{
313 unsigned int p,i,j; 310 LHASH_NODE **n, **n1, **n2, *np;
314 unsigned long hash,nni; 311 unsigned int p, i, j;
312 unsigned long hash, nni;
315 313
316 lh->num_nodes++; 314 lh->num_nodes++;
317 lh->num_expands++; 315 lh->num_expands++;
318 p=(int)lh->p++; 316 p = (int)lh->p++;
319 n1= &(lh->b[p]); 317 n1 = &(lh->b[p]);
320 n2= &(lh->b[p+(int)lh->pmax]); 318 n2 = &(lh->b[p + (int)lh->pmax]);
321 *n2=NULL; /* 27/07/92 - eay - undefined pointer bug */ 319 *n2 = NULL; /* 27/07/92 - eay - undefined pointer bug */
322 nni=lh->num_alloc_nodes; 320 nni = lh->num_alloc_nodes;
323 321
324 for (np= *n1; np != NULL; ) 322 for (np = *n1; np != NULL; ) {
325 {
326#ifndef OPENSSL_NO_HASH_COMP 323#ifndef OPENSSL_NO_HASH_COMP
327 hash=np->hash; 324 hash = np->hash;
328#else 325#else
329 hash=lh->hash(np->data); 326 hash = lh->hash(np->data);
330 lh->num_hash_calls++; 327 lh->num_hash_calls++;
331#endif 328#endif
332 if ((hash%nni) != p) 329 if ((hash % nni) != p) { /* move it */
333 { /* move it */ 330 *n1 = (*n1)->next;
334 *n1= (*n1)->next;
335 np->next= *n2; 331 np->next= *n2;
336 *n2=np; 332 *n2 = np;
337 } 333 } else
338 else 334 n1 = &((*n1)->next);
339 n1= &((*n1)->next);
340 np= *n1; 335 np= *n1;
341 } 336 }
342 337
343 if ((lh->p) >= lh->pmax) 338 if ((lh->p) >= lh->pmax) {
344 { 339 j = (int)lh->num_alloc_nodes * 2;
345 j=(int)lh->num_alloc_nodes*2; 340 n = (LHASH_NODE **)realloc(lh->b,
346 n=(LHASH_NODE **)realloc(lh->b, 341 (int)(sizeof(LHASH_NODE *) * j));
347 (int)(sizeof(LHASH_NODE *)*j)); 342 if (n == NULL) {
348 if (n == NULL) 343/* fputs("realloc error in lhash", stderr); */
349 {
350/* fputs("realloc error in lhash",stderr); */
351 lh->error++; 344 lh->error++;
352 lh->p=0; 345 lh->p = 0;
353 return; 346 return;
354 } 347 }
355 /* else */ 348 /* else */
356 for (i=(int)lh->num_alloc_nodes; i<j; i++)/* 26/02/92 eay */ 349 for (i = (int)lh->num_alloc_nodes; i < j; i++)/* 26/02/92 eay */
357 n[i]=NULL; /* 02/03/92 eay */ 350 n[i] = NULL; /* 02/03/92 eay */
358 lh->pmax=lh->num_alloc_nodes; 351 lh->pmax = lh->num_alloc_nodes;
359 lh->num_alloc_nodes=j; 352 lh->num_alloc_nodes = j;
360 lh->num_expand_reallocs++; 353 lh->num_expand_reallocs++;
361 lh->p=0; 354 lh->p = 0;
362 lh->b=n; 355 lh->b = n;
363 }
364 } 356 }
365 357}
366static void contract(_LHASH *lh) 358
367 { 359static void
368 LHASH_NODE **n,*n1,*np; 360contract(_LHASH *lh)
369 361{
370 np=lh->b[lh->p+lh->pmax-1]; 362 LHASH_NODE **n, *n1, *np;
371 lh->b[lh->p+lh->pmax-1]=NULL; /* 24/07-92 - eay - weird but :-( */ 363
372 if (lh->p == 0) 364 np = lh->b[lh->p + lh->pmax - 1];
373 { 365 lh->b[lh->p+lh->pmax - 1] = NULL; /* 24/07-92 - eay - weird but :-( */
374 n=(LHASH_NODE **)realloc(lh->b, 366 if (lh->p == 0) {
375 (unsigned int)(sizeof(LHASH_NODE *)*lh->pmax)); 367 n = (LHASH_NODE **)realloc(lh->b,
376 if (n == NULL) 368 (unsigned int)(sizeof(LHASH_NODE *) * lh->pmax));
377 { 369 if (n == NULL) {
378/* fputs("realloc error in lhash",stderr); */ 370/* fputs("realloc error in lhash", stderr); */
379 lh->error++; 371 lh->error++;
380 return; 372 return;
381 }
382 lh->num_contract_reallocs++;
383 lh->num_alloc_nodes/=2;
384 lh->pmax/=2;
385 lh->p=lh->pmax-1;
386 lh->b=n;
387 } 373 }
388 else 374 lh->num_contract_reallocs++;
375 lh->num_alloc_nodes /= 2;
376 lh->pmax /= 2;
377 lh->p = lh->pmax - 1;
378 lh->b = n;
379 } else
389 lh->p--; 380 lh->p--;
390 381
391 lh->num_nodes--; 382 lh->num_nodes--;
392 lh->num_contracts++; 383 lh->num_contracts++;
393 384
394 n1=lh->b[(int)lh->p]; 385 n1 = lh->b[(int)lh->p];
395 if (n1 == NULL) 386 if (n1 == NULL)
396 lh->b[(int)lh->p]=np; 387 lh->b[(int)lh->p] = np;
397 else 388 else {
398 {
399 while (n1->next != NULL) 389 while (n1->next != NULL)
400 n1=n1->next; 390 n1 = n1->next;
401 n1->next=np; 391 n1->next = np;
402 }
403 } 392 }
393}
404 394
405static LHASH_NODE **getrn(_LHASH *lh, const void *data, unsigned long *rhash) 395static LHASH_NODE **getrn(_LHASH *lh, const void *data, unsigned long *rhash)
406 { 396{
407 LHASH_NODE **ret,*n1; 397 LHASH_NODE **ret, *n1;
408 unsigned long hash,nn; 398 unsigned long hash, nn;
409 LHASH_COMP_FN_TYPE cf; 399 LHASH_COMP_FN_TYPE cf;
410 400
411 hash=(*(lh->hash))(data); 401 hash = (*(lh->hash))(data);
412 lh->num_hash_calls++; 402 lh->num_hash_calls++;
413 *rhash=hash; 403 *rhash = hash;
414 404
415 nn=hash%lh->pmax; 405 nn = hash % lh->pmax;
416 if (nn < lh->p) 406 if (nn < lh->p)
417 nn=hash%lh->num_alloc_nodes; 407 nn = hash % lh->num_alloc_nodes;
418 408
419 cf=lh->comp; 409 cf = lh->comp;
420 ret= &(lh->b[(int)nn]); 410 ret = &(lh->b[(int)nn]);
421 for (n1= *ret; n1 != NULL; n1=n1->next) 411 for (n1 = *ret; n1 != NULL; n1 = n1->next) {
422 {
423#ifndef OPENSSL_NO_HASH_COMP 412#ifndef OPENSSL_NO_HASH_COMP
424 lh->num_hash_comps++; 413 lh->num_hash_comps++;
425 if (n1->hash != hash) 414 if (n1->hash != hash) {
426 { 415 ret = &(n1->next);
427 ret= &(n1->next);
428 continue; 416 continue;
429 } 417 }
430#endif 418#endif
431 lh->num_comp_calls++; 419 lh->num_comp_calls++;
432 if(cf(n1->data,data) == 0) 420 if (cf(n1->data, data) == 0)
433 break; 421 break;
434 ret= &(n1->next); 422 ret = &(n1->next);
435 }
436 return(ret);
437 } 423 }
424 return (ret);
425}
438 426
439/* The following hash seems to work very well on normal text strings 427/* The following hash seems to work very well on normal text strings
440 * no collisions on /usr/dict/words and it distributes on %2^n quite 428 * no collisions on /usr/dict/words and it distributes on %2^n quite
441 * well, not as good as MD5, but still good. 429 * well, not as good as MD5, but still good.
442 */ 430 */
443unsigned long lh_strhash(const char *c) 431unsigned long
444 { 432lh_strhash(const char *c)
445 unsigned long ret=0; 433{
434 unsigned long ret = 0;
446 long n; 435 long n;
447 unsigned long v; 436 unsigned long v;
448 int r; 437 int r;
449 438
450 if ((c == NULL) || (*c == '\0')) 439 if ((c == NULL) || (*c == '\0'))
451 return(ret); 440 return (ret);
452/* 441/*
453 unsigned char b[16]; 442 unsigned char b[16];
454 MD5(c,strlen(c),b); 443 MD5(c,strlen(c),b);
455 return(b[0]|(b[1]<<8)|(b[2]<<16)|(b[3]<<24)); 444 return(b[0]|(b[1]<<8)|(b[2]<<16)|(b[3]<<24));
456*/ 445*/
457 446
458 n=0x100; 447 n = 0x100;
459 while (*c) 448 while (*c) {
460 { 449 v = n | (*c);
461 v=n|(*c); 450 n += 0x100;
462 n+=0x100; 451 r = (int)((v >> 2) ^ v) & 0x0f;
463 r= (int)((v>>2)^v)&0x0f; 452 ret = (ret << r)|(ret >> (32 - r));
464 ret=(ret<<r)|(ret>>(32-r)); 453 ret &= 0xFFFFFFFFL;
465 ret&=0xFFFFFFFFL; 454 ret ^= v * v;
466 ret^=v*v;
467 c++; 455 c++;
468 }
469 return((ret>>16)^ret);
470 } 456 }
457 return ((ret >> 16) ^ ret);
458}
471 459
472unsigned long lh_num_items(const _LHASH *lh) 460unsigned long
473 { 461lh_num_items(const _LHASH *lh)
462{
474 return lh ? lh->num_items : 0; 463 return lh ? lh->num_items : 0;
475 } 464}