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