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

📄 hash_page.c

📁 这是linux下运行的mysql软件包,可用于linux 下安装 php + mysql + apach 的网络配置
💻 C
📖 第 1 页 / 共 4 页
字号:
			end = (u_int8_t *)tdata.data + tdata.size;			src = (u_int8_t *)tdata.data + dbt->doff + dbt->dlen;			if (src < end && tdata.size > dbt->doff + dbt->dlen) {				len = tdata.size - dbt->doff - dbt->dlen;				dest = src + change;				memmove(dest, src, len);			}			memcpy((u_int8_t *)tdata.data + dbt->doff,			    dbt->data, dbt->size);			tdata.size += change;			/* Now add the pair. */			ret = __ham_add_el(dbc, &tmp, &tdata, type);			__os_free(dbenv, memp);		}		F_SET(hcp, dup_flag);err:		return (ret);	}	/*	 * Set up pointer into existing data. Do it before the log	 * message so we can use it inside of the log setup.	 */	beg = HKEYDATA_DATA(H_PAIRDATA(dbp, hcp->page, hcp->indx));	beg += dbt->doff;	/*	 * If we are going to have to move bytes at all, figure out	 * all the parameters here.  Then log the call before moving	 * anything around.	 */	if (DBC_LOGGING(dbc)) {		old_dbt.data = beg;		old_dbt.size = dbt->dlen;		if ((ret = __ham_replace_log(dbp,		    dbc->txn, &new_lsn, 0, PGNO(hcp->page),		    (u_int32_t)H_DATAINDEX(hcp->indx), &LSN(hcp->page),		    (u_int32_t)dbt->doff, &old_dbt, dbt, make_dup)) != 0)			return (ret);	} else		LSN_NOT_LOGGED(new_lsn);	LSN(hcp->page) = new_lsn;	/* Structure assignment. */	__ham_onpage_replace(dbp, hcp->page, (u_int32_t)H_DATAINDEX(hcp->indx),	    (int32_t)dbt->doff, change, dbt);	return (0);}/* * Replace data on a page with new data, possibly growing or shrinking what's * there.  This is called on two different occasions. On one (from replpair) * we are interested in changing only the data.  On the other (from recovery) * we are replacing the entire data (header and all) with a new element.  In * the latter case, the off argument is negative. * pagep: the page that we're changing * ndx: page index of the element that is growing/shrinking. * off: Offset at which we are beginning the replacement. * change: the number of bytes (+ or -) that the element is growing/shrinking. * dbt: the new data that gets written at beg. * * PUBLIC: void __ham_onpage_replace __P((DB *, PAGE *, u_int32_t, * PUBLIC:     int32_t, int32_t,  DBT *)); */void__ham_onpage_replace(dbp, pagep, ndx, off, change, dbt)	DB *dbp;	PAGE *pagep;	u_int32_t ndx;	int32_t off;	int32_t change;	DBT *dbt;{	db_indx_t i, *inp;	int32_t len;	size_t pgsize;	u_int8_t *src, *dest;	int zero_me;	pgsize = dbp->pgsize;	inp = P_INP(dbp, pagep);	if (change != 0) {		zero_me = 0;		src = (u_int8_t *)(pagep) + HOFFSET(pagep);		if (off < 0)			len = inp[ndx] - HOFFSET(pagep);		else if ((u_int32_t)off >=		    LEN_HKEYDATA(dbp, pagep, pgsize, ndx)) {			len = (int32_t)(HKEYDATA_DATA(P_ENTRY(dbp, pagep, ndx))			    + LEN_HKEYDATA(dbp, pagep, pgsize, ndx) - src);			zero_me = 1;		} else			len = (int32_t)(			    (HKEYDATA_DATA(P_ENTRY(dbp, pagep, ndx)) + off) -			    src);		dest = src - change;		memmove(dest, src, len);		if (zero_me)			memset(dest + len, 0, change);		/* Now update the indices. */		for (i = ndx; i < NUM_ENT(pagep); i++)			inp[i] -= change;		HOFFSET(pagep) -= change;	}	if (off >= 0)		memcpy(HKEYDATA_DATA(P_ENTRY(dbp, pagep, ndx)) + off,		    dbt->data, dbt->size);	else		memcpy(P_ENTRY(dbp, pagep, ndx), dbt->data, dbt->size);}/* * PUBLIC: int __ham_split_page __P((DBC *, u_int32_t, u_int32_t)); */int__ham_split_page(dbc, obucket, nbucket)	DBC *dbc;	u_int32_t obucket, nbucket;{	DB *dbp;	DBC **carray;	DBT key, page_dbt;	DB_ENV *dbenv;	DB_LOCK block;	DB_LSN new_lsn;	DB_MPOOLFILE *mpf;	HASH_CURSOR *hcp, *cp;	PAGE **pp, *old_pagep, *temp_pagep, *new_pagep;	db_indx_t n;	db_pgno_t bucket_pgno, npgno, next_pgno;	u_int32_t big_len, len;	int found, i, ret, t_ret;	void *big_buf;	dbp = dbc->dbp;	dbenv = dbp->dbenv;	mpf = dbp->mpf;	hcp = (HASH_CURSOR *)dbc->internal;	temp_pagep = old_pagep = new_pagep = NULL;	carray = NULL;	LOCK_INIT(block);	bucket_pgno = BUCKET_TO_PAGE(hcp, obucket);	if ((ret = __db_lget(dbc,	    0, bucket_pgno, DB_LOCK_WRITE, 0, &block)) != 0)		goto err;	if ((ret = mpf->get(mpf,	    &bucket_pgno, DB_MPOOL_CREATE, &old_pagep)) != 0)		goto err;	/* Properly initialize the new bucket page. */	npgno = BUCKET_TO_PAGE(hcp, nbucket);	if ((ret = mpf->get(mpf, &npgno, DB_MPOOL_CREATE, &new_pagep)) != 0)		goto err;	P_INIT(new_pagep,	    dbp->pgsize, npgno, PGNO_INVALID, PGNO_INVALID, 0, P_HASH);	temp_pagep = hcp->split_buf;	memcpy(temp_pagep, old_pagep, dbp->pgsize);	if (DBC_LOGGING(dbc)) {		page_dbt.size = dbp->pgsize;		page_dbt.data = old_pagep;		if ((ret = __ham_splitdata_log(dbp,		    dbc->txn, &new_lsn, 0, SPLITOLD,		    PGNO(old_pagep), &page_dbt, &LSN(old_pagep))) != 0)			goto err;	} else		LSN_NOT_LOGGED(new_lsn);	LSN(old_pagep) = new_lsn;	/* Structure assignment. */	P_INIT(old_pagep, dbp->pgsize, PGNO(old_pagep), PGNO_INVALID,	    PGNO_INVALID, 0, P_HASH);	big_len = 0;	big_buf = NULL;	key.flags = 0;	while (temp_pagep != NULL) {		if ((ret = __ham_get_clist(dbp,		    PGNO(temp_pagep), NDX_INVALID, &carray)) != 0)			goto err;		for (n = 0; n < (db_indx_t)NUM_ENT(temp_pagep); n += 2) {			if ((ret = __db_ret(dbp, temp_pagep,			    H_KEYINDEX(n), &key, &big_buf, &big_len)) != 0)				goto err;			if (__ham_call_hash(dbc, key.data, key.size) == obucket)				pp = &old_pagep;			else				pp = &new_pagep;			/*			 * Figure out how many bytes we need on the new			 * page to store the key/data pair.			 */			len = LEN_HITEM(dbp, temp_pagep, dbp->pgsize,			    H_DATAINDEX(n)) +			    LEN_HITEM(dbp, temp_pagep, dbp->pgsize,			    H_KEYINDEX(n)) +			    2 * sizeof(db_indx_t);			if (P_FREESPACE(dbp, *pp) < len) {				if (DBC_LOGGING(dbc)) {					page_dbt.size = dbp->pgsize;					page_dbt.data = *pp;					if ((ret = __ham_splitdata_log(dbp,					    dbc->txn, &new_lsn, 0,					    SPLITNEW, PGNO(*pp), &page_dbt,					    &LSN(*pp))) != 0)						goto err;				} else					LSN_NOT_LOGGED(new_lsn);				LSN(*pp) = new_lsn;				if ((ret =				    __ham_add_ovflpage(dbc, *pp, 1, pp)) != 0)					goto err;			}			/* Check if we need to update a cursor. */			if (carray != NULL) {				found = 0;				for (i = 0; carray[i] != NULL; i++) {					cp =					    (HASH_CURSOR *)carray[i]->internal;					if (cp->pgno == PGNO(temp_pagep) &&					    cp->indx == n) {						cp->pgno = PGNO(*pp);						cp->indx = NUM_ENT(*pp);						found = 1;					}				}				if (found && DBC_LOGGING(dbc) &&				    IS_SUBTRANSACTION(dbc->txn)) {					if ((ret =					    __ham_chgpg_log(dbp,					    dbc->txn, &new_lsn, 0,					    DB_HAM_SPLIT, PGNO(temp_pagep),					    PGNO(*pp), n, NUM_ENT(*pp))) != 0)						goto err;				}			}			__ham_copy_item(dbp, temp_pagep, H_KEYINDEX(n), *pp);			__ham_copy_item(dbp, temp_pagep, H_DATAINDEX(n), *pp);		}		next_pgno = NEXT_PGNO(temp_pagep);		/* Clear temp_page; if it's a link overflow page, free it. */		if (PGNO(temp_pagep) != bucket_pgno && (ret =		    __db_free(dbc, temp_pagep)) != 0) {			temp_pagep = NULL;			goto err;		}		if (next_pgno == PGNO_INVALID)			temp_pagep = NULL;		else if ((ret = mpf->get(		    mpf, &next_pgno, DB_MPOOL_CREATE, &temp_pagep)) != 0)			goto err;		if (temp_pagep != NULL) {			if (DBC_LOGGING(dbc)) {				page_dbt.size = dbp->pgsize;				page_dbt.data = temp_pagep;				if ((ret = __ham_splitdata_log(dbp,				    dbc->txn, &new_lsn, 0,				    SPLITOLD, PGNO(temp_pagep),				    &page_dbt, &LSN(temp_pagep))) != 0)					goto err;			} else				LSN_NOT_LOGGED(new_lsn);			LSN(temp_pagep) = new_lsn;		}		if (carray != NULL)	/* We never knew its size. */			__os_free(dbenv, carray);		carray = NULL;	}	if (big_buf != NULL)		__os_free(dbenv, big_buf);	/*	 * If the original bucket spanned multiple pages, then we've got	 * a pointer to a page that used to be on the bucket chain.  It	 * should be deleted.	 */	if (temp_pagep != NULL && PGNO(temp_pagep) != bucket_pgno &&	    (ret = __db_free(dbc, temp_pagep)) != 0) {		temp_pagep = NULL;		goto err;	}	/*	 * Write new buckets out.	 */	if (DBC_LOGGING(dbc)) {		page_dbt.size = dbp->pgsize;		page_dbt.data = old_pagep;		if ((ret = __ham_splitdata_log(dbp, dbc->txn,		    &new_lsn, 0, SPLITNEW, PGNO(old_pagep), &page_dbt,		    &LSN(old_pagep))) != 0)			goto err;		LSN(old_pagep) = new_lsn;		page_dbt.data = new_pagep;		if ((ret = __ham_splitdata_log(dbp, dbc->txn, &new_lsn, 0,		    SPLITNEW, PGNO(new_pagep), &page_dbt,		    &LSN(new_pagep))) != 0)			goto err;		LSN(new_pagep) = new_lsn;	} else {		LSN_NOT_LOGGED(LSN(old_pagep));		LSN_NOT_LOGGED(LSN(new_pagep));	}	ret = mpf->put(mpf, old_pagep, DB_MPOOL_DIRTY);	if ((t_ret =	    mpf->put(mpf, new_pagep, DB_MPOOL_DIRTY)) != 0 && ret == 0)		ret = t_ret;	if (0) {err:		if (old_pagep != NULL)			(void)mpf->put(mpf, old_pagep, DB_MPOOL_DIRTY);		if (new_pagep != NULL)			(void)mpf->put(mpf, new_pagep, DB_MPOOL_DIRTY);		if (temp_pagep != NULL && PGNO(temp_pagep) != bucket_pgno)			(void)mpf->put(mpf, temp_pagep, DB_MPOOL_DIRTY);	}	if (LOCK_ISSET(block))		__TLPUT(dbc, block);	if (carray != NULL)		/* We never knew its size. */		__os_free(dbenv, carray);	return (ret);}/* * Add the given pair to the page.  The page in question may already be * held (i.e. it was already gotten).  If it is, then the page is passed * in via the pagep parameter.  On return, pagep will contain the page * to which we just added something.  This allows us to link overflow * pages and return the new page having correctly put the last page. * * PUBLIC: int __ham_add_el __P((DBC *, const DBT *, const DBT *, int)); */int__ham_add_el(dbc, key, val, type)	DBC *dbc;	const DBT *key, *val;	int type;{	const DBT *pkey, *pdata;	DB *dbp;	DBT key_dbt, data_dbt;	DB_LSN new_lsn;	DB_MPOOLFILE *mpf;	HASH_CURSOR *hcp;	HOFFPAGE doff, koff;	db_pgno_t next_pgno, pgno;	u_int32_t data_size, key_size, pairsize, rectype;	int do_expand, is_keybig, is_databig, ret;	int key_type, data_type;	dbp = dbc->dbp;	mpf = dbp->mpf;	hcp = (HASH_CURSOR *)dbc->internal;	do_expand = 0;	pgno = hcp->seek_found_page != PGNO_INVALID ?	    hcp->seek_found_page : hcp->pgno;	if (hcp->page == NULL &&	    (ret = mpf->get(mpf, &pgno, DB_MPOOL_CREATE, &hcp->page)) != 0)		return (ret);	key_size = HKEYDATA_PSIZE(key->size);	data_size = HKEYDATA_PSIZE(val->size);	is_keybig = ISBIG(hcp, key->size);	is_databig = ISBIG(hcp, val->size);	if (is_keybig)		key_size = HOFFPAGE_PSIZE;	if (is_databig)		data_size = HOFFPAGE_PSIZE;	pairsize = key_size + data_size;	/* Advance to first page in chain with room for item. */	while (H_NUMPAIRS(hcp->page) && NEXT_PGNO(hcp->page) != PGNO_INVALID) {		/*		 * This may not be the end of the chain, but the pair may fit		 * anyway.  Check if it's a bigpair that fits or a regular		 * pair that fits.		 */		if (P_FREESPACE(dbp, hcp->page) >= pairsize)			break;		next_pgno = NEXT_PGNO(hcp->page);		if ((ret = __ham_next_cpage(dbc, next_pgno, 0)) != 0)			return (ret);	}	/*	 * Check if we need to allocate a new page.	 */	if (P_FREESPACE(dbp, hcp->page) < pairsize) {		do_expand = 1;		if ((ret = __ham_add_ovflpage(dbc,		    (PAGE *)hcp->page, 1, (PAGE **)&hcp->page)) != 0)			return (ret);		hcp->pgno = PGNO(hcp->page);	}	/*	 * Update cursor.	 */	hcp->indx = NUM_ENT(hcp->page);	F_CLR(hcp, H_DELETED);	if (is_keybig) {		koff.type = H_OFFPAGE;		UMRW_SET(koff.unused[0]);		UMRW_SET(koff.unused[1]);		UMRW_SET(koff.unused[2]);		if ((ret = __db_poff(dbc, key, &koff.pgno)) != 0)			return (ret);		koff.tlen = key->size;		key_dbt.data = &koff;		key_dbt.size = sizeof(koff);		pkey = &key_dbt;		key_type = H_OFFPAGE;	} else {		pkey = key;		key_type = H_KEYDATA;	}	if (is_databig) {		doff.type = H_OFFPAGE;		UMRW_SET(doff.unused[0]);		UMRW_SET(doff.unused[1]);		UMRW_SET(doff.unused[2]);		if ((ret = __db_poff(dbc, val, &doff.pgno)) != 0)			return (ret);		doff.tlen = val->size;		data_dbt.data = &doff;		data_dbt.size = sizeof(doff);		pdata = &data_dbt;		data_type = H_OFFPAGE;	} else {		pdata = val;		data_type = type;	}	if (DBC_LOGGING(dbc)) {		rectype = PUTPAIR;		if (is_databig)			rectype |= PAIR_DATAMASK;		if (is_keybig)			rectype |= PAIR_KEYMASK;		if (type == H_DUPLICATE)			rectype |= PAIR_DUPMASK;		if ((ret = __ham_insdel_log(dbp, dbc->txn, &new_lsn, 0,		    rectype, PGNO(hcp->page), (u_int32_t)NUM_ENT(hcp->page),		    &LSN(hcp->page), pkey, pdata)) != 0)			return (ret);

⌨️ 快捷键说明

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