1*0b46a53aSSimon J. Gerraty /* $NetBSD: hash.c,v 1.80 2025/04/22 19:28:50 rillig Exp $ */
23955d011SMarcel Moolenaar
33955d011SMarcel Moolenaar /*
43955d011SMarcel Moolenaar * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
53955d011SMarcel Moolenaar * All rights reserved.
63955d011SMarcel Moolenaar *
73955d011SMarcel Moolenaar * This code is derived from software contributed to Berkeley by
83955d011SMarcel Moolenaar * Adam de Boor.
93955d011SMarcel Moolenaar *
103955d011SMarcel Moolenaar * Redistribution and use in source and binary forms, with or without
113955d011SMarcel Moolenaar * modification, are permitted provided that the following conditions
123955d011SMarcel Moolenaar * are met:
133955d011SMarcel Moolenaar * 1. Redistributions of source code must retain the above copyright
143955d011SMarcel Moolenaar * notice, this list of conditions and the following disclaimer.
153955d011SMarcel Moolenaar * 2. Redistributions in binary form must reproduce the above copyright
163955d011SMarcel Moolenaar * notice, this list of conditions and the following disclaimer in the
173955d011SMarcel Moolenaar * documentation and/or other materials provided with the distribution.
183955d011SMarcel Moolenaar * 3. Neither the name of the University nor the names of its contributors
193955d011SMarcel Moolenaar * may be used to endorse or promote products derived from this software
203955d011SMarcel Moolenaar * without specific prior written permission.
213955d011SMarcel Moolenaar *
223955d011SMarcel Moolenaar * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
233955d011SMarcel Moolenaar * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
243955d011SMarcel Moolenaar * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
253955d011SMarcel Moolenaar * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
263955d011SMarcel Moolenaar * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
273955d011SMarcel Moolenaar * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
283955d011SMarcel Moolenaar * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
293955d011SMarcel Moolenaar * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
303955d011SMarcel Moolenaar * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
313955d011SMarcel Moolenaar * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
323955d011SMarcel Moolenaar * SUCH DAMAGE.
333955d011SMarcel Moolenaar */
343955d011SMarcel Moolenaar
353955d011SMarcel Moolenaar /*
363955d011SMarcel Moolenaar * Copyright (c) 1988, 1989 by Adam de Boor
373955d011SMarcel Moolenaar * Copyright (c) 1989 by Berkeley Softworks
383955d011SMarcel Moolenaar * All rights reserved.
393955d011SMarcel Moolenaar *
403955d011SMarcel Moolenaar * This code is derived from software contributed to Berkeley by
413955d011SMarcel Moolenaar * Adam de Boor.
423955d011SMarcel Moolenaar *
433955d011SMarcel Moolenaar * Redistribution and use in source and binary forms, with or without
443955d011SMarcel Moolenaar * modification, are permitted provided that the following conditions
453955d011SMarcel Moolenaar * are met:
463955d011SMarcel Moolenaar * 1. Redistributions of source code must retain the above copyright
473955d011SMarcel Moolenaar * notice, this list of conditions and the following disclaimer.
483955d011SMarcel Moolenaar * 2. Redistributions in binary form must reproduce the above copyright
493955d011SMarcel Moolenaar * notice, this list of conditions and the following disclaimer in the
503955d011SMarcel Moolenaar * documentation and/or other materials provided with the distribution.
513955d011SMarcel Moolenaar * 3. All advertising materials mentioning features or use of this software
523955d011SMarcel Moolenaar * must display the following acknowledgement:
533955d011SMarcel Moolenaar * This product includes software developed by the University of
543955d011SMarcel Moolenaar * California, Berkeley and its contributors.
553955d011SMarcel Moolenaar * 4. Neither the name of the University nor the names of its contributors
563955d011SMarcel Moolenaar * may be used to endorse or promote products derived from this software
573955d011SMarcel Moolenaar * without specific prior written permission.
583955d011SMarcel Moolenaar *
593955d011SMarcel Moolenaar * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
603955d011SMarcel Moolenaar * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
613955d011SMarcel Moolenaar * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
623955d011SMarcel Moolenaar * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
633955d011SMarcel Moolenaar * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
643955d011SMarcel Moolenaar * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
653955d011SMarcel Moolenaar * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
663955d011SMarcel Moolenaar * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
673955d011SMarcel Moolenaar * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
683955d011SMarcel Moolenaar * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
693955d011SMarcel Moolenaar * SUCH DAMAGE.
703955d011SMarcel Moolenaar */
713955d011SMarcel Moolenaar
72d5e0a182SSimon J. Gerraty /* Hash tables with string keys and pointer values. */
733955d011SMarcel Moolenaar
743955d011SMarcel Moolenaar #include "make.h"
753955d011SMarcel Moolenaar
76956e45f6SSimon J. Gerraty /* "@(#)hash.c 8.1 (Berkeley) 6/6/93" */
77*0b46a53aSSimon J. Gerraty MAKE_RCSID("$NetBSD: hash.c,v 1.80 2025/04/22 19:28:50 rillig Exp $");
783955d011SMarcel Moolenaar
793955d011SMarcel Moolenaar /*
80956e45f6SSimon J. Gerraty * The ratio of # entries to # buckets at which we rebuild the table to
81956e45f6SSimon J. Gerraty * make it larger.
823955d011SMarcel Moolenaar */
833955d011SMarcel Moolenaar #define rebuildLimit 3
843955d011SMarcel Moolenaar
85dba7b0efSSimon J. Gerraty /* This hash function matches Gosling's Emacs and java.lang.String. */
86*0b46a53aSSimon J. Gerraty static unsigned
Hash_String(const char * key,const char ** out_keyEnd)879f45a3c8SSimon J. Gerraty Hash_String(const char *key, const char **out_keyEnd)
88956e45f6SSimon J. Gerraty {
89*0b46a53aSSimon J. Gerraty unsigned h;
9006b9b3e0SSimon J. Gerraty const char *p;
9106b9b3e0SSimon J. Gerraty
9206b9b3e0SSimon J. Gerraty h = 0;
9306b9b3e0SSimon J. Gerraty for (p = key; *p != '\0'; p++)
9406b9b3e0SSimon J. Gerraty h = 31 * h + (unsigned char)*p;
9506b9b3e0SSimon J. Gerraty
969f45a3c8SSimon J. Gerraty *out_keyEnd = p;
97956e45f6SSimon J. Gerraty return h;
98956e45f6SSimon J. Gerraty }
992c3632d1SSimon J. Gerraty
100b0c40a00SSimon J. Gerraty /* This hash function matches Gosling's Emacs and java.lang.String. */
101*0b46a53aSSimon J. Gerraty unsigned
Hash_Substring(Substring key)102b0c40a00SSimon J. Gerraty Hash_Substring(Substring key)
103956e45f6SSimon J. Gerraty {
104*0b46a53aSSimon J. Gerraty unsigned h;
105b0c40a00SSimon J. Gerraty const char *p;
106b0c40a00SSimon J. Gerraty
107b0c40a00SSimon J. Gerraty h = 0;
108b0c40a00SSimon J. Gerraty for (p = key.start; p != key.end; p++)
109b0c40a00SSimon J. Gerraty h = 31 * h + (unsigned char)*p;
110b0c40a00SSimon J. Gerraty return h;
111956e45f6SSimon J. Gerraty }
1122c3632d1SSimon J. Gerraty
113956e45f6SSimon J. Gerraty static HashEntry *
HashTable_Find(HashTable * t,Substring key,unsigned h)114*0b46a53aSSimon J. Gerraty HashTable_Find(HashTable *t, Substring key, unsigned h)
115956e45f6SSimon J. Gerraty {
116d5e0a182SSimon J. Gerraty HashEntry *he;
1179f45a3c8SSimon J. Gerraty size_t keyLen = Substring_Length(key);
118956e45f6SSimon J. Gerraty
119956e45f6SSimon J. Gerraty #ifdef DEBUG_HASH_LOOKUP
1209f45a3c8SSimon J. Gerraty DEBUG4(HASH, "HashTable_Find: %p h=%08x key=%.*s\n",
1219f45a3c8SSimon J. Gerraty t, h, (int)keyLen, key.start);
1222c3632d1SSimon J. Gerraty #endif
1232c3632d1SSimon J. Gerraty
124d5e0a182SSimon J. Gerraty for (he = t->buckets[h & t->bucketsMask]; he != NULL; he = he->next) {
125d5e0a182SSimon J. Gerraty if (he->hash == h &&
126d5e0a182SSimon J. Gerraty strncmp(he->key, key.start, keyLen) == 0 &&
127d5e0a182SSimon J. Gerraty he->key[keyLen] == '\0')
128b0c40a00SSimon J. Gerraty break;
129b0c40a00SSimon J. Gerraty }
130b0c40a00SSimon J. Gerraty
131d5e0a182SSimon J. Gerraty return he;
132b0c40a00SSimon J. Gerraty }
133b0c40a00SSimon J. Gerraty
134956e45f6SSimon J. Gerraty /* Set up the hash table. */
135956e45f6SSimon J. Gerraty void
HashTable_Init(HashTable * t)136956e45f6SSimon J. Gerraty HashTable_Init(HashTable *t)
137956e45f6SSimon J. Gerraty {
138*0b46a53aSSimon J. Gerraty unsigned n = 16, i;
139e2eeea75SSimon J. Gerraty HashEntry **buckets = bmake_malloc(sizeof *buckets * n);
140956e45f6SSimon J. Gerraty for (i = 0; i < n; i++)
141956e45f6SSimon J. Gerraty buckets[i] = NULL;
142956e45f6SSimon J. Gerraty
143956e45f6SSimon J. Gerraty t->buckets = buckets;
144956e45f6SSimon J. Gerraty t->bucketsSize = n;
1453955d011SMarcel Moolenaar t->numEntries = 0;
146956e45f6SSimon J. Gerraty t->bucketsMask = n - 1;
1473955d011SMarcel Moolenaar }
1483955d011SMarcel Moolenaar
149dba7b0efSSimon J. Gerraty /*
150dba7b0efSSimon J. Gerraty * Remove everything from the hash table and free up the memory for the keys
151dba7b0efSSimon J. Gerraty * of the hash table, but not for the values associated to these keys.
152dba7b0efSSimon J. Gerraty */
1533955d011SMarcel Moolenaar void
HashTable_Done(HashTable * t)154956e45f6SSimon J. Gerraty HashTable_Done(HashTable *t)
1553955d011SMarcel Moolenaar {
156956e45f6SSimon J. Gerraty HashEntry **buckets = t->buckets;
157956e45f6SSimon J. Gerraty size_t i, n = t->bucketsSize;
1583955d011SMarcel Moolenaar
159956e45f6SSimon J. Gerraty for (i = 0; i < n; i++) {
160956e45f6SSimon J. Gerraty HashEntry *he = buckets[i];
161956e45f6SSimon J. Gerraty while (he != NULL) {
162956e45f6SSimon J. Gerraty HashEntry *next = he->next;
163956e45f6SSimon J. Gerraty free(he);
164956e45f6SSimon J. Gerraty he = next;
1653955d011SMarcel Moolenaar }
1663955d011SMarcel Moolenaar }
1673955d011SMarcel Moolenaar
168dba7b0efSSimon J. Gerraty free(t->buckets);
169956e45f6SSimon J. Gerraty #ifdef CLEANUP
1702c3632d1SSimon J. Gerraty t->buckets = NULL;
1712c3632d1SSimon J. Gerraty #endif
1723955d011SMarcel Moolenaar }
1733955d011SMarcel Moolenaar
174956e45f6SSimon J. Gerraty /* Find the entry corresponding to the key, or return NULL. */
175956e45f6SSimon J. Gerraty HashEntry *
HashTable_FindEntry(HashTable * t,const char * key)176956e45f6SSimon J. Gerraty HashTable_FindEntry(HashTable *t, const char *key)
1773955d011SMarcel Moolenaar {
1789f45a3c8SSimon J. Gerraty const char *keyEnd;
179*0b46a53aSSimon J. Gerraty unsigned h = Hash_String(key, &keyEnd);
1809f45a3c8SSimon J. Gerraty return HashTable_Find(t, Substring_Init(key, keyEnd), h);
181956e45f6SSimon J. Gerraty }
1823955d011SMarcel Moolenaar
183956e45f6SSimon J. Gerraty /* Find the value corresponding to the key, or return NULL. */
184956e45f6SSimon J. Gerraty void *
HashTable_FindValue(HashTable * t,const char * key)185956e45f6SSimon J. Gerraty HashTable_FindValue(HashTable *t, const char *key)
186956e45f6SSimon J. Gerraty {
187956e45f6SSimon J. Gerraty HashEntry *he = HashTable_FindEntry(t, key);
188956e45f6SSimon J. Gerraty return he != NULL ? he->value : NULL;
189956e45f6SSimon J. Gerraty }
190956e45f6SSimon J. Gerraty
19106b9b3e0SSimon J. Gerraty /*
19206b9b3e0SSimon J. Gerraty * Find the value corresponding to the key and the precomputed hash,
19306b9b3e0SSimon J. Gerraty * or return NULL.
19406b9b3e0SSimon J. Gerraty */
195956e45f6SSimon J. Gerraty void *
HashTable_FindValueBySubstringHash(HashTable * t,Substring key,unsigned h)196*0b46a53aSSimon J. Gerraty HashTable_FindValueBySubstringHash(HashTable *t, Substring key, unsigned h)
197956e45f6SSimon J. Gerraty {
1989f45a3c8SSimon J. Gerraty HashEntry *he = HashTable_Find(t, key, h);
199956e45f6SSimon J. Gerraty return he != NULL ? he->value : NULL;
200956e45f6SSimon J. Gerraty }
201956e45f6SSimon J. Gerraty
20222619282SSimon J. Gerraty static unsigned
HashTable_MaxChain(const HashTable * t)20322619282SSimon J. Gerraty HashTable_MaxChain(const HashTable *t)
20422619282SSimon J. Gerraty {
20522619282SSimon J. Gerraty unsigned b, cl, max_cl = 0;
20622619282SSimon J. Gerraty for (b = 0; b < t->bucketsSize; b++) {
20722619282SSimon J. Gerraty const HashEntry *he = t->buckets[b];
20822619282SSimon J. Gerraty for (cl = 0; he != NULL; he = he->next)
20922619282SSimon J. Gerraty cl++;
21022619282SSimon J. Gerraty if (cl > max_cl)
21122619282SSimon J. Gerraty max_cl = cl;
21222619282SSimon J. Gerraty }
21322619282SSimon J. Gerraty return max_cl;
21422619282SSimon J. Gerraty }
21522619282SSimon J. Gerraty
21606b9b3e0SSimon J. Gerraty /*
21706b9b3e0SSimon J. Gerraty * Make the hash table larger. Any bucket numbers from the old table become
218d5e0a182SSimon J. Gerraty * invalid; the hash values stay valid though.
21906b9b3e0SSimon J. Gerraty */
220956e45f6SSimon J. Gerraty static void
HashTable_Enlarge(HashTable * t)221956e45f6SSimon J. Gerraty HashTable_Enlarge(HashTable *t)
222956e45f6SSimon J. Gerraty {
223*0b46a53aSSimon J. Gerraty unsigned oldSize = t->bucketsSize;
224956e45f6SSimon J. Gerraty HashEntry **oldBuckets = t->buckets;
225*0b46a53aSSimon J. Gerraty unsigned newSize = 2 * oldSize;
226*0b46a53aSSimon J. Gerraty unsigned newMask = newSize - 1;
227e2eeea75SSimon J. Gerraty HashEntry **newBuckets = bmake_malloc(sizeof *newBuckets * newSize);
228956e45f6SSimon J. Gerraty size_t i;
229956e45f6SSimon J. Gerraty
230956e45f6SSimon J. Gerraty for (i = 0; i < newSize; i++)
231956e45f6SSimon J. Gerraty newBuckets[i] = NULL;
232956e45f6SSimon J. Gerraty
233956e45f6SSimon J. Gerraty for (i = 0; i < oldSize; i++) {
234956e45f6SSimon J. Gerraty HashEntry *he = oldBuckets[i];
235956e45f6SSimon J. Gerraty while (he != NULL) {
236956e45f6SSimon J. Gerraty HashEntry *next = he->next;
237d5e0a182SSimon J. Gerraty he->next = newBuckets[he->hash & newMask];
238d5e0a182SSimon J. Gerraty newBuckets[he->hash & newMask] = he;
239956e45f6SSimon J. Gerraty he = next;
2402c3632d1SSimon J. Gerraty }
2412c3632d1SSimon J. Gerraty }
2423955d011SMarcel Moolenaar
243956e45f6SSimon J. Gerraty free(oldBuckets);
244956e45f6SSimon J. Gerraty
245956e45f6SSimon J. Gerraty t->bucketsSize = newSize;
246956e45f6SSimon J. Gerraty t->bucketsMask = newMask;
247956e45f6SSimon J. Gerraty t->buckets = newBuckets;
2489f45a3c8SSimon J. Gerraty DEBUG4(HASH, "HashTable_Enlarge: %p size=%d entries=%d maxchain=%d\n",
24922619282SSimon J. Gerraty (void *)t, t->bucketsSize, t->numEntries, HashTable_MaxChain(t));
250956e45f6SSimon J. Gerraty }
251956e45f6SSimon J. Gerraty
25206b9b3e0SSimon J. Gerraty /*
25306b9b3e0SSimon J. Gerraty * Find or create an entry corresponding to the key.
25406b9b3e0SSimon J. Gerraty * Return in out_isNew whether a new entry has been created.
25506b9b3e0SSimon J. Gerraty */
256956e45f6SSimon J. Gerraty HashEntry *
HashTable_CreateEntry(HashTable * t,const char * key,bool * out_isNew)257b0c40a00SSimon J. Gerraty HashTable_CreateEntry(HashTable *t, const char *key, bool *out_isNew)
258956e45f6SSimon J. Gerraty {
2599f45a3c8SSimon J. Gerraty const char *keyEnd;
260*0b46a53aSSimon J. Gerraty unsigned h = Hash_String(key, &keyEnd);
2619f45a3c8SSimon J. Gerraty HashEntry *he = HashTable_Find(t, Substring_Init(key, keyEnd), h);
262956e45f6SSimon J. Gerraty
263956e45f6SSimon J. Gerraty if (he != NULL) {
264956e45f6SSimon J. Gerraty if (out_isNew != NULL)
265b0c40a00SSimon J. Gerraty *out_isNew = false;
266956e45f6SSimon J. Gerraty return he;
267956e45f6SSimon J. Gerraty }
268956e45f6SSimon J. Gerraty
2692c3632d1SSimon J. Gerraty if (t->numEntries >= rebuildLimit * t->bucketsSize)
270956e45f6SSimon J. Gerraty HashTable_Enlarge(t);
271956e45f6SSimon J. Gerraty
2729f45a3c8SSimon J. Gerraty he = bmake_malloc(sizeof *he + (size_t)(keyEnd - key));
273956e45f6SSimon J. Gerraty he->value = NULL;
274d5e0a182SSimon J. Gerraty he->hash = h;
2759f45a3c8SSimon J. Gerraty memcpy(he->key, key, (size_t)(keyEnd - key) + 1);
276956e45f6SSimon J. Gerraty
277956e45f6SSimon J. Gerraty he->next = t->buckets[h & t->bucketsMask];
278956e45f6SSimon J. Gerraty t->buckets[h & t->bucketsMask] = he;
2793955d011SMarcel Moolenaar t->numEntries++;
2803955d011SMarcel Moolenaar
281956e45f6SSimon J. Gerraty if (out_isNew != NULL)
282b0c40a00SSimon J. Gerraty *out_isNew = true;
283956e45f6SSimon J. Gerraty return he;
2843955d011SMarcel Moolenaar }
2853955d011SMarcel Moolenaar
2869f45a3c8SSimon J. Gerraty void
HashTable_Set(HashTable * t,const char * key,void * value)287e2eeea75SSimon J. Gerraty HashTable_Set(HashTable *t, const char *key, void *value)
288e2eeea75SSimon J. Gerraty {
289e2eeea75SSimon J. Gerraty HashEntry *he = HashTable_CreateEntry(t, key, NULL);
290e2eeea75SSimon J. Gerraty HashEntry_Set(he, value);
291e2eeea75SSimon J. Gerraty }
292e2eeea75SSimon J. Gerraty
2931d3f2ddcSSimon J. Gerraty /* Delete the entry from the table, don't free the value of the entry. */
2943955d011SMarcel Moolenaar void
HashTable_DeleteEntry(HashTable * t,HashEntry * he)295956e45f6SSimon J. Gerraty HashTable_DeleteEntry(HashTable *t, HashEntry *he)
2963955d011SMarcel Moolenaar {
297d5e0a182SSimon J. Gerraty HashEntry **ref = &t->buckets[he->hash & t->bucketsMask];
2983955d011SMarcel Moolenaar
2998d5c8e21SSimon J. Gerraty for (; *ref != he; ref = &(*ref)->next)
3008d5c8e21SSimon J. Gerraty continue;
3018d5c8e21SSimon J. Gerraty *ref = he->next;
3028d5c8e21SSimon J. Gerraty free(he);
3033955d011SMarcel Moolenaar t->numEntries--;
3043955d011SMarcel Moolenaar }
3053955d011SMarcel Moolenaar
30606b9b3e0SSimon J. Gerraty /*
3078d5c8e21SSimon J. Gerraty * Place the next entry from the hash table in hi->entry, or return false if
3088d5c8e21SSimon J. Gerraty * the end of the table is reached.
30906b9b3e0SSimon J. Gerraty */
3108d5c8e21SSimon J. Gerraty bool
HashIter_Next(HashIter * hi)311956e45f6SSimon J. Gerraty HashIter_Next(HashIter *hi)
3123955d011SMarcel Moolenaar {
313956e45f6SSimon J. Gerraty HashTable *t = hi->table;
314956e45f6SSimon J. Gerraty HashEntry *he = hi->entry;
315956e45f6SSimon J. Gerraty HashEntry **buckets = t->buckets;
316*0b46a53aSSimon J. Gerraty unsigned bucketsSize = t->bucketsSize;
3173955d011SMarcel Moolenaar
318956e45f6SSimon J. Gerraty if (he != NULL)
319956e45f6SSimon J. Gerraty he = he->next; /* skip the most recently returned entry */
320956e45f6SSimon J. Gerraty
321956e45f6SSimon J. Gerraty while (he == NULL) { /* find the next nonempty chain */
322956e45f6SSimon J. Gerraty if (hi->nextBucket >= bucketsSize)
3238d5c8e21SSimon J. Gerraty return false;
324956e45f6SSimon J. Gerraty he = buckets[hi->nextBucket++];
3253955d011SMarcel Moolenaar }
326956e45f6SSimon J. Gerraty hi->entry = he;
3278d5c8e21SSimon J. Gerraty return true;
3283955d011SMarcel Moolenaar }
3293841c287SSimon J. Gerraty
3302c3632d1SSimon J. Gerraty void
HashTable_DebugStats(const HashTable * t,const char * name)33122619282SSimon J. Gerraty HashTable_DebugStats(const HashTable *t, const char *name)
3323841c287SSimon J. Gerraty {
33322619282SSimon J. Gerraty DEBUG4(HASH, "HashTable \"%s\": size=%u entries=%u maxchain=%u\n",
33422619282SSimon J. Gerraty name, t->bucketsSize, t->numEntries, HashTable_MaxChain(t));
3352c3632d1SSimon J. Gerraty }
336