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

📄 bt_cursor.c

📁 这是linux下运行的mysql软件包,可用于linux 下安装 php + mysql + apach 的网络配置
💻 C
📖 第 1 页 / 共 5 页
字号:
	if ((ret = __bam_c_prev(dbc)) != 0)		return (ret);	if (__bam_isopd(dbc, &pgno)) {		cp = (BTREE_CURSOR *)dbc->internal;		if ((ret = __db_c_newopd(dbc, pgno, cp->opd, &cp->opd)) != 0)			return (ret);		if ((ret = cp->opd->c_am_get(cp->opd,		    &key, &data, DB_LAST, NULL)) != 0)			return (ret);	}	return (0);}/* * __bam_bulk -- Return bulk data from a btree. */static int__bam_bulk(dbc, data, flags)	DBC *dbc;	DBT *data;	u_int32_t flags;{	BKEYDATA *bk;	BOVERFLOW *bo;	BTREE_CURSOR *cp;	PAGE *pg;	db_indx_t *inp, indx, pg_keyoff;	int32_t  *endp, key_off, *offp, *saveoffp;	u_int8_t *dbuf, *dp, *np;	u_int32_t key_size, size, space;	int adj, is_key, need_pg, next_key, no_dup;	int pagesize, rec_key, ret;	ret = 0;	key_off = 0;	size = 0;	pagesize = dbc->dbp->pgsize;	cp = (BTREE_CURSOR *)dbc->internal;	/*	 * dp tracks the beginging of the page in the buffer.	 * np is the next place to copy things into the buffer.	 * dbuf always stays at the beging of the buffer.	 */	dbuf = data->data;	np = dp = dbuf;	/* Keep track of space that is left.  There is a termination entry */	space = data->ulen;	space -= sizeof(*offp);	/* Build the offset/size table from the end up. */	endp = (int32_t *)((u_int8_t *)dbuf + data->ulen);	endp--;	offp = endp;	key_size = 0;	/*	 * Distinguish between BTREE and RECNO.	 * There are no keys in RECNO.  If MULTIPLE_KEY is specified	 * then we return the record numbers.	 * is_key indicates that multiple btree keys are returned.	 * rec_key is set if we are returning record numbers.	 * next_key is set if we are going after the next key rather than dup.	 */	if (dbc->dbtype == DB_BTREE) {		is_key = LF_ISSET(DB_MULTIPLE_KEY) ? 1: 0;		rec_key = 0;		next_key = is_key && LF_ISSET(DB_OPFLAGS_MASK) != DB_NEXT_DUP;		adj = 2;	} else {		is_key = 0;		rec_key = LF_ISSET(DB_MULTIPLE_KEY) ? 1 : 0;		next_key = LF_ISSET(DB_OPFLAGS_MASK) != DB_NEXT_DUP;		adj = 1;	}	no_dup = LF_ISSET(DB_OPFLAGS_MASK) == DB_NEXT_NODUP;next_pg:	indx = cp->indx;	pg = cp->page;	inp = P_INP(dbc->dbp, pg);	/* The current page is not yet in the buffer. */	need_pg = 1;	/*	 * Keep track of the offset of the current key on the page.	 * If we are returning keys, set it to 0 first so we force	 * the copy of the key to the buffer.	 */	pg_keyoff = 0;	if (is_key == 0)		pg_keyoff = inp[indx];	do {		if (IS_DELETED(dbc->dbp, pg, indx)) {			if (dbc->dbtype != DB_RECNO)				continue;			cp->recno++;			/*			 * If we are not returning recnos then we			 * need to fill in every slot so the user			 * can calculate the record numbers.			 */			if (rec_key != 0)				continue;			space -= 2 * sizeof(*offp);			/* Check if space as underflowed. */			if (space > data->ulen)				goto back_up;			/* Just mark the empty recno slots. */			*offp-- = 0;			*offp-- = 0;			continue;		}		/*		 * Check to see if we have a new key.		 * If so, then see if we need to put the		 * key on the page.  If its already there		 * then we just point to it.		 */		if (is_key && pg_keyoff != inp[indx]) {			bk = GET_BKEYDATA(dbc->dbp, pg, indx);			if (B_TYPE(bk->type) == B_OVERFLOW) {				bo = (BOVERFLOW *)bk;				size = key_size = bo->tlen;				if (key_size > space)					goto get_key_space;				if ((ret = __bam_bulk_overflow(dbc,				    bo->tlen, bo->pgno, np)) != 0)					return (ret);				space -= key_size;				key_off = (int32_t)(np - dbuf);				np += key_size;			} else {				if (need_pg) {					dp = np;					size = pagesize - HOFFSET(pg);					if (space < size) {get_key_space:						/* Nothing added, then error. */						if (offp == endp) {							data->size =							    ALIGN(size +							    pagesize,							    sizeof(u_int32_t));							return (ENOMEM);						}						/*						 * We need to back up to the						 * last record put into the						 * buffer so that it is						 * CURRENT.						 */						if (indx != 0)							indx -= P_INDX;						else {							if ((ret =							    __bam_get_prev(							    dbc)) != 0)								return (ret);							indx = cp->indx;							pg = cp->page;						}						break;					}					/*					 * Move the data part of the page					 * to the buffer.					 */					memcpy(dp,					   (u_int8_t *)pg + HOFFSET(pg), size);					need_pg = 0;					space -= size;					np += size;				}				key_size = bk->len;				key_off = (int32_t)(inp[indx] - HOFFSET(pg)				    + dp - dbuf + SSZA(BKEYDATA, data));				pg_keyoff = inp[indx];			}		}		/*		 * Reserve space for the pointers and sizes.		 * Either key/data pair or just for a data item.		 */		space -= (is_key ? 4 : 2) * sizeof(*offp);		if (rec_key)			space -= sizeof(*offp);		/* Check to see if space has underflowed. */		if (space > data->ulen)			goto back_up;		/*		 * Determine if the next record is in the		 * buffer already or if it needs to be copied in.		 * If we have an off page dup, then copy as many		 * as will fit into the buffer.		 */		bk = GET_BKEYDATA(dbc->dbp, pg, indx + adj - 1);		if (B_TYPE(bk->type) == B_DUPLICATE) {			bo = (BOVERFLOW *)bk;			if (is_key) {				*offp-- = key_off;				*offp-- = key_size;			}			/*			 * We pass the offset of the current key.			 * On return we check to see if offp has			 * moved to see if any data fit.			 */			saveoffp = offp;			if ((ret = __bam_bulk_duplicates(dbc, bo->pgno,			    dbuf, is_key ? offp + P_INDX : NULL,			    &offp, &np, &space, no_dup)) != 0) {				if (ret == ENOMEM) {					size = space;					/* If nothing was added, then error. */					if (offp == saveoffp) {						offp += 2;						goto back_up;					}					goto get_space;				}				return (ret);			}		} else if (B_TYPE(bk->type) == B_OVERFLOW) {			bo = (BOVERFLOW *)bk;			size = bo->tlen;			if (size > space)				goto back_up;			if ((ret =			    __bam_bulk_overflow(dbc,				bo->tlen, bo->pgno, np)) != 0)				return (ret);			space -= size;			if (is_key) {				*offp-- = key_off;				*offp-- = key_size;			} else if (rec_key)				*offp-- = cp->recno;			*offp-- = (int32_t)(np - dbuf);			np += size;			*offp-- = size;		} else {			if (need_pg) {				dp = np;				size = pagesize - HOFFSET(pg);				if (space < size) {back_up:					/*					 * Back up the index so that the					 * last record in the buffer is CURRENT					 */					if (indx >= adj)						indx -= adj;					else {						if ((ret =						    __bam_get_prev(dbc)) != 0 &&						    ret != DB_NOTFOUND)							return (ret);						indx = cp->indx;						pg = cp->page;					}					if (dbc->dbtype == DB_RECNO)						cp->recno--;get_space:					/*					 * See if we put anything in the					 * buffer or if we are doing a DBP->get					 * did we get all of the data.					 */					if (offp >=					    (is_key ? &endp[-1] : endp) ||					    F_ISSET(dbc, DBC_TRANSIENT)) {						data->size = ALIGN(size +						    data->ulen - space,						    sizeof(u_int32_t));						return (ENOMEM);					}					break;				}				memcpy(dp, (u_int8_t *)pg + HOFFSET(pg), size);				need_pg = 0;				space -= size;				np += size;			}			/*			 * Add the offsets and sizes to the end of the buffer.			 * First add the key info then the data info.			 */			if (is_key) {				*offp-- = key_off;				*offp-- = key_size;			} else if (rec_key)				*offp-- = cp->recno;			*offp-- = (int32_t)(inp[indx + adj - 1] - HOFFSET(pg)			    + dp - dbuf + SSZA(BKEYDATA, data));			*offp-- = bk->len;		}		if (dbc->dbtype == DB_RECNO)			cp->recno++;		else if (no_dup) {			while (indx + adj < NUM_ENT(pg) &&			    pg_keyoff == inp[indx + adj])				indx += adj;		}	/*	 * Stop when we either run off the page or we	 * move to the next key and we are not returning mulitple keys.	 */	} while ((indx += adj) < NUM_ENT(pg) &&	    (next_key || pg_keyoff == inp[indx]));	/* If we are off the page then try to the next page. */	if (ret == 0 && next_key && indx >= NUM_ENT(pg)) {		cp->indx = indx;		ret = __bam_c_next(dbc, 0, 1);		if (ret == 0)			goto next_pg;		if (ret != DB_NOTFOUND)			return (ret);	}	/*	 * If we did a DBP->get we must error if we did not return	 * all the data for the current key because there is	 * no way to know if we did not get it all, nor any	 * interface to fetch the balance.	 */	if (ret == 0 &&	    F_ISSET(dbc, DBC_TRANSIENT) && pg_keyoff == inp[indx]) {		data->size = (data->ulen - space) + size;		return (ENOMEM);	}	/*	 * Must leave the index pointing at the last record fetched.	 * If we are not fetching keys, we may have stepped to the	 * next key.	 */	if (next_key || pg_keyoff == inp[indx])		cp->indx = indx;	else		cp->indx = indx - P_INDX;	if (rec_key == 1)		*offp = (u_int32_t) RECNO_OOB;	else		*offp = (u_int32_t) -1;	return (0);}/* * __bam_bulk_overflow -- *	Dump overflow record into the buffer. *	The space requirements have already been checked. * PUBLIC: int __bam_bulk_overflow * PUBLIC:    __P((DBC *, u_int32_t, db_pgno_t, u_int8_t *)); */int__bam_bulk_overflow(dbc, len, pgno, dp)	DBC *dbc;	u_int32_t len;	db_pgno_t pgno;	u_int8_t *dp;{	DBT dbt;	memset(&dbt, 0, sizeof(dbt));	F_SET(&dbt, DB_DBT_USERMEM);	dbt.ulen = len;	dbt.data = (void *)dp;	return (__db_goff(dbc->dbp, &dbt, len, pgno, NULL, NULL));}/* * __bam_bulk_duplicates -- *	Put as many off page duplicates as will fit into the buffer. * This routine will adjust the cursor to reflect the position in * the overflow tree. * PUBLIC: int __bam_bulk_duplicates __P((DBC *, * PUBLIC:       db_pgno_t, u_int8_t *, int32_t *, * PUBLIC:	 int32_t **, u_int8_t **, u_int32_t *, int)); */int__bam_bulk_duplicates(dbc, pgno, dbuf, keyoff, offpp, dpp, spacep, no_dup)	DBC *dbc;	db_pgno_t pgno;	u_int8_t *dbuf;	int32_t *keyoff, **offpp;	u_int8_t **dpp;	u_int32_t *spacep;	int no_dup;{	DB *dbp;	BKEYDATA *bk;	BOVERFLOW *bo;	BTREE_CURSOR *cp;	DBC *opd;	DBT key, data;	PAGE *pg;	db_indx_t indx, *inp;	int32_t *offp;	u_int32_t size, space;	u_int8_t *dp, *np;	int first, need_pg, pagesize, ret, t_ret;	ret = 0;	dbp = dbc->dbp;	cp = (BTREE_CURSOR *)dbc->internal;	opd = cp->opd;	if (opd == NULL) {		if ((ret = __db_c_newopd(dbc, pgno, NULL, &opd)) != 0)			return (ret);		cp->opd = opd;		if ((ret = opd->c_am_get(opd,		    &key, &data, DB_FIRST, NULL)) != 0)			return (ret);	}	pagesize = opd->dbp->pgsize;	cp = (BTREE_CURSOR *)opd->internal;	space = *spacep;	/* Get current offset slot. */	offp = *offpp;	/*	 * np is the next place to put data.	 * dp is the begining of the current page in the buffer.	 */	np = dp = *dpp;	first = 1;	indx = cp->indx;	do {		/* Fetch the current record.  No initial move. */		if ((ret = __bam_c_next(opd, 0, 0)) != 0)			break;		pg = cp->page;		indx = cp->indx;		inp = P_INP(dbp, pg);		/* We need to copy the page to the buffer. */		need_pg = 1;		do {			if (IS_DELETED(dbp, pg, indx))				goto contin;			bk = GET_BKEYDATA(dbp, pg, indx);			space -= 2 * sizeof(*offp);			/* Allocate space for key if needed. */			if (first == 0 && keyoff != NULL)				space -= 2 * sizeof(*offp);			/* Did space underflow? */			if (space > *spacep) {				ret = ENOMEM;				if (first == 1) {					space = *spacep + -(int32_t)space;					if (need_pg)						space += pagesize - HOFFSET(pg);				}				break;			}			if (B_TYPE(bk->type) == B_OVERFLOW) {				bo = (BOVERFLOW *)bk;				size = bo->tlen;				if (size > space) {					ret = ENOMEM;					if (first == 1) {						space = *spacep + size;					}					break;				}				if (first == 0 && keyoff != NULL) {					*offp-- = keyoff[0];					*offp-- = keyoff[-1];				}				if ((ret = __bam_bulk_overflow(dbc,				    bo->tlen, bo->pgno, np)) != 0)					return (ret);				space -= size;				*offp-- = (int32_t)(np - dbuf);				np += size;			} else {				if (need_pg) {					dp = np;					size = pagesize - HOFFSET(pg);					if (space < size) {						ret = ENOMEM;						/* Return space required. */						if (first == 1) {

⌨️ 快捷键说明

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