Synced with libiberty in the gcc repository.
[deliverable/binutils-gdb.git] / libiberty / hashtab.c
CommitLineData
e2eaf477 1/* An expandable hash tables datatype.
eb383413 2 Copyright (C) 1999, 2000 Free Software Foundation, Inc.
e2eaf477
ILT
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
38#include <sys/types.h>
39
40#ifdef HAVE_STDLIB_H
41#include <stdlib.h>
42#endif
43
5c82d20a
ZW
44#ifdef HAVE_STRING_H
45#include <string.h>
46#endif
47
e2eaf477
ILT
48#include <stdio.h>
49
50#include "libiberty.h"
51#include "hashtab.h"
52
e2eaf477
ILT
53/* This macro defines reserved value for empty table entry. */
54
b4fe2683 55#define EMPTY_ENTRY ((void *) 0)
e2eaf477
ILT
56
57/* This macro defines reserved value for table entry which contained
58 a deleted element. */
59
60#define DELETED_ENTRY ((void *) 1)
61
eb383413
L
62static unsigned long higher_prime_number PARAMS ((unsigned long));
63static hashval_t hash_pointer PARAMS ((const void *));
64static int eq_pointer PARAMS ((const void *, const void *));
65static void htab_expand PARAMS ((htab_t));
66static void **find_empty_slot_for_expand PARAMS ((htab_t, hashval_t));
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;
73
e2eaf477 74/* The following function returns the nearest prime number which is
eb383413 75 greater than a given source number, N. */
e2eaf477
ILT
76
77static unsigned long
b4fe2683
JM
78higher_prime_number (n)
79 unsigned long n;
e2eaf477
ILT
80{
81 unsigned long i;
82
eb383413
L
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. */
b4fe2683 88 if (n < 9)
eb383413
L
89 return n;
90
91 /* Otherwise find the next prime using a sieve. */
b4fe2683
JM
92
93 next:
eb383413
L
94
95 for (i = 3; i * i <= n; i += 2)
96 if (n % i == 0)
97 {
98 n += 2;
99 goto next;
100 }
b4fe2683
JM
101
102 return n;
e2eaf477
ILT
103}
104
eb383413
L
105/* Returns a hash code for P. */
106
107static hashval_t
108hash_pointer (p)
109 const void *p;
110{
111 return (hashval_t) ((long)p >> 3);
112}
113
114/* Returns non-zero if P1 and P2 are equal. */
115
116static int
117eq_pointer (p1, p2)
118 const void *p1;
119 const void *p2;
120{
121 return p1 == p2;
122}
123
e2eaf477
ILT
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
127 created hash table. */
128
b4fe2683
JM
129htab_t
130htab_create (size, hash_f, eq_f, del_f)
e2eaf477 131 size_t size;
b4fe2683
JM
132 htab_hash hash_f;
133 htab_eq eq_f;
134 htab_del del_f;
e2eaf477 135{
b4fe2683 136 htab_t result;
e2eaf477
ILT
137
138 size = higher_prime_number (size);
b4fe2683
JM
139 result = (htab_t) xcalloc (1, sizeof (struct htab));
140 result->entries = (void **) xcalloc (size, sizeof (void *));
e2eaf477 141 result->size = size;
b4fe2683
JM
142 result->hash_f = hash_f;
143 result->eq_f = eq_f;
144 result->del_f = del_f;
e2eaf477
ILT
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
b4fe2683
JM
152htab_delete (htab)
153 htab_t htab;
e2eaf477 154{
b4fe2683 155 int i;
eb383413 156
b4fe2683
JM
157 if (htab->del_f)
158 for (i = htab->size - 1; i >= 0; i--)
eb383413
L
159 if (htab->entries[i] != EMPTY_ENTRY
160 && htab->entries[i] != DELETED_ENTRY)
161 (*htab->del_f) (htab->entries[i]);
b4fe2683 162
e2eaf477
ILT
163 free (htab->entries);
164 free (htab);
165}
166
167/* This function clears all entries in the given hash table. */
168
169void
b4fe2683
JM
170htab_empty (htab)
171 htab_t htab;
172{
173 int i;
eb383413 174
b4fe2683
JM
175 if (htab->del_f)
176 for (i = htab->size - 1; i >= 0; i--)
eb383413
L
177 if (htab->entries[i] != EMPTY_ENTRY
178 && htab->entries[i] != DELETED_ENTRY)
179 (*htab->del_f) (htab->entries[i]);
b4fe2683
JM
180
181 memset (htab->entries, 0, htab->size * sizeof (void *));
182}
183
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. */
eb383413 190
b4fe2683
JM
191static void **
192find_empty_slot_for_expand (htab, hash)
193 htab_t htab;
eb383413 194 hashval_t hash;
e2eaf477 195{
b4fe2683 196 size_t size = htab->size;
eb383413 197 hashval_t hash2 = 1 + hash % (size - 2);
b4fe2683
JM
198 unsigned int index = hash % size;
199
200 for (;;)
201 {
202 void **slot = htab->entries + index;
eb383413 203
b4fe2683
JM
204 if (*slot == EMPTY_ENTRY)
205 return slot;
eb383413 206 else if (*slot == DELETED_ENTRY)
b4fe2683
JM
207 abort ();
208
209 index += hash2;
210 if (index >= size)
211 index -= size;
212 }
e2eaf477
ILT
213}
214
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
219 table entries is changed. */
220
221static void
b4fe2683
JM
222htab_expand (htab)
223 htab_t htab;
e2eaf477 224{
b4fe2683
JM
225 void **oentries;
226 void **olimit;
227 void **p;
228
229 oentries = htab->entries;
230 olimit = oentries + htab->size;
231
232 htab->size = higher_prime_number (htab->size * 2);
eb383413 233 htab->entries = (void **) xcalloc (htab->size, sizeof (void **));
b4fe2683
JM
234
235 htab->n_elements -= htab->n_deleted;
236 htab->n_deleted = 0;
237
238 p = oentries;
239 do
240 {
241 void *x = *p;
eb383413 242
b4fe2683
JM
243 if (x != EMPTY_ENTRY && x != DELETED_ENTRY)
244 {
245 void **q = find_empty_slot_for_expand (htab, (*htab->hash_f) (x));
eb383413 246
b4fe2683
JM
247 *q = x;
248 }
eb383413 249
b4fe2683
JM
250 p++;
251 }
252 while (p < olimit);
eb383413 253
b4fe2683 254 free (oentries);
e2eaf477
ILT
255}
256
b4fe2683
JM
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
260void *
261htab_find_with_hash (htab, element, hash)
262 htab_t htab;
263 const void *element;
eb383413 264 hashval_t hash;
e2eaf477 265{
eb383413
L
266 unsigned int index;
267 hashval_t hash2;
b4fe2683 268 size_t size;
eb383413 269 void *entry;
e2eaf477 270
b4fe2683
JM
271 htab->searches++;
272 size = htab->size;
b4fe2683
JM
273 index = hash % size;
274
eb383413
L
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
b4fe2683 282 for (;;)
e2eaf477 283 {
b4fe2683
JM
284 htab->collisions++;
285 index += hash2;
286 if (index >= size)
287 index -= size;
eb383413
L
288
289 entry = htab->entries[index];
290 if (entry == EMPTY_ENTRY
291 || (entry != DELETED_ENTRY && (*htab->eq_f) (entry, element)))
292 return entry;
e2eaf477 293 }
b4fe2683
JM
294}
295
296/* Like htab_find_slot_with_hash, but compute the hash value from the
297 element. */
eb383413 298
b4fe2683
JM
299void *
300htab_find (htab, element)
301 htab_t htab;
302 const void *element;
303{
304 return htab_find_with_hash (htab, element, (*htab->hash_f) (element));
305}
306
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
313void **
314htab_find_slot_with_hash (htab, element, hash, insert)
315 htab_t htab;
316 const void *element;
eb383413
L
317 hashval_t hash;
318 enum insert_option insert;
b4fe2683
JM
319{
320 void **first_deleted_slot;
eb383413
L
321 unsigned int index;
322 hashval_t hash2;
b4fe2683
JM
323 size_t size;
324
eb383413 325 if (insert == INSERT && htab->size * 3 <= htab->n_elements * 4)
b4fe2683
JM
326 htab_expand (htab);
327
328 size = htab->size;
329 hash2 = 1 + hash % (size - 2);
330 index = hash % size;
331
e2eaf477 332 htab->searches++;
b4fe2683
JM
333 first_deleted_slot = NULL;
334
335 for (;;)
e2eaf477 336 {
b4fe2683
JM
337 void *entry = htab->entries[index];
338 if (entry == EMPTY_ENTRY)
339 {
eb383413 340 if (insert == NO_INSERT)
b4fe2683
JM
341 return NULL;
342
343 htab->n_elements++;
344
345 if (first_deleted_slot)
e2eaf477 346 {
b4fe2683
JM
347 *first_deleted_slot = EMPTY_ENTRY;
348 return first_deleted_slot;
e2eaf477 349 }
b4fe2683
JM
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 }
eb383413
L
359 else if ((*htab->eq_f) (entry, element))
360 return &htab->entries[index];
b4fe2683
JM
361
362 htab->collisions++;
363 index += hash2;
364 if (index >= size)
365 index -= size;
e2eaf477 366 }
e2eaf477
ILT
367}
368
b4fe2683
JM
369/* Like htab_find_slot_with_hash, but compute the hash value from the
370 element. */
eb383413 371
b4fe2683
JM
372void **
373htab_find_slot (htab, element, insert)
374 htab_t htab;
375 const void *element;
eb383413 376 enum insert_option insert;
b4fe2683
JM
377{
378 return htab_find_slot_with_hash (htab, element, (*htab->hash_f) (element),
379 insert);
380}
381
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. */
e2eaf477
ILT
385
386void
b4fe2683
JM
387htab_remove_elt (htab, element)
388 htab_t htab;
389 void *element;
e2eaf477 390{
b4fe2683
JM
391 void **slot;
392
eb383413 393 slot = htab_find_slot (htab, element, NO_INSERT);
b4fe2683
JM
394 if (*slot == EMPTY_ENTRY)
395 return;
396
397 if (htab->del_f)
398 (*htab->del_f) (*slot);
e2eaf477 399
b4fe2683
JM
400 *slot = DELETED_ENTRY;
401 htab->n_deleted++;
e2eaf477
ILT
402}
403
b4fe2683
JM
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. */
e2eaf477
ILT
407
408void
b4fe2683
JM
409htab_clear_slot (htab, slot)
410 htab_t htab;
411 void **slot;
e2eaf477
ILT
412{
413 if (slot < htab->entries || slot >= htab->entries + htab->size
414 || *slot == EMPTY_ENTRY || *slot == DELETED_ENTRY)
415 abort ();
eb383413 416
b4fe2683
JM
417 if (htab->del_f)
418 (*htab->del_f) (*slot);
eb383413 419
e2eaf477 420 *slot = DELETED_ENTRY;
b4fe2683 421 htab->n_deleted++;
e2eaf477
ILT
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
b4fe2683
JM
430htab_traverse (htab, callback, info)
431 htab_t htab;
432 htab_trav callback;
e2eaf477
ILT
433 void *info;
434{
eb383413
L
435 void **slot = htab->entries;
436 void **limit = slot + htab->size;
437
b4fe2683
JM
438 do
439 {
440 void *x = *slot;
eb383413 441
b4fe2683
JM
442 if (x != EMPTY_ENTRY && x != DELETED_ENTRY)
443 if (!(*callback) (slot, info))
444 break;
445 }
446 while (++slot < limit);
e2eaf477
ILT
447}
448
eb383413 449/* Return the current size of given hash table. */
e2eaf477
ILT
450
451size_t
b4fe2683
JM
452htab_size (htab)
453 htab_t htab;
e2eaf477
ILT
454{
455 return htab->size;
456}
457
eb383413 458/* Return the current number of elements in given hash table. */
e2eaf477
ILT
459
460size_t
b4fe2683
JM
461htab_elements (htab)
462 htab_t htab;
e2eaf477 463{
b4fe2683 464 return htab->n_elements - htab->n_deleted;
e2eaf477
ILT
465}
466
eb383413
L
467/* Return the fraction of fixed collisions during all work with given
468 hash table. */
e2eaf477 469
b4fe2683
JM
470double
471htab_collisions (htab)
472 htab_t htab;
e2eaf477 473{
eb383413 474 if (htab->searches == 0)
b4fe2683 475 return 0.0;
eb383413
L
476
477 return (double) htab->collisions / (double) htab->searches;
e2eaf477 478}
This page took 0.053546 seconds and 4 git commands to generate.