src/misc/st/st.c File Reference

#include <stdio.h>
#include <stdlib.h>
#include "st.h"
Include dependency graph for st.c:

Go to the source code of this file.

Defines

#define ST_NUMCMP(x, y)   ((x) != (y))
#define ST_NUMHASH(x, size)   (ABS((long)x)%(size))
#define ST_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 st_numhash ()
int st_ptrhash ()
int st_numcmp ()
int st_ptrcmp ()
st_tablest_init_table_with_params (int(*compare)(), int(*hash)(), int size, int density, double grow_factor, int reorder_flag)
st_tablest_init_table (int(*compare)(), int(*hash)())
void st_free_table (st_table *table)
int st_lookup (st_table *table, char *key, char **value)
int st_lookup_int (st_table *table, char *key, int *value)
int st_insert (st_table *table, char *key, char *value)
int st_add_direct (st_table *table, char *key, char *value)
int st_find_or_add (st_table *table, char *key, char ***slot)
int st_find (st_table *table, char *key, char ***slot)
static int rehash (st_table *table)
st_tablest_copy (st_table *old_table)
int st_delete (st_table *table, char **keyp, char **value)
int st_delete_int (st_table *table, long *keyp, char **value)
int st_foreach (st_table *table, enum st_retval(*func)(), char *arg)
int st_strhash (char *string, int modulus)
int st_numhash (char *x, int size)
int st_ptrhash (char *x, int size)
int st_numcmp (char *x, char *y)
int st_ptrcmp (char *x, char *y)
st_generatorst_init_gen (st_table *table)
int st_gen (st_generator *gen, char **key_p, char **value_p)
int st_gen_int (st_generator *gen, char **key_p, long *value_p)
void st_free_gen (st_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 = ALLOC(st_table_entry, 1);\
    \
    new->key = key;\
    new->record = value;\
    new->next = table->bins[hash_val];\
    table->bins[hash_val] = new;\
    table->num_entries++;\
}

Definition at line 179 of file st.c.

#define do_hash ( key,
table   ) 
Value:
((table->hash == st_ptrhash) ? ST_PTRHASH((key),(table)->num_bins) :\
     (table->hash == st_numhash) ? ST_NUMHASH((key), (table)->num_bins) :\
     (*table->hash)((key), (table)->num_bins))

Definition at line 41 of file st.c.

#define EQUAL ( func,
x,
 ) 
Value:
((((func) == st_numcmp) || ((func) == st_ptrcmp)) ?\
      (ST_NUMCMP((x),(y)) == 0) : ((*func)((x), (y)) == 0))

Definition at line 36 of file st.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 120 of file st.c.

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

Definition at line 117 of file st.c.

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

Definition at line 32 of file st.c.

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

Definition at line 33 of file st.c.

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

Definition at line 35 of file st.c.


Function Documentation

static int rehash ( st_table table  )  [static]

Definition at line 321 of file st.c.

00323 {
00324     register st_table_entry *ptr, *next, **old_bins;
00325     int             i, old_num_bins, hash_val, old_num_entries;
00326 
00327     /* save old values */
00328     old_bins = table->bins;
00329     old_num_bins = table->num_bins;
00330     old_num_entries = table->num_entries;
00331 
00332     /* rehash */
00333     table->num_bins = (int)(table->grow_factor * old_num_bins);
00334     if (table->num_bins % 2 == 0) {
00335         table->num_bins += 1;
00336     }
00337     table->num_entries = 0;
00338     table->bins = ALLOC(st_table_entry *, table->num_bins);
00339     if (table->bins == NULL) {
00340         table->bins = old_bins;
00341         table->num_bins = old_num_bins;
00342         table->num_entries = old_num_entries;
00343         return ST_OUT_OF_MEM;
00344     }
00345     /* initialize */
00346     for (i = 0; i < table->num_bins; i++) {
00347         table->bins[i] = 0;
00348     }
00349 
00350     /* copy data over */
00351     for (i = 0; i < old_num_bins; i++) {
00352         ptr = old_bins[i];
00353         while (ptr != NULL) {
00354             next = ptr->next;
00355             hash_val = do_hash(ptr->key, table);
00356             ptr->next = table->bins[hash_val];
00357             table->bins[hash_val] = ptr;
00358             table->num_entries++;
00359             ptr = next;
00360         }
00361     }
00362     FREE(old_bins);
00363 
00364     return 1;
00365 }

static int rehash (  )  [static]
int st_add_direct ( st_table table,
char *  key,
char *  value 
)

