VPR-6.0
|
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 }