00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "config.h"
00023 #include "system.h"
00024 #include "hash.h"
00025 #include "obstack.h"
00026 #include "toplev.h"
00027
00028
00029 #define obstack_chunk_alloc xmalloc
00030 #define obstack_chunk_free free
00031
00032
00033 #define DEFAULT_SIZE 1009
00034
00035
00036
00037 void
00038 hash_table_init_n (table, newfunc, hash, comp, size)
00039 struct hash_table *table;
00040 struct hash_entry *(*newfunc) PARAMS ((struct hash_entry *,
00041 struct hash_table *,
00042 hash_table_key));
00043 unsigned long (*hash) PARAMS ((hash_table_key));
00044 bool (*comp) PARAMS ((hash_table_key, hash_table_key));
00045 unsigned int size;
00046 {
00047 unsigned int alloc;
00048
00049 alloc = size * sizeof (struct hash_entry *);
00050 obstack_begin (&table->memory, alloc);
00051 table->table = ((struct hash_entry **)
00052 obstack_alloc (&table->memory, alloc));
00053 memset ((PTR) table->table, 0, alloc);
00054 table->size = size;
00055 table->newfunc = newfunc;
00056 table->hash = hash;
00057 table->comp = comp;
00058 }
00059
00060
00061
00062 void
00063 hash_table_init (table, newfunc, hash, comp)
00064 struct hash_table *table;
00065 struct hash_entry *(*newfunc) PARAMS ((struct hash_entry *,
00066 struct hash_table *,
00067 hash_table_key));
00068 unsigned long (*hash) PARAMS ((hash_table_key));
00069 bool (*comp) PARAMS ((hash_table_key, hash_table_key));
00070 {
00071 hash_table_init_n (table, newfunc, hash, comp, DEFAULT_SIZE);
00072 }
00073
00074
00075
00076 void
00077 hash_table_free (table)
00078 struct hash_table *table;
00079 {
00080 obstack_free (&table->memory, (PTR) NULL);
00081 }
00082
00083
00084
00085
00086 struct hash_entry *
00087 hash_lookup (table, key, create, copy)
00088 struct hash_table *table;
00089 hash_table_key key;
00090 int create;
00091 hash_table_key (*copy) PARAMS ((struct obstack* memory,
00092 hash_table_key key));
00093 {
00094 unsigned long hash;
00095 struct hash_entry *hashp;
00096 unsigned int index;
00097
00098 hash = (*table->hash)(key);
00099
00100 index = hash % table->size;
00101 for (hashp = table->table[index]; hashp != 0; hashp = hashp->next)
00102 if (hashp->hash == hash
00103 && (*table->comp)(hashp->key, key))
00104 return hashp;
00105
00106 if (! create)
00107 return 0;
00108
00109 hashp = (*table->newfunc) ((struct hash_entry *) NULL, table, key);
00110 if (hashp == 0)
00111 return 0;
00112
00113 if (copy)
00114 key = (*copy) (&table->memory, key);
00115
00116 hashp->key = key;
00117 hashp->hash = hash;
00118 hashp->next = table->table[index];
00119 table->table[index] = hashp;
00120
00121 return hashp;
00122 }
00123
00124
00125
00126 struct hash_entry *
00127 hash_newfunc (entry, table, p)
00128 struct hash_entry *entry;
00129 struct hash_table *table;
00130 hash_table_key p ATTRIBUTE_UNUSED;
00131 {
00132 if (entry == 0)
00133 entry = ((struct hash_entry *)
00134 hash_allocate (table, sizeof (struct hash_entry)));
00135 return entry;
00136 }
00137
00138
00139
00140 PTR
00141 hash_allocate (table, size)
00142 struct hash_table *table;
00143 unsigned int size;
00144 {
00145 return obstack_alloc (&table->memory, size);
00146 }
00147
00148
00149
00150 void
00151 hash_traverse (table, func, info)
00152 struct hash_table *table;
00153 bool (*func) PARAMS ((struct hash_entry *, hash_table_key));
00154 PTR info;
00155 {
00156 unsigned int i;
00157 struct hash_entry *p;
00158
00159 for (i = 0; i < table->size; i++)
00160 for (p = table->table[i]; p != 0; p = p->next)
00161 if (! (*func) (p, info))
00162 return;
00163 }
00164
00165
00166
00167 unsigned long
00168 string_hash (k)
00169 hash_table_key k;
00170 {
00171 const unsigned char *s;
00172 unsigned long hash;
00173 unsigned char c;
00174 unsigned int len;
00175
00176 s = (const unsigned char *) k;
00177 hash = 0;
00178 len = 0;
00179
00180 while ((c = *s++) != '\0')
00181 {
00182 hash += c + (c << 17);
00183 hash ^= hash >> 2;
00184 ++len;
00185 }
00186
00187 hash += len + (len << 17);
00188 hash ^= hash >> 2;
00189
00190 return hash;
00191 }
00192
00193
00194
00195
00196 bool
00197 string_compare (k1, k2)
00198 hash_table_key k1;
00199 hash_table_key k2;
00200 {
00201 return (strcmp ((char*) k1, (char*) k2) == 0);
00202 }
00203
00204
00205
00206 hash_table_key
00207 string_copy (memory, k)
00208 struct obstack *memory;
00209 hash_table_key k;
00210 {
00211 char *new;
00212 char *string = (char *) k;
00213
00214 new = (char *) obstack_alloc (memory, strlen (string) + 1);
00215 strcpy (new, string);
00216
00217 return new;
00218 }