Definition at line 233 of file st.c.

00237 {
00238     int hash_val;
00239     st_table_entry *new;
00240     
00241     hash_val = do_hash(key, table);
00242     if (table->num_entries / table->num_bins >= table->max_density) {
00243         if (rehash(table) == ST_OUT_OF_MEM) {
00244             return ST_OUT_OF_MEM;
00245         }
00246     }
00247     hash_val = do_hash(key, table);
00248     new = ALLOC(st_table_entry, 1);
00249     if (new == NULL) {
00250         return ST_OUT_OF_MEM;
00251     }
00252     new->key = key;
00253     new->record = value;
00254     new->next = table->bins[hash_val];
00255     table->bins[hash_val] = new;
00256     table->num_entries++;
00257     return 1;
00258 }

st_table* st_copy ( st_table old_table  ) 

Definition at line 368 of file st.c.

00370 {
00371     st_table *new_table;
00372     st_table_entry *ptr, *newptr, *next, *new;
00373     int i, j, num_bins = old_table->num_bins;
00374 
00375     new_table = ALLOC(st_table, 1);
00376     if (new_table == NULL) {
00377         return NULL;
00378     }
00379     
00380     *new_table = *old_table;
00381     new_table->bins = ALLOC(st_table_entry *, num_bins);
00382     if (new_table->bins == NULL) {
00383         FREE(new_table);
00384         return NULL;
00385     }
00386     for(i = 0; i < num_bins ; i++) {
00387         new_table->bins[i] = NULL;
00388         ptr = old_table->bins[i];
00389         while (ptr != NULL) {
00390             new = ALLOC(st_table_entry, 1);
00391             if (new == NULL) {
00392                 for (j = 0; j <= i; j++) {
00393                     newptr = new_table->bins[j];
00394                     while (newptr != NULL) {
00395                         next = newptr->next;
00396                         FREE(newptr);
00397                         newptr = next;
00398                     }
00399                 }
00400                 FREE(new_table->bins);
00401                 FREE(new_table);
00402                 return NULL;
00403             }
00404             *new = *ptr;
00405             new->next = new_table->bins[i];
00406             new_table->bins[i] = new;
00407             ptr = ptr->next;
00408         }
00409     }
00410     return new_table;
00411 }

int st_delete ( st_table table,
char **  keyp,
char **  value 
)

Definition at line 414 of file st.c.

00418 {
00419     int hash_val;
00420     char *key = *keyp;
00421     register st_table_entry *ptr, **last;
00422 
00423     hash_val = do_hash(key, table);
00424 
00425     FIND_ENTRY(table, hash_val, key, ptr ,last);
00426     
00427     if (ptr == NULL) {
00428         return 0;
00429     }
00430 
00431     *last = ptr->next;
00432     if (value != NULL) *value = ptr->record;
00433     *keyp = ptr->key;
00434     FREE(ptr);
00435     table->num_entries--;
00436     return 1;
00437 }

int st_delete_int ( st_table table,
long *  keyp,
char **  value 
)

Definition at line 440 of file st.c.

00444 {
00445     int hash_val;
00446     char *key = (char *) *keyp;
00447     register st_table_entry *ptr, **last;
00448 
00449     hash_val = do_hash(key, table);
00450 
00451     FIND_ENTRY(table, hash_val, key, ptr ,last);
00452 
00453     if (ptr == NULL) {
00454         return 0;
00455     }
00456 
00457     *last = ptr->next;
00458     if (value != NULL) *value = ptr->record;
00459     *keyp = (long) ptr->key;
00460     FREE(ptr);
00461     table->num_entries--;
00462     return 1;
00463 }

int st_find ( st_table table,
char *  key,
char ***  slot 
)

Definition at line 298 of file st.c.

00302 {
00303     int hash_val;
00304     st_table_entry *ptr, **last;
00305 
00306     hash_val = do_hash(key, table);
00307 
00308     FIND_ENTRY(table, hash_val, key, ptr, last);
00309 
00310     if (ptr == NULL) {
00311         return 0;
00312     } else {
00313         if (slot != NULL) {
00314             *slot = &ptr->record;
00315         }
00316         return 1;
00317     }
00318 }

int st_find_or_add ( st_table table,
char *  key,
char ***  slot 
)

Definition at line 261 of file st.c.

