1 /* An expandable hash tables datatype.
2 Copyright (C) 1999 Free Software Foundation, Inc.
3 Contributed by Vladimir Makarov (vmakarov@cygnus.com).
5 This file is part of the libiberty library.
6 Libiberty is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public
8 License as published by the Free Software Foundation; either
9 version 2 of the License, or (at your option) any later version.
11 Libiberty is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Library General Public License for more details.
16 You should have received a copy of the GNU Library General Public
17 License along with libiberty; see the file COPYING.LIB. If
18 not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
21 /* This package implements basic hash table functionality. It is possible
22 to search for an entry, create an entry and destroy an entry.
24 Elements in the table are generic pointers.
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.
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. */
42 #include "libiberty.h"
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. */
48 static int all_searches
= 0;
50 /* The following variable is used for debugging. Its value is number
51 of collisions fixed for time of work with all hash tables. */
53 static int all_collisions
= 0;
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
59 static int all_expansions
= 0;
61 /* This macro defines reserved value for empty table entry. */
63 #define EMPTY_ENTRY NULL
65 /* This macro defines reserved value for table entry which contained
68 #define DELETED_ENTRY ((void *) 1)
70 /* The following function returns the nearest prime number which is
71 greater than given source number. */
74 higher_prime_number (number
)
79 for (number
= (number
/ 2) * 2 + 3;; number
+= 2)
81 for (i
= 3; i
* i
<= number
; i
+= 2)
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. */
95 create_hash_table (size
, hash_function
, eq_function
)
97 unsigned (*hash_function
) PARAMS ((hash_table_entry_t
));
98 int (*eq_function
) PARAMS ((hash_table_entry_t
, hash_table_entry_t
));
102 size
= higher_prime_number (size
);
103 result
= (hash_table_t
) xmalloc (sizeof (*result
));
105 = (hash_table_entry_t
*) xmalloc (size
* sizeof (hash_table_entry_t
));
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
));
117 /* This function frees all memory allocated for given hash table.
118 Naturally the hash table must already exist. */
121 delete_hash_table (htab
)
124 free (htab
->entries
);
128 /* This function clears all entries in the given hash table. */
131 empty_hash_table (htab
)
134 memset (htab
->entries
, 0, htab
->size
* sizeof (hash_table_entry_t
));
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. */
144 expand_hash_table (htab
)
147 hash_table_t new_htab
;
148 hash_table_entry_t
*entry_ptr
;
149 hash_table_entry_t
*new_entry_ptr
;
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
;
155 if (*entry_ptr
!= EMPTY_ENTRY
&& *entry_ptr
!= DELETED_ENTRY
)
157 new_entry_ptr
= find_hash_table_entry (new_htab
, *entry_ptr
, 1);
158 *new_entry_ptr
= (*entry_ptr
);
160 free (htab
->entries
);
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'. */
178 find_hash_table_entry (htab
, element
, reserve
)
180 hash_table_entry_t element
;
183 hash_table_entry_t
*entry_ptr
;
184 hash_table_entry_t
*first_deleted_entry_ptr
;
185 unsigned index
, hash_value
, secondary_hash_value
;
187 if (htab
->size
* 3 <= htab
->number_of_elements
* 4)
190 expand_hash_table (htab
);
192 hash_value
= (*htab
->hash_function
) (element
);
193 secondary_hash_value
= 1 + hash_value
% (htab
->size
- 2);
194 index
= hash_value
% htab
->size
;
197 first_deleted_entry_ptr
= NULL
;
198 for (;;htab
->collisions
++, all_collisions
++)
200 entry_ptr
= htab
->entries
+ index
;
201 if (*entry_ptr
== EMPTY_ENTRY
)
205 htab
->number_of_elements
++;
206 if (first_deleted_entry_ptr
!= NULL
)
208 entry_ptr
= first_deleted_entry_ptr
;
209 *entry_ptr
= EMPTY_ENTRY
;
214 else if (*entry_ptr
!= DELETED_ENTRY
)
216 if ((*htab
->eq_function
) (*entry_ptr
, element
))
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
)
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). */
234 remove_element_from_hash_table_entry (htab
, element
)
236 hash_table_entry_t element
;
238 hash_table_entry_t
*entry_ptr
;
240 entry_ptr
= find_hash_table_entry (htab
, element
, 0);
241 *entry_ptr
= DELETED_ENTRY
;
242 htab
->number_of_deleted_elements
++;
245 /* This function clears a specified slot in a hash table.
246 It is useful when you've already done the lookup and don't want to
250 clear_hash_table_slot (htab
, slot
)
252 hash_table_entry_t
*slot
;
254 if (slot
< htab
->entries
|| slot
>= htab
->entries
+ htab
->size
255 || *slot
== EMPTY_ENTRY
|| *slot
== DELETED_ENTRY
)
257 *slot
= DELETED_ENTRY
;
258 htab
->number_of_deleted_elements
++;
261 /* This function scans over the entire hash table calling
262 CALLBACK for each live entry. If CALLBACK returns false,
263 the iteration stops. INFO is passed as CALLBACK's second
267 traverse_hash_table (htab
, callback
, info
)
269 int (*callback
) (hash_table_entry_t
, void *);
272 hash_table_entry_t
*entry_ptr
;
273 for (entry_ptr
= htab
->entries
; entry_ptr
< htab
->entries
+ htab
->size
;
275 if (*entry_ptr
!= EMPTY_ENTRY
&& *entry_ptr
!= DELETED_ENTRY
)
276 if (!callback (*entry_ptr
, info
))
280 /* The following function returns current size of given hash table. */
283 hash_table_size (htab
)
289 /* The following function returns current number of elements in given
293 hash_table_elements_number (htab
)
296 return htab
->number_of_elements
- htab
->number_of_deleted_elements
;
299 /* The following function returns number of percents of fixed
300 collisions during all work with given hash table. */
303 hash_table_collisions (htab
)
308 searches
= htab
->searches
;
311 return htab
->collisions
* 100 / searches
;
314 /* The following function returns number of percents of fixed
315 collisions during all work with all hash tables. */
318 all_hash_table_collisions ()
322 searches
= all_searches
;
325 return all_collisions
* 100 / searches
;