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

📄 pair.c

📁 Altera recommends the following system configuration: * Pentium II 400 with 512-MB system memory (fa
💻 C
字号:
/* * sdbm - ndbm work-alike hashed database library * based on Per-Aake Larson's Dynamic Hashing algorithms. BIT 18 (1978). * author: oz@nexus.yorku.ca * status: public domain. * * page-level routines */#include "config.h"#ifdef __CYGWIN__# define EXTCONST extern const#else# include "EXTERN.h"#endif#include "sdbm.h"#include "tune.h"#include "pair.h"#define exhash(item)	sdbm_hash((item).dptr, (item).dsize)/*  * forward  */static int seepair proto((char *, int, char *, int));/* * page format: *	+------------------------------+ * ino	| n | keyoff | datoff | keyoff | * 	+------------+--------+--------+ *	| datoff | - - - ---->	       | *	+--------+---------------------+ *	|	 F R E E A R E A       | *	+--------------+---------------+ *	|  <---- - - - | data          | *	+--------+-----+----+----------+ *	|  key   | data     | key      | *	+--------+----------+----------+ * * calculating the offsets for free area:  if the number * of entries (ino[0]) is zero, the offset to the END of * the free area is the block size. Otherwise, it is the * nth (ino[ino[0]]) entry's offset. */intfitpair(char *pag, int need){	register int n;	register int off;	register int free;	register short *ino = (short *) pag;	off = ((n = ino[0]) > 0) ? ino[n] : PBLKSIZ;	free = off - (n + 1) * sizeof(short);	need += 2 * sizeof(short);	debug(("free %d need %d\n", free, need));	return need <= free;}voidputpair(char *pag, datum key, datum val){	register int n;	register int off;	register short *ino = (short *) pag;	off = ((n = ino[0]) > 0) ? ino[n] : PBLKSIZ;/* * enter the key first */	off -= key.dsize;	(void) memcpy(pag + off, key.dptr, key.dsize);	ino[n + 1] = off;/* * now the data */	off -= val.dsize;	(void) memcpy(pag + off, val.dptr, val.dsize);	ino[n + 2] = off;/* * adjust item count */	ino[0] += 2;}datumgetpair(char *pag, datum key){	register int i;	register int n;	datum val;	register short *ino = (short *) pag;	if ((n = ino[0]) == 0)		return nullitem;	if ((i = seepair(pag, n, key.dptr, key.dsize)) == 0)		return nullitem;	val.dptr = pag + ino[i + 1];	val.dsize = ino[i] - ino[i + 1];	return val;}intexipair(char *pag, datum key){	register short *ino = (short *) pag;	if (ino[0] == 0)		return 0;	return (seepair(pag, ino[0], key.dptr, key.dsize) != 0);}#ifdef SEEDUPSintduppair(char *pag, datum key){	register short *ino = (short *) pag;	return ino[0] > 0 && seepair(pag, ino[0], key.dptr, key.dsize) > 0;}#endifdatumgetnkey(char *pag, int num){	datum key;	register int off;	register short *ino = (short *) pag;	num = num * 2 - 1;	if (ino[0] == 0 || num > ino[0])		return nullitem;	off = (num > 1) ? ino[num - 1] : PBLKSIZ;	key.dptr = pag + ino[num];	key.dsize = off - ino[num];	return key;}intdelpair(char *pag, datum key){	register int n;	register int i;	register short *ino = (short *) pag;	if ((n = ino[0]) == 0)		return 0;	if ((i = seepair(pag, n, key.dptr, key.dsize)) == 0)		return 0;/* * found the key. if it is the last entry * [i.e. i == n - 1] we just adjust the entry count. * hard case: move all data down onto the deleted pair, * shift offsets onto deleted offsets, and adjust them. * [note: 0 < i < n] */	if (i < n - 1) {		register int m;		register char *dst = pag + (i == 1 ? PBLKSIZ : ino[i - 1]);		register char *src = pag + ino[i + 1];		register int   zoo = dst - src;		debug(("free-up %d ", zoo));/* * shift data/keys down */		m = ino[i + 1] - ino[n];#ifdef DUFF#define MOVB 	*--dst = *--src		if (m > 0) {			register int loop = (m + 8 - 1) >> 3;			switch (m & (8 - 1)) {			case 0:	do {				MOVB;	case 7:	MOVB;			case 6:	MOVB;	case 5:	MOVB;			case 4:	MOVB;	case 3:	MOVB;			case 2:	MOVB;	case 1:	MOVB;				} while (--loop);			}		}#else#ifdef HAS_MEMMOVE		dst -= m;		src -= m;		memmove(dst, src, m);#else		while (m--)			*--dst = *--src;#endif#endif/* * adjust offset index up */		while (i < n - 1) {			ino[i] = ino[i + 2] + zoo;			i++;		}	}	ino[0] -= 2;	return 1;}/* * search for the key in the page. * return offset index in the range 0 < i < n. * return 0 if not found. */static intseepair(char *pag, register int n, register char *key, register int siz){	register int i;	register int off = PBLKSIZ;	register short *ino = (short *) pag;	for (i = 1; i < n; i += 2) {		if (siz == off - ino[i] &&		    memEQ(key, pag + ino[i], siz))			return i;		off = ino[i + 1];	}	return 0;}voidsplpage(char *pag, char *New, long int sbit){	datum key;	datum val;	register int n;	register int off = PBLKSIZ;	char cur[PBLKSIZ];	register short *ino = (short *) cur;	(void) memcpy(cur, pag, PBLKSIZ);	(void) memset(pag, 0, PBLKSIZ);	(void) memset(New, 0, PBLKSIZ);	n = ino[0];	for (ino++; n > 0; ino += 2) {		key.dptr = cur + ino[0]; 		key.dsize = off - ino[0];		val.dptr = cur + ino[1];		val.dsize = ino[0] - ino[1];/* * select the page pointer (by looking at sbit) and insert */		(void) putpair((exhash(key) & sbit) ? New : pag, key, val);		off = ino[1];		n -= 2;	}	debug(("%d split %d/%d\n", ((short *) cur)[0] / 2, 	       ((short *) New)[0] / 2,	       ((short *) pag)[0] / 2));}/* * check page sanity:  * number of entries should be something * reasonable, and all offsets in the index should be in order. * this could be made more rigorous. */intchkpage(char *pag){	register int n;	register int off;	register short *ino = (short *) pag;	if ((n = ino[0]) < 0 || n > PBLKSIZ / sizeof(short))		return 0;	if (n > 0) {		off = PBLKSIZ;		for (ino++; n > 0; ino += 2) {			if (ino[0] > off || ino[1] > off ||			    ino[1] > ino[0])				return 0;			off = ino[1];			n -= 2;		}	}	return 1;}

⌨️ 快捷键说明

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