⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hash.c

📁 asterisk 一个模拟IPPBX的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	fp = hashp->fp;	whdrp = &hashp->hdr;#if BYTE_ORDER == LITTLE_ENDIAN	whdrp = &whdr;	swap_header_copy(&hashp->hdr, whdrp);#endif	if ((lseek(fp, (off_t)0, SEEK_SET) == -1) ||	    ((wsize = write(fp, whdrp, sizeof(HASHHDR))) == -1))		return (-1);	else		if (wsize != sizeof(HASHHDR)) {			errno = EFTYPE;			hashp->errnum = errno;			return (-1);		}	for (i = 0; i < NCACHED; i++)		if (hashp->mapp[i])			if (__put_page(hashp, (char *)hashp->mapp[i],				hashp->BITMAPS[i], 0, 1))				return (-1);	return (0);}/*******************************SEARCH ROUTINES *****************************//* * All the access routines return * * Returns: *	 0 on SUCCESS *	 1 to indicate an external ERROR (i.e. key not found, etc) *	-1 to indicate an internal ERROR (i.e. out of memory, etc) */static inthash_get(dbp, key, data, flag)	const DB *dbp;	const DBT *key;	DBT *data;	u_int32_t flag;{	HTAB *hashp;	hashp = (HTAB *)dbp->internal;	if (flag) {		hashp->errnum = errno = EINVAL;		return (ERROR);	}	return (hash_access(hashp, HASH_GET, (DBT *)key, data));}static inthash_put(dbp, key, data, flag)	const DB *dbp;	DBT *key;	const DBT *data;	u_int32_t flag;{	HTAB *hashp;	hashp = (HTAB *)dbp->internal;	if (flag && flag != R_NOOVERWRITE) {		hashp->errnum = errno = EINVAL;		return (ERROR);	}	if ((hashp->flags & O_ACCMODE) == O_RDONLY) {		hashp->errnum = errno = EPERM;		return (ERROR);	}	return (hash_access(hashp, flag == R_NOOVERWRITE ?	    HASH_PUTNEW : HASH_PUT, (DBT *)key, (DBT *)data));}static inthash_delete(dbp, key, flag)	const DB *dbp;	const DBT *key;	u_int32_t flag;		/* Ignored */{	HTAB *hashp;	hashp = (HTAB *)dbp->internal;	if (flag && flag != R_CURSOR) {		hashp->errnum = errno = EINVAL;		return (ERROR);	}	if ((hashp->flags & O_ACCMODE) == O_RDONLY) {		hashp->errnum = errno = EPERM;		return (ERROR);	}	return (hash_access(hashp, HASH_DELETE, (DBT *)key, NULL));}/* * Assume that hashp has been set in wrapper routine. */static inthash_access(hashp, action, key, val)	HTAB *hashp;	ACTION action;	DBT *key, *val;{	register BUFHEAD *rbufp;	BUFHEAD *bufp, *save_bufp;	register u_int16_t *bp;	register int n, ndx, off, size;	register char *kp;	u_int16_t pageno;#ifdef HASH_STATISTICS	hash_accesses++;#endif	off = hashp->BSIZE;	size = key->size;	kp = (char *)key->data;	rbufp = __get_buf(hashp, __call_hash(hashp, kp, size), NULL, 0);	if (!rbufp)		return (ERROR);	save_bufp = rbufp;	/* Pin the bucket chain */	rbufp->flags |= BUF_PIN;	for (bp = (u_int16_t *)rbufp->page, n = *bp++, ndx = 1; ndx < n;)		if (bp[1] >= REAL_KEY) {			/* Real key/data pair */			if (size == off - *bp &&			    memcmp(kp, rbufp->page + *bp, size) == 0)				goto found;			off = bp[1];#ifdef HASH_STATISTICS			hash_collisions++;#endif			bp += 2;			ndx += 2;		} else if (bp[1] == OVFLPAGE) {			rbufp = __get_buf(hashp, *bp, rbufp, 0);			if (!rbufp) {				save_bufp->flags &= ~BUF_PIN;				return (ERROR);			}			/* FOR LOOP INIT */			bp = (u_int16_t *)rbufp->page;			n = *bp++;			ndx = 1;			off = hashp->BSIZE;		} else if (bp[1] < REAL_KEY) {			if ((ndx =			    __find_bigpair(hashp, rbufp, ndx, kp, size)) > 0)				goto found;			if (ndx == -2) {				bufp = rbufp;				if (!(pageno =				    __find_last_page(hashp, &bufp))) {					ndx = 0;					rbufp = bufp;					break;	/* FOR */				}				rbufp = __get_buf(hashp, pageno, bufp, 0);				if (!rbufp) {					save_bufp->flags &= ~BUF_PIN;					return (ERROR);				}				/* FOR LOOP INIT */				bp = (u_int16_t *)rbufp->page;				n = *bp++;				ndx = 1;				off = hashp->BSIZE;			} else {				save_bufp->flags &= ~BUF_PIN;				return (ERROR);			}		}	/* Not found */	switch (action) {	case HASH_PUT:	case HASH_PUTNEW:		if (__addel(hashp, rbufp, key, val)) {			save_bufp->flags &= ~BUF_PIN;			return (ERROR);		} else {			save_bufp->flags &= ~BUF_PIN;			return (SUCCESS);		}	case HASH_GET:	case HASH_DELETE:	default:		save_bufp->flags &= ~BUF_PIN;		return (ABNORMAL);	}found:	switch (action) {	case HASH_PUTNEW:		save_bufp->flags &= ~BUF_PIN;		return (ABNORMAL);	case HASH_GET:		bp = (u_int16_t *)rbufp->page;		if (bp[ndx + 1] < REAL_KEY) {			if (__big_return(hashp, rbufp, ndx, val, 0))				return (ERROR);		} else {			val->data = (u_char *)rbufp->page + (int)bp[ndx + 1];			val->size = bp[ndx] - bp[ndx + 1];		}		break;	case HASH_PUT:		if ((__delpair(hashp, rbufp, ndx)) ||		    (__addel(hashp, rbufp, key, val))) {			save_bufp->flags &= ~BUF_PIN;			return (ERROR);		}		break;	case HASH_DELETE:		if (__delpair(hashp, rbufp, ndx))			return (ERROR);		break;	default:		abort();	}	save_bufp->flags &= ~BUF_PIN;	return (SUCCESS);}static inthash_seq(dbp, key, data, flag)	const DB *dbp;	DBT *key, *data;	u_int32_t flag;{	register u_int32_t bucket;	register BUFHEAD *bufp = NULL;	HTAB *hashp;	u_int16_t *bp, ndx;	hashp = (HTAB *)dbp->internal;	if (flag && flag != R_FIRST && flag != R_NEXT) {		hashp->errnum = errno = EINVAL;		return (ERROR);	}#ifdef HASH_STATISTICS	hash_accesses++;#endif	if ((hashp->cbucket < 0) || (flag == R_FIRST)) {		hashp->cbucket = 0;		hashp->cndx = 1;		hashp->cpage = NULL;	}	for (bp = NULL; !bp || !bp[0]; ) {		if (!(bufp = hashp->cpage)) {			for (bucket = hashp->cbucket;			    bucket <= (u_int32_t) hashp->MAX_BUCKET;			    bucket++, hashp->cndx = 1) {				bufp = __get_buf(hashp, bucket, NULL, 0);				if (!bufp)					return (ERROR);				hashp->cpage = bufp;				bp = (u_int16_t *)bufp->page;				if (bp[0])					break;			}			hashp->cbucket = bucket;			if (hashp->cbucket > hashp->MAX_BUCKET) {				hashp->cbucket = -1;				return (ABNORMAL);			}		} else			bp = (u_int16_t *)hashp->cpage->page;#ifdef DEBUG		assert(bp);		assert(bufp);#endif		while (bp[hashp->cndx + 1] == OVFLPAGE) {			bufp = hashp->cpage =			    __get_buf(hashp, bp[hashp->cndx], bufp, 0);			if (!bufp)				return (ERROR);			bp = (u_int16_t *)(bufp->page);			hashp->cndx = 1;		}		if (!bp[0]) {			hashp->cpage = NULL;			++hashp->cbucket;		}	}	ndx = hashp->cndx;	if (bp[ndx + 1] < REAL_KEY) {		if (__big_keydata(hashp, bufp, key, data, 1))			return (ERROR);	} else {		key->data = (u_char *)hashp->cpage->page + bp[ndx];		key->size = (ndx > 1 ? bp[ndx - 1] : hashp->BSIZE) - bp[ndx];		data->data = (u_char *)hashp->cpage->page + bp[ndx + 1];		data->size = bp[ndx] - bp[ndx + 1];		ndx += 2;		if (ndx > bp[0]) {			hashp->cpage = NULL;			hashp->cbucket++;			hashp->cndx = 1;		} else			hashp->cndx = ndx;	}	return (SUCCESS);}/********************************* UTILITIES ************************//* * Returns: *	 0 ==> OK *	-1 ==> Error */extern int__expand_table(hashp)	HTAB *hashp;{	u_int32_t old_bucket, new_bucket;	int dirsize, new_segnum, spare_ndx;#ifdef HASH_STATISTICS	hash_expansions++;#endif	new_bucket = ++hashp->MAX_BUCKET;	old_bucket = (hashp->MAX_BUCKET & hashp->LOW_MASK);	new_segnum = new_bucket >> hashp->SSHIFT;	/* Check if we need a new segment */	if (new_segnum >= hashp->nsegs) {		/* Check if we need to expand directory */		if (new_segnum >= hashp->DSIZE) {			/* Reallocate directory */			dirsize = hashp->DSIZE * sizeof(SEGMENT *);			if (!hash_realloc(&hashp->dir, dirsize, dirsize << 1))				return (-1);			hashp->DSIZE = dirsize << 1;		}		if ((hashp->dir[new_segnum] =		    (SEGMENT)calloc(hashp->SGSIZE, sizeof(SEGMENT))) == NULL)			return (-1);		hashp->exsegs++;		hashp->nsegs++;	}	/*	 * If the split point is increasing (MAX_BUCKET's log base 2	 * * increases), we need to copy the current contents of the spare	 * split bucket to the next bucket.	 */	spare_ndx = __hash_log2(hashp->MAX_BUCKET + 1);	if (spare_ndx > hashp->OVFL_POINT) {		hashp->SPARES[spare_ndx] = hashp->SPARES[hashp->OVFL_POINT];		hashp->OVFL_POINT = spare_ndx;	}	if (new_bucket > (u_int32_t) hashp->HIGH_MASK) {		/* Starting a new doubling */		hashp->LOW_MASK = hashp->HIGH_MASK;		hashp->HIGH_MASK = new_bucket | hashp->LOW_MASK;	}	/* Relocate records to the new bucket */	return (__split_page(hashp, old_bucket, new_bucket));}/* * If realloc guarantees that the pointer is not destroyed if the realloc * fails, then this routine can go away. */static void *hash_realloc(p_ptr, oldsize, newsize)	SEGMENT **p_ptr;	int oldsize, newsize;{	register void *p;	if ((p = malloc(newsize))) {		memmove(p, *p_ptr, oldsize);		memset((char *)p + oldsize, 0, newsize - oldsize);		free(*p_ptr);		*p_ptr = p;	}	return (p);}extern u_int32_t__call_hash(hashp, k, len)	HTAB *hashp;	char *k;	int len;{	int n, bucket;	n = hashp->hash(k, len);	bucket = n & hashp->HIGH_MASK;	if (bucket > hashp->MAX_BUCKET)		bucket = bucket & hashp->LOW_MASK;	return (bucket);}/* * Allocate segment table.  On error, destroy the table and set errno. * * Returns 0 on success */static intalloc_segs(hashp, nsegs)	HTAB *hashp;	int nsegs;{	register int i;	register SEGMENT store;	int save_errno;	if ((hashp->dir =	    (SEGMENT *)calloc(hashp->DSIZE, sizeof(SEGMENT *))) == NULL) {		save_errno = errno;		(void)hdestroy(hashp);		errno = save_errno;		return (-1);	}	/* Allocate segments */	if ((store =	    (SEGMENT)calloc(nsegs << hashp->SSHIFT, sizeof(SEGMENT))) == NULL) {		save_errno = errno;		(void)hdestroy(hashp);		errno = save_errno;		return (-1);	}	for (i = 0; i < nsegs; i++, hashp->nsegs++)		hashp->dir[i] = &store[i << hashp->SSHIFT];	return (0);}#if BYTE_ORDER == LITTLE_ENDIAN/* * Hashp->hdr needs to be byteswapped. */static voidswap_header_copy(srcp, destp)	HASHHDR *srcp, *destp;{	int i;	P_32_COPY(srcp->magic, destp->magic);	P_32_COPY(srcp->version, destp->version);	P_32_COPY(srcp->lorder, destp->lorder);	P_32_COPY(srcp->bsize, destp->bsize);	P_32_COPY(srcp->bshift, destp->bshift);	P_32_COPY(srcp->dsize, destp->dsize);	P_32_COPY(srcp->ssize, destp->ssize);	P_32_COPY(srcp->sshift, destp->sshift);	P_32_COPY(srcp->ovfl_point, destp->ovfl_point);	P_32_COPY(srcp->last_freed, destp->last_freed);	P_32_COPY(srcp->max_bucket, destp->max_bucket);	P_32_COPY(srcp->high_mask, destp->high_mask);	P_32_COPY(srcp->low_mask, destp->low_mask);	P_32_COPY(srcp->ffactor, destp->ffactor);	P_32_COPY(srcp->nkeys, destp->nkeys);	P_32_COPY(srcp->hdrpages, destp->hdrpages);	P_32_COPY(srcp->h_charkey, destp->h_charkey);	for (i = 0; i < NCACHED; i++) {		P_32_COPY(srcp->spares[i], destp->spares[i]);		P_16_COPY(srcp->bitmaps[i], destp->bitmaps[i]);	}}static voidswap_header(hashp)	HTAB *hashp;{	HASHHDR *hdrp;	int i;	hdrp = &hashp->hdr;	M_32_SWAP(hdrp->magic);	M_32_SWAP(hdrp->version);	M_32_SWAP(hdrp->lorder);	M_32_SWAP(hdrp->bsize);	M_32_SWAP(hdrp->bshift);	M_32_SWAP(hdrp->dsize);	M_32_SWAP(hdrp->ssize);	M_32_SWAP(hdrp->sshift);	M_32_SWAP(hdrp->ovfl_point);	M_32_SWAP(hdrp->last_freed);	M_32_SWAP(hdrp->max_bucket);	M_32_SWAP(hdrp->high_mask);	M_32_SWAP(hdrp->low_mask);	M_32_SWAP(hdrp->ffactor);	M_32_SWAP(hdrp->nkeys);	M_32_SWAP(hdrp->hdrpages);	M_32_SWAP(hdrp->h_charkey);	for (i = 0; i < NCACHED; i++) {		M_32_SWAP(hdrp->spares[i]);		M_16_SWAP(hdrp->bitmaps[i]);	}}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -