blob: 56e41fa82605a924139aeec37708ad8914f65788 [file] [log] [blame]
paul718e3742002-12-13 20:15:29 +00001/* Hash routine.
2 * Copyright (C) 1998 Kunihiro Ishiguro
3 *
4 * This file is part of GNU Zebra.
5 *
6 * GNU Zebra is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published
8 * by the Free Software Foundation; either version 2, or (at your
9 * option) any later version.
10 *
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with GNU Zebra; see the file COPYING. If not, write to the
18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
20 */
21
22#include <zebra.h>
23
24#include "hash.h"
25#include "memory.h"
26
27/* Allocate a new hash. */
28struct hash *
paul8cc41982005-05-06 21:25:49 +000029hash_create_size (unsigned int size, unsigned int (*hash_key) (void *),
Stephen Hemmingerffe11cf2008-08-14 16:25:25 +010030 int (*hash_cmp) (const void *, const void *))
paul718e3742002-12-13 20:15:29 +000031{
32 struct hash *hash;
33
Stephen Hemminger90645f52013-01-04 22:29:21 +000034 assert ((size & (size-1)) == 0);
paul718e3742002-12-13 20:15:29 +000035 hash = XMALLOC (MTYPE_HASH, sizeof (struct hash));
Stephen Hemminger393deb92008-08-18 14:13:29 -070036 hash->index = XCALLOC (MTYPE_HASH_INDEX,
paul718e3742002-12-13 20:15:29 +000037 sizeof (struct hash_backet *) * size);
paul718e3742002-12-13 20:15:29 +000038 hash->size = size;
Jorge Boncompte [DTI2]6d729ee2013-07-31 15:01:18 +000039 hash->no_expand = 0;
paul718e3742002-12-13 20:15:29 +000040 hash->hash_key = hash_key;
41 hash->hash_cmp = hash_cmp;
42 hash->count = 0;
43
44 return hash;
45}
46
47/* Allocate a new hash with default hash size. */
48struct hash *
paul8cc41982005-05-06 21:25:49 +000049hash_create (unsigned int (*hash_key) (void *),
Stephen Hemmingerffe11cf2008-08-14 16:25:25 +010050 int (*hash_cmp) (const void *, const void *))
paul718e3742002-12-13 20:15:29 +000051{
Stephen Hemminger97c84db2013-01-11 18:25:26 +000052 return hash_create_size (HASH_INITIAL_SIZE, hash_key, hash_cmp);
paul718e3742002-12-13 20:15:29 +000053}
54
55/* Utility function for hash_get(). When this function is specified
56 as alloc_func, return arugment as it is. This function is used for
57 intern already allocated value. */
58void *
59hash_alloc_intern (void *arg)
60{
61 return arg;
62}
63
Stephen Hemminger97c84db2013-01-11 18:25:26 +000064/* Expand hash if the chain length exceeds the threshold. */
65static void hash_expand (struct hash *hash)
66{
67 unsigned int i, new_size, losers;
68 struct hash_backet *hb, *hbnext, **new_index;
69
70 new_size = hash->size * 2;
71 new_index = XCALLOC(MTYPE_HASH_INDEX, sizeof(struct hash_backet *) * new_size);
72 if (new_index == NULL)
73 return;
74
75 for (i = 0; i < hash->size; i++)
76 for (hb = hash->index[i]; hb; hb = hbnext)
77 {
78 unsigned int h = hb->key & (new_size - 1);
79
80 hbnext = hb->next;
81 hb->next = new_index[h];
82 new_index[h] = hb;
83 }
84
85 /* Switch to new table */
86 XFREE(MTYPE_HASH_INDEX, hash->index);
87 hash->size = new_size;
88 hash->index = new_index;
89
90 /* Ideally, new index should have chains half as long as the original.
91 If expansion didn't help, then not worth expanding again,
92 the problem is the hash function. */
93 losers = 0;
94 for (i = 0; i < hash->size; i++)
95 {
96 unsigned int len = 0;
97 for (hb = hash->index[i]; hb; hb = hb->next)
98 {
99 if (++len > HASH_THRESHOLD/2)
100 ++losers;
101 if (len >= HASH_THRESHOLD)
102 hash->no_expand = 1;
103 }
104 }
105
106 if (losers > hash->count / 2)
107 hash->no_expand = 1;
108}
109
paul718e3742002-12-13 20:15:29 +0000110/* Lookup and return hash backet in hash. If there is no
111 corresponding hash backet and alloc_func is specified, create new
112 hash backet. */
113void *
paul8cc41982005-05-06 21:25:49 +0000114hash_get (struct hash *hash, void *data, void * (*alloc_func) (void *))
paul718e3742002-12-13 20:15:29 +0000115{
116 unsigned int key;
117 unsigned int index;
118 void *newdata;
Stephen Hemminger97c84db2013-01-11 18:25:26 +0000119 unsigned int len;
paul718e3742002-12-13 20:15:29 +0000120 struct hash_backet *backet;
121
122 key = (*hash->hash_key) (data);
Stephen Hemminger90645f52013-01-04 22:29:21 +0000123 index = key & (hash->size - 1);
Stephen Hemminger97c84db2013-01-11 18:25:26 +0000124 len = 0;
paul718e3742002-12-13 20:15:29 +0000125
Stephen Hemminger97c84db2013-01-11 18:25:26 +0000126 for (backet = hash->index[index]; backet != NULL; backet = backet->next)
127 {
128 if (backet->key == key && (*hash->hash_cmp) (backet->data, data))
129 return backet->data;
130 ++len;
131 }
paul718e3742002-12-13 20:15:29 +0000132
133 if (alloc_func)
134 {
135 newdata = (*alloc_func) (data);
136 if (newdata == NULL)
137 return NULL;
138
Stephen Hemminger97c84db2013-01-11 18:25:26 +0000139 if (len > HASH_THRESHOLD && !hash->no_expand)
140 {
141 hash_expand (hash);
142 index = key & (hash->size - 1);
143 }
144
paul718e3742002-12-13 20:15:29 +0000145 backet = XMALLOC (MTYPE_HASH_BACKET, sizeof (struct hash_backet));
146 backet->data = newdata;
147 backet->key = key;
148 backet->next = hash->index[index];
149 hash->index[index] = backet;
150 hash->count++;
151 return backet->data;
152 }
153 return NULL;
154}
155
156/* Hash lookup. */
157void *
158hash_lookup (struct hash *hash, void *data)
159{
160 return hash_get (hash, data, NULL);
161}
162
Stephen Hemminger6392aa82010-08-27 14:11:14 -0700163/* Simple Bernstein hash which is simple and fast for common case */
164unsigned int string_hash_make (const char *str)
165{
166 unsigned int hash = 0;
167
168 while (*str)
169 hash = (hash * 33) ^ (unsigned int) *str++;
170
171 return hash;
172}
173
paul718e3742002-12-13 20:15:29 +0000174/* This function release registered value from specified hash. When
175 release is successfully finished, return the data pointer in the
176 hash backet. */
177void *
178hash_release (struct hash *hash, void *data)
179{
180 void *ret;
181 unsigned int key;
182 unsigned int index;
183 struct hash_backet *backet;
184 struct hash_backet *pp;
185
186 key = (*hash->hash_key) (data);
Stephen Hemminger90645f52013-01-04 22:29:21 +0000187 index = key & (hash->size - 1);
paul718e3742002-12-13 20:15:29 +0000188
189 for (backet = pp = hash->index[index]; backet; backet = backet->next)
190 {
191 if (backet->key == key && (*hash->hash_cmp) (backet->data, data))
192 {
193 if (backet == pp)
194 hash->index[index] = backet->next;
195 else
196 pp->next = backet->next;
197
198 ret = backet->data;
199 XFREE (MTYPE_HASH_BACKET, backet);
200 hash->count--;
201 return ret;
202 }
203 pp = backet;
204 }
205 return NULL;
206}
207
208/* Iterator function for hash. */
209void
210hash_iterate (struct hash *hash,
211 void (*func) (struct hash_backet *, void *), void *arg)
212{
hasso8c328f12004-10-05 21:01:23 +0000213 unsigned int i;
paul718e3742002-12-13 20:15:29 +0000214 struct hash_backet *hb;
gdt630e4802004-08-31 17:28:41 +0000215 struct hash_backet *hbnext;
paul718e3742002-12-13 20:15:29 +0000216
217 for (i = 0; i < hash->size; i++)
gdt630e4802004-08-31 17:28:41 +0000218 for (hb = hash->index[i]; hb; hb = hbnext)
219 {
220 /* get pointer to next hash backet here, in case (*func)
221 * decides to delete hb by calling hash_release
222 */
223 hbnext = hb->next;
224 (*func) (hb, arg);
225 }
paul718e3742002-12-13 20:15:29 +0000226}
227
228/* Clean up hash. */
229void
230hash_clean (struct hash *hash, void (*free_func) (void *))
231{
hasso8c328f12004-10-05 21:01:23 +0000232 unsigned int i;
paul718e3742002-12-13 20:15:29 +0000233 struct hash_backet *hb;
234 struct hash_backet *next;
235
236 for (i = 0; i < hash->size; i++)
237 {
238 for (hb = hash->index[i]; hb; hb = next)
239 {
240 next = hb->next;
241
242 if (free_func)
243 (*free_func) (hb->data);
244
245 XFREE (MTYPE_HASH_BACKET, hb);
246 hash->count--;
247 }
248 hash->index[i] = NULL;
249 }
250}
251
252/* Free hash memory. You may call hash_clean before call this
253 function. */
254void
255hash_free (struct hash *hash)
256{
257 XFREE (MTYPE_HASH_INDEX, hash->index);
258 XFREE (MTYPE_HASH, hash);
259}