Browse Source

* bfd-in.h (bfd_hash_table): Add count field.

* bfd-in2.h: Regenerate.
* hash.c (higher_prime_number): New.
(bfd_hash_table_inint_n): Init count field.
(bfd_hash_lookup): Grow table as needed.
cr-0x5f1
DJ Delorie 21 years ago
parent
commit
aa149cf7d1
  1. 8
      bfd/ChangeLog
  2. 2
      bfd/bfd-in.h
  3. 2
      bfd/bfd-in2.h
  4. 101
      bfd/hash.c

8
bfd/ChangeLog

@ -1,3 +1,11 @@
2006-05-01 DJ Delorie <dj@redhat.com>
* bfd-in.h (bfd_hash_table): Add count field.
* bfd-in2.h: Regenerate.
* hash.c (higher_prime_number): New.
(bfd_hash_table_inint_n): Init count field.
(bfd_hash_lookup): Grow table as needed.
2006-04-27 Kaz Kojima <kkojima@rr.iij4u.or.jp> 2006-04-27 Kaz Kojima <kkojima@rr.iij4u.or.jp>
PR binutils/2584 PR binutils/2584

2
bfd/bfd-in.h

@ -376,6 +376,8 @@ struct bfd_hash_table
struct bfd_hash_entry **table; struct bfd_hash_entry **table;
/* The number of slots in the hash table. */ /* The number of slots in the hash table. */
unsigned int size; unsigned int size;
/* The number of entries in the hash table. */
unsigned int count;
/* The size of elements. */ /* The size of elements. */
unsigned int entsize; unsigned int entsize;
/* A function used to create new elements in the hash table. The /* A function used to create new elements in the hash table. The

2
bfd/bfd-in2.h

@ -383,6 +383,8 @@ struct bfd_hash_table
struct bfd_hash_entry **table; struct bfd_hash_entry **table;
/* The number of slots in the hash table. */ /* The number of slots in the hash table. */
unsigned int size; unsigned int size;
/* The number of entries in the hash table. */
unsigned int count;
/* The size of elements. */ /* The size of elements. */
unsigned int entsize; unsigned int entsize;
/* A function used to create new elements in the hash table. The /* A function used to create new elements in the hash table. The

101
bfd/hash.c

@ -298,7 +298,72 @@ SUBSUBSECTION
*/ */
/* The default number of entries to use when creating a hash table. */ /* The default number of entries to use when creating a hash table. */
#define DEFAULT_SIZE 4051 #define DEFAULT_SIZE (4093)
/* The following function returns a nearest prime number which is
greater than N, and near a power of two. Copied from libiberty. */
static unsigned long
higher_prime_number (unsigned long n)
{
/* These are primes that are near, but slightly smaller than, a
power of two. */
static const unsigned long primes[] = {
(unsigned long) 7,
(unsigned long) 13,
(unsigned long) 31,
(unsigned long) 61,
(unsigned long) 127,
(unsigned long) 251,
(unsigned long) 509,
(unsigned long) 1021,
(unsigned long) 2039,
(unsigned long) 4093,
(unsigned long) 8191,
(unsigned long) 16381,
(unsigned long) 32749,
(unsigned long) 65521,
(unsigned long) 131071,
(unsigned long) 262139,
(unsigned long) 524287,
(unsigned long) 1048573,
(unsigned long) 2097143,
(unsigned long) 4194301,
(unsigned long) 8388593,
(unsigned long) 16777213,
(unsigned long) 33554393,
(unsigned long) 67108859,
(unsigned long) 134217689,
(unsigned long) 268435399,
(unsigned long) 536870909,
(unsigned long) 1073741789,
(unsigned long) 2147483647,
/* 4294967291L */
((unsigned long) 2147483647) + ((unsigned long) 2147483644),
};
const unsigned long *low = &primes[0];
const unsigned long *high = &primes[sizeof(primes) / sizeof(primes[0])];
while (low != high)
{
const unsigned long *mid = low + (high - low) / 2;
if (n >= *mid)
low = mid + 1;
else
high = mid;
}
/* If we've run out of primes, abort. */
if (n > *low)
{
fprintf (stderr, "Cannot find prime bigger than %lu\n", n);
abort ();
}
return *low;
}
static size_t bfd_default_hash_table_size = DEFAULT_SIZE; static size_t bfd_default_hash_table_size = DEFAULT_SIZE;
/* Create a new hash table, given a number of entries. */ /* Create a new hash table, given a number of entries. */
@ -330,6 +395,7 @@ bfd_hash_table_init_n (struct bfd_hash_table *table,
memset ((void *) table->table, 0, alloc); memset ((void *) table->table, 0, alloc);
table->size = size; table->size = size;
table->entsize = entsize; table->entsize = entsize;
table->count = 0;
table->newfunc = newfunc; table->newfunc = newfunc;
return TRUE; return TRUE;
} }
@ -402,6 +468,7 @@ bfd_hash_lookup (struct bfd_hash_table *table,
if (copy) if (copy)
{ {
char *new; char *new;
table->count ++;
new = objalloc_alloc ((struct objalloc *) table->memory, len + 1); new = objalloc_alloc ((struct objalloc *) table->memory, len + 1);
if (!new) if (!new)
@ -417,6 +484,38 @@ bfd_hash_lookup (struct bfd_hash_table *table,
hashp->next = table->table[index]; hashp->next = table->table[index];
table->table[index] = hashp; table->table[index] = hashp;
if (table->count > table->size * 3 / 4)
{
int newsize = higher_prime_number (table->size);
struct bfd_hash_entry **newtable;
unsigned int hi;
unsigned int alloc;
alloc = newsize * sizeof (struct bfd_hash_entry *);
newtable = ((struct bfd_hash_entry **)
objalloc_alloc ((struct objalloc *) table->memory, alloc));
memset ((PTR) newtable, 0, alloc);
for (hi = 0; hi < table->size; hi ++)
while (table->table[hi])
{
struct bfd_hash_entry *chain = table->table[hi];
struct bfd_hash_entry *chain_end = chain;
int index;
while (chain_end->next && chain_end->next->hash == chain->hash)
chain_end = chain_end->next;
table->table[hi] = chain_end->next;
index = chain->hash % newsize;
chain_end->next = newtable[index];
newtable[index] = chain;
}
table->table = newtable;
table->size = newsize;
}
return hashp; return hashp;
} }

Loading…
Cancel
Save