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

📄 bt_recno.c

📁 这是linux下运行的mysql软件包,可用于linux 下安装 php + mysql + apach 的网络配置
💻 C
📖 第 1 页 / 共 3 页
字号:
			break;		}		ret = DB_NOTFOUND;		goto err;		/* NOTREACHED */	case DB_GET_BOTH:	case DB_GET_BOTH_RANGE:		/*		 * If we're searching a set of off-page dups, we start		 * a new linear search from the first record.  Otherwise,		 * we compare the single data item associated with the		 * requested record for a match.		 */		if (F_ISSET(dbc, DBC_OPD)) {			cp->recno = 1;			break;		}		/* FALLTHROUGH */	case DB_SET:	case DB_SET_RANGE:		if ((ret = __ram_getno(dbc, key, &cp->recno, 0)) != 0)			goto err;		break;	default:		ret = __db_unknown_flag(dbp->dbenv, "__ram_c_get", flags);		goto err;	}	/*	 * For DB_PREV, DB_LAST, DB_SET and DB_SET_RANGE, we have already	 * called __ram_update() to make sure sufficient records have been	 * read from the backing source file.  Do it now for DB_CURRENT (if	 * the current record was deleted we may need more records from the	 * backing file for a DB_CURRENT operation), DB_FIRST and DB_NEXT.	 * (We don't have to test for flags == DB_FIRST, because the switch	 * statement above re-set flags to DB_NEXT in that case.)	 */	if ((flags == DB_NEXT || flags == DB_CURRENT) && ((ret =	    __ram_update(dbc, cp->recno, 0)) != 0) && ret != DB_NOTFOUND)		goto err;	for (;; ++cp->recno) {		/* Search the tree for the record. */		if ((ret = __bam_rsearch(dbc, &cp->recno,		    F_ISSET(dbc, DBC_RMW) ? S_FIND_WR : S_FIND,		    1, &exact)) != 0)			goto err;		if (!exact) {			ret = DB_NOTFOUND;			goto err;		}		/* Copy the page into the cursor. */		STACK_TO_CURSOR(cp);		/*		 * If re-numbering records, the on-page deleted flag means this		 * record was implicitly created.  If not re-numbering records,		 * the on-page deleted flag means this record was implicitly		 * created, or, it was deleted at some time.  Regardless, we		 * skip such records if doing cursor next/prev operations or		 * walking through off-page duplicates, and fail if they were		 * requested explicitly by the application.		 */		if (B_DISSET(GET_BKEYDATA(dbp, cp->page, cp->indx)->type))			switch (flags) {			case DB_NEXT:			case DB_PREV:				(void)__bam_stkrel(dbc, STK_CLRDBC);				goto retry;			case DB_GET_BOTH:			case DB_GET_BOTH_RANGE:				/*				 * If we're an OPD tree, we don't care about				 * matching a record number on a DB_GET_BOTH				 * -- everything belongs to the same tree.  A				 * normal recno should give up and return				 * DB_NOTFOUND if the matching recno is deleted.				 */				if (F_ISSET(dbc, DBC_OPD)) {					(void)__bam_stkrel(dbc, STK_CLRDBC);					continue;				}				ret = DB_NOTFOUND;				goto err;			default:				ret = DB_KEYEMPTY;				goto err;			}		if (flags == DB_GET_BOTH ||		    flags == DB_GET_BOTHC || flags == DB_GET_BOTH_RANGE) {			if ((ret = __bam_cmp(dbp, data,			    cp->page, cp->indx, __bam_defcmp, &cmp)) != 0)				return (ret);			if (cmp == 0)				break;			if (!F_ISSET(dbc, DBC_OPD)) {				ret = DB_NOTFOUND;				goto err;			}			(void)__bam_stkrel(dbc, STK_CLRDBC);		} else			break;	}	/* Return the key if the user didn't give us one. */	if (!F_ISSET(dbc, DBC_OPD)) {		if (flags != DB_GET_BOTH && flags != DB_GET_BOTH_RANGE &&		    flags != DB_SET && flags != DB_SET_RANGE)			ret = __db_retcopy(dbp->dbenv,			    key, &cp->recno, sizeof(cp->recno),			    &dbc->rkey->data, &dbc->rkey->ulen);		F_SET(key, DB_DBT_ISSET);	}	/* The cursor was reset, no further delete adjustment is necessary. */err:	CD_CLR(cp);	return (ret);}/* * __ram_c_put -- *	Recno cursor->c_put function. * * PUBLIC: int __ram_c_put __P((DBC *, DBT *, DBT *, u_int32_t, db_pgno_t *)); */int__ram_c_put(dbc, key, data, flags, pgnop)	DBC *dbc;	DBT *key, *data;	u_int32_t flags;	db_pgno_t *pgnop;{	BTREE_CURSOR *cp;	DB *dbp;	DB_LSN lsn;	int exact, nc, ret, t_ret;	u_int32_t iiflags;	void *arg;	COMPQUIET(pgnop, NULL);	dbp = dbc->dbp;	cp = (BTREE_CURSOR *)dbc->internal;	/*	 * DB_KEYFIRST and DB_KEYLAST mean different things if they're	 * used in an off-page duplicate tree.  If we're an off-page	 * duplicate tree, they really mean "put at the beginning of the	 * tree" and "put at the end of the tree" respectively, so translate	 * them to something else.	 */	if (F_ISSET(dbc, DBC_OPD))		switch (flags) {		case DB_KEYFIRST:			cp->recno = 1;			flags = DB_BEFORE;			break;		case DB_KEYLAST:			if ((ret = __ram_add(dbc,			    &cp->recno, data, DB_APPEND, 0)) != 0)				return (ret);			if (CURADJ_LOG(dbc) &&			    (ret = __bam_rcuradj_log(dbp, dbc->txn, &lsn, 0,			    CA_ICURRENT, cp->root, cp->recno, cp->order)))				return (ret);			return (0);		}	/*	 * Handle normal DB_KEYFIRST/DB_KEYLAST;  for a recno, which has	 * no duplicates, these are identical and mean "put the given	 * datum at the given recno".	 *	 * Note that the code here used to be in __ram_put;  now, we	 * go through the access-method-common __db_put function, which	 * handles DB_NOOVERWRITE, so we and __ram_add don't have to.	 */	if (flags == DB_KEYFIRST || flags == DB_KEYLAST) {		ret = __ram_getno(dbc, key, &cp->recno, 1);		if (ret == 0 || ret == DB_NOTFOUND)			ret = __ram_add(dbc, &cp->recno, data, 0, 0);		return (ret);	}	/*	 * If we're putting with a cursor that's marked C_DELETED, we need to	 * take special care;  the cursor doesn't "really" reference the item	 * corresponding to its current recno, but instead is "between" that	 * record and the current one.  Translate the actual insert into	 * DB_BEFORE, and let the __ram_ca work out the gory details of what	 * should wind up pointing where.	 */	if (CD_ISSET(cp))		iiflags = DB_BEFORE;	else		iiflags = flags;split:	if ((ret = __bam_rsearch(dbc, &cp->recno, S_INSERT, 1, &exact)) != 0)		goto err;	/*	 * An inexact match is okay;  it just means we're one record past the	 * end, which is reasonable if we're marked deleted.	 */	DB_ASSERT(exact || CD_ISSET(cp));	/* Copy the page into the cursor. */	STACK_TO_CURSOR(cp);	ret = __bam_iitem(dbc, key, data, iiflags, 0);	t_ret = __bam_stkrel(dbc, STK_CLRDBC);	if (t_ret != 0 && (ret == 0 || ret == DB_NEEDSPLIT))		ret = t_ret;	else if (ret == DB_NEEDSPLIT) {		arg = &cp->recno;		if ((ret = __bam_split(dbc, arg, NULL)) != 0)			goto err;		goto split;	}	if (ret != 0)		goto err;	switch (flags) {			/* Adjust the cursors. */	case DB_AFTER:		nc = __ram_ca(dbc, CA_IAFTER);		/*		 * We only need to adjust this cursor forward if we truly added		 * the item after the current recno, rather than remapping it		 * to DB_BEFORE.		 */		if (iiflags == DB_AFTER)			++cp->recno;		/* Only log if __ram_ca found any relevant cursors. */		if (nc > 0 && CURADJ_LOG(dbc) &&		    (ret = __bam_rcuradj_log(dbp, dbc->txn, &lsn, 0, CA_IAFTER,		    cp->root, cp->recno, cp->order)) != 0)			goto err;		break;	case DB_BEFORE:		nc = __ram_ca(dbc, CA_IBEFORE);		--cp->recno;		/* Only log if __ram_ca found any relevant cursors. */		if (nc > 0 && CURADJ_LOG(dbc) &&		    (ret = __bam_rcuradj_log(dbp, dbc->txn, &lsn, 0, CA_IBEFORE,		    cp->root, cp->recno, cp->order)) != 0)			goto err;		break;	case DB_CURRENT:		/*		 * We only need to do an adjustment if we actually		 * added an item, which we only would have done if the		 * cursor was marked deleted.		 *		 * Only log if __ram_ca found any relevant cursors.		 */		if (CD_ISSET(cp) && __ram_ca(dbc, CA_ICURRENT) > 0 &&		    CURADJ_LOG(dbc) &&		    (ret = __bam_rcuradj_log(dbp, dbc->txn, &lsn, 0,		    CA_ICURRENT, cp->root, cp->recno, cp->order)) != 0)			goto err;		break;	}	/* Return the key if we've created a new record. */	if (!F_ISSET(dbc, DBC_OPD) && (flags == DB_AFTER || flags == DB_BEFORE))		ret = __db_retcopy(dbp->dbenv, key, &cp->recno,		    sizeof(cp->recno), &dbc->rkey->data, &dbc->rkey->ulen);	/* The cursor was reset, no further delete adjustment is necessary. */err:	CD_CLR(cp);	return (ret);}/* * __ram_ca -- *	Adjust cursors.  Returns the number of relevant cursors. * * PUBLIC: int __ram_ca __P((DBC *, ca_recno_arg)); */int__ram_ca(dbc_arg, op)	DBC *dbc_arg;	ca_recno_arg op;{	BTREE_CURSOR *cp, *cp_arg;	DB *dbp, *ldbp;	DB_ENV *dbenv;	DBC *dbc;	db_recno_t recno;	int adjusted, found;	u_int32_t order;	dbp = dbc_arg->dbp;	dbenv = dbp->dbenv;	cp_arg = (BTREE_CURSOR *)dbc_arg->internal;	recno = cp_arg->recno;	found = 0;	/*	 * It only makes sense to adjust cursors if we're a renumbering	 * recno;  we should only be called if this is one.	 */	DB_ASSERT(F_ISSET(cp_arg, C_RENUMBER));	MUTEX_THREAD_LOCK(dbenv, dbenv->dblist_mutexp);	/*	 * Adjust the cursors.  See the comment in __bam_ca_delete().	 */	/*	 * If we're doing a delete, we need to find the highest	 * order of any cursor currently pointing at this item,	 * so we can assign a higher order to the newly deleted	 * cursor.  Unfortunately, this requires a second pass through	 * the cursor list.	 */	if (op == CA_DELETE) {		order = 1;		for (ldbp = __dblist_get(dbenv, dbp->adj_fileid);		    ldbp != NULL && ldbp->adj_fileid == dbp->adj_fileid;		    ldbp = LIST_NEXT(ldbp, dblistlinks)) {			MUTEX_THREAD_LOCK(dbenv, dbp->mutexp);			for (dbc = TAILQ_FIRST(&ldbp->active_queue);			    dbc != NULL; dbc = TAILQ_NEXT(dbc, links)) {				cp = (BTREE_CURSOR *)dbc->internal;				if (cp_arg->root == cp->root &&				    recno == cp->recno && CD_ISSET(cp) &&				    order <= cp->order)					order = cp->order + 1;			}			MUTEX_THREAD_UNLOCK(dbenv, dbp->mutexp);		}	} else		order = INVALID_ORDER;	/* Now go through and do the actual adjustments. */	for (ldbp = __dblist_get(dbenv, dbp->adj_fileid);	    ldbp != NULL && ldbp->adj_fileid == dbp->adj_fileid;	    ldbp = LIST_NEXT(ldbp, dblistlinks)) {		MUTEX_THREAD_LOCK(dbenv, dbp->mutexp);		for (dbc = TAILQ_FIRST(&ldbp->active_queue);		    dbc != NULL; dbc = TAILQ_NEXT(dbc, links)) {			cp = (BTREE_CURSOR *)dbc->internal;			if (cp_arg->root != cp->root)				continue;			++found;			adjusted = 0;			switch (op) {			case CA_DELETE:				if (recno < cp->recno) {					--cp->recno;					/*					 * If the adjustment made them equal,					 * we have to merge the orders.					 */					if (recno == cp->recno && CD_ISSET(cp))						cp->order += order;				} else if (recno == cp->recno &&				    !CD_ISSET(cp)) {					CD_SET(cp);					cp->order = order;				}				break;			case CA_IBEFORE:				/*				 * IBEFORE is just like IAFTER, except that we				 * adjust cursors on the current record too.				 */				if (C_EQUAL(cp_arg, cp)) {					++cp->recno;					adjusted = 1;				}				goto iafter;			case CA_ICURRENT:				/*				 * If the original cursor wasn't deleted, we				 * just did a replacement and so there's no				 * need to adjust anything--we shouldn't have				 * gotten this far.  Otherwise, we behave				 * much like an IAFTER, except that all				 * cursors pointing to the current item get				 * marked undeleted and point to the new				 * item.				 */				DB_ASSERT(CD_ISSET(cp_arg));				if (C_EQUAL(cp_arg, cp)) {					CD_CLR(cp);					break;				}				/* FALLTHROUGH */			case CA_IAFTER:iafter:				if (!adjusted && C_LESSTHAN(cp_arg, cp)) {					++cp->recno;					adjusted = 1;				}				if (recno == cp->recno && adjusted)					/*					 * If we've moved this cursor's recno,					 * split its order number--i.e.,					 * decrement it by enough so that					 * the lowest cursor moved has order 1.					 * cp_arg->order is the split point,					 * so decrement by one less than that.					 */					cp->order -= (cp_arg->order - 1);				break;			}		}		MUTEX_THREAD_UNLOCK(dbp->dbenv, dbp->mutexp);	}	MUTEX_THREAD_UNLOCK(dbenv, dbenv->dblist_mutexp);	return (found);}/* * __ram_getno -- *	Check the user's record number, and make sure we've seen it. * * PUBLIC: int __ram_getno __P((DBC *, const DBT *, db_recno_t *, int)); */int__ram_getno(dbc, key, rep, can_create)	DBC *dbc;	const DBT *key;	db_recno_t *rep;	int can_create;{	DB *dbp;	db_recno_t recno;	dbp = dbc->dbp;	/* Check the user's record number. */	if ((recno = *(db_recno_t *)key->data) == 0) {

⌨️ 快捷键说明

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