You should have received a copy of the GNU General Public License
along with GAS; see the file COPYING. If not, write to the Free
- Software Foundation, 59 Temple Place - Suite 330, Boston, MA
- 02111-1307, USA. */
+ Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
+ 02110-1301, USA. */
/* This version of the hash table code is a wholescale replacement of
the old hash table code, which was fairly bad. This is based on
switch --reduce-memory-overheads, or set to other values by using
the --hash-size=<NUMBER> switch. */
-static unsigned int gas_hash_table_size = 65537;
+static unsigned long gas_hash_table_size = 65537;
void
-set_gas_hash_table_size (unsigned int size)
+set_gas_hash_table_size (unsigned long size)
{
gas_hash_table_size = size;
}
/* FIXME: This function should be amalgmated with bfd/hash.c:bfd_hash_set_default_size(). */
-static unsigned int
+static unsigned long
get_gas_hash_table_size (void)
{
/* Extend this prime list if you want more granularity of hash table size. */
- static const unsigned int hash_size_primes[] =
+ static const unsigned long hash_size_primes[] =
{
1021, 4051, 8599, 16699, 65537
};
struct hash_control *
hash_new (void)
{
- unsigned int size;
+ unsigned long size;
+ unsigned long alloc;
struct hash_control *ret;
- unsigned int alloc;
size = get_gas_hash_table_size ();
Each time we look up a string, we move it to the start of the list
for its hash code, to take advantage of referential locality. */
-static struct hash_entry *hash_lookup (struct hash_control *,
- const char *,
- struct hash_entry ***,
- unsigned long *);
-
static struct hash_entry *
-hash_lookup (struct hash_control *table, const char *key,
+hash_lookup (struct hash_control *table, const char *key, size_t len,
struct hash_entry ***plist, unsigned long *phash)
{
- register unsigned long hash;
- unsigned int len;
- register const unsigned char *s;
- register unsigned int c;
+ unsigned long hash;
+ size_t n;
+ unsigned int c;
unsigned int index;
struct hash_entry **list;
struct hash_entry *p;
#endif
hash = 0;
- len = 0;
- s = (const unsigned char *) key;
- while ((c = *s++) != '\0')
+ for (n = 0; n < len; n++)
{
+ c = key[n];
hash += c + (c << 17);
hash ^= hash >> 2;
- ++len;
}
hash += len + (len << 17);
hash ^= hash >> 2;
++table->string_compares;
#endif
- if (strcmp (p->string, key) == 0)
+ if (strncmp (p->string, key, len) == 0 && p->string[len] == '\0')
{
if (prev != NULL)
{
struct hash_entry **list;
unsigned long hash;
- p = hash_lookup (table, key, &list, &hash);
+ p = hash_lookup (table, key, strlen (key), &list, &hash);
if (p != NULL)
return "exists";
struct hash_entry **list;
unsigned long hash;
- p = hash_lookup (table, key, &list, &hash);
+ p = hash_lookup (table, key, strlen (key), &list, &hash);
if (p != NULL)
{
#ifdef HASH_STATISTICS
struct hash_entry *p;
PTR ret;
- p = hash_lookup (table, key, NULL, NULL);
+ p = hash_lookup (table, key, strlen (key), NULL, NULL);
if (p == NULL)
return NULL;
{
struct hash_entry *p;
- p = hash_lookup (table, key, NULL, NULL);
+ p = hash_lookup (table, key, strlen (key), NULL, NULL);
+ if (p == NULL)
+ return NULL;
+
+ return p->data;
+}
+
+/* As hash_find, but KEY is of length LEN and is not guaranteed to be
+ NUL-terminated. */
+
+PTR
+hash_find_n (struct hash_control *table, const char *key, size_t len)
+{
+ struct hash_entry *p;
+
+ p = hash_lookup (table, key, len, NULL, NULL);
if (p == NULL)
return NULL;
struct hash_entry *p;
struct hash_entry **list;
- p = hash_lookup (table, key, &list, NULL);
+ p = hash_lookup (table, key, strlen (key), &list, NULL);
if (p == NULL)
return NULL;