src/misc/st/stmm.c File Reference

#include <stdio.h>
#include "extra.h"
#include "stmm.h"
Include dependency graph for stmm.c:

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_tablestmm_init_table_with_params (int(*)() compare, int(*)() hash, int size, int density, double grow_factor, int reorder_flag)
stmm_tablestmm_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_tablestmm_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_generatorstmm_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)

Define Documentation

#define ADD_DIRECT ( table,
key,
value,
hash_val,
new   ) 
Value:
{\
    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++;\
}

Definition at line 201 of file stmm.c.

#define do_hash ( key,
table   ) 
Value:
((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))

Definition at line 27 of file stmm.c.

#define EQUAL ( func,
x,
 ) 
Value:
((((func) == stmm_numcmp) || ((func) == stmm_ptrcmp)) ?\
      (STMM_NUMCMP((x),(y)) == 0) : ((*func)((x), (y)) == 0))

Definition at line 22 of file stmm.c.

#define FIND_ENTRY ( table,
hash_val,
key,
ptr,
last   ) 
Value:
(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);\
    }

Definition at line 133 of file stmm.c.

#define PTR_NOT_EQUAL ( table,
ptr,
user_key   )     (ptr != NULL && !EQUAL(table->compare, user_key, (ptr)->key))

Definition at line 130 of file stmm.c.

#define STMM_NUMCMP ( x,
 )     ((x) != (y))

Definition at line 18 of file stmm.c.

#define STMM_NUMHASH ( x,
size   )     (ABS((long)x)%(size))

Definition at line 19 of file stmm.c.

#define STMM_PTRHASH ( x,
size   )     ((int)(((unsigned long)(x)>>2)%size))

Definition at line 21 of file stmm.c.


Function Documentation

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  ) 

Definition at line 684 of file stmm.c.

00686 {
00687     FREE (gen);
00688 }

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  ) 

Definition at line 606 of file stmm.c.

00608 {
00609     stmm_generator *gen;
00610 
00611     gen = ALLOC (stmm_generator, 1);
00612     if (gen == NULL) {
00613         return NULL;
00614     }
00615     gen->table = table;
00616     gen->entry = NULL;
00617     gen->index = 0;
00618     return gen;
00619 }

stmm_table* stmm_init_table ( int (*) ()  compare,
int (*) ()  hash 
)

Definition at line 77 of file stmm.c.

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 (  ) 
int stmm_strhash ( char *  string,
int  modulus 
)

Definition at line 559 of file stmm.c.

00562 {
00563     register int val = 0;
00564     register int c;
00565 
00566     while ((c = *string++) != '\0') {
00567         val = val * 997 + c;
00568     }
00569 
00570     return ((val < 0) ? -val : val) % modulus;
00571 }


Generated on Tue Jan 5 12:19:19 2010 for abc70930 by  doxygen 1.6.1