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, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 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. 13 * 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] 19 * 20 * CDDL HEADER END 21 */ 22 23 /* 24 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 25 * Use is subject to license terms. 26 */ 27 28 #include <fmd_alloc.h> 29 #include <fmd_string.h> 30 #include <fmd_subr.h> 31 #include <fmd_buf.h> 32 #include <fmd.h> 33 34 static fmd_buf_t * 35 fmd_buf_alloc(const char *name, size_t size) 36 { 37 fmd_buf_t *bp = fmd_alloc(sizeof (fmd_buf_t), FMD_SLEEP); 38 39 bp->buf_name = fmd_strdup(name, FMD_SLEEP); 40 bp->buf_next = NULL; 41 bp->buf_data = fmd_zalloc(size, FMD_SLEEP); 42 bp->buf_size = size; 43 bp->buf_flags = FMD_BUF_DIRTY; 44 45 return (bp); 46 } 47 48 static void 49 fmd_buf_free(fmd_buf_t *bp) 50 { 51 fmd_strfree(bp->buf_name); 52 fmd_free(bp->buf_data, bp->buf_size); 53 fmd_free(bp, sizeof (fmd_buf_t)); 54 } 55 56 void 57 fmd_buf_hash_create(fmd_buf_hash_t *bhp) 58 { 59 bhp->bh_hashlen = fmd.d_str_buckets; 60 bhp->bh_hash = fmd_zalloc(sizeof (void *) * bhp->bh_hashlen, FMD_SLEEP); 61 bhp->bh_count = 0; 62 } 63 64 size_t 65 fmd_buf_hash_destroy(fmd_buf_hash_t *bhp) 66 { 67 size_t total = 0; 68 fmd_buf_t *bp, *np; 69 uint_t i; 70 71 for (i = 0; i < bhp->bh_hashlen; i++) { 72 for (bp = bhp->bh_hash[i]; bp != NULL; bp = np) { 73 np = bp->buf_next; 74 total += bp->buf_size; 75 fmd_buf_free(bp); 76 } 77 } 78 79 fmd_free(bhp->bh_hash, sizeof (void *) * bhp->bh_hashlen); 80 bzero(bhp, sizeof (fmd_buf_hash_t)); 81 return (total); 82 } 83 84 void 85 fmd_buf_hash_apply(fmd_buf_hash_t *bhp, fmd_buf_f *func, void *arg) 86 { 87 fmd_buf_t *bp; 88 uint_t i; 89 90 for (i = 0; i < bhp->bh_hashlen; i++) { 91 for (bp = bhp->bh_hash[i]; bp != NULL; bp = bp->buf_next) 92 func(bp, arg); 93 } 94 } 95 96 void 97 fmd_buf_hash_commit(fmd_buf_hash_t *bhp) 98 { 99 fmd_buf_t *bp; 100 uint_t i; 101 102 for (i = 0; i < bhp->bh_hashlen; i++) { 103 for (bp = bhp->bh_hash[i]; bp != NULL; bp = bp->buf_next) 104 bp->buf_flags &= ~FMD_BUF_DIRTY; 105 } 106 } 107 108 uint_t 109 fmd_buf_hash_count(fmd_buf_hash_t *bhp) 110 { 111 return (bhp->bh_count); 112 } 113 114 fmd_buf_t * 115 fmd_buf_insert(fmd_buf_hash_t *bhp, const char *name, size_t size) 116 { 117 uint_t h = fmd_strhash(name) % bhp->bh_hashlen; 118 fmd_buf_t *bp = fmd_buf_alloc(name, size); 119 120 bp->buf_next = bhp->bh_hash[h]; 121 bhp->bh_hash[h] = bp; 122 bhp->bh_count++; 123 124 return (bp); 125 } 126 127 fmd_buf_t * 128 fmd_buf_lookup(fmd_buf_hash_t *bhp, const char *name) 129 { 130 uint_t h = fmd_strhash(name) % bhp->bh_hashlen; 131 fmd_buf_t *bp; 132 133 for (bp = bhp->bh_hash[h]; bp != NULL; bp = bp->buf_next) { 134 if (strcmp(name, bp->buf_name) == 0) 135 return (bp); 136 } 137 138 return (NULL); 139 } 140 141 void 142 fmd_buf_delete(fmd_buf_hash_t *bhp, const char *name) 143 { 144 uint_t h = fmd_strhash(name) % bhp->bh_hashlen; 145 fmd_buf_t *bp, **pp = &bhp->bh_hash[h]; 146 147 for (bp = *pp; bp != NULL; bp = bp->buf_next) { 148 if (strcmp(bp->buf_name, name) != 0) 149 pp = &bp->buf_next; 150 else 151 break; 152 } 153 154 if (bp != NULL) { 155 *pp = bp->buf_next; 156 fmd_buf_free(bp); 157 ASSERT(bhp->bh_count != 0); 158 bhp->bh_count--; 159 } 160 } 161