1 /* Copyright (C) 2000-2010 Red Hat, Inc.
2 This file is part of elfutils.
3 Written by Ulrich Drepper <drepper@redhat.com>, 2000.
5 This file is free software; you can redistribute it and/or modify
6 it under the terms of either
8 * the GNU Lesser General Public License as published by the Free
9 Software Foundation; either version 3 of the License, or (at
10 your option) any later version
14 * the GNU General Public License as published by the Free
15 Software Foundation; either version 2 of the License, or (at
16 your option) any later version
18 or both in parallel, as here.
20 elfutils is distributed in the hope that it will be useful, but
21 WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 General Public License for more details.
25 You should have received copies of the GNU General Public License and
26 the GNU Lesser General Public License along with this program. If
27 not, see <http://www.gnu.org/licenses/>. */
33 /* Before including this file the following macros must be defined:
35 NAME name of the hash table structure.
36 TYPE data type of the hash table entries
37 COMPARE comparison function taking two pointers to TYPE objects
39 The following macros if present select features:
41 ITERATE iterating over the table entries is possible
42 REVERSE iterate in reverse order of insert
47 lookup (htab, hval, val)
50 TYPE val __attribute__ ((unused));
52 /* First hash function: simply take the modul but prevent zero. */
53 size_t idx = 1 + hval % htab->size;
55 if (htab->table[idx].hashval != 0)
59 if (htab->table[idx].hashval == hval
60 && COMPARE (htab->table[idx].data, val) == 0)
63 /* Second hash function as suggested in [Knuth]. */
64 hash = 1 + hval % (htab->size - 2);
69 idx = htab->size + idx - hash;
73 /* If entry is found use it. */
74 if (htab->table[idx].hashval == hval
75 && COMPARE (htab->table[idx].data, val) == 0)
78 while (htab->table[idx].hashval);
85 insert_entry_2 (NAME *htab, HASHTYPE hval, size_t idx, TYPE data)
88 if (htab->table[idx].hashval == 0)
91 htab->table[idx].next = htab->first;
92 htab->first = &htab->table[idx];
94 /* Add the new value to the list. */
95 if (htab->first == NULL)
96 htab->first = htab->table[idx].next = &htab->table[idx];
99 htab->table[idx].next = htab->first->next;
100 htab->first = htab->first->next = &htab->table[idx];
106 htab->table[idx].hashval = hval;
107 htab->table[idx].data = data;
110 if (100 * htab->filled > 90 * htab->size)
112 /* Table is filled more than 90%. Resize the table. */
114 __typeof__ (htab->first) first;
116 __typeof__ (htab->first) runp;
119 size_t old_size = htab->size;
121 #define _TABLE(name) \
122 name##_ent *table = htab->table
123 #define TABLE(name) _TABLE (name)
126 htab->size = next_prime (htab->size * 2);
132 htab->table = calloc ((1 + htab->size), sizeof (htab->table[0]));
133 if (htab->table == NULL)
135 /* We cannot enlarge the table. Live with what we got. This
136 might lead to an infinite loop at some point, though. */
141 /* Add the old entries to the new table. When iteration is
142 supported we maintain the order. */
145 while (first != NULL)
147 insert_entry_2 (htab, first->hashval,
148 lookup (htab, first->hashval, first->data),
154 assert (first != NULL);
155 runp = first = first->next;
157 insert_entry_2 (htab, runp->hashval,
158 lookup (htab, runp->hashval, runp->data), runp->data);
159 while ((runp = runp->next) != first);
162 for (idx = 1; idx <= old_size; ++idx)
163 if (table[idx].hashval != 0)
164 insert_entry_2 (htab, table[idx].hashval,
165 lookup (htab, table[idx].hashval, table[idx].data),
175 #define INIT(name) _INIT (name)
176 #define _INIT(name) \
178 INIT(NAME) (htab, init_size)
182 /* We need the size to be a prime. */
183 init_size = next_prime (init_size);
185 /* Initialize the data structure. */
186 htab->size = init_size;
191 htab->table = (void *) calloc ((init_size + 1), sizeof (htab->table[0]));
192 if (htab->table == NULL)
200 #define FREE(name) _FREE (name)
201 #define _FREE(name) \
212 #define INSERT(name) _INSERT (name)
213 #define _INSERT(name) \
215 INSERT(NAME) (htab, hval, data)
222 /* Make the hash value nonzero. */
225 idx = lookup (htab, hval, data);
227 if (htab->table[idx].hashval != 0)
228 /* We don't want to overwrite the old value. */
231 /* An empty bucket has been found. */
232 insert_entry_2 (htab, hval, idx, data);
239 #define INSERT(name) _INSERT (name)
240 #define _INSERT(name) \
242 INSERT(NAME) (htab, hval, data)
249 /* Make the hash value nonzero. */
252 idx = lookup (htab, hval, data);
254 /* The correct bucket has been found. */
255 insert_entry_2 (htab, hval, idx, data);
262 #define FIND(name) _FIND (name)
263 #define _FIND(name) \
265 FIND(NAME) (htab, hval, val)
272 /* Make the hash value nonzero. */
275 idx = lookup (htab, hval, val);
277 if (htab->table[idx].hashval == 0)
280 return htab->table[idx].data;
285 # define ITERATEFCT(name) _ITERATEFCT (name)
286 # define _ITERATEFCT(name) \
289 ITERATEFCT(NAME) (htab, ptr)
295 # define TYPENAME(name) _TYPENAME (name)
296 # define _TYPENAME(name) name##_ent
302 p = ((TYPENAME(NAME) *) p)->next;
312 if (htab->first == NULL)
314 p = htab->first->next;
318 if (p == htab->first)
321 p = ((TYPENAME(NAME) *) p)->next;
325 /* Prepare the next element. If possible this will pull the data
326 into the cache, for reading. */
327 __builtin_prefetch (((TYPENAME(NAME) *) p)->next, 0, 2);
329 return ((TYPENAME(NAME) *) (*ptr = p))->data;