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