2000-10-30 Kazu Hirata <kazu@hxi.com>
[external/binutils.git] / gas / hash.c
1 /* hash.c -- gas hash table code
2    Copyright (C) 1987, 90, 91, 92, 93, 94, 95, 96, 98, 99, 2000
3    Free Software Foundation, Inc.
4
5    This file is part of GAS, the GNU Assembler.
6
7    GAS is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2, or (at your option)
10    any later version.
11
12    GAS is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with GAS; see the file COPYING.  If not, write to the Free
19    Software Foundation, 59 Temple Place - Suite 330, Boston, MA
20    02111-1307, USA.  */
21
22 /* This version of the hash table code is a wholescale replacement of
23    the old hash table code, which was fairly bad.  This is based on
24    the hash table code in BFD, but optimized slightly for the
25    asssembler.  The assembler does not need to derive structures that
26    are stored in the hash table.  Instead, it always stores a pointer.
27    The assembler uses the hash table mostly to store symbols, and we
28    don't need to confuse the symbol structure with a hash table
29    structure.  */
30
31 #include "as.h"
32 #include "obstack.h"
33
34 /* The default number of entries to use when creating a hash table.  */
35
36 #define DEFAULT_SIZE (4051)
37
38 /* An entry in a hash table.  */
39
40 struct hash_entry {
41   /* Next entry for this hash code.  */
42   struct hash_entry *next;
43   /* String being hashed.  */
44   const char *string;
45   /* Hash code.  This is the full hash code, not the index into the
46      table.  */
47   unsigned long hash;
48   /* Pointer being stored in the hash table.  */
49   PTR data;
50 };
51
52 /* A hash table.  */
53
54 struct hash_control {
55   /* The hash array.  */
56   struct hash_entry **table;
57   /* The number of slots in the hash table.  */
58   unsigned int size;
59   /* An obstack for this hash table.  */
60   struct obstack memory;
61
62 #ifdef HASH_STATISTICS
63   /* Statistics.  */
64   unsigned long lookups;
65   unsigned long hash_compares;
66   unsigned long string_compares;
67   unsigned long insertions;
68   unsigned long replacements;
69   unsigned long deletions;
70 #endif /* HASH_STATISTICS */
71 };
72
73 /* Create a hash table.  This return a control block.  */
74
75 struct hash_control *
76 hash_new ()
77 {
78   unsigned int size;
79   struct hash_control *ret;
80   unsigned int alloc;
81
82   size = DEFAULT_SIZE;
83
84   ret = (struct hash_control *) xmalloc (sizeof *ret);
85   obstack_begin (&ret->memory, chunksize);
86   alloc = size * sizeof (struct hash_entry *);
87   ret->table = (struct hash_entry **) obstack_alloc (&ret->memory, alloc);
88   memset (ret->table, 0, alloc);
89   ret->size = size;
90
91 #ifdef HASH_STATISTICS
92   ret->lookups = 0;
93   ret->hash_compares = 0;
94   ret->string_compares = 0;
95   ret->insertions = 0;
96   ret->replacements = 0;
97   ret->deletions = 0;
98 #endif
99
100   return ret;
101 }
102
103 /* Delete a hash table, freeing all allocated memory.  */
104
105 void
106 hash_die (table)
107      struct hash_control *table;
108 {
109   obstack_free (&table->memory, 0);
110   free (table);
111 }
112
113 /* Look up a string in a hash table.  This returns a pointer to the
114    hash_entry, or NULL if the string is not in the table.  If PLIST is
115    not NULL, this sets *PLIST to point to the start of the list which
116    would hold this hash entry.  If PHASH is not NULL, this sets *PHASH
117    to the hash code for KEY.
118
119    Each time we look up a string, we move it to the start of the list
120    for its hash code, to take advantage of referential locality.  */
121
122 static struct hash_entry *hash_lookup PARAMS ((struct hash_control *,
123                                                const char *,
124                                                struct hash_entry ***,
125                                                unsigned long *));
126
127 static struct hash_entry *
128 hash_lookup (table, key, plist, phash)
129      struct hash_control *table;
130      const char *key;
131      struct hash_entry ***plist;
132      unsigned long *phash;
133 {
134   register unsigned long hash;
135   unsigned int len;
136   register const unsigned char *s;
137   register unsigned int c;
138   unsigned int index;
139   struct hash_entry **list;
140   struct hash_entry *p;
141   struct hash_entry *prev;
142
143 #ifdef HASH_STATISTICS
144   ++table->lookups;
145 #endif
146
147   hash = 0;
148   len = 0;
149   s = (const unsigned char *) key;
150   while ((c = *s++) != '\0')
151     {
152       hash += c + (c << 17);
153       hash ^= hash >> 2;
154       ++len;
155     }
156   hash += len + (len << 17);
157   hash ^= hash >> 2;
158
159   if (phash != NULL)
160     *phash = hash;
161
162   index = hash % table->size;
163   list = table->table + index;
164
165   if (plist != NULL)
166     *plist = list;
167
168   prev = NULL;
169   for (p = *list; p != NULL; p = p->next)
170     {
171 #ifdef HASH_STATISTICS
172       ++table->hash_compares;
173 #endif
174
175       if (p->hash == hash)
176         {
177 #ifdef HASH_STATISTICS
178           ++table->string_compares;
179 #endif
180
181           if (strcmp (p->string, key) == 0)
182             {
183               if (prev != NULL)
184                 {
185                   prev->next = p->next;
186                   p->next = *list;
187                   *list = p;
188                 }
189
190               return p;
191             }
192         }
193
194       prev = p;
195     }
196
197   return NULL;
198 }
199
200 /* Insert an entry into a hash table.  This returns NULL on success.
201    On error, it returns a printable string indicating the error.  It
202    is considered to be an error if the entry already exists in the
203    hash table.  */
204
205 const char *
206 hash_insert (table, key, value)
207      struct hash_control *table;
208      const char *key;
209      PTR value;
210 {
211   struct hash_entry *p;
212   struct hash_entry **list;
213   unsigned long hash;
214
215   p = hash_lookup (table, key, &list, &hash);
216   if (p != NULL)
217     return "exists";
218
219 #ifdef HASH_STATISTICS
220   ++table->insertions;
221 #endif
222
223   p = (struct hash_entry *) obstack_alloc (&table->memory, sizeof (*p));
224   p->string = key;
225   p->hash = hash;
226   p->data = value;
227
228   p->next = *list;
229   *list = p;
230
231   return NULL;
232 }
233
234 /* Insert or replace an entry in a hash table.  This returns NULL on
235    success.  On error, it returns a printable string indicating the
236    error.  If an entry already exists, its value is replaced.  */
237
238 const char *
239 hash_jam (table, key, value)
240      struct hash_control *table;
241      const char *key;
242      PTR value;
243 {
244   struct hash_entry *p;
245   struct hash_entry **list;
246   unsigned long hash;
247
248   p = hash_lookup (table, key, &list, &hash);
249   if (p != NULL)
250     {
251 #ifdef HASH_STATISTICS
252       ++table->replacements;
253 #endif
254
255       p->data = value;
256     }
257   else
258     {
259 #ifdef HASH_STATISTICS
260       ++table->insertions;
261 #endif
262
263       p = (struct hash_entry *) obstack_alloc (&table->memory, sizeof (*p));
264       p->string = key;
265       p->hash = hash;
266       p->data = value;
267
268       p->next = *list;
269       *list = p;
270     }
271
272   return NULL;
273 }
274
275 /* Replace an existing entry in a hash table.  This returns the old
276    value stored for the entry.  If the entry is not found in the hash
277    table, this does nothing and returns NULL.  */
278
279 PTR
280 hash_replace (table, key, value)
281      struct hash_control *table;
282      const char *key;
283      PTR value;
284 {
285   struct hash_entry *p;
286   PTR ret;
287
288   p = hash_lookup (table, key, NULL, NULL);
289   if (p == NULL)
290     return NULL;
291
292 #ifdef HASH_STATISTICS
293   ++table->replacements;
294 #endif
295
296   ret = p->data;
297
298   p->data = value;
299
300   return ret;
301 }
302
303 /* Find an entry in a hash table, returning its value.  Returns NULL
304    if the entry is not found.  */
305
306 PTR
307 hash_find (table, key)
308      struct hash_control *table;
309      const char *key;
310 {
311   struct hash_entry *p;
312
313   p = hash_lookup (table, key, NULL, NULL);
314   if (p == NULL)
315     return NULL;
316
317   return p->data;
318 }
319
320 /* Delete an entry from a hash table.  This returns the value stored
321    for that entry, or NULL if there is no such entry.  */
322
323 PTR
324 hash_delete (table, key)
325      struct hash_control *table;
326      const char *key;
327 {
328   struct hash_entry *p;
329   struct hash_entry **list;
330
331   p = hash_lookup (table, key, &list, NULL);
332   if (p == NULL)
333     return NULL;
334
335   if (p != *list)
336     abort ();
337
338 #ifdef HASH_STATISTICS
339   ++table->deletions;
340 #endif
341
342   *list = p->next;
343
344   /* Note that we never reclaim the memory for this entry.  If gas
345      ever starts deleting hash table entries in a big way, this will
346      have to change.  */
347
348   return p->data;
349 }
350
351 /* Traverse a hash table.  Call the function on every entry in the
352    hash table.  */
353
354 void
355 hash_traverse (table, pfn)
356      struct hash_control *table;
357      void (*pfn) PARAMS ((const char *key, PTR value));
358 {
359   unsigned int i;
360
361   for (i = 0; i < table->size; ++i)
362     {
363       struct hash_entry *p;
364
365       for (p = table->table[i]; p != NULL; p = p->next)
366         (*pfn) (p->string, p->data);
367     }
368 }
369
370 /* Print hash table statistics on the specified file.  NAME is the
371    name of the hash table, used for printing a header.  */
372
373 void
374 hash_print_statistics (f, name, table)
375      FILE *f ATTRIBUTE_UNUSED;
376      const char *name ATTRIBUTE_UNUSED;
377      struct hash_control *table ATTRIBUTE_UNUSED;
378 {
379 #ifdef HASH_STATISTICS
380   unsigned int i;
381   unsigned long total;
382   unsigned long empty;
383
384   fprintf (f, "%s hash statistics:\n", name);
385   fprintf (f, "\t%lu lookups\n", table->lookups);
386   fprintf (f, "\t%lu hash comparisons\n", table->hash_compares);
387   fprintf (f, "\t%lu string comparisons\n", table->string_compares);
388   fprintf (f, "\t%lu insertions\n", table->insertions);
389   fprintf (f, "\t%lu replacements\n", table->replacements);
390   fprintf (f, "\t%lu deletions\n", table->deletions);
391
392   total = 0;
393   empty = 0;
394   for (i = 0; i < table->size; ++i)
395     {
396       struct hash_entry *p;
397
398       if (table->table[i] == NULL)
399         ++empty;
400       else
401         {
402           for (p = table->table[i]; p != NULL; p = p->next)
403             ++total;
404         }
405     }
406
407   fprintf (f, "\t%g average chain length\n", (double) total / table->size);
408   fprintf (f, "\t%lu empty slots\n", empty);
409 #endif
410 }
411 \f
412 #ifdef TEST
413
414 /* This test program is left over from the old hash table code.  */
415
416 /* Number of hash tables to maintain (at once) in any testing.  */
417 #define TABLES (6)
418
419 /* We can have 12 statistics.  */
420 #define STATBUFSIZE (12)
421
422 /* Display statistics here.  */
423 int statbuf[STATBUFSIZE];
424
425 /* Human farts here.  */
426 char answer[100];
427
428 /* We test many hash tables at once.  */
429 char *hashtable[TABLES];
430
431 /* Points to curent hash_control.  */
432 char *h;
433 char **pp;
434 char *p;
435 char *name;
436 char *value;
437 int size;
438 int used;
439 char command;
440
441 /* Number 0:TABLES-1 of current hashed symbol table.  */
442 int number;
443
444 int
445 main ()
446 {
447   void applicatee ();
448   void destroy ();
449   char *what ();
450   int *ip;
451
452   number = 0;
453   h = 0;
454   printf ("type h <RETURN> for help\n");
455   for (;;)
456     {
457       printf ("hash_test command: ");
458       gets (answer);
459       command = answer[0];
460       if (isupper (command))
461         command = tolower (command);    /* Ecch!  */
462       switch (command)
463         {
464         case '#':
465           printf ("old hash table #=%d.\n", number);
466           whattable ();
467           break;
468         case '?':
469           for (pp = hashtable; pp < hashtable + TABLES; pp++)
470             {
471               printf ("address of hash table #%d control block is %xx\n",
472                       pp - hashtable, *pp);
473             }
474           break;
475         case 'a':
476           hash_traverse (h, applicatee);
477           break;
478         case 'd':
479           hash_traverse (h, destroy);
480           hash_die (h);
481           break;
482         case 'f':
483           p = hash_find (h, name = what ("symbol"));
484           printf ("value of \"%s\" is \"%s\"\n", name, p ? p : "NOT-PRESENT");
485           break;
486         case 'h':
487           printf ("# show old, select new default hash table number\n");
488           printf ("? display all hashtable control block addresses\n");
489           printf ("a apply a simple display-er to each symbol in table\n");
490           printf ("d die: destroy hashtable\n");
491           printf ("f find value of nominated symbol\n");
492           printf ("h this help\n");
493           printf ("i insert value into symbol\n");
494           printf ("j jam value into symbol\n");
495           printf ("n new hashtable\n");
496           printf ("r replace a value with another\n");
497           printf ("s say what %% of table is used\n");
498           printf ("q exit this program\n");
499           printf ("x delete a symbol from table, report its value\n");
500           break;
501         case 'i':
502           p = hash_insert (h, name = what ("symbol"), value = what ("value"));
503           if (p)
504             {
505               printf ("symbol=\"%s\"  value=\"%s\"  error=%s\n", name, value,
506                       p);
507             }
508           break;
509         case 'j':
510           p = hash_jam (h, name = what ("symbol"), value = what ("value"));
511           if (p)
512             {
513               printf ("symbol=\"%s\"  value=\"%s\"  error=%s\n", name, value, p);
514             }
515           break;
516         case 'n':
517           h = hashtable[number] = (char *) hash_new ();
518           break;
519         case 'q':
520           exit (EXIT_SUCCESS);
521         case 'r':
522           p = hash_replace (h, name = what ("symbol"), value = what ("value"));
523           printf ("old value was \"%s\"\n", p ? p : "{}");
524           break;
525         case 's':
526           hash_say (h, statbuf, STATBUFSIZE);
527           for (ip = statbuf; ip < statbuf + STATBUFSIZE; ip++)
528             {
529               printf ("%d ", *ip);
530             }
531           printf ("\n");
532           break;
533         case 'x':
534           p = hash_delete (h, name = what ("symbol"));
535           printf ("old value was \"%s\"\n", p ? p : "{}");
536           break;
537         default:
538           printf ("I can't understand command \"%c\"\n", command);
539           break;
540         }
541     }
542 }
543
544 char *
545 what (description)
546      char *description;
547 {
548   char *retval;
549   char *malloc ();
550
551   printf ("   %s : ", description);
552   gets (answer);
553   /* Will one day clean up answer here.  */
554   retval = malloc (strlen (answer) + 1);
555   if (!retval)
556     {
557       error ("room");
558     }
559   (void) strcpy (retval, answer);
560   return (retval);
561 }
562
563 void
564 destroy (string, value)
565      char *string;
566      char *value;
567 {
568   free (string);
569   free (value);
570 }
571
572 void
573 applicatee (string, value)
574      char *string;
575      char *value;
576 {
577   printf ("%.20s-%.20s\n", string, value);
578 }
579
580 /* Determine number: what hash table to use.
581    Also determine h: points to hash_control.  */
582
583 void
584 whattable ()
585 {
586   for (;;)
587     {
588       printf ("   what hash table (%d:%d) ?  ", 0, TABLES - 1);
589       gets (answer);
590       sscanf (answer, "%d", &number);
591       if (number >= 0 && number < TABLES)
592         {
593           h = hashtable[number];
594           if (!h)
595             {
596               printf ("warning: current hash-table-#%d. has no hash-control\n", number);
597             }
598           return;
599         }
600       else
601         {
602           printf ("invalid hash table number: %d\n", number);
603         }
604     }
605 }
606
607 #endif /* TEST */