| OLD | NEW |
| 1 /* crypto/lhash/lhash.c */ | 1 /* crypto/lhash/lhash.c */ |
| 2 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
| 3 * All rights reserved. | 3 * All rights reserved. |
| 4 * | 4 * |
| 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 |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 100 #include <openssl/crypto.h> | 100 #include <openssl/crypto.h> |
| 101 #include <openssl/lhash.h> | 101 #include <openssl/lhash.h> |
| 102 | 102 |
| 103 const char lh_version[]="lhash" OPENSSL_VERSION_PTEXT; | 103 const 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) */ |
| 109 | 109 |
| 110 static void expand(LHASH *lh); | 110 static void expand(_LHASH *lh); |
| 111 static void contract(LHASH *lh); | 111 static void contract(_LHASH *lh); |
| 112 static LHASH_NODE **getrn(LHASH *lh, const void *data, unsigned long *rhash); | 112 static 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 *lh_new(LHASH_HASH_FN_TYPE h, LHASH_COMP_FN_TYPE c) |
| 115 { | 115 { |
| 116 » LHASH *ret; | 116 » _LHASH *ret; |
| 117 int i; | 117 int i; |
| 118 | 118 |
| 119 » if ((ret=(LHASH *)OPENSSL_malloc(sizeof(LHASH))) == NULL) | 119 » if ((ret=OPENSSL_malloc(sizeof(_LHASH))) == NULL) |
| 120 goto err0; | 120 goto err0; |
| 121 » if ((ret->b=(LHASH_NODE **)OPENSSL_malloc(sizeof(LHASH_NODE *)*MIN_NODES
)) == NULL) | 121 » if ((ret->b=OPENSSL_malloc(sizeof(LHASH_NODE *)*MIN_NODES)) == NULL) |
| 122 goto err1; | 122 goto err1; |
| 123 for (i=0; i<MIN_NODES; i++) | 123 for (i=0; i<MIN_NODES; i++) |
| 124 ret->b[i]=NULL; | 124 ret->b[i]=NULL; |
| 125 ret->comp=((c == NULL)?(LHASH_COMP_FN_TYPE)strcmp:c); | 125 ret->comp=((c == NULL)?(LHASH_COMP_FN_TYPE)strcmp:c); |
| 126 ret->hash=((h == NULL)?(LHASH_HASH_FN_TYPE)lh_strhash:h); | 126 ret->hash=((h == NULL)?(LHASH_HASH_FN_TYPE)lh_strhash:h); |
| 127 ret->num_nodes=MIN_NODES/2; | 127 ret->num_nodes=MIN_NODES/2; |
| 128 ret->num_alloc_nodes=MIN_NODES; | 128 ret->num_alloc_nodes=MIN_NODES; |
| 129 ret->p=0; | 129 ret->p=0; |
| 130 ret->pmax=MIN_NODES/2; | 130 ret->pmax=MIN_NODES/2; |
| 131 ret->up_load=UP_LOAD; | 131 ret->up_load=UP_LOAD; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 147 ret->num_hash_comps=0; | 147 ret->num_hash_comps=0; |
| 148 | 148 |
| 149 ret->error=0; | 149 ret->error=0; |
| 150 return(ret); | 150 return(ret); |
| 151 err1: | 151 err1: |
| 152 OPENSSL_free(ret); | 152 OPENSSL_free(ret); |
| 153 err0: | 153 err0: |
| 154 return(NULL); | 154 return(NULL); |
| 155 } | 155 } |
| 156 | 156 |
| 157 void lh_free(LHASH *lh) | 157 void lh_free(_LHASH *lh) |
| 158 { | 158 { |
| 159 unsigned int i; | 159 unsigned int i; |
| 160 LHASH_NODE *n,*nn; | 160 LHASH_NODE *n,*nn; |
| 161 | 161 |
| 162 if (lh == NULL) | 162 if (lh == NULL) |
| 163 return; | 163 return; |
| 164 | 164 |
| 165 for (i=0; i<lh->num_nodes; i++) | 165 for (i=0; i<lh->num_nodes; i++) |
| 166 { | 166 { |
| 167 n=lh->b[i]; | 167 n=lh->b[i]; |
| 168 while (n != NULL) | 168 while (n != NULL) |
| 169 { | 169 { |
| 170 nn=n->next; | 170 nn=n->next; |
| 171 OPENSSL_free(n); | 171 OPENSSL_free(n); |
| 172 n=nn; | 172 n=nn; |
| 173 } | 173 } |
| 174 } | 174 } |
| 175 OPENSSL_free(lh->b); | 175 OPENSSL_free(lh->b); |
| 176 OPENSSL_free(lh); | 176 OPENSSL_free(lh); |
| 177 } | 177 } |
| 178 | 178 |
| 179 void *lh_insert(LHASH *lh, void *data) | 179 void *lh_insert(_LHASH *lh, void *data) |
| 180 { | 180 { |
| 181 unsigned long hash; | 181 unsigned long hash; |
| 182 LHASH_NODE *nn,**rn; | 182 LHASH_NODE *nn,**rn; |
| 183 void *ret; | 183 void *ret; |
| 184 | 184 |
| 185 lh->error=0; | 185 lh->error=0; |
| 186 if (lh->up_load <= (lh->num_items*LH_LOAD_MULT/lh->num_nodes)) | 186 if (lh->up_load <= (lh->num_items*LH_LOAD_MULT/lh->num_nodes)) |
| 187 expand(lh); | 187 expand(lh); |
| 188 | 188 |
| 189 rn=getrn(lh,data,&hash); | 189 rn=getrn(lh,data,&hash); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 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 } | 213 } |
| 214 return(ret); | 214 return(ret); |
| 215 } | 215 } |
| 216 | 216 |
| 217 void *lh_delete(LHASH *lh, const void *data) | 217 void *lh_delete(_LHASH *lh, const void *data) |
| 218 { | 218 { |
| 219 unsigned long hash; | 219 unsigned long hash; |
| 220 LHASH_NODE *nn,**rn; | 220 LHASH_NODE *nn,**rn; |
| 221 void *ret; | 221 void *ret; |
| 222 | 222 |
| 223 lh->error=0; | 223 lh->error=0; |
| 224 rn=getrn(lh,data,&hash); | 224 rn=getrn(lh,data,&hash); |
| 225 | 225 |
| 226 if (*rn == NULL) | 226 if (*rn == NULL) |
| 227 { | 227 { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 238 } | 238 } |
| 239 | 239 |
| 240 lh->num_items--; | 240 lh->num_items--; |
| 241 if ((lh->num_nodes > MIN_NODES) && | 241 if ((lh->num_nodes > MIN_NODES) && |
| 242 (lh->down_load >= (lh->num_items*LH_LOAD_MULT/lh->num_nodes))) | 242 (lh->down_load >= (lh->num_items*LH_LOAD_MULT/lh->num_nodes))) |
| 243 contract(lh); | 243 contract(lh); |
| 244 | 244 |
| 245 return(ret); | 245 return(ret); |
| 246 } | 246 } |
| 247 | 247 |
| 248 void *lh_retrieve(LHASH *lh, const void *data) | 248 void *lh_retrieve(_LHASH *lh, const void *data) |
| 249 { | 249 { |
| 250 unsigned long hash; | 250 unsigned long hash; |
| 251 LHASH_NODE **rn; | 251 LHASH_NODE **rn; |
| 252 void *ret; | 252 void *ret; |
| 253 | 253 |
| 254 lh->error=0; | 254 lh->error=0; |
| 255 rn=getrn(lh,data,&hash); | 255 rn=getrn(lh,data,&hash); |
| 256 | 256 |
| 257 if (*rn == NULL) | 257 if (*rn == NULL) |
| 258 { | 258 { |
| 259 lh->num_retrieve_miss++; | 259 lh->num_retrieve_miss++; |
| 260 return(NULL); | 260 return(NULL); |
| 261 } | 261 } |
| 262 else | 262 else |
| 263 { | 263 { |
| 264 ret= (*rn)->data; | 264 ret= (*rn)->data; |
| 265 lh->num_retrieve++; | 265 lh->num_retrieve++; |
| 266 } | 266 } |
| 267 return(ret); | 267 return(ret); |
| 268 } | 268 } |
| 269 | 269 |
| 270 static void doall_util_fn(LHASH *lh, int use_arg, LHASH_DOALL_FN_TYPE func, | 270 static void doall_util_fn(_LHASH *lh, int use_arg, LHASH_DOALL_FN_TYPE func, |
| 271 LHASH_DOALL_ARG_FN_TYPE func_arg, void *arg) | 271 LHASH_DOALL_ARG_FN_TYPE func_arg, void *arg) |
| 272 { | 272 { |
| 273 int i; | 273 int i; |
| 274 LHASH_NODE *a,*n; | 274 LHASH_NODE *a,*n; |
| 275 | 275 |
| 276 if (lh == NULL) |
| 277 return; |
| 278 |
| 276 /* reverse the order so we search from 'top to bottom' | 279 /* reverse the order so we search from 'top to bottom' |
| 277 * We were having memory leaks otherwise */ | 280 * We were having memory leaks otherwise */ |
| 278 for (i=lh->num_nodes-1; i>=0; i--) | 281 for (i=lh->num_nodes-1; i>=0; i--) |
| 279 { | 282 { |
| 280 a=lh->b[i]; | 283 a=lh->b[i]; |
| 281 while (a != NULL) | 284 while (a != NULL) |
| 282 { | 285 { |
| 283 /* 28/05/91 - eay - n added so items can be deleted | 286 /* 28/05/91 - eay - n added so items can be deleted |
| 284 * via lh_doall */ | 287 * via lh_doall */ |
| 288 /* 22/05/08 - ben - eh? since a is not passed, |
| 289 * this should not be needed */ |
| 285 n=a->next; | 290 n=a->next; |
| 286 if(use_arg) | 291 if(use_arg) |
| 287 func_arg(a->data,arg); | 292 func_arg(a->data,arg); |
| 288 else | 293 else |
| 289 func(a->data); | 294 func(a->data); |
| 290 a=n; | 295 a=n; |
| 291 } | 296 } |
| 292 } | 297 } |
| 293 } | 298 } |
| 294 | 299 |
| 295 void lh_doall(LHASH *lh, LHASH_DOALL_FN_TYPE func) | 300 void lh_doall(_LHASH *lh, LHASH_DOALL_FN_TYPE func) |
| 296 { | 301 { |
| 297 doall_util_fn(lh, 0, func, (LHASH_DOALL_ARG_FN_TYPE)0, NULL); | 302 doall_util_fn(lh, 0, func, (LHASH_DOALL_ARG_FN_TYPE)0, NULL); |
| 298 } | 303 } |
| 299 | 304 |
| 300 void lh_doall_arg(LHASH *lh, LHASH_DOALL_ARG_FN_TYPE func, void *arg) | 305 void lh_doall_arg(_LHASH *lh, LHASH_DOALL_ARG_FN_TYPE func, void *arg) |
| 301 { | 306 { |
| 302 doall_util_fn(lh, 1, (LHASH_DOALL_FN_TYPE)0, func, arg); | 307 doall_util_fn(lh, 1, (LHASH_DOALL_FN_TYPE)0, func, arg); |
| 303 } | 308 } |
| 304 | 309 |
| 305 static void expand(LHASH *lh) | 310 static void expand(_LHASH *lh) |
| 306 { | 311 { |
| 307 LHASH_NODE **n,**n1,**n2,*np; | 312 LHASH_NODE **n,**n1,**n2,*np; |
| 308 » unsigned int p,i,j,pmax; | 313 » unsigned int p,i,j; |
| 309 unsigned long hash,nni; | 314 unsigned long hash,nni; |
| 310 | 315 |
| 311 p=(int)lh->p++; | |
| 312 nni=lh->num_alloc_nodes; | |
| 313 pmax=lh->pmax; | |
| 314 | |
| 315 if ((lh->p) >= lh->pmax) | |
| 316 { | |
| 317 j=(int)lh->num_alloc_nodes*2; | |
| 318 n=(LHASH_NODE **)OPENSSL_realloc(lh->b, | |
| 319 (int)sizeof(LHASH_NODE *)*j); | |
| 320 if (n == NULL) | |
| 321 { | |
| 322 /* fputs("realloc error in lhash",stderr); */ | |
| 323 lh->error++; | |
| 324 lh->p=0; | |
| 325 return; | |
| 326 } | |
| 327 /* else */ | |
| 328 for (i=(int)lh->num_alloc_nodes; i<j; i++)/* 26/02/92 eay */ | |
| 329 n[i]=NULL; /* 02/03/92 eay */ | |
| 330 lh->pmax=lh->num_alloc_nodes; | |
| 331 lh->num_alloc_nodes=j; | |
| 332 lh->num_expand_reallocs++; | |
| 333 lh->p=0; | |
| 334 lh->b=n; | |
| 335 } | |
| 336 | |
| 337 lh->num_nodes++; | 316 lh->num_nodes++; |
| 338 lh->num_expands++; | 317 lh->num_expands++; |
| 318 p=(int)lh->p++; |
| 339 n1= &(lh->b[p]); | 319 n1= &(lh->b[p]); |
| 340 » n2= &(lh->b[p+pmax]); | 320 » n2= &(lh->b[p+(int)lh->pmax]); |
| 341 *n2=NULL; /* 27/07/92 - eay - undefined pointer bug */ | 321 *n2=NULL; /* 27/07/92 - eay - undefined pointer bug */ |
| 322 nni=lh->num_alloc_nodes; |
| 342 | 323 |
| 343 for (np= *n1; np != NULL; ) | 324 for (np= *n1; np != NULL; ) |
| 344 { | 325 { |
| 345 #ifndef OPENSSL_NO_HASH_COMP | 326 #ifndef OPENSSL_NO_HASH_COMP |
| 346 hash=np->hash; | 327 hash=np->hash; |
| 347 #else | 328 #else |
| 348 hash=lh->hash(np->data); | 329 hash=lh->hash(np->data); |
| 349 lh->num_hash_calls++; | 330 lh->num_hash_calls++; |
| 350 #endif | 331 #endif |
| 351 if ((hash%nni) != p) | 332 if ((hash%nni) != p) |
| 352 { /* move it */ | 333 { /* move it */ |
| 353 *n1= (*n1)->next; | 334 *n1= (*n1)->next; |
| 354 np->next= *n2; | 335 np->next= *n2; |
| 355 *n2=np; | 336 *n2=np; |
| 356 } | 337 } |
| 357 else | 338 else |
| 358 n1= &((*n1)->next); | 339 n1= &((*n1)->next); |
| 359 np= *n1; | 340 np= *n1; |
| 360 } | 341 } |
| 361 | 342 |
| 343 if ((lh->p) >= lh->pmax) |
| 344 { |
| 345 j=(int)lh->num_alloc_nodes*2; |
| 346 n=(LHASH_NODE **)OPENSSL_realloc(lh->b, |
| 347 (int)(sizeof(LHASH_NODE *)*j)); |
| 348 if (n == NULL) |
| 349 { |
| 350 /* fputs("realloc error in lhash",stderr); */ |
| 351 lh->error++; |
| 352 lh->p=0; |
| 353 return; |
| 354 } |
| 355 /* else */ |
| 356 for (i=(int)lh->num_alloc_nodes; i<j; i++)/* 26/02/92 eay */ |
| 357 n[i]=NULL; /* 02/03/92 eay */ |
| 358 lh->pmax=lh->num_alloc_nodes; |
| 359 lh->num_alloc_nodes=j; |
| 360 lh->num_expand_reallocs++; |
| 361 lh->p=0; |
| 362 lh->b=n; |
| 363 } |
| 362 } | 364 } |
| 363 | 365 |
| 364 static void contract(LHASH *lh) | 366 static void contract(_LHASH *lh) |
| 365 { | 367 { |
| 366 LHASH_NODE **n,*n1,*np; | 368 LHASH_NODE **n,*n1,*np; |
| 367 int idx = lh->p+lh->pmax-1; | |
| 368 | 369 |
| 369 » np=lh->b[idx]; | 370 » np=lh->b[lh->p+lh->pmax-1]; |
| 371 » lh->b[lh->p+lh->pmax-1]=NULL; /* 24/07-92 - eay - weird but :-( */ |
| 370 if (lh->p == 0) | 372 if (lh->p == 0) |
| 371 { | 373 { |
| 372 n=(LHASH_NODE **)OPENSSL_realloc(lh->b, | 374 n=(LHASH_NODE **)OPENSSL_realloc(lh->b, |
| 373 (unsigned int)(sizeof(LHASH_NODE *)*lh->pmax)); | 375 (unsigned int)(sizeof(LHASH_NODE *)*lh->pmax)); |
| 374 if (n == NULL) | 376 if (n == NULL) |
| 375 { | 377 { |
| 376 /* fputs("realloc error in lhash",stderr); */ | 378 /* fputs("realloc error in lhash",stderr); */ |
| 377 lh->error++; | 379 lh->error++; |
| 378 return; | 380 return; |
| 379 } | 381 } |
| 380 lh->num_contract_reallocs++; | 382 lh->num_contract_reallocs++; |
| 381 lh->num_alloc_nodes/=2; | 383 lh->num_alloc_nodes/=2; |
| 382 lh->pmax/=2; | 384 lh->pmax/=2; |
| 383 lh->p=lh->pmax-1; | 385 lh->p=lh->pmax-1; |
| 384 lh->b=n; | 386 lh->b=n; |
| 385 } | 387 } |
| 386 else | 388 else |
| 387 lh->p--; | 389 lh->p--; |
| 388 | 390 |
| 389 lh->b[idx] = NULL; | |
| 390 lh->num_nodes--; | 391 lh->num_nodes--; |
| 391 lh->num_contracts++; | 392 lh->num_contracts++; |
| 392 | 393 |
| 393 n1=lh->b[(int)lh->p]; | 394 n1=lh->b[(int)lh->p]; |
| 394 if (n1 == NULL) | 395 if (n1 == NULL) |
| 395 lh->b[(int)lh->p]=np; | 396 lh->b[(int)lh->p]=np; |
| 396 else | 397 else |
| 397 { | 398 { |
| 398 while (n1->next != NULL) | 399 while (n1->next != NULL) |
| 399 n1=n1->next; | 400 n1=n1->next; |
| 400 n1->next=np; | 401 n1->next=np; |
| 401 } | 402 } |
| 402 } | 403 } |
| 403 | 404 |
| 404 static LHASH_NODE **getrn(LHASH *lh, const void *data, unsigned long *rhash) | 405 static LHASH_NODE **getrn(_LHASH *lh, const void *data, unsigned long *rhash) |
| 405 { | 406 { |
| 406 LHASH_NODE **ret,*n1; | 407 LHASH_NODE **ret,*n1; |
| 407 unsigned long hash,nn; | 408 unsigned long hash,nn; |
| 408 LHASH_COMP_FN_TYPE cf; | 409 LHASH_COMP_FN_TYPE cf; |
| 409 | 410 |
| 410 hash=(*(lh->hash))(data); | 411 hash=(*(lh->hash))(data); |
| 411 lh->num_hash_calls++; | 412 lh->num_hash_calls++; |
| 412 *rhash=hash; | 413 *rhash=hash; |
| 413 | 414 |
| 414 nn=hash%lh->pmax; | 415 nn=hash%lh->pmax; |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 461 n+=0x100; | 462 n+=0x100; |
| 462 r= (int)((v>>2)^v)&0x0f; | 463 r= (int)((v>>2)^v)&0x0f; |
| 463 ret=(ret<<r)|(ret>>(32-r)); | 464 ret=(ret<<r)|(ret>>(32-r)); |
| 464 ret&=0xFFFFFFFFL; | 465 ret&=0xFFFFFFFFL; |
| 465 ret^=v*v; | 466 ret^=v*v; |
| 466 c++; | 467 c++; |
| 467 } | 468 } |
| 468 return((ret>>16)^ret); | 469 return((ret>>16)^ret); |
| 469 } | 470 } |
| 470 | 471 |
| 471 unsigned long lh_num_items(const LHASH *lh) | 472 unsigned long lh_num_items(const _LHASH *lh) |
| 472 { | 473 { |
| 473 return lh ? lh->num_items : 0; | 474 return lh ? lh->num_items : 0; |
| 474 } | 475 } |
| OLD | NEW |