]> git.ipfire.org Git - thirdparty/gcc.git/blame - libiberty/hashtab.c
hashtab.h (struct htab): Add member return_allocation_failure.
[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 *));
8e02c4d0 65static void 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
35e9340f 127 created hash table. */
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;
a2f945c6
VM
145 return result;
146}
147
148/* This function frees all memory allocated for given hash table.
149 Naturally the hash table must already exist. */
150
151void
5194cf08
ZW
152htab_delete (htab)
153 htab_t htab;
a2f945c6 154{
5dc9cffd 155 int i;
e38992e8 156
5dc9cffd
ZW
157 if (htab->del_f)
158 for (i = htab->size - 1; i >= 0; i--)
e38992e8
RK
159 if (htab->entries[i] != EMPTY_ENTRY
160 && htab->entries[i] != DELETED_ENTRY)
161 (*htab->del_f) (htab->entries[i]);
5dc9cffd 162
a2f945c6
VM
163 free (htab->entries);
164 free (htab);
165}
166
167/* This function clears all entries in the given hash table. */
168
169void
5194cf08
ZW
170htab_empty (htab)
171 htab_t htab;
a2f945c6 172{
5dc9cffd 173 int i;
e38992e8 174
5dc9cffd
ZW
175 if (htab->del_f)
176 for (i = htab->size - 1; i >= 0; i--)
e38992e8
RK
177 if (htab->entries[i] != EMPTY_ENTRY
178 && htab->entries[i] != DELETED_ENTRY)
179 (*htab->del_f) (htab->entries[i]);
5dc9cffd 180
35e9340f 181 memset (htab->entries, 0, htab->size * sizeof (PTR));
a2f945c6
VM
182}
183
8c5d513f
BS
184/* Similar to htab_find_slot, but without several unwanted side effects:
185 - Does not call htab->eq_f when it finds an existing entry.
186 - Does not change the count of elements/searches/collisions in the
187 hash table.
188 This function also assumes there are no deleted entries in the table.
189 HASH is the hash value for the element to be inserted. */
e38992e8 190
35e9340f 191static PTR *
8c5d513f
BS
192find_empty_slot_for_expand (htab, hash)
193 htab_t htab;
b13eb66b 194 hashval_t hash;
8c5d513f
BS
195{
196 size_t size = htab->size;
b13eb66b 197 hashval_t hash2 = 1 + hash % (size - 2);
8c5d513f
BS
198 unsigned int index = hash % size;
199
200 for (;;)
201 {
35e9340f 202 PTR *slot = htab->entries + index;
e38992e8 203
8c5d513f
BS
204 if (*slot == EMPTY_ENTRY)
205 return slot;
e38992e8 206 else if (*slot == DELETED_ENTRY)
8c5d513f
BS
207 abort ();
208
209 index += hash2;
210 if (index >= size)
211 index -= size;
212 }
213}
214
a2f945c6
VM
215/* The following function changes size of memory allocated for the
216 entries and repeatedly inserts the table elements. The occupancy
217 of the table after the call will be about 50%. Naturally the hash
218 table must already exist. Remember also that the place of the
35e9340f 219 table entries is changed. */
a2f945c6
VM
220
221static void
5194cf08
ZW
222htab_expand (htab)
223 htab_t htab;
a2f945c6 224{
35e9340f
HPN
225 PTR *oentries;
226 PTR *olimit;
227 PTR *p;
5194cf08
ZW
228
229 oentries = htab->entries;
230 olimit = oentries + htab->size;
231
232 htab->size = higher_prime_number (htab->size * 2);
35e9340f 233 htab->entries = (PTR *) xcalloc (htab->size, sizeof (PTR *));
5194cf08
ZW
234
235 htab->n_elements -= htab->n_deleted;
236 htab->n_deleted = 0;
237
238 p = oentries;
239 do
240 {
35e9340f 241 PTR x = *p;
e38992e8 242
5194cf08
ZW
243 if (x != EMPTY_ENTRY && x != DELETED_ENTRY)
244 {
35e9340f 245 PTR *q = find_empty_slot_for_expand (htab, (*htab->hash_f) (x));
e38992e8 246
5194cf08
ZW
247 *q = x;
248 }
e38992e8 249
5194cf08
ZW
250 p++;
251 }
252 while (p < olimit);
e38992e8 253
5194cf08 254 free (oentries);
a2f945c6
VM
255}
256
5194cf08
ZW
257/* This function searches for a hash table entry equal to the given
258 element. It cannot be used to insert or delete an element. */
259
35e9340f 260PTR
8c5d513f 261htab_find_with_hash (htab, element, hash)
5194cf08 262 htab_t htab;
35e9340f 263 const PTR element;
b13eb66b 264 hashval_t hash;
a2f945c6 265{
b13eb66b
MM
266 unsigned int index;
267 hashval_t hash2;
5194cf08 268 size_t size;
35e9340f 269 PTR entry;
5194cf08
ZW
270
271 htab->searches++;
272 size = htab->size;
5194cf08 273 index = hash % size;
a2f945c6 274
0194e877
ZW
275 entry = htab->entries[index];
276 if (entry == EMPTY_ENTRY
277 || (entry != DELETED_ENTRY && (*htab->eq_f) (entry, element)))
278 return entry;
279
280 hash2 = 1 + hash % (size - 2);
281
5194cf08 282 for (;;)
a2f945c6 283 {
5194cf08
ZW
284 htab->collisions++;
285 index += hash2;
286 if (index >= size)
287 index -= size;
0194e877
ZW
288
289 entry = htab->entries[index];
290 if (entry == EMPTY_ENTRY
291 || (entry != DELETED_ENTRY && (*htab->eq_f) (entry, element)))
292 return entry;
a2f945c6 293 }
5194cf08
ZW
294}
295
8c5d513f
BS
296/* Like htab_find_slot_with_hash, but compute the hash value from the
297 element. */
e38992e8 298
35e9340f 299PTR
8c5d513f
BS
300htab_find (htab, element)
301 htab_t htab;
35e9340f 302 const PTR element;
8c5d513f
BS
303{
304 return htab_find_with_hash (htab, element, (*htab->hash_f) (element));
305}
306
5194cf08
ZW
307/* This function searches for a hash table slot containing an entry
308 equal to the given element. To delete an entry, call this with
309 INSERT = 0, then call htab_clear_slot on the slot returned (possibly
310 after doing some checks). To insert an entry, call this with
311 INSERT = 1, then write the value you want into the returned slot. */
312
35e9340f 313PTR *
8c5d513f 314htab_find_slot_with_hash (htab, element, hash, insert)
5194cf08 315 htab_t htab;
35e9340f 316 const PTR element;
b13eb66b 317 hashval_t hash;
e38992e8 318 enum insert_option insert;
5194cf08 319{
35e9340f 320 PTR *first_deleted_slot;
b13eb66b
MM
321 unsigned int index;
322 hashval_t hash2;
5194cf08
ZW
323 size_t size;
324
e38992e8 325 if (insert == INSERT && htab->size * 3 <= htab->n_elements * 4)
5194cf08
ZW
326 htab_expand (htab);
327
328 size = htab->size;
5194cf08
ZW
329 hash2 = 1 + hash % (size - 2);
330 index = hash % size;
331
a2f945c6 332 htab->searches++;
5194cf08
ZW
333 first_deleted_slot = NULL;
334
335 for (;;)
a2f945c6 336 {
35e9340f 337 PTR entry = htab->entries[index];
5194cf08
ZW
338 if (entry == EMPTY_ENTRY)
339 {
e38992e8 340 if (insert == NO_INSERT)
5194cf08
ZW
341 return NULL;
342
343 htab->n_elements++;
344
345 if (first_deleted_slot)
a2f945c6 346 {
5194cf08
ZW
347 *first_deleted_slot = EMPTY_ENTRY;
348 return first_deleted_slot;
a2f945c6 349 }
5194cf08
ZW
350
351 return &htab->entries[index];
352 }
353
354 if (entry == DELETED_ENTRY)
355 {
356 if (!first_deleted_slot)
357 first_deleted_slot = &htab->entries[index];
358 }
e38992e8
RK
359 else if ((*htab->eq_f) (entry, element))
360 return &htab->entries[index];
5194cf08
ZW
361
362 htab->collisions++;
363 index += hash2;
364 if (index >= size)
365 index -= size;
a2f945c6 366 }
a2f945c6
VM
367}
368
8c5d513f
BS
369/* Like htab_find_slot_with_hash, but compute the hash value from the
370 element. */
e38992e8 371
35e9340f 372PTR *
8c5d513f
BS
373htab_find_slot (htab, element, insert)
374 htab_t htab;
35e9340f 375 const PTR element;
e38992e8 376 enum insert_option insert;
8c5d513f
BS
377{
378 return htab_find_slot_with_hash (htab, element, (*htab->hash_f) (element),
379 insert);
380}
381
5194cf08
ZW
382/* This function deletes an element with the given value from hash
383 table. If there is no matching element in the hash table, this
384 function does nothing. */
a2f945c6
VM
385
386void
5194cf08
ZW
387htab_remove_elt (htab, element)
388 htab_t htab;
35e9340f 389 PTR element;
a2f945c6 390{
35e9340f 391 PTR *slot;
a2f945c6 392
e38992e8 393 slot = htab_find_slot (htab, element, NO_INSERT);
5194cf08
ZW
394 if (*slot == EMPTY_ENTRY)
395 return;
396
5dc9cffd
ZW
397 if (htab->del_f)
398 (*htab->del_f) (*slot);
399
5194cf08
ZW
400 *slot = DELETED_ENTRY;
401 htab->n_deleted++;
a2f945c6
VM
402}
403
5194cf08
ZW
404/* This function clears a specified slot in a hash table. It is
405 useful when you've already done the lookup and don't want to do it
406 again. */
ed38f5d5
ZW
407
408void
5194cf08
ZW
409htab_clear_slot (htab, slot)
410 htab_t htab;
35e9340f 411 PTR *slot;
ed38f5d5
ZW
412{
413 if (slot < htab->entries || slot >= htab->entries + htab->size
414 || *slot == EMPTY_ENTRY || *slot == DELETED_ENTRY)
415 abort ();
e38992e8 416
5dc9cffd
ZW
417 if (htab->del_f)
418 (*htab->del_f) (*slot);
e38992e8 419
ed38f5d5 420 *slot = DELETED_ENTRY;
5194cf08 421 htab->n_deleted++;
ed38f5d5
ZW
422}
423
424/* This function scans over the entire hash table calling
425 CALLBACK for each live entry. If CALLBACK returns false,
426 the iteration stops. INFO is passed as CALLBACK's second
427 argument. */
428
429void
5194cf08
ZW
430htab_traverse (htab, callback, info)
431 htab_t htab;
432 htab_trav callback;
35e9340f 433 PTR info;
ed38f5d5 434{
35e9340f
HPN
435 PTR *slot = htab->entries;
436 PTR *limit = slot + htab->size;
e38992e8 437
5194cf08
ZW
438 do
439 {
35e9340f 440 PTR x = *slot;
e38992e8 441
5194cf08 442 if (x != EMPTY_ENTRY && x != DELETED_ENTRY)
8c5d513f 443 if (!(*callback) (slot, info))
5194cf08
ZW
444 break;
445 }
446 while (++slot < limit);
ed38f5d5
ZW
447}
448
e38992e8 449/* Return the current size of given hash table. */
a2f945c6
VM
450
451size_t
5194cf08
ZW
452htab_size (htab)
453 htab_t htab;
a2f945c6
VM
454{
455 return htab->size;
456}
457
e38992e8 458/* Return the current number of elements in given hash table. */
a2f945c6
VM
459
460size_t
5194cf08
ZW
461htab_elements (htab)
462 htab_t htab;
a2f945c6 463{
5194cf08 464 return htab->n_elements - htab->n_deleted;
a2f945c6
VM
465}
466
e38992e8
RK
467/* Return the fraction of fixed collisions during all work with given
468 hash table. */
a2f945c6 469
5194cf08
ZW
470double
471htab_collisions (htab)
472 htab_t htab;
a2f945c6 473{
e38992e8 474 if (htab->searches == 0)
5194cf08 475 return 0.0;
e38992e8
RK
476
477 return (double) htab->collisions / (double) htab->searches;
a2f945c6 478}