00265 {
00266     int hash_val;
00267     st_table_entry *new, *ptr, **last;
00268 
00269     hash_val = do_hash(key, table);
00270 
00271     FIND_ENTRY(table, hash_val, key, ptr, last);
00272 
00273     if (ptr == NULL) {
00274         if (table->num_entries / table->num_bins >= table->max_density) {
00275             if (rehash(table) == ST_OUT_OF_MEM) {
00276                 return ST_OUT_OF_MEM;
00277             }
00278             hash_val = do_hash(key, table);
00279         }
00280         new = ALLOC(st_table_entry, 1);
00281         if (new == NULL) {
00282             return ST_OUT_OF_MEM;
00283         }
00284         new->key = key;
00285         new->record = (char *) 0;
00286         new->next = table->bins[hash_val];
00287         table->bins[hash_val] = new;
00288         table->num_entries++;
00289         if (slot != NULL) *slot = &new->record;
00290         return 0;
00291     } else {
00292         if (slot != NULL) *slot = &ptr->record;
00293         return 1;
00294     }
00295 }

int st_foreach ( st_table table,
enum st_retval (*)()  func,
char *  arg 
)

Definition at line 466 of file st.c.

00470 {
00471     st_table_entry *ptr, **last;
00472     enum st_retval retval;
00473     int i;
00474 
00475     for(i = 0; i < table->num_bins; i++) {
00476         last = &table->bins[i]; ptr = *last;
00477         while (ptr != NULL) {
00478             retval = (*func)(ptr->key, ptr->record, arg);
00479             switch (retval) {
00480             case ST_CONTINUE:
00481                 last = &ptr->next; ptr = *last;
00482                 break;
00483             case ST_STOP:
00484                 return 0;
00485             case ST_DELETE:
00486                 *last = ptr->next;
00487                 table->num_entries--;   /* cstevens@ic */
00488                 FREE(ptr);
00489                 ptr = *last;
00490             }
00491         }
00492     }
00493     return 1;
00494 }

void st_free_gen ( st_generator gen  ) 

Definition at line 621 of file st.c.

00623 {
00624     FREE(gen);
00625 }

void st_free_table ( st_table table  ) 

Definition at line 99 of file st.c.

00101 {
00102     register st_table_entry *ptr, *next;
00103     int i;
00104 
00105     for(i = 0; i < table->num_bins ; i++) {
00106         ptr = table->bins[i];
00107         while (ptr != NULL) {
00108             next = ptr->next;
00109             FREE(ptr);
00110             ptr = next;
00111         }
00112     }
00113     FREE(table->bins);
00114     FREE(table);
00115 }

int st_gen ( st_generator gen,
char **  key_p,
char **  value_p 
)

Definition at line 561 of file st.c.

00565 {
00566     register int i;
00567 
00568     if (gen->entry == NULL) {
00569         /* try to find next entry */
00570         for(i = gen->index; i < gen->table->num_bins; i++) {
00571             if (gen->table->bins[i] != NULL) {
00572                 gen->index = i+1;
00573                 gen->entry = gen->table->bins[i];
00574                 break;
00575             }
00576         }
00577         if (gen->entry == NULL) {
00578             return 0;           /* that's all folks ! */
00579         }
00580     }
00581     *key_p = gen->entry->key;
00582     if (value_p != 0) {
00583         *value_p = gen->entry->record;
00584     }
00585     gen->entry = gen->entry->next;
00586     return 1;
00587 }

int st_gen_int ( st_generator gen,
char **  key_p,
long *  value_p 
)

Definition at line 591 of file st.c.

00595 {
00596     register int i;
00597 
00598     if (gen->entry == NULL) {
00599         /* try to find next entry */
00600         for(i = gen->index; i < gen->table->num_bins; i++) {
00601             if (gen->table->bins[i] != NULL) {
00602                 gen->index = i+1;
00603                 gen->entry = gen->table->bins[i];
00604                 break;
00605             }
00606         }
00607         if (gen->entry == NULL) {
00608             return 0;           /* that's all folks ! */
00609         }
00610     }
00611     *key_p = gen->entry->key;
00612     if (value_p != 0) {
00613         *value_p = (long) gen->entry->record;
00614     }
00615     gen->entry = gen->entry->next;
00616     return 1;
00617 }

st_generator* st_init_gen ( st_table table  ) 

Definition at line 544 of file st.c.

00546 {
00547     st_generator *gen;
00548 
00549     gen = ALLOC(st_generator, 1);
00550     if (gen == NULL) {
00551         return NULL;
00552     }
00553     gen->table = table;
00554     gen->entry = NULL;
00555     gen->index = 0;
00556     return gen;
00557 }

