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