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

📄 db_cam.c

📁 这是linux下运行的mysql软件包,可用于linux 下安装 php + mysql + apach 的网络配置
💻 C
📖 第 1 页 / 共 5 页
字号:
		dbc_n->flags |= dbc_orig->flags & ~DBC_OWN_LID;		int_n->indx = int_orig->indx;		int_n->pgno = int_orig->pgno;		int_n->root = int_orig->root;		int_n->lock_mode = int_orig->lock_mode;		switch (dbc_orig->dbtype) {		case DB_QUEUE:			if ((ret = __qam_c_dup(dbc_orig, dbc_n)) != 0)				goto err;			break;		case DB_BTREE:		case DB_RECNO:			if ((ret = __bam_c_dup(dbc_orig, dbc_n)) != 0)				goto err;			break;		case DB_HASH:			if ((ret = __ham_c_dup(dbc_orig, dbc_n)) != 0)				goto err;			break;		default:			ret = __db_unknown_type(dbp->dbenv,			    "__db_c_idup", dbc_orig->dbtype);			goto err;		}	}	/* Now take care of duping the CDB information. */	CDB_LOCKING_COPY(dbp, dbc_orig, dbc_n);	/* Copy the dirty read flag to the new cursor. */	F_SET(dbc_n, F_ISSET(dbc_orig, DBC_DIRTY_READ));	*dbcp = dbc_n;	return (0);err:	(void)dbc_n->c_close(dbc_n);	return (ret);}/* * __db_c_newopd -- *	Create a new off-page duplicate cursor. * * PUBLIC: int __db_c_newopd __P((DBC *, db_pgno_t, DBC *, DBC **)); */int__db_c_newopd(dbc_parent, root, oldopd, dbcp)	DBC *dbc_parent;	db_pgno_t root;	DBC *oldopd;	DBC **dbcp;{	DB *dbp;	DBC *opd;	DBTYPE dbtype;	int ret;	dbp = dbc_parent->dbp;	dbtype = (dbp->dup_compare == NULL) ? DB_RECNO : DB_BTREE;	/*	 * On failure, we want to default to returning the old off-page dup	 * cursor, if any;  our caller can't be left with a dangling pointer	 * to a freed cursor.  On error the only allowable behavior is to	 * close the cursor (and the old OPD cursor it in turn points to), so	 * this should be safe.	 */	*dbcp = oldopd;	if ((ret = __db_icursor(dbp,	    dbc_parent->txn, dbtype, root, 1, dbc_parent->locker, &opd)) != 0)		return (ret);	/* !!!	 * If the parent is a DBC_WRITER, this won't copy anything.  That's	 * not actually a problem--we only need lock information in an	 * off-page dup cursor in order to upgrade at cursor close time	 * if we've done a delete, but WRITERs don't need to upgrade.	 */	CDB_LOCKING_COPY(dbp, dbc_parent, opd);	*dbcp = opd;	/*	 * Check to see if we already have an off-page dup cursor that we've	 * passed in.  If we do, close it.  It'd be nice to use it again	 * if it's a cursor belonging to the right tree, but if we're doing	 * a cursor-relative operation this might not be safe, so for now	 * we'll take the easy way out and always close and reopen.	 *	 * Note that under no circumstances do we want to close the old	 * cursor without returning a valid new one;  we don't want to	 * leave the main cursor in our caller with a non-NULL pointer	 * to a freed off-page dup cursor.	 */	if (oldopd != NULL && (ret = oldopd->c_close(oldopd)) != 0)		return (ret);	return (0);}/* * __db_c_get -- *	Get using a cursor. * * PUBLIC: int __db_c_get __P((DBC *, DBT *, DBT *, u_int32_t)); */int__db_c_get(dbc_arg, key, data, flags)	DBC *dbc_arg;	DBT *key, *data;	u_int32_t flags;{	DB *dbp;	DBC *dbc, *dbc_n, *opd;	DBC_INTERNAL *cp, *cp_n;	DB_MPOOLFILE *mpf;	db_pgno_t pgno;	u_int32_t multi, tmp_dirty, tmp_flags, tmp_rmw;	u_int8_t type;	int ret, t_ret;	/*	 * Cursor Cleanup Note:	 * All of the cursors passed to the underlying access methods by this	 * routine are duplicated cursors.  On return, any referenced pages	 * will be discarded, and, if the cursor is not intended to be used	 * again, the close function will be called.  So, pages/locks that	 * the cursor references do not need to be resolved by the underlying	 * functions.	 */	dbp = dbc_arg->dbp;	mpf = dbp->mpf;	dbc_n = NULL;	opd = NULL;	PANIC_CHECK(dbp->dbenv);	/* Check for invalid flags. */	if ((ret =	    __db_cgetchk(dbp, key, data, flags, IS_INITIALIZED(dbc_arg))) != 0)		return (ret);	/* Clear OR'd in additional bits so we can check for flag equality. */	tmp_rmw = LF_ISSET(DB_RMW);	LF_CLR(DB_RMW);	tmp_dirty = LF_ISSET(DB_DIRTY_READ);	LF_CLR(DB_DIRTY_READ);	multi = LF_ISSET(DB_MULTIPLE|DB_MULTIPLE_KEY);	LF_CLR(DB_MULTIPLE|DB_MULTIPLE_KEY);	DEBUG_LREAD(dbc_arg, dbc_arg->txn, "db_c_get",	    flags == DB_SET || flags == DB_SET_RANGE ? key : NULL, NULL, flags);	/*	 * Return a cursor's record number.  It has nothing to do with the	 * cursor get code except that it was put into the interface.	 */	if (flags == DB_GET_RECNO) {		if (tmp_rmw)			F_SET(dbc_arg, DBC_RMW);		if (tmp_dirty)			F_SET(dbc_arg, DBC_DIRTY_READ);		ret = __bam_c_rget(dbc_arg, data);		if (tmp_rmw)			F_CLR(dbc_arg, DBC_RMW);		if (tmp_dirty)			F_CLR(dbc_arg, DBC_DIRTY_READ);		return (ret);	}	if (flags == DB_CONSUME || flags == DB_CONSUME_WAIT)		CDB_LOCKING_INIT(dbp, dbc_arg);	/*	 * If we have an off-page duplicates cursor, and the operation applies	 * to it, perform the operation.  Duplicate the cursor and call the	 * underlying function.	 *	 * Off-page duplicate trees are locked in the primary tree, that is,	 * we acquire a write lock in the primary tree and no locks in the	 * off-page dup tree.  If the DB_RMW flag was specified and the get	 * operation is done in an off-page duplicate tree, call the primary	 * cursor's upgrade routine first.	 */	cp = dbc_arg->internal;	if (cp->opd != NULL &&	    (flags == DB_CURRENT || flags == DB_GET_BOTHC ||	    flags == DB_NEXT || flags == DB_NEXT_DUP || flags == DB_PREV)) {		if (tmp_rmw && (ret = dbc_arg->c_am_writelock(dbc_arg)) != 0)			return (ret);		if ((ret = __db_c_idup(cp->opd, &opd, DB_POSITIONI)) != 0)			return (ret);		switch (ret =		    opd->c_am_get(opd, key, data, flags, NULL)) {		case 0:			goto done;		case DB_NOTFOUND:			/*			 * Translate DB_NOTFOUND failures for the DB_NEXT and			 * DB_PREV operations into a subsequent operation on			 * the parent cursor.			 */			if (flags == DB_NEXT || flags == DB_PREV) {				if ((ret = opd->c_close(opd)) != 0)					goto err;				opd = NULL;				break;			}			goto err;		default:			goto err;		}	}	/*	 * Perform an operation on the main cursor.  Duplicate the cursor,	 * upgrade the lock as required, and call the underlying function.	 */	switch (flags) {	case DB_CURRENT:	case DB_GET_BOTHC:	case DB_NEXT:	case DB_NEXT_DUP:	case DB_NEXT_NODUP:	case DB_PREV:	case DB_PREV_NODUP:		tmp_flags = DB_POSITIONI;		break;	default:		tmp_flags = 0;		break;	}	if (tmp_dirty)		F_SET(dbc_arg, DBC_DIRTY_READ);	/*	 * If this cursor is going to be closed immediately, we don't	 * need to take precautions to clean it up on error.	 */	if (F_ISSET(dbc_arg, DBC_TRANSIENT))		dbc_n = dbc_arg;	else {		ret = __db_c_idup(dbc_arg, &dbc_n, tmp_flags);		if (tmp_dirty)			F_CLR(dbc_arg, DBC_DIRTY_READ);		if (ret != 0)			goto err;		COPY_RET_MEM(dbc_arg, dbc_n);	}	if (tmp_rmw)		F_SET(dbc_n, DBC_RMW);	switch (multi) {	case DB_MULTIPLE:		F_SET(dbc_n, DBC_MULTIPLE);		break;	case DB_MULTIPLE_KEY:		F_SET(dbc_n, DBC_MULTIPLE_KEY);		break;	case DB_MULTIPLE | DB_MULTIPLE_KEY:		F_SET(dbc_n, DBC_MULTIPLE|DBC_MULTIPLE_KEY);		break;	case 0:		break;	}	pgno = PGNO_INVALID;	ret = dbc_n->c_am_get(dbc_n, key, data, flags, &pgno);	if (tmp_rmw)		F_CLR(dbc_n, DBC_RMW);	if (tmp_dirty)		F_CLR(dbc_arg, DBC_DIRTY_READ);	F_CLR(dbc_n, DBC_MULTIPLE|DBC_MULTIPLE_KEY);	if (ret != 0)		goto err;	cp_n = dbc_n->internal;	/*	 * We may be referencing a new off-page duplicates tree.  Acquire	 * a new cursor and call the underlying function.	 */	if (pgno != PGNO_INVALID) {		if ((ret = __db_c_newopd(dbc_arg,		    pgno, cp_n->opd, &cp_n->opd)) != 0)			goto err;		switch (flags) {		case DB_FIRST:		case DB_NEXT:		case DB_NEXT_NODUP:		case DB_SET:		case DB_SET_RECNO:		case DB_SET_RANGE:			tmp_flags = DB_FIRST;			break;		case DB_LAST:		case DB_PREV:		case DB_PREV_NODUP:			tmp_flags = DB_LAST;			break;		case DB_GET_BOTH:		case DB_GET_BOTHC:		case DB_GET_BOTH_RANGE:			tmp_flags = flags;			break;		default:			ret =			    __db_unknown_flag(dbp->dbenv, "__db_c_get", flags);			goto err;		}		if ((ret = cp_n->opd->c_am_get(		    cp_n->opd, key, data, tmp_flags, NULL)) != 0)			goto err;	}done:	/*	 * Return a key/data item.  The only exception is that we don't return	 * a key if the user already gave us one, that is, if the DB_SET flag	 * was set.  The DB_SET flag is necessary.  In a Btree, the user's key	 * doesn't have to be the same as the key stored the tree, depending on	 * the magic performed by the comparison function.  As we may not have	 * done any key-oriented operation here, the page reference may not be	 * valid.  Fill it in as necessary.  We don't have to worry about any	 * locks, the cursor must already be holding appropriate locks.	 *	 * XXX	 * If not a Btree and DB_SET_RANGE is set, we shouldn't return a key	 * either, should we?	 */	cp_n = dbc_n == NULL ? dbc_arg->internal : dbc_n->internal;	if (!F_ISSET(key, DB_DBT_ISSET)) {		if (cp_n->page == NULL && (ret =		    mpf->get(mpf, &cp_n->pgno, 0, &cp_n->page)) != 0)			goto err;		if ((ret = __db_ret(dbp, cp_n->page, cp_n->indx,		    key, &dbc_arg->rkey->data, &dbc_arg->rkey->ulen)) != 0)			goto err;	}	if (multi != 0) {		/*		 * Even if fetching from the OPD cursor we need a duplicate		 * primary cursor if we are going after multiple keys.		 */		if (dbc_n == NULL) {			/*			 * Non-"_KEY" DB_MULTIPLE doesn't move the main cursor,			 * so it's safe to just use dbc_arg, unless dbc_arg			 * has an open OPD cursor whose state might need to			 * be preserved.			 */			if ((!(multi & DB_MULTIPLE_KEY) && 			    dbc_arg->internal->opd == NULL) ||			    F_ISSET(dbc_arg, DBC_TRANSIENT))				dbc_n = dbc_arg;			else {				if ((ret = __db_c_idup(dbc_arg,				    &dbc_n, DB_POSITIONI)) != 0)					goto err;				if ((ret = dbc_n->c_am_get(dbc_n,				    key, data, DB_CURRENT, &pgno)) != 0)					goto err;			}			cp_n = dbc_n->internal;		}		/*		 * If opd is set then we dupped the opd that we came in with.		 * When we return we may have a new opd if we went to another		 * key.		 */		if (opd != NULL) {			DB_ASSERT(cp_n->opd == NULL);			cp_n->opd = opd;			opd = NULL;		}		/*		 * Bulk get doesn't use __db_retcopy, so data.size won't		 * get set up unless there is an error.  Assume success		 * here.  This is the only call to c_am_bulk, and it avoids		 * setting it exactly the same everywhere.  If we have an		 * ENOMEM error, it'll get overwritten with the needed value.		 */		data->size = data->ulen;		ret = dbc_n->c_am_bulk(dbc_n, data, flags | multi);	} else if (!F_ISSET(data, DB_DBT_ISSET)) {		dbc = opd != NULL ? opd : cp_n->opd != NULL ? cp_n->opd : dbc_n;		type = TYPE(dbc->internal->page);		ret = __db_ret(dbp, dbc->internal->page, dbc->internal->indx +		    (type == P_LBTREE || type == P_HASH ? O_INDX : 0),		    data, &dbc_arg->rdata->data, &dbc_arg->rdata->ulen);	}err:	/* Don't pass DB_DBT_ISSET back to application level, error or no. */	F_CLR(key, DB_DBT_ISSET);	F_CLR(data, DB_DBT_ISSET);	/* Cleanup and cursor resolution. */	if (opd != NULL) {		if ((t_ret = __db_c_cleanup(		    dbc_arg->internal->opd, opd, ret)) != 0 && ret == 0)			ret = t_ret;	}	if ((t_ret = __db_c_cleanup(dbc_arg, dbc_n, ret)) != 0 && ret == 0)		ret = t_ret;	if (flags == DB_CONSUME || flags == DB_CONSUME_WAIT)		CDB_LOCKING_DONE(dbp, dbc_arg);	return (ret);}/* * __db_c_put -- *	Put using a cursor. * * PUBLIC: int __db_c_put __P((DBC *, DBT *, DBT *, u_int32_t)); */int__db_c_put(dbc_arg, key, data, flags)	DBC *dbc_arg;	DBT *key, *data;	u_int32_t flags;{	DB *dbp, *sdbp;	DBC *dbc_n, *oldopd, *opd, *sdbc, *pdbc;	DBT olddata, oldpkey, oldskey, newdata, pkey, save_skey, skey, temp;	db_pgno_t pgno;	int cmp, have_oldrec, ispartial, nodel, re_pad, ret, rmw, t_ret;	u_int32_t re_len, size, tmp_flags;	/*	 * Cursor Cleanup Note:	 * All of the cursors passed to the underlying access methods by this	 * routine are duplicated cursors.  On return, any referenced pages	 * will be discarded, and, if the cursor is not intended to be used	 * again, the close function will be called.  So, pages/locks that	 * the cursor references do not need to be resolved by the underlying	 * functions.	 */	dbp = dbc_arg->dbp;	sdbp = NULL;	pdbc = dbc_n = NULL;	memset(&newdata, 0, sizeof(DBT));

⌨️ 快捷键说明

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