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

📄 bt_cursor.c

📁 这是linux下运行的mysql软件包,可用于linux 下安装 php + mysql + apach 的网络配置
💻 C
📖 第 1 页 / 共 5 页
字号:
	DBT *data;{	BTREE_CURSOR *cp;	DB *dbp;	DBT dbt;	DB_MPOOLFILE *mpf;	db_recno_t recno;	int exact, ret;	dbp = dbc->dbp;	mpf = dbp->mpf;	cp = (BTREE_CURSOR *)dbc->internal;	/*	 * Get the page with the current item on it.	 * Get a copy of the key.	 * Release the page, making sure we don't release it twice.	 */	if ((ret = mpf->get(mpf, &cp->pgno, 0, &cp->page)) != 0)		return (ret);	memset(&dbt, 0, sizeof(DBT));	if ((ret = __db_ret(dbp, cp->page,	    cp->indx, &dbt, &dbc->rkey->data, &dbc->rkey->ulen)) != 0)		goto err;	ret = mpf->put(mpf, cp->page, 0);	cp->page = NULL;	if (ret != 0)		return (ret);	if ((ret = __bam_search(dbc, PGNO_INVALID, &dbt,	    F_ISSET(dbc, DBC_RMW) ? S_FIND_WR : S_FIND,	    1, &recno, &exact)) != 0)		goto err;	ret = __db_retcopy(dbp->dbenv, data,	    &recno, sizeof(recno), &dbc->rdata->data, &dbc->rdata->ulen);	/* Release the stack. */err:	__bam_stkrel(dbc, 0);	return (ret);}/* * __bam_c_writelock -- *	Upgrade the cursor to a write lock. */static int__bam_c_writelock(dbc)	DBC *dbc;{	BTREE_CURSOR *cp;	int ret;	cp = (BTREE_CURSOR *)dbc->internal;	if (cp->lock_mode == DB_LOCK_WRITE)		return (0);	/*	 * When writing to an off-page duplicate tree, we need to have the	 * appropriate page in the primary tree locked.  The general DBC	 * code calls us first with the primary cursor so we can acquire the	 * appropriate lock.	 */	ACQUIRE_WRITE_LOCK(dbc, ret);	return (ret);}/* * __bam_c_first -- *	Return the first record. */static int__bam_c_first(dbc)	DBC *dbc;{	BTREE_CURSOR *cp;	db_pgno_t pgno;	int ret;	cp = (BTREE_CURSOR *)dbc->internal;	ret = 0;	/* Walk down the left-hand side of the tree. */	for (pgno = cp->root;;) {		ACQUIRE_CUR_COUPLE(dbc, DB_LOCK_READ, pgno, ret);		if (ret != 0)			return (ret);		/* If we find a leaf page, we're done. */		if (ISLEAF(cp->page))			break;		pgno = GET_BINTERNAL(dbc->dbp, cp->page, 0)->pgno;	}	/* If we want a write lock instead of a read lock, get it now. */	if (F_ISSET(dbc, DBC_RMW)) {		ACQUIRE_WRITE_LOCK(dbc, ret);		if (ret != 0)			return (ret);	}	cp->indx = 0;	/* If on an empty page or a deleted record, move to the next one. */	if (NUM_ENT(cp->page) == 0 || IS_CUR_DELETED(dbc))		if ((ret = __bam_c_next(dbc, 0, 0)) != 0)			return (ret);	return (0);}/* * __bam_c_last -- *	Return the last record. */static int__bam_c_last(dbc)	DBC *dbc;{	BTREE_CURSOR *cp;	db_pgno_t pgno;	int ret;	cp = (BTREE_CURSOR *)dbc->internal;	ret = 0;	/* Walk down the right-hand side of the tree. */	for (pgno = cp->root;;) {		ACQUIRE_CUR_COUPLE(dbc, DB_LOCK_READ, pgno, ret);		if (ret != 0)			return (ret);		/* If we find a leaf page, we're done. */		if (ISLEAF(cp->page))			break;		pgno = GET_BINTERNAL(dbc->dbp, cp->page,		    NUM_ENT(cp->page) - O_INDX)->pgno;	}	/* If we want a write lock instead of a read lock, get it now. */	if (F_ISSET(dbc, DBC_RMW)) {		ACQUIRE_WRITE_LOCK(dbc, ret);		if (ret != 0)			return (ret);	}	cp->indx = NUM_ENT(cp->page) == 0 ? 0 :	    NUM_ENT(cp->page) -	    (TYPE(cp->page) == P_LBTREE ? P_INDX : O_INDX);	/* If on an empty page or a deleted record, move to the previous one. */	if (NUM_ENT(cp->page) == 0 || IS_CUR_DELETED(dbc))		if ((ret = __bam_c_prev(dbc)) != 0)			return (ret);	return (0);}/* * __bam_c_next -- *	Move to the next record. */static int__bam_c_next(dbc, initial_move, deleted_okay)	DBC *dbc;	int initial_move, deleted_okay;{	BTREE_CURSOR *cp;	db_indx_t adjust;	db_lockmode_t lock_mode;	db_pgno_t pgno;	int ret;	cp = (BTREE_CURSOR *)dbc->internal;	ret = 0;	/*	 * We're either moving through a page of duplicates or a btree leaf	 * page.	 *	 * !!!	 * This code handles empty pages and pages with only deleted entries.	 */	if (F_ISSET(dbc, DBC_OPD)) {		adjust = O_INDX;		lock_mode = DB_LOCK_NG;	} else {		adjust = dbc->dbtype == DB_BTREE ? P_INDX : O_INDX;		lock_mode =		    F_ISSET(dbc, DBC_RMW) ? DB_LOCK_WRITE : DB_LOCK_READ;	}	if (cp->page == NULL) {		ACQUIRE_CUR(dbc, lock_mode, cp->pgno, ret);		if (ret != 0)			return (ret);	}	if (initial_move)		cp->indx += adjust;	for (;;) {		/*		 * If at the end of the page, move to a subsequent page.		 *		 * !!!		 * Check for >= NUM_ENT.  If the original search landed us on		 * NUM_ENT, we may have incremented indx before the test.		 */		if (cp->indx >= NUM_ENT(cp->page)) {			if ((pgno			    = NEXT_PGNO(cp->page)) == PGNO_INVALID)				return (DB_NOTFOUND);			ACQUIRE_CUR(dbc, lock_mode, pgno, ret);			if (ret != 0)				return (ret);			cp->indx = 0;			continue;		}		if (!deleted_okay && IS_CUR_DELETED(dbc)) {			cp->indx += adjust;			continue;		}		break;	}	return (0);}/* * __bam_c_prev -- *	Move to the previous record. */static int__bam_c_prev(dbc)	DBC *dbc;{	BTREE_CURSOR *cp;	db_indx_t adjust;	db_lockmode_t lock_mode;	db_pgno_t pgno;	int ret;	cp = (BTREE_CURSOR *)dbc->internal;	ret = 0;	/*	 * We're either moving through a page of duplicates or a btree leaf	 * page.	 *	 * !!!	 * This code handles empty pages and pages with only deleted entries.	 */	if (F_ISSET(dbc, DBC_OPD)) {		adjust = O_INDX;		lock_mode = DB_LOCK_NG;	} else {		adjust = dbc->dbtype == DB_BTREE ? P_INDX : O_INDX;		lock_mode =		    F_ISSET(dbc, DBC_RMW) ? DB_LOCK_WRITE : DB_LOCK_READ;	}	if (cp->page == NULL) {		ACQUIRE_CUR(dbc, lock_mode, cp->pgno, ret);		if (ret != 0)			return (ret);	}	for (;;) {		/* If at the beginning of the page, move to a previous one. */		if (cp->indx == 0) {			if ((pgno =			    PREV_PGNO(cp->page)) == PGNO_INVALID)				return (DB_NOTFOUND);			ACQUIRE_CUR(dbc, lock_mode, pgno, ret);			if (ret != 0)				return (ret);			if ((cp->indx = NUM_ENT(cp->page)) == 0)				continue;		}		/* Ignore deleted records. */		cp->indx -= adjust;		if (IS_CUR_DELETED(dbc))			continue;		break;	}	return (0);}/* * __bam_c_search -- *	Move to a specified record. */static int__bam_c_search(dbc, root_pgno, key, flags, exactp)	DBC *dbc;	db_pgno_t root_pgno;	const DBT *key;	u_int32_t flags;	int *exactp;{	BTREE *t;	BTREE_CURSOR *cp;	DB *dbp;	PAGE *h;	db_indx_t indx, *inp;	db_pgno_t bt_lpgno;	db_recno_t recno;	u_int32_t sflags;	int cmp, ret;	dbp = dbc->dbp;	cp = (BTREE_CURSOR *)dbc->internal;	t = dbp->bt_internal;	ret = 0;	/*	 * Find an entry in the database.  Discard any lock we currently hold,	 * we're going to search the tree.	 */	DISCARD_CUR(dbc, ret);	if (ret != 0)		return (ret);	switch (flags) {	case DB_SET_RECNO:		if ((ret = __ram_getno(dbc, key, &recno, 0)) != 0)			return (ret);		sflags = (F_ISSET(dbc, DBC_RMW) ? S_FIND_WR : S_FIND) | S_EXACT;		if ((ret = __bam_rsearch(dbc, &recno, sflags, 1, exactp)) != 0)			return (ret);		break;	case DB_SET:	case DB_GET_BOTH:		sflags = (F_ISSET(dbc, DBC_RMW) ? S_FIND_WR : S_FIND) | S_EXACT;		goto search;	case DB_GET_BOTH_RANGE:		sflags = (F_ISSET(dbc, DBC_RMW) ? S_FIND_WR : S_FIND);		goto search;	case DB_SET_RANGE:		sflags =		    (F_ISSET(dbc, DBC_RMW) ? S_WRITE : S_READ) | S_DUPFIRST;		goto search;	case DB_KEYFIRST:		sflags = S_KEYFIRST;		goto fast_search;	case DB_KEYLAST:	case DB_NODUPDATA:		sflags = S_KEYLAST;fast_search:	/*		 * If the application has a history of inserting into the first		 * or last pages of the database, we check those pages first to		 * avoid doing a full search.		 *		 * If the tree has record numbers, we need a complete stack so		 * that we can adjust the record counts, so fast_search isn't		 * possible.		 */		if (F_ISSET(cp, C_RECNUM))			goto search;		/*		 * !!!		 * We do not mutex protect the t->bt_lpgno field, which means		 * that it can only be used in an advisory manner.  If we find		 * page we can use, great.  If we don't, we don't care, we do		 * it the slow way instead.  Regardless, copy it into a local		 * variable, otherwise we might acquire a lock for a page and		 * then read a different page because it changed underfoot.		 */		bt_lpgno = t->bt_lpgno;		/*		 * If the tree has no history of insertion, do it the slow way.		 */		if (bt_lpgno == PGNO_INVALID)			goto search;		/* Lock and retrieve the page on which we last inserted. */		h = NULL;		ACQUIRE(dbc,		    DB_LOCK_WRITE, bt_lpgno, cp->lock, bt_lpgno, h, ret);		if (ret != 0)			goto fast_miss;		inp = P_INP(dbp, h);		/*		 * It's okay if the page type isn't right or it's empty, it		 * just means that the world changed.		 */		if (TYPE(h) != P_LBTREE || NUM_ENT(h) == 0)			goto fast_miss;		/*		 * What we do here is test to see if we're at the beginning or		 * end of the tree and if the new item sorts before/after the		 * first/last page entry.  We don't try and catch inserts into		 * the middle of the tree (although we could, as long as there		 * were two keys on the page and we saved both the index and		 * the page number of the last insert).		 */		if (h->next_pgno == PGNO_INVALID) {			indx = NUM_ENT(h) - P_INDX;			if ((ret = __bam_cmp(dbp,			    key, h, indx, t->bt_compare, &cmp)) != 0)				return (ret);			if (cmp < 0)				goto try_begin;			if (cmp > 0) {				indx += P_INDX;				goto fast_hit;			}			/*			 * Found a duplicate.  If doing DB_KEYLAST, we're at			 * the correct position, otherwise, move to the first			 * of the duplicates.  If we're looking at off-page			 * duplicates, duplicate duplicates aren't permitted,			 * so we're done.			 */			if (flags == DB_KEYLAST)				goto fast_hit;			for (;			    indx > 0 && inp[indx - P_INDX] == inp[indx];			    indx -= P_INDX)				;			goto fast_hit;		}try_begin:	if (h->prev_pgno == PGNO_INVALID) {			indx = 0;			if ((ret = __bam_cmp(dbp,			    key, h, indx, t->bt_compare, &cmp)) != 0)				return (ret);			if (cmp > 0)				goto fast_miss;			if (cmp < 0)				goto fast_hit;			/*			 * Found a duplicate.  If doing DB_KEYFIRST, we're at			 * the correct position, otherwise, move to the last			 * of the duplicates.  If we're looking at off-page			 * duplicates, duplicate duplicates aren't permitted,			 * so we're done.			 */			if (flags == DB_KEYFIRST)				goto fast_hit;			for (;			    indx < (db_indx_t)(NUM_ENT(h) - P_INDX) &&			    inp[indx] == inp[indx + P_INDX];			    indx += P_INDX)				;			goto fast_hit;		}		goto fast_miss;fast_hit:	/* Set the exact match flag, we may have found a duplicate. */		*exactp = cmp == 0;		/*		 * Insert the entry in the stack.  (Our caller is likely to		 * call __bam_stkrel() after our return.)		 */		BT_STK_CLR(cp);		BT_STK_ENTER(dbp->dbenv,		    cp, h, indx, cp->lock, cp->lock_mode, ret);		if (ret != 0)			return (ret);		break;fast_miss:	/*		 * This was not the right page, so we do not need to retain		 * the lock even in the presence of transactions.		 */		DISCARD(dbc, 1, cp->lock, h, ret);		if (ret != 0)			return (ret);search:		if ((ret = __bam_search(dbc, root_pgno,		    key, sflags, 1, NULL, exactp)) != 0)			return (ret);		break;	default:		return (__db_unknown_flag(dbp->dbenv, "__bam_c_search", flags));	}	/* Initialize the cursor from the stack. */	cp->page = cp->csp->page;	cp->pgno = cp->csp->page->pgno;	cp->indx = cp->csp->indx;	cp->lock = cp->csp->lock;	cp->lock_mode = cp->csp->lock_mode;	/*	 * If we inser

⌨️ 快捷键说明

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