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

📄 hash_page.c

📁 这是linux下运行的mysql软件包,可用于linux 下安装 php + mysql + apach 的网络配置
💻 C
📖 第 1 页 / 共 4 页
字号:
	/* Put the item element on the page. */	if (type == H_OFFPAGE) {		off = HOFFSET(p) - dbt->size;		HOFFSET(p) = inp[n] = off;		memcpy(P_ENTRY(dbp, p, n), dbt->data, dbt->size);	} else {		off = HOFFSET(p) - HKEYDATA_SIZE(dbt->size);		HOFFSET(p) = inp[n] = off;		PUT_HKEYDATA(P_ENTRY(dbp, p, n), dbt->data, dbt->size, type);	}	/* Adjust page info. */	NUM_ENT(p) += 1;}/* * PUBLIC: void __ham_reputpair  __P((DB *, PAGE *, * PUBLIC:    u_int32_t, const DBT *, const DBT *)); * * This is a special case to restore a key/data pair to its original * location during recovery.  We are guaranteed that the pair fits * on the page and is not the last pair on the page (because if it's * the last pair, the normal insert works). */void__ham_reputpair(dbp, p, ndx, key, data)	DB *dbp;	PAGE *p;	u_int32_t ndx;	const DBT *key, *data;{	db_indx_t i, *inp, movebytes, newbytes;	size_t psize;	u_int8_t *from;	psize = dbp->pgsize;	inp = P_INP(dbp, p);	/* First shuffle the existing items up on the page.  */	movebytes = (db_indx_t)(	    (ndx == 0 ? psize : inp[H_DATAINDEX(ndx - 2)]) - HOFFSET(p));	newbytes = key->size + data->size;	from = (u_int8_t *)p + HOFFSET(p);	memmove(from - newbytes, from, movebytes);	/*	 * Adjust the indices and move them up 2 spaces. Note that we	 * have to check the exit condition inside the loop just in case	 * we are dealing with index 0 (db_indx_t's are unsigned).	 */	for (i = NUM_ENT(p) - 1; ; i-- ) {		inp[i + 2] = inp[i] - newbytes;		if (i == H_KEYINDEX(ndx))			break;	}	/* Put the key and data on the page. */	inp[H_KEYINDEX(ndx)] = (db_indx_t)(	    (ndx == 0 ? psize : inp[H_DATAINDEX(ndx - 2)]) - key->size);	inp[H_DATAINDEX(ndx)] = inp[H_KEYINDEX(ndx)] - data->size;	memcpy(P_ENTRY(dbp, p, H_KEYINDEX(ndx)), key->data, key->size);	memcpy(P_ENTRY(dbp, p, H_DATAINDEX(ndx)), data->data, data->size);	/* Adjust page info. */	HOFFSET(p) -= newbytes;	NUM_ENT(p) += 2;}/* * PUBLIC: int __ham_del_pair __P((DBC *, int)); */int__ham_del_pair(dbc, reclaim_page)	DBC *dbc;	int reclaim_page;{	DB *dbp;	DBT data_dbt, key_dbt;	DB_LSN new_lsn, *n_lsn, tmp_lsn;	DB_MPOOLFILE *mpf;	HASH_CURSOR *hcp;	PAGE *n_pagep, *nn_pagep, *p, *p_pagep;	db_ham_mode op;	db_indx_t ndx;	db_pgno_t chg_pgno, pgno, tmp_pgno;	int ret, t_ret;	u_int32_t order;	dbp = dbc->dbp;	mpf = dbp->mpf;	hcp = (HASH_CURSOR *)dbc->internal;	n_pagep = p_pagep = nn_pagep = NULL;	ndx = hcp->indx;	if (hcp->page == NULL &&	    (ret = mpf->get(mpf, &hcp->pgno, DB_MPOOL_CREATE, &hcp->page)) != 0)		return (ret);	p = hcp->page;	/*	 * We optimize for the normal case which is when neither the key nor	 * the data are large.  In this case, we write a single log record	 * and do the delete.  If either is large, we'll call __big_delete	 * to remove the big item and then update the page to remove the	 * entry referring to the big item.	 */	ret = 0;	if (HPAGE_PTYPE(H_PAIRKEY(dbp, p, ndx)) == H_OFFPAGE) {		memcpy(&pgno, HOFFPAGE_PGNO(P_ENTRY(dbp, p, H_KEYINDEX(ndx))),		    sizeof(db_pgno_t));		ret = __db_doff(dbc, pgno);	}	if (ret == 0)		switch (HPAGE_PTYPE(H_PAIRDATA(dbp, p, ndx))) {		case H_OFFPAGE:			memcpy(&pgno,			    HOFFPAGE_PGNO(P_ENTRY(dbp, p, H_DATAINDEX(ndx))),			    sizeof(db_pgno_t));			ret = __db_doff(dbc, pgno);			break;		case H_OFFDUP:		case H_DUPLICATE:			/*			 * If we delete a pair that is/was a duplicate, then			 * we had better clear the flag so that we update the			 * cursor appropriately.			 */			F_CLR(hcp, H_ISDUP);			break;		}	if (ret)		return (ret);	/* Now log the delete off this page. */	if (DBC_LOGGING(dbc)) {		key_dbt.data = P_ENTRY(dbp, p, H_KEYINDEX(ndx));		key_dbt.size = LEN_HITEM(dbp, p, dbp->pgsize, H_KEYINDEX(ndx));		data_dbt.data = P_ENTRY(dbp, p, H_DATAINDEX(ndx));		data_dbt.size = LEN_HITEM(dbp, p, dbp->pgsize, H_DATAINDEX(ndx));		if ((ret = __ham_insdel_log(dbp,		    dbc->txn, &new_lsn, 0, DELPAIR, PGNO(p), (u_int32_t)ndx,		    &LSN(p), &key_dbt, &data_dbt)) != 0)			return (ret);	} else		LSN_NOT_LOGGED(new_lsn);	/* Move lsn onto page. */	LSN(p) = new_lsn;	/* Do the delete. */	__ham_dpair(dbp, p, ndx);	/*	 * Mark item deleted so that we don't try to return it, and	 * so that we update the cursor correctly on the next call	 * to next.	 */	F_SET(hcp, H_DELETED);	F_CLR(hcp, H_OK);	/*	 * Update cursors that are on the page where the delete happend.	 */	if ((ret = __ham_c_update(dbc, 0, 0, 0)) != 0)		return (ret);	/*	 * If we are locking, we will not maintain this, because it is	 * a hot spot.	 *	 * XXX	 * Perhaps we can retain incremental numbers and apply them later.	 */	if (!STD_LOCKING(dbc)) {		--hcp->hdr->nelem;		if ((ret = __ham_dirty_meta(dbc)) != 0)			return (ret);	}	/*	 * If we need to reclaim the page, then check if the page is empty.	 * There are two cases.  If it's empty and it's not the first page	 * in the bucket (i.e., the bucket page) then we can simply remove	 * it. If it is the first chain in the bucket, then we need to copy	 * the second page into it and remove the second page.	 * If its the only page in the bucket we leave it alone.	 */	if (!reclaim_page ||	    NUM_ENT(p) != 0 ||	    (PREV_PGNO(p) == PGNO_INVALID && NEXT_PGNO(p) == PGNO_INVALID))		return (mpf->set(mpf, p, DB_MPOOL_DIRTY));	if (PREV_PGNO(p) == PGNO_INVALID) {		/*		 * First page in chain is empty and we know that there		 * are more pages in the chain.		 */		if ((ret = mpf->get(mpf, &NEXT_PGNO(p), 0, &n_pagep)) != 0)			return (ret);		if (NEXT_PGNO(n_pagep) != PGNO_INVALID && (ret =		    mpf->get(mpf, &NEXT_PGNO(n_pagep), 0, &nn_pagep)) != 0)			goto err;		if (DBC_LOGGING(dbc)) {			key_dbt.data = n_pagep;			key_dbt.size = dbp->pgsize;			if ((ret = __ham_copypage_log(dbp,			    dbc->txn, &new_lsn, 0, PGNO(p),			    &LSN(p), PGNO(n_pagep), &LSN(n_pagep),			    NEXT_PGNO(n_pagep),			    nn_pagep == NULL ? NULL : &LSN(nn_pagep),			    &key_dbt)) != 0)				goto err;		} else			LSN_NOT_LOGGED(new_lsn);		/* Move lsn onto page. */		LSN(p) = new_lsn;	/* Structure assignment. */		LSN(n_pagep) = new_lsn;		if (NEXT_PGNO(n_pagep) != PGNO_INVALID)			LSN(nn_pagep) = new_lsn;		if (nn_pagep != NULL) {			PREV_PGNO(nn_pagep) = PGNO(p);			if ((ret =			    mpf->put(mpf, nn_pagep, DB_MPOOL_DIRTY)) != 0) {				nn_pagep = NULL;				goto err;			}		}		tmp_pgno = PGNO(p);		tmp_lsn = LSN(p);		memcpy(p, n_pagep, dbp->pgsize);		PGNO(p) = tmp_pgno;		LSN(p) = tmp_lsn;		PREV_PGNO(p) = PGNO_INVALID;		/*		 * Update cursors to reflect the fact that records		 * on the second page have moved to the first page.		 */		if ((ret = __ham_c_delpg(dbc, PGNO(n_pagep),		    PGNO(p), 0, DB_HAM_DELFIRSTPG, &order)) != 0)			goto err;		/*		 * Update the cursor to reflect its new position.		 */		hcp->indx = 0;		hcp->pgno = PGNO(p);		hcp->order += order;		if ((ret = mpf->set(mpf, p, DB_MPOOL_DIRTY)) != 0)			goto err;		if ((ret = __db_free(dbc, n_pagep)) != 0) {			n_pagep = NULL;			goto err;		}	} else {		if ((ret = mpf->get(mpf, &PREV_PGNO(p), 0, &p_pagep)) != 0)			goto err;		if (NEXT_PGNO(p) != PGNO_INVALID) {			if ((ret =			    mpf->get(mpf, &NEXT_PGNO(p), 0, &n_pagep)) != 0)				goto err;			n_lsn = &LSN(n_pagep);		} else {			n_pagep = NULL;			n_lsn = NULL;		}		NEXT_PGNO(p_pagep) = NEXT_PGNO(p);		if (n_pagep != NULL)			PREV_PGNO(n_pagep) = PGNO(p_pagep);		if (DBC_LOGGING(dbc)) {			if ((ret = __ham_newpage_log(dbp, dbc->txn,			    &new_lsn, 0, DELOVFL, PREV_PGNO(p), &LSN(p_pagep),			    PGNO(p), &LSN(p), NEXT_PGNO(p), n_lsn)) != 0)				goto err;		} else			LSN_NOT_LOGGED(new_lsn);		/* Move lsn onto page. */		LSN(p_pagep) = new_lsn;	/* Structure assignment. */		if (n_pagep)			LSN(n_pagep) = new_lsn;		LSN(p) = new_lsn;		if (NEXT_PGNO(p) == PGNO_INVALID) {			/*			 * There is no next page; put the cursor on the			 * previous page as if we'd deleted the last item			 * on that page, with index after the last valid			 * entry.			 *			 * The deleted flag was set up above.			 */			hcp->pgno = PGNO(p_pagep);			hcp->indx = NUM_ENT(p_pagep);			op = DB_HAM_DELLASTPG;		} else {			/*			 * There is a next page, so put the cursor at			 * the beginning of it.			 */			hcp->pgno = NEXT_PGNO(p);			hcp->indx = 0;			op = DB_HAM_DELMIDPG;		}		/*		 * Since we are about to delete the cursor page and we have		 * just moved the cursor, we need to make sure that the		 * old page pointer isn't left hanging around in the cursor.		 */		hcp->page = NULL;		chg_pgno = PGNO(p);		ret = __db_free(dbc, p);		if ((t_ret =		    mpf->put(mpf, p_pagep, DB_MPOOL_DIRTY)) != 0 && ret == 0)			ret = t_ret;		if (n_pagep != NULL && (t_ret =		    mpf->put(mpf, n_pagep, DB_MPOOL_DIRTY)) != 0 && ret == 0)			ret = t_ret;		if (ret != 0)			return (ret);		if ((ret = __ham_c_delpg(dbc,		    chg_pgno, hcp->pgno, hcp->indx, op, &order)) != 0)			return (ret);		hcp->order += order;	}	return (ret);err:	/* Clean up any pages. */	if (n_pagep != NULL)		(void)mpf->put(mpf, n_pagep, 0);	if (nn_pagep != NULL)		(void)mpf->put(mpf, nn_pagep, 0);	if (p_pagep != NULL)		(void)mpf->put(mpf, p_pagep, 0);	return (ret);}/* * __ham_replpair -- *	Given the key data indicated by the cursor, replace part/all of it *	according to the fields in the dbt. * * PUBLIC: int __ham_replpair __P((DBC *, DBT *, u_int32_t)); */int__ham_replpair(dbc, dbt, make_dup)	DBC *dbc;	DBT *dbt;	u_int32_t make_dup;{	DB *dbp;	DBT old_dbt, tdata, tmp;	DB_ENV *dbenv;	DB_LSN	new_lsn;	HASH_CURSOR *hcp;	int32_t change;			/* XXX: Possible overflow. */	u_int32_t dup_flag, len, memsize;	int beyond_eor, is_big, ret, type;	u_int8_t *beg, *dest, *end, *hk, *src;	void *memp;	/*	 * Big item replacements are handled in generic code.	 * Items that fit on the current page fall into 4 classes.	 * 1. On-page element, same size	 * 2. On-page element, new is bigger (fits)	 * 3. On-page element, new is bigger (does not fit)	 * 4. On-page element, old is bigger	 * Numbers 1, 2, and 4 are essentially the same (and should	 * be the common case).  We handle case 3 as a delete and	 * add.	 */	dbp = dbc->dbp;	dbenv = dbp->dbenv;	hcp = (HASH_CURSOR *)dbc->internal;	/*	 * We need to compute the number of bytes that we are adding or	 * removing from the entry.  Normally, we can simply substract	 * the number of bytes we are replacing (dbt->dlen) from the	 * number of bytes we are inserting (dbt->size).  However, if	 * we are doing a partial put off the end of a record, then this	 * formula doesn't work, because we are essentially adding	 * new bytes.	 */	change = dbt->size - dbt->dlen;	hk = H_PAIRDATA(dbp, hcp->page, hcp->indx);	is_big = HPAGE_PTYPE(hk) == H_OFFPAGE;	if (is_big)		memcpy(&len, HOFFPAGE_TLEN(hk), sizeof(u_int32_t));	else		len = LEN_HKEYDATA(dbp, hcp->page,		    dbp->pgsize, H_DATAINDEX(hcp->indx));	beyond_eor = dbt->doff + dbt->dlen > len;	if (beyond_eor)		change += dbt->doff + dbt->dlen - len;	if (change > (int32_t)P_FREESPACE(dbp, hcp->page) ||	    beyond_eor || is_big) {		/*		 * Case 3 -- two subcases.		 * A. This is not really a partial operation, but an overwrite.		 *    Simple del and add works.		 * B. This is a partial and we need to construct the data that		 *    we are really inserting (yuck).		 * In both cases, we need to grab the key off the page (in		 * some cases we could do this outside of this routine; for		 * cleanliness we do it here.  If you happen to be on a big		 * key, this could be a performance hit).		 */		memset(&tmp, 0, sizeof(tmp));		if ((ret =		    __db_ret(dbp, hcp->page, H_KEYINDEX(hcp->indx),		    &tmp, &dbc->rkey->data, &dbc->rkey->ulen)) != 0)			return (ret);		/* Preserve duplicate info. */		dup_flag = F_ISSET(hcp, H_ISDUP);		if (dbt->doff == 0 && dbt->dlen == len) {			ret = __ham_del_pair(dbc, 0);			if (ret == 0)			    ret = __ham_add_el(dbc,				&tmp, dbt, dup_flag ? H_DUPLICATE : H_KEYDATA);		} else {					/* Case B */			type = HPAGE_PTYPE(hk) != H_OFFPAGE ?			    HPAGE_PTYPE(hk) : H_KEYDATA;			memset(&tdata, 0, sizeof(tdata));			memp = NULL;			memsize = 0;			if ((ret = __db_ret(dbp, hcp->page,			    H_DATAINDEX(hcp->indx), &tdata, &memp, &memsize))			    != 0)				goto err;			/* Now we can delete the item. */			if ((ret = __ham_del_pair(dbc, 0)) != 0) {				__os_free(dbenv, memp);				goto err;			}			/* Now shift old data around to make room for new. */			if (change > 0) {				if ((ret = __os_realloc(dbenv,				    tdata.size + change, &tdata.data)) != 0)					return (ret);				memp = tdata.data;				memsize = tdata.size + change;				memset((u_int8_t *)tdata.data + tdata.size,				    0, change);			}

⌨️ 快捷键说明

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