/* Hash tables.
- Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2001, 2003 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "hashtable.h"
/* The code below is a specialization of Vladimir Makarov's expandable
existing entry with a potential new one. Also, the ability to
delete members from the table has been removed. */
-static unsigned int calc_hash PARAMS ((const unsigned char *, unsigned int));
-static void ht_expand PARAMS ((hash_table *));
-
-/* Let particular systems override the size of a chunk. */
-#ifndef OBSTACK_CHUNK_SIZE
-#define OBSTACK_CHUNK_SIZE 0
-#endif
- /* Let them override the alloc and free routines too. */
-#ifndef OBSTACK_CHUNK_ALLOC
-#define OBSTACK_CHUNK_ALLOC xmalloc
-#endif
-#ifndef OBSTACK_CHUNK_FREE
-#define OBSTACK_CHUNK_FREE free
-#endif
-
-/* Initialise an obstack. */
-void
-gcc_obstack_init (obstack)
- struct obstack *obstack;
-{
- _obstack_begin (obstack, OBSTACK_CHUNK_SIZE, 0,
- (void *(*) PARAMS ((long))) OBSTACK_CHUNK_ALLOC,
- (void (*) PARAMS ((void *))) OBSTACK_CHUNK_FREE);
-}
+static unsigned int calc_hash (const unsigned char *, unsigned int);
+static void ht_expand (hash_table *);
/* Calculate the hash of the string STR of length LEN. */
static unsigned int
-calc_hash (str, len)
- const unsigned char *str;
- unsigned int len;
+calc_hash (const unsigned char *str, unsigned int len)
{
unsigned int n = len;
unsigned int r = 0;
/* Initialize an identifier hashtable. */
hash_table *
-ht_create (order)
- unsigned int order;
+ht_create (unsigned int order)
{
unsigned int nslots = 1 << order;
hash_table *table;
return table;
}
+/* Frees all memory associated with a hash table. */
+
+void
+ht_destroy (hash_table *table)
+{
+ obstack_free (&table->stack, NULL);
+ free (table->entries);
+ free (table);
+}
+
/* Returns the hash entry for the a STR of length LEN. If that string
already exists in the table, returns the existing entry, and, if
INSERT is CPP_ALLOCED, frees the last obstack object. If the
CPP_ALLOCED and the item is assumed to be at the top of the
obstack. */
hashnode
-ht_lookup (table, str, len, insert)
- hash_table *table;
- const unsigned char *str;
- unsigned int len;
- enum ht_lookup_option insert;
+ht_lookup (hash_table *table, const unsigned char *str, unsigned int len,
+ enum ht_lookup_option insert)
{
unsigned int hash = calc_hash (str, len);
unsigned int hash2;
if (node == NULL)
break;
- if (HT_LEN (node) == len && !memcmp (HT_STR (node), str, len))
+ if (node->hash_value == hash && HT_LEN (node) == len
+ && !memcmp (HT_STR (node), str, len))
{
if (insert == HT_ALLOCED)
/* The string we search for was placed at the end of the
obstack. Release it. */
- obstack_free (&table->stack, (PTR) str);
+ obstack_free (&table->stack, (void *) str);
return node;
}
table->entries[index] = node;
HT_LEN (node) = len;
+ node->hash_value = hash;
if (insert == HT_ALLOC)
- HT_STR (node) = obstack_copy (&table->stack, str, len + 1);
+ HT_STR (node) = obstack_copy0 (&table->stack, str, len);
else
HT_STR (node) = str;
/* Double the size of a hash table, re-hashing existing entries. */
static void
-ht_expand (table)
- hash_table *table;
+ht_expand (hash_table *table)
{
hashnode *nentries, *p, *limit;
unsigned int size, sizemask;
{
unsigned int index, hash, hash2;
- hash = calc_hash (HT_STR (*p), HT_LEN (*p));
+ hash = (*p)->hash_value;
hash2 = ((hash * 17) & sizemask) | 1;
index = hash & sizemask;
/* For all nodes in TABLE, callback CB with parameters TABLE->PFILE,
the node, and V. */
void
-ht_forall (table, cb, v)
- hash_table *table;
- ht_cb cb;
- const PTR v;
+ht_forall (hash_table *table, ht_cb cb, const void *v)
{
hashnode *p, *limit;
/* Dump allocation statistics to stderr. */
void
-ht_dump_statistics (table)
- hash_table *table;
+ht_dump_statistics (hash_table *table)
{
size_t nelts, nids, overhead, headers;
size_t total_bytes, longest, sum_of_squares;
nids++;
}
while (++p < limit);
-
+
nelts = table->nelements;
overhead = obstack_memory_used (&table->stack) - total_bytes;
headers = table->nslots * sizeof (hashnode);
/* Return the approximate positive square root of a number N. This is for
statistical reports, not code generation. */
double
-approx_sqrt (x)
- double x;
+approx_sqrt (double x)
{
double s, d;