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 #include <string.h> 28 #include <sys/types.h> 29 30 #include <inj.h> 31 #include <inj_err.h> 32 33 #define INJ_HASHSZ 211 34 35 struct inj_var { 36 struct inj_var *v_next; 37 uintmax_t v_uvalue; 38 void *v_key; 39 }; 40 41 void 42 inj_hash_create(inj_hash_t *h, ulong_t (*hfn)(void *), 43 int (*cfn)(void *, void *)) 44 { 45 h->h_hash = inj_zalloc(sizeof (inj_var_t *) * INJ_HASHSZ); 46 h->h_hashsz = INJ_HASHSZ; 47 h->h_nelems = 0; 48 49 h->h_hashfn = hfn; 50 h->h_cmpfn = cfn; 51 } 52 53 static inj_var_t * 54 inj_var_alloc(void *key, uintmax_t value, inj_var_t *next) 55 { 56 inj_var_t *v = inj_alloc(sizeof (inj_var_t)); 57 58 v->v_next = next; 59 v->v_key = key; 60 v->v_uvalue = value; 61 62 return (v); 63 } 64 65 static void 66 inj_var_free(inj_var_t *v, void (*freefn)(inj_var_t *, void *), void *arg) 67 { 68 if (freefn != NULL) 69 freefn(v, arg); 70 71 inj_free(v, sizeof (inj_var_t)); 72 } 73 74 void 75 inj_hash_destroy(inj_hash_t *h, void (*freefn)(inj_var_t *, void *), void *arg) 76 { 77 inj_var_t *v, *w; 78 size_t i; 79 80 for (i = 0; i < h->h_hashsz; i++) { 81 for (v = h->h_hash[i]; v != NULL; v = w) { 82 w = v->v_next; 83 inj_var_free(v, freefn, arg); 84 } 85 } 86 87 inj_free(h->h_hash, sizeof (inj_var_t *) * INJ_HASHSZ); 88 } 89 90 int 91 inj_hash_insert(inj_hash_t *h, void *key, uintmax_t value) 92 { 93 size_t i = h->h_hashfn(key) % h->h_hashsz; 94 inj_var_t *v; 95 96 for (v = h->h_hash[i]; v != NULL; v = v->v_next) { 97 if (h->h_cmpfn(v->v_key, key) == 0) 98 return (-1); 99 } 100 101 /* not found - make a new one */ 102 v = inj_var_alloc(key, value, h->h_hash[i]); 103 h->h_hash[i] = v; 104 h->h_nelems++; 105 106 return (0); 107 } 108 109 inj_var_t * 110 inj_hash_lookup(inj_hash_t *h, void *key) 111 { 112 size_t i = h->h_hashfn(key) % h->h_hashsz; 113 inj_var_t *v; 114 115 for (v = h->h_hash[i]; v != NULL; v = v->v_next) { 116 if (h->h_cmpfn(v->v_key, key) == 0) 117 return (v); 118 } 119 120 return (NULL); 121 } 122 123 void * 124 inj_hash_get_key(inj_var_t *v) 125 { 126 return (v->v_key); 127 } 128 129 uintmax_t 130 inj_hash_get_value(inj_var_t *v) 131 { 132 return (v->v_uvalue); 133 } 134 135 void * 136 inj_hash_get_cookie(inj_var_t *v) 137 { 138 return ((void *)(uintptr_t)v->v_uvalue); 139 } 140