VPR-6.0

vpr/SRC/util/hash.c

Go to the documentation of this file.
00001 #include <stdlib.h>
00002 #include <string.h>
00003 #include "hash.h"
00004 #include "util.h"
00005 
00006 #define HASHSIZE 4093
00007 
00008 static int hash_value(char *name);
00009 
00010 
00011 
00012 /** Creates a hash table with HASHSIZE different locations (hash values).   */
00013 struct s_hash **
00014 alloc_hash_table(void)
00015 {
00016     struct s_hash **hash_table;
00017 
00018     hash_table = (struct s_hash **)my_calloc(sizeof(struct s_hash *),
00019                                              HASHSIZE);
00020     return (hash_table);
00021 }
00022 
00023 
00024 /** Frees all the storage associated with a hash table. */
00025 void
00026 free_hash_table(struct s_hash **hash_table)
00027 {
00028     int i;
00029     struct s_hash *h_ptr, *temp_ptr;
00030 
00031     for(i = 0; i < HASHSIZE; i++)
00032         {
00033             h_ptr = hash_table[i];
00034             while(h_ptr != NULL)
00035                 {
00036                     free(h_ptr->name);
00037                     temp_ptr = h_ptr->next;
00038                     free(h_ptr);
00039                     h_ptr = temp_ptr;
00040                 }
00041         }
00042 
00043     free(hash_table);
00044 }
00045 
00046 
00047 /** Call this routine before you start going through all the elements in    
00048  * a hash table.  It sets the internal indices to the start of the table.  
00049  */
00050 struct s_hash_iterator
00051 start_hash_table_iterator(void)
00052 {
00053     struct s_hash_iterator hash_iterator;
00054 
00055     hash_iterator.i = -1;
00056     hash_iterator.h_ptr = NULL;
00057     return (hash_iterator);
00058 }
00059 
00060 /** Returns the next occupied hash entry, and moves the iterator structure    
00061  * forward so the next call gets the next entry.                             
00062  */
00063 struct s_hash *
00064 get_next_hash(struct s_hash **hash_table,
00065               struct s_hash_iterator *hash_iterator)
00066 {
00067 
00068     int i;
00069     struct s_hash *h_ptr;
00070 
00071     i = hash_iterator->i;
00072     h_ptr = hash_iterator->h_ptr;
00073 
00074     while(h_ptr == NULL)
00075         {
00076             i++;
00077             if(i >= HASHSIZE)
00078                 return (NULL);  /* End of table */
00079 
00080             h_ptr = hash_table[i];
00081         }
00082 
00083     hash_iterator->h_ptr = h_ptr->next;
00084     hash_iterator->i = i;
00085     return (h_ptr);
00086 }
00087 
00088 /** Adds the string pointed to by name to the hash table, and returns the    
00089  * hash structure created or updated.  If name is already in the hash table 
00090  * the count member of that hash element is incremented.  Otherwise a new   
00091  * hash entry with a count of zero and an index of next_free_index is       
00092  * created.                                                                 
00093  */
00094 struct s_hash *
00095 insert_in_hash_table(struct s_hash **hash_table,
00096                      char *name,
00097                      int next_free_index)
00098 {
00099 
00100     int i;
00101     struct s_hash *h_ptr, *prev_ptr;
00102 
00103     i = hash_value(name);
00104     prev_ptr = NULL;
00105     h_ptr = hash_table[i];
00106 
00107     while(h_ptr != NULL)
00108         {
00109             if(strcmp(h_ptr->name, name) == 0)
00110                 {
00111                     h_ptr->count++;
00112                     return (h_ptr);
00113                 }
00114 
00115             prev_ptr = h_ptr;
00116             h_ptr = h_ptr->next;
00117         }
00118 
00119 /* Name string wasn't in the hash table.  Add it. */
00120 
00121     h_ptr = (struct s_hash *)my_malloc(sizeof(struct s_hash));
00122     if(prev_ptr == NULL)
00123         {
00124             hash_table[i] = h_ptr;
00125         }
00126     else
00127         {
00128             prev_ptr->next = h_ptr;
00129         }
00130     h_ptr->next = NULL;
00131     h_ptr->index = next_free_index;
00132     h_ptr->count = 1;
00133     h_ptr->name = (char *)my_malloc((strlen(name) + 1) * sizeof(char));
00134     strcpy(h_ptr->name, name);
00135     return (h_ptr);
00136 }
00137 
00138 /** Returns the hash entry with this name, or NULL if there is no            
00139  * corresponding entry.                                                     
00140  */
00141 struct s_hash *
00142 get_hash_entry(struct s_hash **hash_table,
00143                char *name)
00144 {
00145 
00146     int i;
00147     struct s_hash *h_ptr;
00148 
00149     i = hash_value(name);
00150     h_ptr = hash_table[i];
00151 
00152     while(h_ptr != NULL)
00153         {
00154             if(strcmp(h_ptr->name, name) == 0)
00155                 return (h_ptr);
00156 
00157             h_ptr = h_ptr->next;
00158         }
00159 
00160     return (NULL);
00161 }
00162 
00163 /** Creates a hash key from a character string.  Only the first character and
00164  * the last 8 characters of the string are used -- that may be dumb.         
00165  */
00166 static int
00167 hash_value(char *name)
00168 {
00169     int i, k;
00170     int val = 0, mult = 1;
00171 
00172         i = strlen(name);
00173     k = max(i - 8, 0);
00174     for(i = strlen(name) - 1; i >= k; i--)
00175         {
00176             val += mult * ((int)name[i]);
00177             mult *= 7;
00178         }
00179     val += (int)name[0];
00180     val %= HASHSIZE;
00181     return (val);
00182 }