]> git.ipfire.org Git - thirdparty/gcc.git/blame - libiberty/hashtab.c
cpplib.h (cpp_reader): Remove if_stack.
[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
36dd3a44
JL
44#include <stdio.h>
45
a2f945c6
VM
46#include "libiberty.h"
47#include "hashtab.h"
48
a2f945c6
VM
49/* This macro defines reserved value for empty table entry. */
50
5194cf08 51#define EMPTY_ENTRY ((void *) 0)
a2f945c6
VM
52
53/* This macro defines reserved value for table entry which contained
54 a deleted element. */
55
56#define DELETED_ENTRY ((void *) 1)
57
0194e877 58static unsigned long higher_prime_number PARAMS ((unsigned long));
18a94a2f
MM
59static hashval_t hash_pointer PARAMS ((const void *));
60static int eq_pointer PARAMS ((const void *, const void *));
8e02c4d0
JH
61static void htab_expand PARAMS ((htab_t));
62static void **find_empty_slot_for_expand PARAMS ((htab_t, hashval_t));
18a94a2f
MM
63
64/* At some point, we could make these be NULL, and modify the
65 hash-table routines to handle NULL specially; that would avoid
66 function-call overhead for the common case of hashing pointers. */
67htab_hash htab_hash_pointer = hash_pointer;
68htab_eq htab_eq_pointer = eq_pointer;
0194e877 69
a2f945c6 70/* The following function returns the nearest prime number which is
e38992e8 71 greater than a given source number, N. */
a2f945c6
VM
72
73static unsigned long
5194cf08
ZW
74higher_prime_number (n)
75 unsigned long n;
a2f945c6
VM
76{
77 unsigned long i;
78
e38992e8
RK
79 /* Ensure we have a larger number and then force to odd. */
80 n++;
81 n |= 0x01;
82
83 /* All odd numbers < 9 are prime. */
5194cf08 84 if (n < 9)
e38992e8
RK
85 return n;
86
87 /* Otherwise find the next prime using a sieve. */
5194cf08
ZW
88
89 next:
e38992e8
RK
90
91 for (i = 3; i * i <= n; i += 2)
92 if (n % i == 0)
93 {
94 n += 2;
95 goto next;
96 }
5194cf08
ZW
97
98 return n;
a2f945c6
VM
99}
100
18a94a2f
MM
101/* Returns a hash code for P. */
102
4feeaae3 103static hashval_t
18a94a2f
MM
104hash_pointer (p)
105 const void *p;
106{
1d2da2e1 107 return (hashval_t) ((long)p >> 3);
18a94a2f
MM
108}
109
110/* Returns non-zero if P1 and P2 are equal. */
111
4feeaae3 112static int
18a94a2f
MM
113eq_pointer (p1, p2)
114 const void *p1;
115 const void *p2;
116{
117 return p1 == p2;
118}
119
a2f945c6
VM
120/* This function creates table with length slightly longer than given
121 source length. Created hash table is initiated as empty (all the
122 hash table entries are EMPTY_ENTRY). The function returns the
123 created hash table. */
124
5194cf08 125htab_t
5dc9cffd 126htab_create (size, hash_f, eq_f, del_f)
a2f945c6 127 size_t size;
5194cf08
ZW
128 htab_hash hash_f;
129 htab_eq eq_f;
5dc9cffd 130 htab_del del_f;
a2f945c6 131{
5194cf08 132 htab_t result;
a2f945c6
VM
133
134 size = higher_prime_number (size);
5194cf08
ZW
135 result = (htab_t) xcalloc (1, sizeof (struct htab));
136 result->entries = (void **) xcalloc (size, sizeof (void *));
a2f945c6 137 result->size = size;
5194cf08
ZW
138 result->hash_f = hash_f;
139 result->eq_f = eq_f;
5dc9cffd 140 result->del_f = del_f;
a2f945c6
VM
141 return result;
142}
143
144/* This function frees all memory allocated for given hash table.
145 Naturally the hash table must already exist. */
146
147void
5194cf08
ZW
148htab_delete (htab)
149 htab_t htab;
a2f945c6 150{
5dc9cffd 151 int i;
e38992e8 152
5dc9cffd
ZW
153 if (htab->del_f)
154 for (i = htab->size - 1; i >= 0; i--)
e38992e8
RK
155 if (htab->entries[i] != EMPTY_ENTRY
156 && htab->entries[i] != DELETED_ENTRY)
157 (*htab->del_f) (htab->entries[i]);
5dc9cffd 158
a2f945c6
VM
159 free (htab->entries);
160 free (htab);
161}
162
163/* This function clears all entries in the given hash table. */
164
165void
5194cf08
ZW
166htab_empty (htab)
167 htab_t htab;
a2f945c6 168{
5dc9cffd 169 int i;
e38992e8 170
5dc9cffd
ZW
171 if (htab->del_f)
172 for (i = htab->size - 1; i >= 0; i--)
e38992e8
RK
173 if (htab->entries[i] != EMPTY_ENTRY
174 && htab->entries[i] != DELETED_ENTRY)
175 (*htab->del_f) (htab->entries[i]);
5dc9cffd 176
5194cf08 177 memset (htab->entries, 0, htab->size * sizeof (void *));
a2f945c6
VM
178}
179
8c5d513f
BS
180/* Similar to htab_find_slot, but without several unwanted side effects:
181 - Does not call htab->eq_f when it finds an existing entry.
182 - Does not change the count of elements/searches/collisions in the
183 hash table.
184 This function also assumes there are no deleted entries in the table.
185 HASH is the hash value for the element to be inserted. */
e38992e8 186
8c5d513f
BS
187static void **
188find_empty_slot_for_expand (htab, hash)
189 htab_t htab;
b13eb66b 190 hashval_t hash;
8c5d513f
BS
191{
192 size_t size = htab->size;
b13eb66b 193 hashval_t hash2 = 1 + hash % (size - 2);
8c5d513f
BS
194 unsigned int index = hash % size;
195
196 for (;;)
197 {
198 void **slot = htab->entries + index;
e38992e8 199
8c5d513f
BS
200 if (*slot == EMPTY_ENTRY)
201 return slot;
e38992e8 202 else if (*slot == DELETED_ENTRY)
8c5d513f
BS
203 abort ();
204
205 index += hash2;
206 if (index >= size)
207 index -= size;
208 }
209}
210
a2f945c6
VM
211/* The following function changes size of memory allocated for the
212 entries and repeatedly inserts the table elements. The occupancy
213 of the table after the call will be about 50%. Naturally the hash
214 table must already exist. Remember also that the place of the
215 table entries is changed. */
216
217static void
5194cf08
ZW
218htab_expand (htab)
219 htab_t htab;
a2f945c6 220{
5194cf08
ZW
221 void **oentries;
222 void **olimit;
223 void **p;
224
225 oentries = htab->entries;
226 olimit = oentries + htab->size;
227
228 htab->size = higher_prime_number (htab->size * 2);
4feeaae3 229 htab->entries = (void **) xcalloc (htab->size, sizeof (void **));
5194cf08
ZW
230
231 htab->n_elements -= htab->n_deleted;
232 htab->n_deleted = 0;
233
234 p = oentries;
235 do
236 {
237 void *x = *p;
e38992e8 238
5194cf08
ZW
239 if (x != EMPTY_ENTRY && x != DELETED_ENTRY)
240 {
8c5d513f 241 void **q = find_empty_slot_for_expand (htab, (*htab->hash_f) (x));
e38992e8 242
5194cf08
ZW
243 *q = x;
244 }
e38992e8 245
5194cf08
ZW
246 p++;
247 }
248 while (p < olimit);
e38992e8 249
5194cf08 250 free (oentries);
a2f945c6
VM
251}
252
5194cf08
ZW
253/* This function searches for a hash table entry equal to the given
254 element. It cannot be used to insert or delete an element. */
255
256void *
8c5d513f 257htab_find_with_hash (htab, element, hash)
5194cf08
ZW
258 htab_t htab;
259 const void *element;
b13eb66b 260 hashval_t hash;
a2f945c6 261{
b13eb66b
MM
262 unsigned int index;
263 hashval_t hash2;
5194cf08 264 size_t size;
0194e877 265 void *entry;
5194cf08
ZW
266
267 htab->searches++;
268 size = htab->size;
5194cf08 269 index = hash % size;
a2f945c6 270
0194e877
ZW
271 entry = htab->entries[index];
272 if (entry == EMPTY_ENTRY
273 || (entry != DELETED_ENTRY && (*htab->eq_f) (entry, element)))
274 return entry;
275
276 hash2 = 1 + hash % (size - 2);
277
5194cf08 278 for (;;)
a2f945c6 279 {
5194cf08
ZW
280 htab->collisions++;
281 index += hash2;
282 if (index >= size)
283 index -= size;
0194e877
ZW
284
285 entry = htab->entries[index];
286 if (entry == EMPTY_ENTRY
287 || (entry != DELETED_ENTRY && (*htab->eq_f) (entry, element)))
288 return entry;
a2f945c6 289 }
5194cf08
ZW
290}
291
8c5d513f
BS
292/* Like htab_find_slot_with_hash, but compute the hash value from the
293 element. */
e38992e8 294
8c5d513f
BS
295void *
296htab_find (htab, element)
297 htab_t htab;
298 const void *element;
299{
300 return htab_find_with_hash (htab, element, (*htab->hash_f) (element));
301}
302
5194cf08
ZW
303/* This function searches for a hash table slot containing an entry
304 equal to the given element. To delete an entry, call this with
305 INSERT = 0, then call htab_clear_slot on the slot returned (possibly
306 after doing some checks). To insert an entry, call this with
307 INSERT = 1, then write the value you want into the returned slot. */
308
309void **
8c5d513f 310htab_find_slot_with_hash (htab, element, hash, insert)
5194cf08
ZW
311 htab_t htab;
312 const void *element;
b13eb66b 313 hashval_t hash;
e38992e8 314 enum insert_option insert;
5194cf08
ZW
315{
316 void **first_deleted_slot;
b13eb66b
MM
317 unsigned int index;
318 hashval_t hash2;
5194cf08
ZW
319 size_t size;
320
e38992e8 321 if (insert == INSERT && htab->size * 3 <= htab->n_elements * 4)
5194cf08
ZW
322 htab_expand (htab);
323
324 size = htab->size;
5194cf08
ZW
325 hash2 = 1 + hash % (size - 2);
326 index = hash % size;
327
a2f945c6 328 htab->searches++;
5194cf08
ZW
329 first_deleted_slot = NULL;
330
331 for (;;)
a2f945c6 332 {
5194cf08
ZW
333 void *entry = htab->entries[index];
334 if (entry == EMPTY_ENTRY)
335 {
e38992e8 336 if (insert == NO_INSERT)
5194cf08
ZW
337 return NULL;
338
339 htab->n_elements++;
340
341 if (first_deleted_slot)
a2f945c6 342 {
5194cf08
ZW
343 *first_deleted_slot = EMPTY_ENTRY;
344 return first_deleted_slot;
a2f945c6 345 }
5194cf08
ZW
346
347 return &htab->entries[index];
348 }
349
350 if (entry == DELETED_ENTRY)
351 {
352 if (!first_deleted_slot)
353 first_deleted_slot = &htab->entries[index];
354 }
e38992e8
RK
355 else if ((*htab->eq_f) (entry, element))
356 return &htab->entries[index];
5194cf08
ZW
357
358 htab->collisions++;
359 index += hash2;
360 if (index >= size)
361 index -= size;
a2f945c6 362 }
a2f945c6
VM
363}
364
8c5d513f
BS
365/* Like htab_find_slot_with_hash, but compute the hash value from the
366 element. */
e38992e8 367
8c5d513f
BS
368void **
369htab_find_slot (htab, element, insert)
370 htab_t htab;
371 const void *element;
e38992e8 372 enum insert_option insert;
8c5d513f
BS
373{
374 return htab_find_slot_with_hash (htab, element, (*htab->hash_f) (element),
375 insert);
376}
377
5194cf08
ZW
378/* This function deletes an element with the given value from hash
379 table. If there is no matching element in the hash table, this
380 function does nothing. */
a2f945c6
VM
381
382void
5194cf08
ZW
383htab_remove_elt (htab, element)
384 htab_t htab;
385 void *element;
a2f945c6 386{
5194cf08 387 void **slot;
a2f945c6 388
e38992e8 389 slot = htab_find_slot (htab, element, NO_INSERT);
5194cf08
ZW
390 if (*slot == EMPTY_ENTRY)
391 return;
392
5dc9cffd
ZW
393 if (htab->del_f)
394 (*htab->del_f) (*slot);
395
5194cf08
ZW
396 *slot = DELETED_ENTRY;
397 htab->n_deleted++;
a2f945c6
VM
398}
399
5194cf08
ZW
400/* This function clears a specified slot in a hash table. It is
401 useful when you've already done the lookup and don't want to do it
402 again. */
ed38f5d5
ZW
403
404void
5194cf08
ZW
405htab_clear_slot (htab, slot)
406 htab_t htab;
407 void **slot;
ed38f5d5
ZW
408{
409 if (slot < htab->entries || slot >= htab->entries + htab->size
410 || *slot == EMPTY_ENTRY || *slot == DELETED_ENTRY)
411 abort ();
e38992e8 412
5dc9cffd
ZW
413 if (htab->del_f)
414 (*htab->del_f) (*slot);
e38992e8 415
ed38f5d5 416 *slot = DELETED_ENTRY;
5194cf08 417 htab->n_deleted++;
ed38f5d5
ZW
418}
419
420/* This function scans over the entire hash table calling
421 CALLBACK for each live entry. If CALLBACK returns false,
422 the iteration stops. INFO is passed as CALLBACK's second
423 argument. */
424
425void
5194cf08
ZW
426htab_traverse (htab, callback, info)
427 htab_t htab;
428 htab_trav callback;
ed38f5d5
ZW
429 void *info;
430{
e38992e8
RK
431 void **slot = htab->entries;
432 void **limit = slot + htab->size;
433
5194cf08
ZW
434 do
435 {
436 void *x = *slot;
e38992e8 437
5194cf08 438 if (x != EMPTY_ENTRY && x != DELETED_ENTRY)
8c5d513f 439 if (!(*callback) (slot, info))
5194cf08
ZW
440 break;
441 }
442 while (++slot < limit);
ed38f5d5
ZW
443}
444
e38992e8 445/* Return the current size of given hash table. */
a2f945c6
VM
446
447size_t
5194cf08
ZW
448htab_size (htab)
449 htab_t htab;
a2f945c6
VM
450{
451 return htab->size;
452}
453
e38992e8 454/* Return the current number of elements in given hash table. */
a2f945c6
VM
455
456size_t
5194cf08
ZW
457htab_elements (htab)
458 htab_t htab;
a2f945c6 459{
5194cf08 460 return htab->n_elements - htab->n_deleted;
a2f945c6
VM
461}
462
e38992e8
RK
463/* Return the fraction of fixed collisions during all work with given
464 hash table. */
a2f945c6 465
5194cf08
ZW
466double
467htab_collisions (htab)
468 htab_t htab;
a2f945c6 469{
e38992e8 470 if (htab->searches == 0)
5194cf08 471 return 0.0;
e38992e8
RK
472
473 return (double) htab->collisions / (double) htab->searches;
a2f945c6 474}