]> git.ipfire.org Git - thirdparty/gcc.git/blame - libiberty/hashtab.c
Daily bump.
[thirdparty/gcc.git] / libiberty / hashtab.c
CommitLineData
a2f945c6
VM
1/* An expandable hash tables datatype.
2 Copyright (C) 1999 Free Software Foundation, Inc.
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#ifdef HAVE_STDLIB_H
39#include <stdlib.h>
40#endif
41
42#include "libiberty.h"
43#include "hashtab.h"
44
45/* The following variable is used for debugging. Its value is number
46 of all calls of `find_hash_table_entry' for all hash tables. */
47
48static int all_searches = 0;
49
50/* The following variable is used for debugging. Its value is number
51 of collisions fixed for time of work with all hash tables. */
52
53static int all_collisions = 0;
54
55/* The following variable is used for debugging. Its value is number
56 of all table expansions fixed for time of work with all hash
57 tables. */
58
59static int all_expansions = 0;
60
61/* This macro defines reserved value for empty table entry. */
62
63#define EMPTY_ENTRY NULL
64
65/* This macro defines reserved value for table entry which contained
66 a deleted element. */
67
68#define DELETED_ENTRY ((void *) 1)
69
70/* The following function returns the nearest prime number which is
71 greater than given source number. */
72
73static unsigned long
74higher_prime_number (number)
75 unsigned long number;
76{
77 unsigned long i;
78
79 for (number = (number / 2) * 2 + 3;; number += 2)
80 {
81 for (i = 3; i * i <= number; i += 2)
82 if (number % i == 0)
83 break;
84 if (i * i > number)
85 return number;
86 }
87}
88
89/* This function creates table with length slightly longer than given
90 source length. Created hash table is initiated as empty (all the
91 hash table entries are EMPTY_ENTRY). The function returns the
92 created hash table. */
93
94hash_table_t
95create_hash_table (size, hash_function, eq_function)
96 size_t size;
97 unsigned (*hash_function) PARAMS ((hash_table_entry_t));
98 int (*eq_function) PARAMS ((hash_table_entry_t, hash_table_entry_t));
99{
100 hash_table_t result;
101
102 size = higher_prime_number (size);
103 result = (hash_table_t) xmalloc (sizeof (*result));
104 result->entries
105 = (hash_table_entry_t *) xmalloc (size * sizeof (hash_table_entry_t));
106 result->size = size;
107 result->hash_function = hash_function;
108 result->eq_function = eq_function;
109 result->number_of_elements = 0;
110 result->number_of_deleted_elements = 0;
111 result->searches = 0;
112 result->collisions = 0;
113 memset (result->entries, 0, size * sizeof (hash_table_entry_t));
114 return result;
115}
116
117/* This function frees all memory allocated for given hash table.
118 Naturally the hash table must already exist. */
119
120void
121delete_hash_table (htab)
122 hash_table_t htab;
123{
124 free (htab->entries);
125 free (htab);
126}
127
128/* This function clears all entries in the given hash table. */
129
130void
131empty_hash_table (htab)
132 hash_table_t htab;
133{
134 memset (htab->entries, 0, htab->size * sizeof (hash_table_entry_t));
135}
136
137/* The following function changes size of memory allocated for the
138 entries and repeatedly inserts the table elements. The occupancy
139 of the table after the call will be about 50%. Naturally the hash
140 table must already exist. Remember also that the place of the
141 table entries is changed. */
142
143static void
144expand_hash_table (htab)
145 hash_table_t htab;
146{
147 hash_table_t new_htab;
148 hash_table_entry_t *entry_ptr;
149 hash_table_entry_t *new_entry_ptr;
150
151 new_htab = create_hash_table (htab->number_of_elements * 2,
152 htab->hash_function, htab->eq_function);
153 for (entry_ptr = htab->entries; entry_ptr < htab->entries + htab->size;
154 entry_ptr++)
155 if (*entry_ptr != EMPTY_ENTRY && *entry_ptr != DELETED_ENTRY)
156 {
157 new_entry_ptr = find_hash_table_entry (new_htab, *entry_ptr, 1);
158 *new_entry_ptr = (*entry_ptr);
159 }
160 free (htab->entries);
161 *htab = (*new_htab);
162 free (new_htab);
163}
164
165/* This function searches for hash table entry which contains element
166 equal to given value or empty entry in which given value can be
167 placed (if the element with given value does not exist in the
168 table). The function works in two regimes. The first regime is
169 used only for search. The second is used for search and
170 reservation empty entry for given value. The table is expanded if
171 occupancy (taking into accout also deleted elements) is more than
172 75%. Naturally the hash table must already exist. If reservation
173 flag is TRUE then the element with given value should be inserted
174 into the table entry before another call of
175 `find_hash_table_entry'. */
176
177hash_table_entry_t *
178find_hash_table_entry (htab, element, reserve)
179 hash_table_t htab;
180 hash_table_entry_t element;
181 int reserve;
182{
183 hash_table_entry_t *entry_ptr;
184 hash_table_entry_t *first_deleted_entry_ptr;
185 unsigned index, hash_value, secondary_hash_value;
186
187 if (htab->size * 3 <= htab->number_of_elements * 4)
188 {
189 all_expansions++;
190 expand_hash_table (htab);
191 }
192 hash_value = (*htab->hash_function) (element);
193 secondary_hash_value = 1 + hash_value % (htab->size - 2);
194 index = hash_value % htab->size;
195 htab->searches++;
196 all_searches++;
197 first_deleted_entry_ptr = NULL;
198 for (;;htab->collisions++, all_collisions++)
199 {
200 entry_ptr = htab->entries + index;
201 if (*entry_ptr == EMPTY_ENTRY)
202 {
203 if (reserve)
204 {
205 htab->number_of_elements++;
206 if (first_deleted_entry_ptr != NULL)
207 {
208 entry_ptr = first_deleted_entry_ptr;
209 *entry_ptr = DELETED_ENTRY;
210 }
211 }
212 break;
213 }
214 else if (*entry_ptr != DELETED_ENTRY)
215 {
216 if ((*htab->eq_function) (*entry_ptr, element))
217 break;
218 }
219 else if (first_deleted_entry_ptr == NULL)
220 first_deleted_entry_ptr = entry_ptr;
221 index += secondary_hash_value;
222 if (index >= htab->size)
223 index -= htab->size;
224 }
225 return entry_ptr;
226}
227
228/* This function deletes element with given value from hash table.
229 The hash table entry value will be `DELETED_ENTRY' after the
230 function call. Naturally the hash table must already exist. Hash
231 table entry for given value should be not empty (or deleted). */
232
233void
234remove_element_from_hash_table_entry (htab, element)
235 hash_table_t htab;
236 hash_table_entry_t element;
237{
238 hash_table_entry_t *entry_ptr;
239
240 entry_ptr = find_hash_table_entry (htab, element, 0);
241 *entry_ptr = DELETED_ENTRY;
242 htab->number_of_deleted_elements++;
243}
244
245/* The following function returns current size of given hash table. */
246
247size_t
248hash_table_size (htab)
249 hash_table_t htab;
250{
251 return htab->size;
252}
253
254/* The following function returns current number of elements in given
255 hash table. */
256
257size_t
258hash_table_elements_number (htab)
259 hash_table_t htab;
260{
261 return htab->number_of_elements - htab->number_of_deleted_elements;
262}
263
264/* The following function returns number of percents of fixed
265 collisions during all work with given hash table. */
266
267int
268hash_table_collisions (htab)
269 hash_table_t htab;
270{
271 int searches;
272
273 searches = htab->searches;
274 if (searches == 0)
275 searches++;
276 return htab->collisions * 100 / searches;
277}
278
279/* The following function returns number of percents of fixed
280 collisions during all work with all hash tables. */
281
282int
283all_hash_table_collisions ()
284{
285 int searches;
286
287 searches = all_searches;
288 if (searches == 0)
289 searches++;
290 return all_collisions * 100 / searches;
291}