st_table* st_init_table ( int (*)()  compare,
int (*)()  hash 
)

Definition at line 88 of file st.c.

st_table* st_init_table_with_params ( int (*)()  compare,
int (*)()  hash,
int  size,
int  density,
double  grow_factor,
int  reorder_flag 
)

Definition at line 50 of file st.c.

00058 {
00059     int i;
00060     st_table *new;
00061 
00062     new = ALLOC(st_table, 1);
00063     if (new == NULL) {
00064         return NULL;
00065     }
00066     new->compare = compare;
00067     new->hash = hash;
00068     new->num_entries = 0;
00069     new->max_density = density;
00070     new->grow_factor = grow_factor;
00071     new->reorder_flag = reorder_flag;
00072     if (size <= 0) {
00073         size = 1;
00074     }
00075     new->num_bins = size;
00076     new->bins = ALLOC(st_table_entry *, size);
00077     if (new->bins == NULL) {
00078         FREE(new);
00079         return NULL;
00080     }
00081     for(i = 0; i < size; i++) {
00082         new->bins[i] = 0;
00083     }
00084     return new;
00085 }

int st_insert ( st_table table,
char *  key,
char *  value 
)

Definition at line 196 of file st.c.

00200 {
00201     int hash_val;
00202     st_table_entry *new;
00203     register st_table_entry *ptr, **last;
00204 
00205     hash_val = do_hash(key, table);
00206 
00207     FIND_ENTRY(table, hash_val, key, ptr, last);
00208 
00209     if (ptr == NULL) {
00210         if (table->num_entries/table->num_bins >= table->max_density) {
00211             if (rehash(table) == ST_OUT_OF_MEM) {
00212                 return ST_OUT_OF_MEM;
00213             }
00214             hash_val = do_hash(key, table);
00215         }
00216         new = ALLOC(st_table_entry, 1);
00217         if (new == NULL) {
00218             return ST_OUT_OF_MEM;
00219         }
00220         new->key = key;
00221         new->record = value;
00222         new->next = table->bins[hash_val];
00223         table->bins[hash_val] = new;
00224         table->num_entries++;
00225         return 0;
00226     } else {
00227         ptr->record = value;
00228         return 1;
00229     }
00230 }

int st_lookup ( st_table table,
char *  key,
char **  value 
)

Definition at line 133 of file st.c.

00137 {
00138     int hash_val;
00139     register st_table_entry *ptr, **last;
00140 
00141     hash_val = do_hash(key, table);
00142 
00143     FIND_ENTRY(table, hash_val, key, ptr, last);
00144     
00145     if (ptr == NULL) {
00146         return 0;
00147     } else {
00148         if (value != NULL) {
00149             *value = ptr->record; 
00150         }
00151         return 1;
00152     }
00153 }

int st_lookup_int ( st_table table,
char *  key,
int *  value 
)

Definition at line 156 of file st.c.

00160 {
00161     int hash_val;
00162     register st_table_entry *ptr, **last;
00163 
00164     hash_val = do_hash(key, table);
00165 
00166     FIND_ENTRY(table, hash_val, key, ptr, last);
00167     
00168     if (ptr == NULL) {
00169         return 0;
00170     } else {
00171         if (value != 0) {
00172             *value = (long) ptr->record;
00173         }
00174         return 1;
00175     }
00176 }

int st_numcmp ( char *  x,
char *  y 
)

Definition at line 528 of file st.c.

00531 {
00532     return ST_NUMCMP(x, y);
00533 }

int st_numcmp (  ) 
int st_numhash ( char *  x,
int  size 
)

Definition at line 512 of file st.c.

00515 {
00516     return ST_NUMHASH(x, size);
00517 }

int st_numhash (  ) 
int st_ptrcmp ( char *  x,
char *  y 
)

Definition at line 536 of file st.c.

00539 {
00540     return ST_NUMCMP(x, y);
00541 }

int st_ptrcmp (  ) 
int st_ptrhash ( char *  x,
int  size 
)

Definition at line 520 of file st.c.

00523 {
00524     return ST_PTRHASH(x, size);
00525 }

int st_ptrhash (  ) 
int st_strhash ( char *  string,
int  modulus 
)

Definition at line 497 of file st.c.

00500 {
00501     register int val = 0;
00502     register int c;
00503     
00504     while ((c = *string++) != '\0') {
00505         val = val*997 + c;
00506     }
00507 
00508     return ((val < 0) ? -val : val)%modulus;
00509 }


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