]> git.ipfire.org Git - thirdparty/gcc.git/blame - libiberty/hashtab.c
Reverted erroneous Makefile.am commit
[thirdparty/gcc.git] / libiberty / hashtab.c
CommitLineData
a2f945c6 1/* An expandable hash tables datatype.
b13eb66b 2 Copyright (C) 1999, 2000 Free Software Foundation, Inc.
a2f945c6
VM
3 Contributed by Vladimir Makarov (vmakarov@cygnus.com).
4
5This file is part of the libiberty library.
6Libiberty is free software; you can redistribute it and/or
7modify it under the terms of the GNU Library General Public
8License as published by the Free Software Foundation; either
9version 2 of the License, or (at your option) any later version.
10
11Libiberty is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14Library General Public License for more details.
15
16You should have received a copy of the GNU Library General Public
17License along with libiberty; see the file COPYING.LIB. If
18not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19Boston, MA 02111-1307, USA. */
20
21/* This package implements basic hash table functionality. It is possible
22 to search for an entry, create an entry and destroy an entry.
23
24 Elements in the table are generic pointers.
25
26 The size of the table is not fixed; if the occupancy of the table
27 grows too high the hash table will be expanded.
28
29 The abstract data implementation is based on generalized Algorithm D
30 from Knuth's book "The art of computer programming". Hash table is
31 expanded by creation of new hash table and transferring elements from
32 the old table to the new table. */
33
34#ifdef HAVE_CONFIG_H
35#include "config.h"
36#endif
37
6de9b8ff
PDM
38#include <sys/types.h>
39
a2f945c6
VM
40#ifdef HAVE_STDLIB_H
41#include <stdlib.h>
42#endif
43
d11ec6f0
ZW
44#ifdef HAVE_STRING_H
45#include <string.h>
46#endif
47
36dd3a44
JL
48#include <stdio.h>
49
a2f945c6
VM
50#include "libiberty.h"
51#include "hashtab.h"
52
a2f945c6
VM
53/* This macro defines reserved value for empty table entry. */
54
35e9340f 55#define EMPTY_ENTRY ((PTR) 0)
a2f945c6
VM
56
57/* This macro defines reserved value for table entry which contained
58 a deleted element. */
59
35e9340f 60#define DELETED_ENTRY ((PTR) 1)
a2f945c6 61
0194e877 62static unsigned long higher_prime_number PARAMS ((unsigned long));
18a94a2f
MM
63static hashval_t hash_pointer PARAMS ((const void *));
64static int eq_pointer PARAMS ((const void *, const void *));
d50d20ec 65static int htab_expand PARAMS ((htab_t));
35e9340f 66static PTR *find_empty_slot_for_expand PARAMS ((htab_t, hashval_t));
18a94a2f
MM
67
68/* At some point, we could make these be NULL, and modify the
69 hash-table routines to handle NULL specially; that would avoid
70 function-call overhead for the common case of hashing pointers. */
71htab_hash htab_hash_pointer = hash_pointer;
72htab_eq htab_eq_pointer = eq_pointer;
0194e877 73
a2f945c6 74/* The following function returns the nearest prime number which is
e38992e8 75 greater than a given source number, N. */
a2f945c6
VM
76
77static unsigned long
5194cf08
ZW
78higher_prime_number (n)
79 unsigned long n;
a2f945c6
VM
80{
81 unsigned long i;
82
e38992e8
RK
83 /* Ensure we have a larger number and then force to odd. */
84 n++;
85 n |= 0x01;
86
87 /* All odd numbers < 9 are prime. */
5194cf08 88 if (n < 9)
e38992e8
RK
89 return n;
90
91 /* Otherwise find the next prime using a sieve. */
5194cf08
ZW
92
93 next:
e38992e8
RK
94
95 for (i = 3; i * i <= n; i += 2)
96 if (n % i == 0)
97 {
98 n += 2;
99 goto next;
100 }
5194cf08
ZW
101
102 return n;
a2f945c6
VM
103}
104
18a94a2f
MM
105/* Returns a hash code for P. */
106
4feeaae3 107static hashval_t
18a94a2f 108hash_pointer (p)
35e9340f 109 const PTR p;
18a94a2f 110{
1d2da2e1 111 return (hashval_t) ((long)p >> 3);
18a94a2f
MM
112}
113
114/* Returns non-zero if P1 and P2 are equal. */
115
4feeaae3 116static int
18a94a2f 117eq_pointer (p1, p2)
35e9340f
HPN
118 const PTR p1;
119 const PTR p2;
18a94a2f
MM
120{
121 return p1 == p2;
122}
123
a2f945c6
VM
124/* This function creates table with length slightly longer than given
125 source length. Created hash table is initiated as empty (all the
126 hash table entries are EMPTY_ENTRY). The function returns the
d50d20ec 127 created hash table. Memory allocation must not fail. */
a2f945c6 128
5194cf08 129htab_t
5dc9cffd 130htab_create (size, hash_f, eq_f, del_f)
a2f945c6 131 size_t size;
5194cf08
ZW
132 htab_hash hash_f;
133 htab_eq eq_f;
5dc9cffd 134 htab_del del_f;
a2f945c6 135{
5194cf08 136 htab_t result;
a2f945c6
VM
137
138 size = higher_prime_number (size);
5194cf08 139 result = (htab_t) xcalloc (1, sizeof (struct htab));
35e9340f 140 result->entries = (PTR *) xcalloc (size, sizeof (PTR));
a2f945c6 141 result->size = size;
5194cf08
ZW
142 result->hash_f = hash_f;
143 result->eq_f = eq_f;
5dc9cffd 144 result->del_f = del_f;
d50d20ec
HPN
145 result->return_allocation_failure = 0;
146 return result;
147}
148
149/* This function creates table with length slightly longer than given
150 source length. The created hash table is initiated as empty (all the
151 hash table entries are EMPTY_ENTRY). The function returns the created
152 hash table. Memory allocation may fail; it may return NULL. */
153
154htab_t
155htab_try_create (size, hash_f, eq_f, del_f)
156 size_t size;
157 htab_hash hash_f;
158 htab_eq eq_f;
159 htab_del del_f;
160{
161 htab_t result;
162
163 size = higher_prime_number (size);
164 result = (htab_t) calloc (1, sizeof (struct htab));
165 if (result == NULL)
166 return NULL;
167
168 result->entries = (PTR *) calloc (size, sizeof (PTR));
169 if (result->entries == NULL)
170 {
171 free (result);
172 return NULL;
173 }
174
175 result->size = size;
176 result->hash_f = hash_f;
177 result->eq_f = eq_f;
178 result->del_f = del_f;
179 result->return_allocation_failure = 1;
a2f945c6
VM
180 return result;
181}
182
183/* This function frees all memory allocated for given hash table.
184 Naturally the hash table must already exist. */
185
186void
5194cf08
ZW
187htab_delete (htab)
188 htab_t htab;
a2f945c6 189{
5dc9cffd 190 int i;
e38992e8 191
5dc9cffd
ZW
192 if (htab->del_f)
193 for (i = htab->size - 1; i >= 0; i--)
e38992e8
RK
194 if (htab->entries[i] != EMPTY_ENTRY
195 && htab->entries[i] != DELETED_ENTRY)
196 (*htab->del_f) (htab->entries[i]);
5dc9cffd 197
a2f945c6
VM
198 free (htab->entries);
199 free (htab);
200}
201
202/* This function clears all entries in the given hash table. */
203
204void
5194cf08
ZW
205htab_empty (htab)
206 htab_t htab;
a2f945c6 207{
5dc9cffd 208 int i;
e38992e8 209
5dc9cffd
ZW
210 if (htab->del_f)
211 for (i = htab->size - 1; i >= 0; i--)
e38992e8
RK
212 if (htab->entries[i] != EMPTY_ENTRY
213 && htab->entries[i] != DELETED_ENTRY)
214 (*htab->del_f) (htab->entries[i]);
5dc9cffd 215
35e9340f 216 memset (htab->entries, 0, htab->size * sizeof (PTR));
a2f945c6
VM
217}
218
8c5d513f
BS
219/* Similar to htab_find_slot, but without several unwanted side effects:
220 - Does not call htab->eq_f when it finds an existing entry.
221 - Does not change the count of elements/searches/collisions in the
222 hash table.
223 This function also assumes there are no deleted entries in the table.
224 HASH is the hash value for the element to be inserted. */
e38992e8 225
35e9340f 226static PTR *
8c5d513f
BS
227find_empty_slot_for_expand (htab, hash)
228 htab_t htab;
b13eb66b 229 hashval_t hash;
8c5d513f
BS
230{
231 size_t size = htab->size;
b13eb66b 232 hashval_t hash2 = 1 + hash % (size - 2);
8c5d513f
BS
233 unsigned int index = hash % size;
234
235 for (;;)
236 {
35e9340f 237 PTR *slot = htab->entries + index;
e38992e8 238
8c5d513f
BS
239 if (*slot == EMPTY_ENTRY)
240 return slot;
e38992e8 241 else if (*slot == DELETED_ENTRY)
8c5d513f
BS
242 abort ();
243
244 index += hash2;
245 if (index >= size)
246 index -= size;
247 }
248}
249
a2f945c6
VM
250/* The following function changes size of memory allocated for the
251 entries and repeatedly inserts the table elements. The occupancy
252 of the table after the call will be about 50%. Naturally the hash
253 table must already exist. Remember also that the place of the
d50d20ec
HPN
254 table entries is changed. If memory allocation failures are allowed,
255 this function will return zero, indicating that the table could not be
256 expanded. If all goes well, it will return a non-zero value. */
a2f945c6 257
d50d20ec 258static int
5194cf08
ZW
259htab_expand (htab)
260 htab_t htab;
a2f945c6 261{
35e9340f
HPN
262 PTR *oentries;
263 PTR *olimit;
264 PTR *p;
5194cf08
ZW
265
266 oentries = htab->entries;
267 olimit = oentries + htab->size;
268
269 htab->size = higher_prime_number (htab->size * 2);
d50d20ec
HPN
270
271 if (htab->return_allocation_failure)
272 {
273 PTR *nentries = (PTR *) calloc (htab->size, sizeof (PTR *));
274 if (nentries == NULL)
275 return 0;
276 htab->entries = nentries;
277 }
278 else
279 htab->entries = (PTR *) xcalloc (htab->size, sizeof (PTR *));
5194cf08
ZW
280
281 htab->n_elements -= htab->n_deleted;
282 htab->n_deleted = 0;
283
284 p = oentries;
285 do
286 {
35e9340f 287 PTR x = *p;
e38992e8 288
5194cf08
ZW
289 if (x != EMPTY_ENTRY && x != DELETED_ENTRY)
290 {
35e9340f 291 PTR *q = find_empty_slot_for_expand (htab, (*htab->hash_f) (x));
e38992e8 292
5194cf08
ZW
293 *q = x;
294 }
e38992e8 295
5194cf08
ZW
296 p++;
297 }
298 while (p < olimit);
e38992e8 299
5194cf08 300 free (oentries);
d50d20ec 301 return 1;
a2f945c6
VM
302}
303
5194cf08
ZW
304/* This function searches for a hash table entry equal to the given
305 element. It cannot be used to insert or delete an element. */
306
35e9340f 307PTR
8c5d513f 308htab_find_with_hash (htab, element, hash)
5194cf08 309 htab_t htab;
35e9340f 310 const PTR element;
b13eb66b 311 hashval_t hash;
a2f945c6 312{
b13eb66b
MM
313 unsigned int index;
314 hashval_t hash2;
5194cf08 315 size_t size;
35e9340f 316 PTR entry;
5194cf08
ZW
317
318 htab->searches++;
319 size = htab->size;
5194cf08 320 index = hash % size;
a2f945c6 321
0194e877
ZW
322 entry = htab->entries[index];
323 if (entry == EMPTY_ENTRY
324 || (entry != DELETED_ENTRY && (*htab->eq_f) (entry, element)))
325 return entry;
326
327 hash2 = 1 + hash % (size - 2);
328
5194cf08 329 for (;;)
a2f945c6 330 {
5194cf08
ZW
331 htab->collisions++;
332 index += hash2;
333 if (index >= size)
334 index -= size;
0194e877
ZW
335
336 entry = htab->entries[index];
337 if (entry == EMPTY_ENTRY
338 || (entry != DELETED_ENTRY && (*htab->eq_f) (entry, element)))
339 return entry;
a2f945c6 340 }
5194cf08
ZW
341}
342
8c5d513f
BS
343/* Like htab_find_slot_with_hash, but compute the hash value from the
344 element. */
e38992e8 345
35e9340f 346PTR
8c5d513f
BS
347htab_find (htab, element)
348 htab_t htab;
35e9340f 349 const PTR element;
8c5d513f
BS
350{
351 return htab_find_with_hash (htab, element, (*htab->hash_f) (element));
352}
353
5194cf08
ZW
354/* This function searches for a hash table slot containing an entry
355 equal to the given element. To delete an entry, call this with
356 INSERT = 0, then call htab_clear_slot on the slot returned (possibly
357 after doing some checks). To insert an entry, call this with
d50d20ec
HPN
358 INSERT = 1, then write the value you want into the returned slot.
359 When inserting an entry, NULL may be returned if memory allocation
360 fails. */
5194cf08 361
35e9340f 362PTR *
8c5d513f 363htab_find_slot_with_hash (htab, element, hash, insert)
5194cf08 364 htab_t htab;
35e9340f 365 const PTR element;
b13eb66b 366 hashval_t hash;
e38992e8 367 enum insert_option insert;
5194cf08 368{
35e9340f 369 PTR *first_deleted_slot;
b13eb66b
MM
370 unsigned int index;
371 hashval_t hash2;
5194cf08
ZW
372 size_t size;
373
d50d20ec
HPN
374 if (insert == INSERT && htab->size * 3 <= htab->n_elements * 4
375 && htab_expand (htab) == 0)
376 return NULL;
5194cf08
ZW
377
378 size = htab->size;
5194cf08
ZW
379 hash2 = 1 + hash % (size - 2);
380 index = hash % size;
381
a2f945c6 382 htab->searches++;
5194cf08
ZW
383 first_deleted_slot = NULL;
384
385 for (;;)
a2f945c6 386 {
35e9340f 387 PTR entry = htab->entries[index];
5194cf08
ZW
388 if (entry == EMPTY_ENTRY)
389 {
e38992e8 390 if (insert == NO_INSERT)
5194cf08
ZW
391 return NULL;
392
393 htab->n_elements++;
394
395 if (first_deleted_slot)
a2f945c6 396 {
5194cf08
ZW
397 *first_deleted_slot = EMPTY_ENTRY;
398 return first_deleted_slot;
a2f945c6 399 }
5194cf08
ZW
400
401 return &htab->entries[index];
402 }
403
404 if (entry == DELETED_ENTRY)
405 {
406 if (!first_deleted_slot)
407 first_deleted_slot = &htab->entries[index];
408 }
e38992e8
RK
409 else if ((*htab->eq_f) (entry, element))
410 return &htab->entries[index];
5194cf08
ZW
411
412 htab->collisions++;
413 index += hash2;
414 if (index >= size)
415 index -= size;
a2f945c6 416 }
a2f945c6
VM
417}
418
8c5d513f
BS
419/* Like htab_find_slot_with_hash, but compute the hash value from the
420 element. */
e38992e8 421
35e9340f 422PTR *
8c5d513f
BS
423htab_find_slot (htab, element, insert)
424 htab_t htab;
35e9340f 425 const PTR element;
e38992e8 426 enum insert_option insert;
8c5d513f
BS
427{
428 return htab_find_slot_with_hash (htab, element, (*htab->hash_f) (element),
429 insert);
430}
431
5194cf08
ZW
432/* This function deletes an element with the given value from hash
433 table. If there is no matching element in the hash table, this
434 function does nothing. */
a2f945c6
VM
435
436void
5194cf08
ZW
437htab_remove_elt (htab, element)
438 htab_t htab;
35e9340f 439 PTR element;
a2f945c6 440{
35e9340f 441 PTR *slot;
a2f945c6 442
e38992e8 443 slot = htab_find_slot (htab, element, NO_INSERT);
5194cf08
ZW
444 if (*slot == EMPTY_ENTRY)
445 return;
446
5dc9cffd
ZW
447 if (htab->del_f)
448 (*htab->del_f) (*slot);
449
5194cf08
ZW
450 *slot = DELETED_ENTRY;
451 htab->n_deleted++;
a2f945c6
VM
452}
453
5194cf08
ZW
454/* This function clears a specified slot in a hash table. It is
455 useful when you've already done the lookup and don't want to do it
456 again. */
ed38f5d5
ZW
457
458void
5194cf08
ZW
459htab_clear_slot (htab, slot)
460 htab_t htab;
35e9340f 461 PTR *slot;
ed38f5d5
ZW
462{
463 if (slot < htab->entries || slot >= htab->entries + htab->size
464 || *slot == EMPTY_ENTRY || *slot == DELETED_ENTRY)
465 abort ();
e38992e8 466
5dc9cffd
ZW
467 if (htab->del_f)
468 (*htab->del_f) (*slot);
e38992e8 469
ed38f5d5 470 *slot = DELETED_ENTRY;
5194cf08 471 htab->n_deleted++;
ed38f5d5
ZW
472}
473
474/* This function scans over the entire hash table calling
475 CALLBACK for each live entry. If CALLBACK returns false,
476 the iteration stops. INFO is passed as CALLBACK's second
477 argument. */
478
479void
5194cf08
ZW
480htab_traverse (htab, callback, info)
481 htab_t htab;
482 htab_trav callback;
35e9340f 483 PTR info;
ed38f5d5 484{
35e9340f
HPN
485 PTR *slot = htab->entries;
486 PTR *limit = slot + htab->size;
e38992e8 487
5194cf08
ZW
488 do
489 {
35e9340f 490 PTR x = *slot;
e38992e8 491
5194cf08 492 if (x != EMPTY_ENTRY && x != DELETED_ENTRY)
8c5d513f 493 if (!(*callback) (slot, info))
5194cf08
ZW
494 break;
495 }
496 while (++slot < limit);
ed38f5d5
ZW
497}
498
e38992e8 499/* Return the current size of given hash table. */
a2f945c6
VM
500
501size_t
5194cf08
ZW
502htab_size (htab)
503 htab_t htab;
a2f945c6
VM
504{
505 return htab->size;
506}
507
e38992e8 508/* Return the current number of elements in given hash table. */
a2f945c6
VM
509
510size_t
5194cf08
ZW
511htab_elements (htab)
512 htab_t htab;
a2f945c6 513{
5194cf08 514 return htab->n_elements - htab->n_deleted;
a2f945c6
VM
515}
516
e38992e8
RK
517/* Return the fraction of fixed collisions during all work with given
518 hash table. */
a2f945c6 519
5194cf08
ZW
520double
521htab_collisions (htab)
522 htab_t htab;
a2f945c6 523{
e38992e8 524 if (htab->searches == 0)
5194cf08 525 return 0.0;
e38992e8
RK
526
527 return (double) htab->collisions / (double) htab->searches;
a2f945c6 528}