diff options
author | Moriah Waterland <Moriah.Waterland@Sun.COM> | 2009-06-03 20:16:25 -0600 |
---|---|---|
committer | Moriah Waterland <Moriah.Waterland@Sun.COM> | 2009-06-03 20:16:25 -0600 |
commit | 5c51f1241dbbdf2656d0e10011981411ed0c9673 (patch) | |
tree | 0f30a2e38fe4e5d53a5a67264ba548577d82a86f /usr/src/lib/libpkg/common/nhash.c | |
parent | 2b79d384d32b4ea1e278466cd9b0f3bb56daae22 (diff) | |
download | illumos-joyent-5c51f1241dbbdf2656d0e10011981411ed0c9673.tar.gz |
6739234 move SVR4 packaging to ONNV gate
Diffstat (limited to 'usr/src/lib/libpkg/common/nhash.c')
-rw-r--r-- | usr/src/lib/libpkg/common/nhash.c | 182 |
1 files changed, 182 insertions, 0 deletions
diff --git a/usr/src/lib/libpkg/common/nhash.c b/usr/src/lib/libpkg/common/nhash.c new file mode 100644 index 0000000000..1b42595fec --- /dev/null +++ b/usr/src/lib/libpkg/common/nhash.c @@ -0,0 +1,182 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (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 2009 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <strings.h> +#include "pkglib.h" +#include "nhash.h" +#include "pkglocale.h" + +#ifndef _KERNEL +#define bcopy(a, b, c) (void) memmove(b, a, c) +#define bcmp memcmp +#define bzero(a, c) (void) memset(a, '\0', c) +#else /* _KERNEL */ +#define malloc bkmem_alloc +#endif /* _KERNEL */ + +#define VERIFY_HASH_REALLOC + +static int +BCMP(void *str1, void *str2, int len) +{ + return (bcmp((char *)str1, (char *)str2, len)); +} + +static int +HASH(void *datap, int datalen, int hsz) +{ + char *cp; + char *np; + int hv = 0; + + /* determine starting and ending positions */ + + cp = (char *)datap; + np = ((char *)cp + datalen); + + /* compute hash over all characters from start to end */ + + while (cp != np) { + hv += ((int)*cp++); + } + + /* return computed hash */ + + return (hv % hsz); +} + +int +init_cache(Cache **cp, int hsz, int bsz, + int (*hfunc)(void *, int, int), int (*cfunc)(void *, void *, int)) +{ + if ((*cp = (Cache *) malloc(sizeof (**cp))) == NULL) { + (void) fprintf(stderr, pkg_gt("malloc(Cache **cp)")); + return (-1); + } + if (((*cp)->bp = + (Bucket *) malloc(sizeof (*(*cp)->bp) * hsz)) == NULL) { + (void) fprintf(stderr, pkg_gt("malloc(Bucket cp->bp)")); + return (-1); + } + + (*cp)->hsz = hsz; + (*cp)->bsz = bsz; + + bzero((*cp)->bp, sizeof (*(*cp)->bp) * hsz); + + if (hfunc != (int (*)()) NULL) { + (*cp)->hfunc = hfunc; + } else { + (*cp)->hfunc = HASH; + } + + if (cfunc != (int (*)()) NULL) { + (*cp)->cfunc = cfunc; + } else { + (*cp)->cfunc = BCMP; + } + return (0); +} + +int +add_cache(Cache *cp, Item *itemp) +{ + Bucket *bp; + Item **titempp; + + /* + * If cp is NULL, then init_cache() wasn't called. Quietly return the + * error code and let the caller deal with it. + */ + if (cp == NULL) + return (-1); + + bp = &cp->bp[(*cp->hfunc)(itemp->key, itemp->keyl, cp->hsz)]; + if (bp->nent >= bp->nalloc) { + if (bp->nalloc == 0) { + bp->itempp = + (Item **) malloc(sizeof (*bp->itempp) * cp->bsz); + } else { +#ifdef VERIFY_HASH_REALLOC + (void) fprintf(stderr, + pkg_gt("realloc(%d) bucket=%d\n"), + bp->nalloc + cp->bsz, + (*cp->hfunc)(itemp->key, itemp->keyl, cp->hsz)); +#endif /* VERIFY_HASH_REALLOC */ + if ((titempp = + (Item **) malloc(sizeof (*bp->itempp) * + (bp->nalloc + cp->bsz))) != NULL) { + bcopy((char *)bp->itempp, (char *)titempp, + (sizeof (*bp->itempp) * bp->nalloc)); +#ifdef _KERNEL + bkmem_free(bp->itempp, + (sizeof (*bp->itempp) * bp->nalloc)); +#else /* !_KERNEL */ + free(bp->itempp); +#endif /* _KERNEL */ + bp->itempp = titempp; + } else + bp->itempp = NULL; + } + if (bp->itempp == NULL) { + (void) fprintf(stderr, + pkg_gt("add_cache(): out of memory\n")); + return (-1); + } + bp->nalloc += cp->bsz; + } + bp->itempp[bp->nent] = itemp; + bp->nent++; + return (0); +} + +Item * +lookup_cache(Cache *cp, void *datap, int datalen) +{ + int i; + Bucket *bp; + + /* + * If cp is NULL, then init_cache() wasn't called. Quietly return the + * error code and let the caller deal with it. + */ + if (cp == NULL) { + return (Null_Item); + } + + bp = &cp->bp[(*cp->hfunc)(datap, datalen, cp->hsz)]; + + for (i = 0; i < bp->nent; i++) { + if (!(*cp->cfunc)((void *)bp->itempp[i]->key, datap, datalen)) { + return (bp->itempp[i]); + } + } + return (Null_Item); +} |