#include <stdio.h>
#include "extra.h"
#include "stmm.h"
Go to the source code of this file.
Defines | |
#define | STMM_NUMCMP(x, y) ((x) != (y)) |
#define | STMM_NUMHASH(x, size) (ABS((long)x)%(size)) |
#define | STMM_PTRHASH(x, size) ((int)(((unsigned long)(x)>>2)%size)) |
#define | EQUAL(func, x, y) |
#define | do_hash(key, table) |
#define | PTR_NOT_EQUAL(table, ptr, user_key) (ptr != NULL && !EQUAL(table->compare, user_key, (ptr)->key)) |
#define | FIND_ENTRY(table, hash_val, key, ptr, last) |
#define | ADD_DIRECT(table, key, value, hash_val, new) |
Functions | |
static int | rehash () |
int | stmm_numhash () |
int | stmm_ptrhash () |
int | stmm_numcmp () |
int | stmm_ptrcmp () |
stmm_table * | stmm_init_table_with_params (int(*)() compare, int(*)() hash, int size, int density, double grow_factor, int reorder_flag) |
stmm_table * | stmm_init_table (int(*)() compare, int(*)() hash) |
void | stmm_free_table (stmm_table *table) |
void | stmm_clean (stmm_table *table) |
int | stmm_lookup (stmm_table *table, char *key, char **value) |
int | stmm_lookup_int (stmm_table *table, char *key, int *value) |
int | stmm_insert (stmm_table *table, char *key, char *value) |
int | stmm_add_direct (stmm_table *table, char *key, char *value) |
int | stmm_find_or_add (stmm_table *table, char *key, char ***slot) |
int | stmm_find (stmm_table *table, char *key, char ***slot) |
static int | rehash (stmm_table *table) |
stmm_table * | stmm_copy (stmm_table *old_table) |
int | stmm_delete (stmm_table *table, char **keyp, char **value) |
int | stmm_delete_int (stmm_table *table, long *keyp, char **value) |
int | stmm_foreach (stmm_table *table, enum stmm_retval(*)() func, char *arg) |
int | stmm_strhash (char *string, int modulus) |
int | stmm_numhash (char *x, int size) |
int | stmm_ptrhash (char *x, int size) |
int | stmm_numcmp (char *x, char *y) |
int | stmm_ptrcmp (char *x, char *y) |
stmm_generator * | stmm_init_gen (stmm_table *table) |
int | stmm_gen (stmm_generator *gen, char **key_p, char **value_p) |
int | stmm_gen_int (stmm_generator *gen, char **key_p, long *value_p) |
void | stmm_free_gen (stmm_generator *gen) |
{\ if (table->num_entries/table->num_bins >= table->max_density) {\ rehash(table);\ hash_val = do_hash(key,table);\ }\ \ new = (stmm_table_entry *)Extra_MmFixedEntryFetch( table->pMemMan );\ \ new->key = key;\ new->record = value;\ new->next = table->bins[hash_val];\ table->bins[hash_val] = new;\ table->num_entries++;\ }
#define do_hash | ( | key, | |||
table | ) |
((table->hash == stmm_ptrhash) ? STMM_PTRHASH((key),(table)->num_bins) :\ (table->hash == stmm_numhash) ? STMM_NUMHASH((key), (table)->num_bins) :\ (*table->hash)((key), (table)->num_bins))
#define EQUAL | ( | func, | |||
x, | |||||
y | ) |
((((func) == stmm_numcmp) || ((func) == stmm_ptrcmp)) ?\ (STMM_NUMCMP((x),(y)) == 0) : ((*func)((x), (y)) == 0))
#define FIND_ENTRY | ( | table, | |||
hash_val, | |||||
key, | |||||
ptr, | |||||
last | ) |
(last) = &(table)->bins[hash_val];\ (ptr) = *(last);\ while (PTR_NOT_EQUAL((table), (ptr), (key))) {\ (last) = &(ptr)->next; (ptr) = *(last);\ }\ if ((ptr) != NULL && (table)->reorder_flag) {\ *(last) = (ptr)->next;\ (ptr)->next = (table)->bins[hash_val];\ (table)->bins[hash_val] = (ptr);\ }
#define PTR_NOT_EQUAL | ( | table, | |||
ptr, | |||||
user_key | ) | (ptr != NULL && !EQUAL(table->compare, user_key, (ptr)->key)) |
static int rehash | ( | stmm_table * | table | ) | [static] |
Definition at line 358 of file stmm.c.
00360 { 00361 register stmm_table_entry *ptr, *next, **old_bins; 00362 int i, old_num_bins, hash_val, old_num_entries; 00363 00364 /* save old values */ 00365 old_bins = table->bins; 00366 old_num_bins = table->num_bins; 00367 old_num_entries = table->num_entries; 00368 00369 /* rehash */ 00370 table->num_bins = (int) (table->grow_factor * old_num_bins); 00371 if (table->num_bins % 2 == 0) { 00372 table->num_bins += 1; 00373 } 00374 table->num_entries = 0; 00375 table->bins = ALLOC (stmm_table_entry *, table->num_bins); 00376 if (table->bins == NULL) { 00377 table->bins = old_bins; 00378 table->num_bins = old_num_bins; 00379 table->num_entries = old_num_entries; 00380 return STMM_OUT_OF_MEM; 00381 } 00382 /* initialize */ 00383 for (i = 0; i < table->num_bins; i++) { 00384 table->bins[i] = 0; 00385 } 00386 00387 /* copy data over */ 00388 for (i = 0; i < old_num_bins; i++) { 00389 ptr = old_bins[i]; 00390 while (ptr != NULL) { 00391 next = ptr->next; 00392 hash_val = do_hash (ptr->key, table); 00393 ptr->next = table->bins[hash_val]; 00394 table->bins[hash_val] = ptr; 00395 table->num_entries++; 00396 ptr = next; 00397 } 00398 } 00399 FREE (old_bins); 00400 00401 return 1; 00402 }
static int rehash | ( | ) | [static] |
int stmm_add_direct | ( | stmm_table * | table, | |
char * | key, | |||
char * | value | |||
) |
Definition at line 259 of file stmm.c.
00263 { 00264 int hash_val; 00265 stmm_table_entry *new; 00266 00267 hash_val = do_hash (key, table); 00268 if (table->num_entries / table->num_bins >= table->max_density) { 00269 if (rehash (table) == STMM_OUT_OF_MEM) { 00270 return STMM_OUT_OF_MEM; 00271 } 00272 } 00273 hash_val = do_hash (key, table); 00274 00275 // new = ALLOC( stmm_table_entry, 1 ); 00276 new = (stmm_table_entry *) Extra_MmFixedEntryFetch (table->pMemMan); 00277 if (new == NULL) { 00278 return STMM_OUT_OF_MEM; 00279 } 00280 00281 new->key = key; 00282 new->record = value; 00283 new->next = table->bins[hash_val]; 00284 table->bins[hash_val] = new; 00285 table->num_entries++; 00286 return 1; 00287 }
void stmm_clean | ( | stmm_table * | table | ) |
Definition at line 116 of file stmm.c.
00118 { 00119 int i; 00120 // clean the bins 00121 for (i = 0; i < table->num_bins; i++) 00122 table->bins[i] = NULL; 00123 // reset the parameters 00124 table->num_entries = 0; 00125 // restart the memory manager 00126 Extra_MmFixedRestart (table->pMemMan); 00127 }
stmm_table* stmm_copy | ( | stmm_table * | old_table | ) |
Definition at line 405 of file stmm.c.
00407 { 00408 stmm_table *new_table; 00409 stmm_table_entry *ptr, /* *newptr, *next, */ *new; 00410 int i, /*j, */ num_bins = old_table->num_bins; 00411 00412 new_table = ALLOC (stmm_table, 1); 00413 if (new_table == NULL) { 00414 return NULL; 00415 } 00416 00417 *new_table = *old_table; 00418 new_table->bins = ALLOC (stmm_table_entry *, num_bins); 00419 if (new_table->bins == NULL) { 00420 FREE (new_table); 00421 return NULL; 00422 } 00423 00424 // allocate the memory manager for the new table 00425 new_table->pMemMan = 00426 Extra_MmFixedStart (sizeof (stmm_table_entry)); 00427 00428 for (i = 0; i < num_bins; i++) { 00429 new_table->bins[i] = NULL; 00430 ptr = old_table->bins[i]; 00431 while (ptr != NULL) { 00432 // new = ALLOC( stmm_table_entry, 1 ); 00433 new = 00434 (stmm_table_entry *) Extra_MmFixedEntryFetch (new_table-> 00435 pMemMan); 00436 00437 if (new == NULL) { 00438 /* 00439 for ( j = 0; j <= i; j++ ) 00440 { 00441 newptr = new_table->bins[j]; 00442 while ( newptr != NULL ) 00443 { 00444 next = newptr->next; 00445 FREE( newptr ); 00446 newptr = next; 00447 } 00448 } 00449 */ 00450 Extra_MmFixedStop (new_table->pMemMan); 00451 00452 FREE (new_table->bins); 00453 FREE (new_table); 00454 return NULL; 00455 } 00456 *new = *ptr; 00457 new->next = new_table->bins[i]; 00458 new_table->bins[i] = new; 00459 ptr = ptr->next; 00460 } 00461 } 00462 return new_table; 00463 }
int stmm_delete | ( | stmm_table * | table, | |
char ** | keyp, | |||
char ** | value | |||
) |
Definition at line 466 of file stmm.c.
00470 { 00471 int hash_val; 00472 char *key = *keyp; 00473 register stmm_table_entry *ptr, **last; 00474 00475 hash_val = do_hash (key, table); 00476 00477 FIND_ENTRY (table, hash_val, key, ptr, last); 00478 00479 if (ptr == NULL) { 00480 return 0; 00481 } 00482 00483 *last = ptr->next; 00484 if (value != NULL) 00485 *value = ptr->record; 00486 *keyp = ptr->key; 00487 // FREE( ptr ); 00488 Extra_MmFixedEntryRecycle (table->pMemMan, (char *) ptr); 00489 00490 table->num_entries--; 00491 return 1; 00492 }
int stmm_delete_int | ( | stmm_table * | table, | |
long * | keyp, | |||
char ** | value | |||
) |
Definition at line 495 of file stmm.c.
00499 { 00500 int hash_val; 00501 char *key = (char *) *keyp; 00502 register stmm_table_entry *ptr, **last; 00503 00504 hash_val = do_hash (key, table); 00505 00506 FIND_ENTRY (table, hash_val, key, ptr, last); 00507 00508 if (ptr == NULL) { 00509 return 0; 00510 } 00511 00512 *last = ptr->next; 00513 if (value != NULL) 00514 *value = ptr->record; 00515 *keyp = (long) ptr->key; 00516 // FREE( ptr ); 00517 Extra_MmFixedEntryRecycle (table->pMemMan, (char *) ptr); 00518 00519 table->num_entries--; 00520 return 1; 00521 }
int stmm_find | ( | stmm_table * | table, | |
char * | key, | |||
char *** | slot | |||
) |
Definition at line 333 of file stmm.c.
00337 { 00338 int hash_val; 00339 stmm_table_entry *ptr, **last; 00340 00341 hash_val = do_hash (key, table); 00342 00343 FIND_ENTRY (table, hash_val, key, ptr, last); 00344 00345 if (ptr == NULL) { 00346 return 0; 00347 } 00348 else { 00349 if (slot != NULL) 00350 { 00351 *slot = &ptr->record; 00352 } 00353 return 1; 00354 } 00355 }
int stmm_find_or_add | ( | stmm_table * | table, | |
char * | key, | |||
char *** | slot | |||
) |
Definition at line 290 of file stmm.c.
00294 { 00295 int hash_val; 00296 stmm_table_entry *new, *ptr, **last; 00297 00298 hash_val = do_hash (key, table); 00299 00300 FIND_ENTRY (table, hash_val, key, ptr, last); 00301 00302 if (ptr == NULL) { 00303 if (table->num_entries / table->num_bins >= table->max_density) { 00304 if (rehash (table) == STMM_OUT_OF_MEM) { 00305 return STMM_OUT_OF_MEM; 00306 } 00307 hash_val = do_hash (key, table); 00308 } 00309 00310 // new = ALLOC( stmm_table_entry, 1 ); 00311 new = (stmm_table_entry *) Extra_MmFixedEntryFetch (table->pMemMan); 00312 if (new == NULL) { 00313 return STMM_OUT_OF_MEM; 00314 } 00315 00316 new->key = key; 00317 new->record = (char *) 0; 00318 new->next = table->bins[hash_val]; 00319 table->bins[hash_val] = new; 00320 table->num_entries++; 00321 if (slot != NULL) 00322 *slot = &new->record; 00323 return 0; 00324 } 00325 else { 00326 if (slot != NULL) 00327 *slot = &ptr->record; 00328 return 1; 00329 } 00330 }
int stmm_foreach | ( | stmm_table * | table, | |
enum stmm_retval (*) () | func, | |||
char * | arg | |||
) |
Definition at line 524 of file stmm.c.
00528 { 00529 stmm_table_entry *ptr, **last; 00530 enum stmm_retval retval; 00531 int i; 00532 00533 for (i = 0; i < table->num_bins; i++) { 00534 last = &table->bins[i]; 00535 ptr = *last; 00536 while (ptr != NULL) { 00537 retval = (*func) (ptr->key, ptr->record, arg); 00538 switch (retval) { 00539 case STMM_CONTINUE: 00540 last = &ptr->next; 00541 ptr = *last; 00542 break; 00543 case STMM_STOP: 00544 return 0; 00545 case STMM_DELETE: 00546 *last = ptr->next; 00547 table->num_entries--; /* cstevens@ic */ 00548 // FREE( ptr ); 00549 Extra_MmFixedEntryRecycle (table->pMemMan, (char *) ptr); 00550 00551 ptr = *last; 00552 } 00553 } 00554 } 00555 return 1; 00556 }
void stmm_free_gen | ( | stmm_generator * | gen | ) |
void stmm_free_table | ( | stmm_table * | table | ) |
Definition at line 89 of file stmm.c.
00091 { 00092 /* 00093 register stmm_table_entry *ptr, *next; 00094 int i; 00095 for ( i = 0; i < table->num_bins; i++ ) 00096 { 00097 ptr = table->bins[i]; 00098 while ( ptr != NULL ) 00099 { 00100 next = ptr->next; 00101 FREE( ptr ); 00102 ptr = next; 00103 } 00104 } 00105 */ 00106 // no need to deallocate entries because they are in the memory manager now 00107 // added by alanmi 00108 if ( table->pMemMan ) 00109 Extra_MmFixedStop (table->pMemMan); 00110 FREE (table->bins); 00111 FREE (table); 00112 }
int stmm_gen | ( | stmm_generator * | gen, | |
char ** | key_p, | |||
char ** | value_p | |||
) |
Definition at line 623 of file stmm.c.
00627 { 00628 register int i; 00629 00630 if (gen->entry == NULL) { 00631 /* try to find next entry */ 00632 for (i = gen->index; i < gen->table->num_bins; i++) { 00633 if (gen->table->bins[i] != NULL) { 00634 gen->index = i + 1; 00635 gen->entry = gen->table->bins[i]; 00636 break; 00637 } 00638 } 00639 if (gen->entry == NULL) { 00640 return 0; /* that's all folks ! */ 00641 } 00642 } 00643 *key_p = gen->entry->key; 00644 if (value_p != 0) { 00645 *value_p = gen->entry->record; 00646 } 00647 gen->entry = gen->entry->next; 00648 return 1; 00649 }
int stmm_gen_int | ( | stmm_generator * | gen, | |
char ** | key_p, | |||
long * | value_p | |||
) |
Definition at line 653 of file stmm.c.
00657 { 00658 register int i; 00659 00660 if (gen->entry == NULL) { 00661 /* try to find next entry */ 00662 for (i = gen->index; i < gen->table->num_bins; i++) { 00663 if (gen->table->bins[i] != NULL) { 00664 gen->index = i + 1; 00665 gen->entry = gen->table->bins[i]; 00666 break; 00667 } 00668 } 00669 if (gen->entry == NULL) { 00670 return 0; /* that's all folks ! */ 00671 } 00672 } 00673 *key_p = gen->entry->key; 00674 if (value_p != 0) 00675 { 00676 *value_p = (long) gen->entry->record; 00677 } 00678 gen->entry = gen->entry->next; 00679 return 1; 00680 }
stmm_generator* stmm_init_gen | ( | stmm_table * | table | ) |
stmm_table* stmm_init_table | ( | int (*) () | compare, | |
int (*) () | hash | |||
) |
Definition at line 77 of file stmm.c.
00080 { 00081 return stmm_init_table_with_params (compare, hash, 00082 STMM_DEFAULT_INIT_TABLE_SIZE, 00083 STMM_DEFAULT_MAX_DENSITY, 00084 STMM_DEFAULT_GROW_FACTOR, 00085 STMM_DEFAULT_REORDER_FLAG); 00086 }
stmm_table* stmm_init_table_with_params | ( | int (*) () | compare, | |
int (*) () | hash, | |||
int | size, | |||
int | density, | |||
double | grow_factor, | |||
int | reorder_flag | |||
) |
Definition at line 36 of file stmm.c.
00044 { 00045 int i; 00046 stmm_table *new; 00047 00048 new = ALLOC (stmm_table, 1); 00049 if (new == NULL) { 00050 return NULL; 00051 } 00052 new->compare = compare; 00053 new->hash = hash; 00054 new->num_entries = 0; 00055 new->max_density = density; 00056 new->grow_factor = grow_factor; 00057 new->reorder_flag = reorder_flag; 00058 if (size <= 0) { 00059 size = 1; 00060 } 00061 new->num_bins = size; 00062 new->bins = ALLOC (stmm_table_entry *, size); 00063 if (new->bins == NULL) { 00064 FREE (new); 00065 return NULL; 00066 } 00067 for (i = 0; i < size; i++) { 00068 new->bins[i] = 0; 00069 } 00070 00071 // added by alanmi 00072 new->pMemMan = Extra_MmFixedStart(sizeof (stmm_table_entry)); 00073 return new; 00074 }
int stmm_insert | ( | stmm_table * | table, | |
char * | key, | |||
char * | value | |||
) |
Definition at line 218 of file stmm.c.
00222 { 00223 int hash_val; 00224 stmm_table_entry *new; 00225 register stmm_table_entry *ptr, **last; 00226 00227 hash_val = do_hash (key, table); 00228 00229 FIND_ENTRY (table, hash_val, key, ptr, last); 00230 00231 if (ptr == NULL) { 00232 if (table->num_entries / table->num_bins >= table->max_density) { 00233 if (rehash (table) == STMM_OUT_OF_MEM) { 00234 return STMM_OUT_OF_MEM; 00235 } 00236 hash_val = do_hash (key, table); 00237 } 00238 00239 // new = ALLOC( stmm_table_entry, 1 ); 00240 new = (stmm_table_entry *) Extra_MmFixedEntryFetch (table->pMemMan); 00241 if (new == NULL) { 00242 return STMM_OUT_OF_MEM; 00243 } 00244 00245 new->key = key; 00246 new->record = value; 00247 new->next = table->bins[hash_val]; 00248 table->bins[hash_val] = new; 00249 table->num_entries++; 00250 return 0; 00251 } 00252 else { 00253 ptr->record = value; 00254 return 1; 00255 } 00256 }
int stmm_lookup | ( | stmm_table * | table, | |
char * | key, | |||
char ** | value | |||
) |
Definition at line 146 of file stmm.c.
00150 { 00151 int hash_val; 00152 register stmm_table_entry *ptr, **last; 00153 00154 hash_val = do_hash (key, table); 00155 00156 FIND_ENTRY (table, hash_val, key, ptr, last); 00157 00158 if (ptr == NULL) { 00159 return 0; 00160 } 00161 else { 00162 if (value != NULL) 00163 { 00164 *value = ptr->record; 00165 } 00166 return 1; 00167 } 00168 }
int stmm_lookup_int | ( | stmm_table * | table, | |
char * | key, | |||
int * | value | |||
) |
Definition at line 171 of file stmm.c.
00175 { 00176 int hash_val; 00177 register stmm_table_entry *ptr, **last; 00178 00179 hash_val = do_hash (key, table); 00180 00181 FIND_ENTRY (table, hash_val, key, ptr, last); 00182 00183 if (ptr == NULL) { 00184 return 0; 00185 } 00186 else { 00187 if (value != 0) 00188 { 00189 *value = (long) ptr->record; 00190 } 00191 return 1; 00192 } 00193 }
int stmm_numcmp | ( | char * | x, | |
char * | y | |||
) |
Definition at line 590 of file stmm.c.
00593 { 00594 return STMM_NUMCMP (x, y); 00595 }
int stmm_numcmp | ( | ) |
int stmm_numhash | ( | char * | x, | |
int | size | |||
) |
Definition at line 574 of file stmm.c.
00577 { 00578 return STMM_NUMHASH (x, size); 00579 }
int stmm_numhash | ( | ) |
int stmm_ptrcmp | ( | char * | x, | |
char * | y | |||
) |
Definition at line 598 of file stmm.c.
00601 { 00602 return STMM_NUMCMP (x, y); 00603 }
int stmm_ptrcmp | ( | ) |
int stmm_ptrhash | ( | char * | x, | |
int | size | |||
) |
Definition at line 582 of file stmm.c.
00585 { 00586 return STMM_PTRHASH (x, size); 00587 }
int stmm_ptrhash | ( | ) |