1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #include <string.h> 30 #include <sys/types.h> 31 32 #include <inj.h> 33 #include <inj_err.h> 34 35 #define INJ_HASHSZ 211 36 37 struct inj_var { 38 struct inj_var *v_next; 39 uintmax_t v_uvalue; 40 void *v_key; 41 }; 42 43 void 44 inj_hash_create(inj_hash_t *h, ulong_t (*hfn)(void *), 45 int (*cfn)(void *, void *)) 46 { 47 h->h_hash = inj_zalloc(sizeof (inj_var_t *) * INJ_HASHSZ); 48 h->h_hashsz = INJ_HASHSZ; 49 h->h_nelems = 0; 50 51 h->h_hashfn = hfn; 52 h->h_cmpfn = cfn; 53 } 54 55 static inj_var_t * 56 inj_var_alloc(void *key, uintmax_t value, inj_var_t *next) 57 { 58 inj_var_t *v = inj_alloc(sizeof (inj_var_t)); 59 60 v->v_next = next; 61 v->v_key = key; 62 v->v_uvalue = value; 63 64 return (v); 65 } 66 67 static void 68 inj_var_free(inj_var_t *v, void (*freefn)(inj_var_t *, void *), void *arg) 69 { 70 if (freefn != NULL) 71 freefn(v, arg); 72 73 inj_free(v, sizeof (inj_var_t)); 74 } 75 76 void 77 inj_hash_destroy(inj_hash_t *h, void (*freefn)(inj_var_t *, void *), void *arg) 78 { 79 inj_var_t *v, *w; 80 size_t i; 81 82 for (i = 0; i < h->h_hashsz; i++) { 83 for (v = h->h_hash[i]; v != NULL; v = w) { 84 w = v->v_next; 85 inj_var_free(v, freefn, arg); 86 } 87 } 88 89 inj_free(h->h_hash, sizeof (inj_var_t *) * INJ_HASHSZ); 90 } 91 92 int 93 inj_hash_insert(inj_hash_t *h, void *key, uintmax_t value) 94 { 95 size_t i = h->h_hashfn(key) % h->h_hashsz; 96 inj_var_t *v; 97 98 for (v = h->h_hash[i]; v != NULL; v = v->v_next) { 99 if (h->h_cmpfn(v->v_key, key) == 0) 100 return (-1); 101 } 102 103 /* not found - make a new one */ 104 v = inj_var_alloc(key, value, h->h_hash[i]); 105 h->h_hash[i] = v; 106 h->h_nelems++; 107 108 return (0); 109 } 110 111 inj_var_t * 112 inj_hash_lookup(inj_hash_t *h, void *key) 113 { 114 size_t i = h->h_hashfn(key) % h->h_hashsz; 115 inj_var_t *v; 116 117 for (v = h->h_hash[i]; v != NULL; v = v->v_next) { 118 if (h->h_cmpfn(v->v_key, key) == 0) 119 return (v); 120 } 121 122 return (NULL); 123 } 124 125 void * 126 inj_hash_get_key(inj_var_t *v) 127 { 128 return (v->v_key); 129 } 130 131 uintmax_t 132 inj_hash_get_value(inj_var_t *v) 133 { 134 return (v->v_uvalue); 135 } 136 137 void * 138 inj_hash_get_cookie(inj_var_t *v) 139 { 140 return ((void *)(uintptr_t)v->v_uvalue); 141 } 142