Files
Arquivotheca.Solaris-2.5/lib/libpkg/nhash.c
seta75D 7c4988eac0 Init
2021-10-11 19:38:01 -03:00

147 lines
3.2 KiB
C
Executable File

/*
* Copyright (c) 1995 by Sun Microsystems, Inc.
* All rights reserved.
*/
#ident "@(#)nhash.c 1.10 95/01/11 SMI"
#include <string.h>
#include <stdlib.h>
#include <stdio.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) 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)
{
register char *cp;
register int hv = 0;
for (cp = (char *)datap; cp != ((char *)datap + datalen); hv += *cp++)
;
return (hv % hsz);
}
int
init_cache(Cache **cp, int hsz, int bsz,
int (*hfunc)(void *, int, int), int (*cfunc)(void *, void *, int))
{
int i;
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;
for (i = 0; i < (*cp)->hsz; i++) {
(*cp)->bp[i].nent = 0;
(*cp)->bp[i].nalloc = 0;
(*cp)->bp[i].itempp = NULL;
}
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);
}