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

📄 bt_put.c

📁 这是linux下运行的mysql软件包,可用于linux 下安装 php + mysql + apach 的网络配置
💻 C
📖 第 1 页 / 共 2 页
字号:
	nbytes =	    B_TYPE(bk->type) == B_OVERFLOW ? ((BOVERFLOW *)bk)->tlen : bk->len;	return (__db_partsize(nbytes, data));}/* * __bam_build -- *	Build the real record for a partial put, or short fixed-length record. */static int__bam_build(dbc, op, dbt, h, indx, nbytes)	DBC *dbc;	u_int32_t op, indx, nbytes;	DBT *dbt;	PAGE *h;{	BKEYDATA *bk, tbk;	BOVERFLOW *bo;	BTREE *t;	DB *dbp;	DBT copy, *rdata;	u_int32_t len, tlen;	u_int8_t *p;	int ret;	COMPQUIET(bo, NULL);	dbp = dbc->dbp;	t = dbp->bt_internal;	/* We use the record data return memory, it's only a short-term use. */	rdata = &dbc->my_rdata;	if (rdata->ulen < nbytes) {		if ((ret = __os_realloc(dbp->dbenv,		    nbytes, &rdata->data)) != 0) {			rdata->ulen = 0;			rdata->data = NULL;			return (ret);		}		rdata->ulen = nbytes;	}	/*	 * We use nul or pad bytes for any part of the record that isn't	 * specified; get it over with.	 */	memset(rdata->data,	   F_ISSET(dbp, DB_AM_FIXEDLEN) ? t->re_pad : 0, nbytes);	/*	 * In the next clauses, we need to do three things: a) set p to point	 * to the place at which to copy the user's data, b) set tlen to the	 * total length of the record, not including the bytes contributed by	 * the user, and c) copy any valid data from an existing record.  If	 * it's not a partial put (this code is called for both partial puts	 * and fixed-length record padding) or it's a new key, we can cut to	 * the chase.	 */	if (!F_ISSET(dbt, DB_DBT_PARTIAL) || op != DB_CURRENT) {		p = (u_int8_t *)rdata->data + dbt->doff;		tlen = dbt->doff;		goto user_copy;	}	/* Find the current record. */	if (indx < NUM_ENT(h)) {		bk = GET_BKEYDATA(dbp, h, indx + (TYPE(h) == P_LBTREE ?		    O_INDX : 0));		bo = (BOVERFLOW *)bk;	} else {		bk = &tbk;		B_TSET(bk->type, B_KEYDATA, 0);		bk->len = 0;	}	if (B_TYPE(bk->type) == B_OVERFLOW) {		/*		 * In the case of an overflow record, we shift things around		 * in the current record rather than allocate a separate copy.		 */		memset(&copy, 0, sizeof(copy));		if ((ret = __db_goff(dbp, &copy, bo->tlen,		    bo->pgno, &rdata->data, &rdata->ulen)) != 0)			return (ret);		/* Skip any leading data from the original record. */		tlen = dbt->doff;		p = (u_int8_t *)rdata->data + dbt->doff;		/*		 * Copy in any trailing data from the original record.		 *		 * If the original record was larger than the original offset		 * plus the bytes being deleted, there is trailing data in the		 * original record we need to preserve.  If we aren't deleting		 * the same number of bytes as we're inserting, copy it up or		 * down, into place.		 *		 * Use memmove(), the regions may overlap.		 */		if (bo->tlen > dbt->doff + dbt->dlen) {			len = bo->tlen - (dbt->doff + dbt->dlen);			if (dbt->dlen != dbt->size)				memmove(p + dbt->size, p + dbt->dlen, len);			tlen += len;		}	} else {		/* Copy in any leading data from the original record. */		memcpy(rdata->data,		    bk->data, dbt->doff > bk->len ? bk->len : dbt->doff);		tlen = dbt->doff;		p = (u_int8_t *)rdata->data + dbt->doff;		/* Copy in any trailing data from the original record. */		len = dbt->doff + dbt->dlen;		if (bk->len > len) {			memcpy(p + dbt->size, bk->data + len, bk->len - len);			tlen += bk->len - len;		}	}user_copy:	/*	 * Copy in the application provided data -- p and tlen must have been	 * initialized above.	 */	memcpy(p, dbt->data, dbt->size);	tlen += dbt->size;	/* Set the DBT to reference our new record. */	rdata->size = F_ISSET(dbp, DB_AM_FIXEDLEN) ? t->re_len : tlen;	rdata->dlen = 0;	rdata->doff = 0;	rdata->flags = 0;	*dbt = *rdata;	return (0);}/* * __bam_ritem -- *	Replace an item on a page. * * PUBLIC: int __bam_ritem __P((DBC *, PAGE *, u_int32_t, DBT *)); */int__bam_ritem(dbc, h, indx, data)	DBC *dbc;	PAGE *h;	u_int32_t indx;	DBT *data;{	BKEYDATA *bk;	DB *dbp;	DBT orig, repl;	db_indx_t cnt, lo, ln, min, off, prefix, suffix;	int32_t nbytes;	int ret;	db_indx_t *inp;	u_int8_t *p, *t;	dbp = dbc->dbp;	/*	 * Replace a single item onto a page.  The logic figuring out where	 * to insert and whether it fits is handled in the caller.  All we do	 * here is manage the page shuffling.	 */	bk = GET_BKEYDATA(dbp, h, indx);	/* Log the change. */	if (DBC_LOGGING(dbc)) {		/*		 * We might as well check to see if the two data items share		 * a common prefix and suffix -- it can save us a lot of log		 * message if they're large.		 */		min = data->size < bk->len ? data->size : bk->len;		for (prefix = 0,		    p = bk->data, t = data->data;		    prefix < min && *p == *t; ++prefix, ++p, ++t)			;		min -= prefix;		for (suffix = 0,		    p = (u_int8_t *)bk->data + bk->len - 1,		    t = (u_int8_t *)data->data + data->size - 1;		    suffix < min && *p == *t; ++suffix, --p, --t)			;		/* We only log the parts of the keys that have changed. */		orig.data = (u_int8_t *)bk->data + prefix;		orig.size = bk->len - (prefix + suffix);		repl.data = (u_int8_t *)data->data + prefix;		repl.size = data->size - (prefix + suffix);		if ((ret = __bam_repl_log(dbp, dbc->txn, &LSN(h), 0, PGNO(h),		    &LSN(h), (u_int32_t)indx, (u_int32_t)B_DISSET(bk->type),		    &orig, &repl, (u_int32_t)prefix, (u_int32_t)suffix)) != 0)			return (ret);	} else		LSN_NOT_LOGGED(LSN(h));	/*	 * Set references to the first in-use byte on the page and the	 * first byte of the item being replaced.	 */	inp = P_INP(dbp, h);	p = (u_int8_t *)h + HOFFSET(h);	t = (u_int8_t *)bk;	/*	 * If the entry is growing in size, shift the beginning of the data	 * part of the page down.  If the entry is shrinking in size, shift	 * the beginning of the data part of the page up.  Use memmove(3),	 * the regions overlap.	 */	lo = BKEYDATA_SIZE(bk->len);	ln = (db_indx_t)BKEYDATA_SIZE(data->size);	if (lo != ln) {		nbytes = lo - ln;		/* Signed difference. */		if (p == t)			/* First index is fast. */			inp[indx] += nbytes;		else {				/* Else, shift the page. */			memmove(p + nbytes, p, t - p);			/* Adjust the indices' offsets. */			off = inp[indx];			for (cnt = 0; cnt < NUM_ENT(h); ++cnt)				if (inp[cnt] <= off)					inp[cnt] += nbytes;		}		/* Clean up the page and adjust the item's reference. */		HOFFSET(h) += nbytes;		t += nbytes;	}	/* Copy the new item onto the page. */	bk = (BKEYDATA *)t;	B_TSET(bk->type, B_KEYDATA, 0);	bk->len = data->size;	memcpy(bk->data, data->data, data->size);	return (0);}/* * __bam_dup_convert -- *	Check to see if the duplicate set at indx should have its own page. *	If it should, create it. */static int__bam_dup_convert(dbc, h, indx)	DBC *dbc;	PAGE *h;	u_int32_t indx;{	BKEYDATA *bk;	DB *dbp;	DBT hdr;	DB_MPOOLFILE *mpf;	PAGE *dp;	db_indx_t cnt, cpindx, dindx, first, *inp, sz;	int ret;	dbp = dbc->dbp;	mpf = dbp->mpf;	inp = P_INP(dbp, h);	/*	 * Count the duplicate records and calculate how much room they're	 * using on the page.	 */	while (indx > 0 && inp[indx] == inp[indx - P_INDX])		indx -= P_INDX;	for (cnt = 0, sz = 0, first = indx;; ++cnt, indx += P_INDX) {		if (indx >= NUM_ENT(h) || inp[first] != inp[indx])			break;		bk = GET_BKEYDATA(dbp, h, indx);		sz += B_TYPE(bk->type) == B_KEYDATA ?		    BKEYDATA_PSIZE(bk->len) : BOVERFLOW_PSIZE;		bk = GET_BKEYDATA(dbp, h, indx + O_INDX);		sz += B_TYPE(bk->type) == B_KEYDATA ?		    BKEYDATA_PSIZE(bk->len) : BOVERFLOW_PSIZE;	}	/*	 * We have to do these checks when the user is replacing the cursor's	 * data item -- if the application replaces a duplicate item with a	 * larger data item, it can increase the amount of space used by the	 * duplicates, requiring this check.  But that means we may have done	 * this check when it wasn't a duplicate item after all.	 */	if (cnt == 1)		return (0);	/*	 * If this set of duplicates is using more than 25% of the page, move	 * them off.  The choice of 25% is a WAG, but the value must be small	 * enough that we can always split a page without putting duplicates	 * on two different pages.	 */	if (sz < dbp->pgsize / 4)		return (0);	/* Get a new page. */	if ((ret = __db_new(dbc,	    dbp->dup_compare == NULL ? P_LRECNO : P_LDUP, &dp)) != 0)		return (ret);	P_INIT(dp, dbp->pgsize, dp->pgno,	    PGNO_INVALID, PGNO_INVALID, LEAFLEVEL, TYPE(dp));	/*	 * Move this set of duplicates off the page.  First points to the first	 * key of the first duplicate key/data pair, cnt is the number of pairs	 * we're dealing with.	 */	memset(&hdr, 0, sizeof(hdr));	dindx = first;	indx = first;	cpindx = 0;	do {		/* Move cursors referencing the old entry to the new entry. */		if ((ret = __bam_ca_dup(dbc, first,		    PGNO(h), indx, PGNO(dp), cpindx)) != 0)			goto err;		/*		 * Copy the entry to the new page.  If the off-duplicate page		 * If the off-duplicate page is a Btree page (i.e. dup_compare		 * will be non-NULL, we use Btree pages for sorted dups,		 * and Recno pages for unsorted dups), move all entries		 * normally, even deleted ones.  If it's a Recno page,		 * deleted entries are discarded (if the deleted entry is		 * overflow, then free up those pages).		 */		bk = GET_BKEYDATA(dbp, h, dindx + 1);		hdr.data = bk;		hdr.size = B_TYPE(bk->type) == B_KEYDATA ?		    BKEYDATA_SIZE(bk->len) : BOVERFLOW_SIZE;		if (dbp->dup_compare == NULL && B_DISSET(bk->type)) {			/*			 * Unsorted dups, i.e. recno page, and we have			 * a deleted entry, don't move it, but if it was			 * an overflow entry, we need to free those pages.			 */			if (B_TYPE(bk->type) == B_OVERFLOW &&			    (ret = __db_doff(dbc,			    (GET_BOVERFLOW(dbp, h, dindx + 1))->pgno)) != 0)				goto err;		} else {			if ((ret = __db_pitem(			    dbc, dp, cpindx, hdr.size, &hdr, NULL)) != 0)				goto err;			++cpindx;		}		/* Delete all but the last reference to the key. */		if (cnt != 1) {			if ((ret = __bam_adjindx(dbc,			    h, dindx, first + 1, 0)) != 0)				goto err;		} else			dindx++;		/* Delete the data item. */		if ((ret = __db_ditem(dbc, h, dindx, hdr.size)) != 0)			goto err;		indx += P_INDX;	} while (--cnt);	/* Put in a new data item that points to the duplicates page. */	if ((ret = __bam_ovput(dbc,	    B_DUPLICATE, dp->pgno, h, first + 1, NULL)) != 0)		goto err;	/* Adjust cursors for all the above movments. */	if ((ret = __bam_ca_di(dbc,	    PGNO(h), first + P_INDX, first + P_INDX - indx)) != 0)		goto err;	return (mpf->put(mpf, dp, DB_MPOOL_DIRTY));err:	(void)mpf->put(mpf, dp, 0);	return (ret);}/* * __bam_ovput -- *	Build an item for an off-page duplicates page or overflow page and *	insert it on the page. */static int__bam_ovput(dbc, type, pgno, h, indx, item)	DBC *dbc;	u_int32_t type, indx;	db_pgno_t pgno;	PAGE *h;	DBT *item;{	BOVERFLOW bo;	DBT hdr;	int ret;	UMRW_SET(bo.unused1);	B_TSET(bo.type, type, 0);	UMRW_SET(bo.unused2);	/*	 * If we're creating an overflow item, do so and acquire the page	 * number for it.  If we're creating an off-page duplicates tree,	 * we are giving the page number as an argument.	 */	if (type == B_OVERFLOW) {		if ((ret = __db_poff(dbc, item, &bo.pgno)) != 0)			return (ret);		bo.tlen = item->size;	} else {		bo.pgno = pgno;		bo.tlen = 0;	}	/* Store the new record on the page. */	memset(&hdr, 0, sizeof(hdr));	hdr.data = &bo;	hdr.size = BOVERFLOW_SIZE;	return (__db_pitem(dbc, h, indx, BOVERFLOW_SIZE, &hdr, NULL));}

⌨️ 快捷键说明

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