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