Avoid using cr[34] registers.
[kopensolaris-gnu/glibc.git] / include / inline-hashtab.h
1 /* Fully-inline hash table, used mainly for managing TLS descriptors.
2
3    Copyright (C) 1999, 2000, 2001, 2002, 2003, 2005, 2008
4      Free Software Foundation, Inc.
5    This file is part of the GNU C Library.
6    Contributed by Alexandre Oliva  <aoliva@redhat.com>
7
8    This file is derived from a 2003's version of libiberty's
9    hashtab.c, contributed by Vladimir Makarov (vmakarov@cygnus.com),
10    but with most adaptation points and support for deleting elements
11    removed.
12
13    The GNU C Library is free software; you can redistribute it and/or
14    modify it under the terms of the GNU Lesser General Public
15    License as published by the Free Software Foundation; either
16    version 2.1 of the License, or (at your option) any later version.
17
18    The GNU C Library is distributed in the hope that it will be useful,
19    but WITHOUT ANY WARRANTY; without even the implied warranty of
20    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21    Lesser General Public License for more details.
22
23    You should have received a copy of the GNU Lesser General Public
24    License along with the GNU C Library; if not, write to the Free
25    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
26    02111-1307 USA.  */
27
28 #ifndef INLINE_HASHTAB_H
29 # define INLINE_HASHTAB_H 1
30
31 extern void weak_function free (void *ptr);
32
33 inline static unsigned long
34 higher_prime_number (unsigned long n)
35 {
36   /* These are primes that are near, but slightly smaller than, a
37      power of two.  */
38   static const uint32_t primes[] = {
39     UINT32_C (7),
40     UINT32_C (13),
41     UINT32_C (31),
42     UINT32_C (61),
43     UINT32_C (127),
44     UINT32_C (251),
45     UINT32_C (509),
46     UINT32_C (1021),
47     UINT32_C (2039),
48     UINT32_C (4093),
49     UINT32_C (8191),
50     UINT32_C (16381),
51     UINT32_C (32749),
52     UINT32_C (65521),
53     UINT32_C (131071),
54     UINT32_C (262139),
55     UINT32_C (524287),
56     UINT32_C (1048573),
57     UINT32_C (2097143),
58     UINT32_C (4194301),
59     UINT32_C (8388593),
60     UINT32_C (16777213),
61     UINT32_C (33554393),
62     UINT32_C (67108859),
63     UINT32_C (134217689),
64     UINT32_C (268435399),
65     UINT32_C (536870909),
66     UINT32_C (1073741789),
67     UINT32_C (2147483647),
68                                         /* 4294967291L */
69     UINT32_C (2147483647) + UINT32_C (2147483644)
70   };
71
72   const uint32_t *low = &primes[0];
73   const uint32_t *high = &primes[sizeof (primes) / sizeof (primes[0])];
74
75   while (low != high)
76     {
77       const uint32_t *mid = low + (high - low) / 2;
78       if (n > *mid)
79         low = mid + 1;
80       else
81         high = mid;
82     }
83
84 #if 0
85   /* If we've run out of primes, abort.  */
86   if (n > *low)
87     {
88       fprintf (stderr, "Cannot find prime bigger than %lu\n", n);
89       abort ();
90     }
91 #endif
92
93   return *low;
94 }
95
96 struct hashtab
97 {
98   /* Table itself.  */
99   void **entries;
100
101   /* Current size (in entries) of the hash table */
102   size_t size;
103
104   /* Current number of elements.  */
105   size_t n_elements;
106
107   /* Free function for the entries array.  This may vary depending on
108      how early the array was allocated.  If it is NULL, then the array
109      can't be freed.  */
110   void (*free) (void *ptr);
111 };
112
113 inline static struct hashtab *
114 htab_create (void)
115 {
116   struct hashtab *ht = malloc (sizeof (struct hashtab));
117
118   if (! ht)
119     return NULL;
120   ht->size = 3;
121   ht->entries = malloc (sizeof (void *) * ht->size);
122   ht->free = free;
123   if (! ht->entries)
124     {
125       if (ht->free)
126         ht->free (ht);
127       return NULL;
128     }
129
130   ht->n_elements = 0;
131
132   memset (ht->entries, 0, sizeof (void *) * ht->size);
133
134   return ht;
135 }
136
137 /* This is only called from _dl_unmap, so it's safe to call
138    free().  */
139 inline static void
140 htab_delete (struct hashtab *htab)
141 {
142   int i;
143
144   for (i = htab->size - 1; i >= 0; i--)
145     free (htab->entries[i]);
146
147   if (htab->free)
148     htab->free (htab->entries);
149   free (htab);
150 }
151
152 /* Similar to htab_find_slot, but without several unwanted side effects:
153     - Does not call htab->eq_f when it finds an existing entry.
154     - Does not change the count of elements/searches/collisions in the
155       hash table.
156    This function also assumes there are no deleted entries in the table.
157    HASH is the hash value for the element to be inserted.  */
158
159 inline static void **
160 find_empty_slot_for_expand (struct hashtab *htab, int hash)
161 {
162   size_t size = htab->size;
163   unsigned int index = hash % size;
164   void **slot = htab->entries + index;
165   int hash2;
166
167   if (! *slot)
168     return slot;
169
170   hash2 = 1 + hash % (size - 2);
171   for (;;)
172     {
173       index += hash2;
174       if (index >= size)
175         index -= size;
176
177       slot = htab->entries + index;
178       if (! *slot)
179         return slot;
180     }
181 }
182
183 /* The following function changes size of memory allocated for the
184    entries and repeatedly inserts the table elements.  The occupancy
185    of the table after the call will be about 50%.  Naturally the hash
186    table must already exist.  Remember also that the place of the
187    table entries is changed.  If memory allocation failures are allowed,
188    this function will return zero, indicating that the table could not be
189    expanded.  If all goes well, it will return a non-zero value.  */
190
191 inline static int
192 htab_expand (struct hashtab *htab, int (*hash_fn) (void *))
193 {
194   void **oentries;
195   void **olimit;
196   void **p;
197   void **nentries;
198   size_t nsize;
199
200   oentries = htab->entries;
201   olimit = oentries + htab->size;
202
203   /* Resize only when table after removal of unused elements is either
204      too full or too empty.  */
205   if (htab->n_elements * 2 > htab->size)
206     nsize = higher_prime_number (htab->n_elements * 2);
207   else
208     nsize = htab->size;
209
210   nentries = malloc (sizeof (void *) * nsize);
211   memset (nentries, 0, sizeof (void *) * nsize);
212   if (nentries == NULL)
213     return 0;
214   htab->entries = nentries;
215   htab->size = nsize;
216
217   p = oentries;
218   do
219     {
220       if (*p)
221         *find_empty_slot_for_expand (htab, hash_fn (*p))
222           = *p;
223
224       p++;
225     }
226   while (p < olimit);
227
228   /* Without recording the free corresponding to the malloc used to
229      allocate the table, we couldn't tell whether this was allocated
230      by the malloc() built into ld.so or the one in the main
231      executable or libc.  Calling free() for something that was
232      allocated by the early malloc(), rather than the final run-time
233      malloc() could do Very Bad Things (TM).  We will waste memory
234      allocated early as long as there's no corresponding free(), but
235      this isn't so much memory as to be significant.  */
236
237   if (htab->free)
238     htab->free (oentries);
239
240   /* Use the free() corresponding to the malloc() above to free this
241      up.  */
242   htab->free = free;
243
244   return 1;
245 }
246
247 /* This function searches for a hash table slot containing an entry
248    equal to the given element.  To delete an entry, call this with
249    INSERT = 0, then call htab_clear_slot on the slot returned (possibly
250    after doing some checks).  To insert an entry, call this with
251    INSERT = 1, then write the value you want into the returned slot.
252    When inserting an entry, NULL may be returned if memory allocation
253    fails.  */
254
255 inline static void **
256 htab_find_slot (struct hashtab *htab, void *ptr, int insert,
257                 int (*hash_fn)(void *), int (*eq_fn)(void *, void *))
258 {
259   unsigned int index;
260   int hash, hash2;
261   size_t size;
262   void **entry;
263
264   if (htab->size * 3 <= htab->n_elements * 4
265       && htab_expand (htab, hash_fn) == 0)
266     return NULL;
267
268   hash = hash_fn (ptr);
269
270   size = htab->size;
271   index = hash % size;
272
273   entry = &htab->entries[index];
274   if (!*entry)
275     goto empty_entry;
276   else if (eq_fn (*entry, ptr))
277     return entry;
278
279   hash2 = 1 + hash % (size - 2);
280   for (;;)
281     {
282       index += hash2;
283       if (index >= size)
284         index -= size;
285
286       entry = &htab->entries[index];
287       if (!*entry)
288         goto empty_entry;
289       else if (eq_fn (*entry, ptr))
290         return entry;
291     }
292
293  empty_entry:
294   if (!insert)
295     return NULL;
296
297   htab->n_elements++;
298   return entry;
299 }
300
301 #endif /* INLINE_HASHTAB_H */