8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / tools / ctf / cvt / hash.c
blobe3c2978f6ed312e219c3541f41a1f46f5a5f2589
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
20 * CDDL HEADER END
23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #pragma ident "%Z%%M% %I% %E% SMI"
30 * Routines for manipulating hash tables
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <strings.h>
36 #include <sys/types.h>
37 #include <sys/sysmacros.h>
39 #include "hash.h"
40 #include "memory.h"
41 #include "list.h"
43 struct hash {
44 int h_nbuckets;
45 list_t **h_buckets;
47 int (*h_hashfn)(int, void *);
48 int (*h_cmp)(void *, void *);
51 struct hash_data {
52 hash_t *hd_hash;
53 int (*hd_fun)();
54 void *hd_key;
55 void *hd_private;
57 void *hd_ret;
60 static int
61 hash_def_hash(int nbuckets, uintptr_t data)
63 return (data % nbuckets);
66 static int
67 hash_def_cmp(uintptr_t d1, uintptr_t d2)
69 return (d1 != d2);
73 int
74 hash_name(int nbuckets, const char *name)
76 const char *c;
77 ulong_t g;
78 int h = 0;
80 for (c = name; *c; c++) {
81 h = (h << 4) + *c;
82 if ((g = (h & 0xf0000000)) != 0) {
83 h ^= (g >> 24);
84 h ^= g;
88 return (h % nbuckets);
91 hash_t *
92 hash_new(int nbuckets, int (*hashfn)(int, void *), int (*cmp)(void *, void *))
94 hash_t *hash;
96 hash = xmalloc(sizeof (hash_t));
97 hash->h_buckets = xcalloc(sizeof (list_t *) * nbuckets);
98 hash->h_nbuckets = nbuckets;
99 hash->h_hashfn = hashfn ? hashfn : (int (*)())hash_def_hash;
100 hash->h_cmp = cmp ? cmp : (int (*)())hash_def_cmp;
102 return (hash);
105 void
106 hash_add(hash_t *hash, void *key)
108 int bucket = hash->h_hashfn(hash->h_nbuckets, key);
110 list_add(&hash->h_buckets[bucket], key);
113 static int
114 hash_add_cb(void *node, void *private)
116 hash_add((hash_t *)private, node);
117 return (0);
120 void
121 hash_merge(hash_t *to, hash_t *from)
123 (void) hash_iter(from, hash_add_cb, to);
126 static int
127 hash_remove_cb(void *key1, void *key2, hash_t *hash)
129 return (hash->h_cmp(key1, key2));
132 void
133 hash_remove(hash_t *hash, void *key)
135 int bucket = hash->h_hashfn(hash->h_nbuckets, key);
137 (void) list_remove(&hash->h_buckets[bucket], key,
138 (int (*)())hash_remove_cb, hash);
142 hash_match(hash_t *hash, void *key, int (*fun)(void *, void *),
143 void *private)
145 int bucket = hash->h_hashfn(hash->h_nbuckets, key);
147 return (list_iter(hash->h_buckets[bucket], fun, private) < 0);
150 static int
151 hash_find_list_cb(void *node, struct hash_data *hd)
153 int cbrc;
154 int rc = 0;
156 if (hd->hd_hash->h_cmp(hd->hd_key, node) == 0) {
157 if ((cbrc = hd->hd_fun(node, hd->hd_private)) < 0)
158 return (cbrc);
159 rc += cbrc;
162 return (rc);
166 hash_find_iter(hash_t *hash, void *key, int (*fun)(void *, void *),
167 void *private)
169 int bucket = hash->h_hashfn(hash->h_nbuckets, key);
170 struct hash_data hd;
172 hd.hd_hash = hash;
173 hd.hd_fun = fun;
174 hd.hd_key = key;
175 hd.hd_private = private;
177 return (list_iter(hash->h_buckets[bucket], (int (*)())hash_find_list_cb,
178 &hd));
181 /* stop on first match */
182 static int
183 hash_find_first_cb(void *node, struct hash_data *hd)
185 if (hd->hd_hash->h_cmp(hd->hd_key, node) == 0) {
186 hd->hd_ret = node;
187 return (-1);
190 return (0);
194 hash_find(hash_t *hash, void *key, void **value)
196 int ret;
197 struct hash_data hd;
199 hd.hd_hash = hash;
200 hd.hd_fun = hash_find_first_cb;
201 hd.hd_key = key;
203 ret = hash_match(hash, key, (int (*)())hash_find_first_cb, &hd);
204 if (ret && value)
205 *value = hd.hd_ret;
207 return (ret);
211 hash_iter(hash_t *hash, int (*fun)(void *, void *), void *private)
213 int cumrc = 0;
214 int cbrc;
215 int i;
217 for (i = 0; i < hash->h_nbuckets; i++) {
218 if (hash->h_buckets[i] != NULL) {
219 if ((cbrc = list_iter(hash->h_buckets[i], fun,
220 private)) < 0)
221 return (cbrc);
222 cumrc += cbrc;
226 return (cumrc);
230 hash_count(hash_t *hash)
232 int num, i;
234 for (num = 0, i = 0; i < hash->h_nbuckets; i++)
235 num += list_count(hash->h_buckets[i]);
237 return (num);
240 void
241 hash_free(hash_t *hash, void (*datafree)(void *, void *), void *private)
243 int i;
245 if (hash == NULL)
246 return;
248 for (i = 0; i < hash->h_nbuckets; i++)
249 list_free(hash->h_buckets[i], datafree, private);
250 free(hash->h_buckets);
251 free(hash);
254 void
255 hash_stats(hash_t *hash, int verbose)
257 int min = list_count(hash->h_buckets[0]);
258 int minidx = 0;
259 int max = min;
260 int maxidx = 0;
261 int tot = min;
262 int count;
263 int i;
265 if (min && verbose)
266 printf("%3d: %d\n", 0, min);
267 for (i = 1; i < hash->h_nbuckets; i++) {
268 count = list_count(hash->h_buckets[i]);
269 if (min > count) {
270 min = count;
271 minidx = i;
273 if (max < count) {
274 max = count;
275 maxidx = i;
277 if (count && verbose)
278 printf("%3d: %d\n", i, count);
279 tot += count;
282 printf("Hash statistics:\n");
283 printf(" Buckets: %d\n", hash->h_nbuckets);
284 printf(" Items : %d\n", tot);
285 printf(" Min/Max: %d in #%d, %d in #%d\n", min, minidx, max, maxidx);
286 printf(" Average: %5.2f\n", (float)tot / (float)hash->h_nbuckets);