/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #include #include #include #include #include static fmd_buf_t * fmd_buf_alloc(const char *name, size_t size) { fmd_buf_t *bp = fmd_alloc(sizeof (fmd_buf_t), FMD_SLEEP); bp->buf_name = fmd_strdup(name, FMD_SLEEP); bp->buf_next = NULL; bp->buf_data = fmd_zalloc(size, FMD_SLEEP); bp->buf_size = size; bp->buf_flags = FMD_BUF_DIRTY; return (bp); } static void fmd_buf_free(fmd_buf_t *bp) { fmd_strfree(bp->buf_name); fmd_free(bp->buf_data, bp->buf_size); fmd_free(bp, sizeof (fmd_buf_t)); } void fmd_buf_hash_create(fmd_buf_hash_t *bhp) { bhp->bh_hashlen = fmd.d_str_buckets; bhp->bh_hash = fmd_zalloc(sizeof (void *) * bhp->bh_hashlen, FMD_SLEEP); bhp->bh_count = 0; } size_t fmd_buf_hash_destroy(fmd_buf_hash_t *bhp) { size_t total = 0; fmd_buf_t *bp, *np; uint_t i; for (i = 0; i < bhp->bh_hashlen; i++) { for (bp = bhp->bh_hash[i]; bp != NULL; bp = np) { np = bp->buf_next; total += bp->buf_size; fmd_buf_free(bp); } } fmd_free(bhp->bh_hash, sizeof (void *) * bhp->bh_hashlen); bzero(bhp, sizeof (fmd_buf_hash_t)); return (total); } void fmd_buf_hash_apply(fmd_buf_hash_t *bhp, fmd_buf_f *func, void *arg) { fmd_buf_t *bp; uint_t i; for (i = 0; i < bhp->bh_hashlen; i++) { for (bp = bhp->bh_hash[i]; bp != NULL; bp = bp->buf_next) func(bp, arg); } } void fmd_buf_hash_commit(fmd_buf_hash_t *bhp) { fmd_buf_t *bp; uint_t i; for (i = 0; i < bhp->bh_hashlen; i++) { for (bp = bhp->bh_hash[i]; bp != NULL; bp = bp->buf_next) bp->buf_flags &= ~FMD_BUF_DIRTY; } } uint_t fmd_buf_hash_count(fmd_buf_hash_t *bhp) { return (bhp->bh_count); } fmd_buf_t * fmd_buf_insert(fmd_buf_hash_t *bhp, const char *name, size_t size) { uint_t h = fmd_strhash(name) % bhp->bh_hashlen; fmd_buf_t *bp = fmd_buf_alloc(name, size); bp->buf_next = bhp->bh_hash[h]; bhp->bh_hash[h] = bp; bhp->bh_count++; return (bp); } fmd_buf_t * fmd_buf_lookup(fmd_buf_hash_t *bhp, const char *name) { uint_t h = fmd_strhash(name) % bhp->bh_hashlen; fmd_buf_t *bp; for (bp = bhp->bh_hash[h]; bp != NULL; bp = bp->buf_next) { if (strcmp(name, bp->buf_name) == 0) return (bp); } return (NULL); } void fmd_buf_delete(fmd_buf_hash_t *bhp, const char *name) { uint_t h = fmd_strhash(name) % bhp->bh_hashlen; fmd_buf_t *bp, **pp = &bhp->bh_hash[h]; for (bp = *pp; bp != NULL; bp = bp->buf_next) { if (strcmp(bp->buf_name, name) != 0) pp = &bp->buf_next; else break; } if (bp != NULL) { *pp = bp->buf_next; fmd_buf_free(bp); ASSERT(bhp->bh_count != 0); bhp->bh_count--; } }