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

📄 hash_page.c

📁 这是linux下运行的mysql软件包,可用于linux 下安装 php + mysql + apach 的网络配置
💻 C
📖 第 1 页 / 共 4 页
字号:
	} else		LSN_NOT_LOGGED(new_lsn);	/* Move lsn onto page. */	LSN(hcp->page) = new_lsn;	/* Structure assignment. */	__ham_putitem(dbp, hcp->page, pkey, key_type);	__ham_putitem(dbp, hcp->page, pdata, data_type);	/*	 * For splits, we are going to update item_info's page number	 * field, so that we can easily return to the same page the	 * next time we come in here.  For other operations, this shouldn't	 * matter, since odds are this is the last thing that happens before	 * we return to the user program.	 */	hcp->pgno = PGNO(hcp->page);	/*	 * XXX	 * Maybe keep incremental numbers here.	 */	if (!STD_LOCKING(dbc)) {		hcp->hdr->nelem++;		if ((ret = __ham_dirty_meta(dbc)) != 0)			return (ret);	}	if (do_expand || (hcp->hdr->ffactor != 0 &&	    (u_int32_t)H_NUMPAIRS(hcp->page) > hcp->hdr->ffactor))		F_SET(hcp, H_EXPAND);	return (0);}/* * Special __putitem call used in splitting -- copies one entry to * another.  Works for all types of hash entries (H_OFFPAGE, H_KEYDATA, * H_DUPLICATE, H_OFFDUP).  Since we log splits at a high level, we * do not need to do any logging here. * * PUBLIC: void __ham_copy_item __P((DB *, PAGE *, u_int32_t, PAGE *)); */void__ham_copy_item(dbp, src_page, src_ndx, dest_page)	DB *dbp;	PAGE *src_page;	u_int32_t src_ndx;	PAGE *dest_page;{	u_int32_t len;	size_t pgsize;	void *src, *dest;	db_indx_t *inp;	pgsize = dbp->pgsize;	inp = P_INP(dbp, dest_page);	/*	 * Copy the key and data entries onto this new page.	 */	src = P_ENTRY(dbp, src_page, src_ndx);	/* Set up space on dest. */	len = (u_int32_t)LEN_HITEM(dbp, src_page, pgsize, src_ndx);	HOFFSET(dest_page) -= len;	inp[NUM_ENT(dest_page)] = HOFFSET(dest_page);	dest = P_ENTRY(dbp, dest_page, NUM_ENT(dest_page));	NUM_ENT(dest_page)++;	memcpy(dest, src, len);}/* * * Returns: *	pointer on success *	NULL on error * * PUBLIC: int __ham_add_ovflpage __P((DBC *, PAGE *, int, PAGE **)); */int__ham_add_ovflpage(dbc, pagep, release, pp)	DBC *dbc;	PAGE *pagep;	int release;	PAGE **pp;{	DB *dbp;	DB_LSN new_lsn;	DB_MPOOLFILE *mpf;	PAGE *new_pagep;	int ret;	dbp = dbc->dbp;	mpf = dbp->mpf;	if ((ret = __db_new(dbc, P_HASH, &new_pagep)) != 0)		return (ret);	if (DBC_LOGGING(dbc)) {		if ((ret = __ham_newpage_log(dbp, dbc->txn, &new_lsn, 0,		    PUTOVFL, PGNO(pagep), &LSN(pagep),		    PGNO(new_pagep), &LSN(new_pagep), PGNO_INVALID, NULL)) != 0)			return (ret);	} else		LSN_NOT_LOGGED(new_lsn);	/* Move lsn onto page. */	LSN(pagep) = LSN(new_pagep) = new_lsn;	NEXT_PGNO(pagep) = PGNO(new_pagep);	PREV_PGNO(new_pagep) = PGNO(pagep);	if (release)		ret = mpf->put(mpf, pagep, DB_MPOOL_DIRTY);	*pp = new_pagep;	return (ret);}/* * PUBLIC: int __ham_get_cpage __P((DBC *, db_lockmode_t)); */int__ham_get_cpage(dbc, mode)	DBC *dbc;	db_lockmode_t mode;{	DB *dbp;	DB_LOCK tmp_lock;	DB_MPOOLFILE *mpf;	HASH_CURSOR *hcp;	int ret;	dbp = dbc->dbp;	mpf = dbp->mpf;	hcp = (HASH_CURSOR *)dbc->internal;	ret = 0;	/*	 * There are four cases with respect to buckets and locks.	 * 1. If there is no lock held, then if we are locking, we should	 *    get the lock.	 * 2. If there is a lock held, it's for the current bucket, and it's	 *    for the right mode, we don't need to do anything.	 * 3. If there is a lock held for the current bucket but it's not	 *    strong enough, we need to upgrade.	 * 4. If there is a lock, but it's for a different bucket, then we need	 *    to release the existing lock and get a new lock.	 */	LOCK_INIT(tmp_lock);	if (STD_LOCKING(dbc)) {		if (hcp->lbucket != hcp->bucket &&	/* Case 4 */		    (ret = __TLPUT(dbc, hcp->lock)) != 0)			return (ret);		if ((LOCK_ISSET(hcp->lock) &&		    (hcp->lock_mode == DB_LOCK_READ &&		    mode == DB_LOCK_WRITE))) {			/* Case 3. */			tmp_lock = hcp->lock;			LOCK_INIT(hcp->lock);		}		/* Acquire the lock. */		if (!LOCK_ISSET(hcp->lock))			/* Cases 1, 3, and 4. */			if ((ret = __ham_lock_bucket(dbc, mode)) != 0)				return (ret);		if (ret == 0) {			hcp->lock_mode = mode;			hcp->lbucket = hcp->bucket;			if (LOCK_ISSET(tmp_lock))				/* Case 3: release the original lock. */				ret =				    dbp->dbenv->lock_put(dbp->dbenv, &tmp_lock);		} else if (LOCK_ISSET(tmp_lock))			hcp->lock = tmp_lock;	}	if (ret == 0 && hcp->page == NULL) {		if (hcp->pgno == PGNO_INVALID)			hcp->pgno = BUCKET_TO_PAGE(hcp, hcp->bucket);		if ((ret = mpf->get(mpf,		    &hcp->pgno, DB_MPOOL_CREATE, &hcp->page)) != 0)			return (ret);	}	return (0);}/* * Get a new page at the cursor, putting the last page if necessary. * If the flag is set to H_ISDUP, then we are talking about the * duplicate page, not the main page. * * PUBLIC: int __ham_next_cpage __P((DBC *, db_pgno_t, int)); */int__ham_next_cpage(dbc, pgno, dirty)	DBC *dbc;	db_pgno_t pgno;	int dirty;{	DB *dbp;	DB_MPOOLFILE *mpf;	HASH_CURSOR *hcp;	PAGE *p;	int ret;	dbp = dbc->dbp;	mpf = dbp->mpf;	hcp = (HASH_CURSOR *)dbc->internal;	if (hcp->page != NULL &&	    (ret = mpf->put(mpf, hcp->page, dirty ? DB_MPOOL_DIRTY : 0)) != 0)		return (ret);	hcp->page = NULL;	if ((ret = mpf->get(mpf, &pgno, DB_MPOOL_CREATE, &p)) != 0)		return (ret);	hcp->page = p;	hcp->pgno = pgno;	hcp->indx = 0;	return (0);}/* * __ham_lock_bucket -- *	Get the lock on a particular bucket. * * PUBLIC: int __ham_lock_bucket __P((DBC *, db_lockmode_t)); */int__ham_lock_bucket(dbc, mode)	DBC *dbc;	db_lockmode_t mode;{	HASH_CURSOR *hcp;	db_pgno_t pgno;	int gotmeta, ret;	hcp = (HASH_CURSOR *)dbc->internal;	gotmeta = hcp->hdr == NULL ? 1 : 0;	if (gotmeta)		if ((ret = __ham_get_meta(dbc)) != 0)			return (ret);	pgno = BUCKET_TO_PAGE(hcp, hcp->bucket);	if (gotmeta)		if ((ret = __ham_release_meta(dbc)) != 0)			return (ret);	ret = __db_lget(dbc, 0, pgno, mode, 0, &hcp->lock);	hcp->lock_mode = mode;	return (ret);}/* * __ham_dpair -- *	Delete a pair on a page, paying no attention to what the pair *	represents.  The caller is responsible for freeing up duplicates *	or offpage entries that might be referenced by this pair. * *	Recovery assumes that this may be called without the metadata *	page pinned. * * PUBLIC: void __ham_dpair __P((DB *, PAGE *, u_int32_t)); */void__ham_dpair(dbp, p, indx)	DB *dbp;	PAGE *p;	u_int32_t indx;{	db_indx_t delta, n, *inp;	u_int8_t *dest, *src;	inp = P_INP(dbp, p);	/*	 * Compute "delta", the amount we have to shift all of the	 * offsets.  To find the delta, we just need to calculate	 * the size of the pair of elements we are removing.	 */	delta = H_PAIRSIZE(dbp, p, dbp->pgsize, indx);	/*	 * The hard case: we want to remove something other than	 * the last item on the page.  We need to shift data and	 * offsets down.	 */	if ((db_indx_t)indx != NUM_ENT(p) - 2) {		/*		 * Move the data: src is the first occupied byte on		 * the page. (Length is delta.)		 */		src = (u_int8_t *)p + HOFFSET(p);		/*		 * Destination is delta bytes beyond src.  This might		 * be an overlapping copy, so we have to use memmove.		 */		dest = src + delta;		memmove(dest, src, inp[H_DATAINDEX(indx)] - HOFFSET(p));	}	/* Adjust page metadata. */	HOFFSET(p) = HOFFSET(p) + delta;	NUM_ENT(p) = NUM_ENT(p) - 2;	/* Adjust the offsets. */	for (n = (db_indx_t)indx; n < (db_indx_t)(NUM_ENT(p)); n++)		inp[n] = inp[n + 2] + delta;}/* * __ham_c_delpg -- * * Adjust the cursors after we've emptied a page in a bucket, taking * care that when we move cursors pointing to deleted items, their * orders don't collide with the orders of cursors on the page we move * them to (since after this function is called, cursors with the same * index on the two pages will be otherwise indistinguishable--they'll * all have pgno new_pgno).  There are three cases: * *	1) The emptied page is the first page in the bucket.  In this *	case, we've copied all the items from the second page into the *	first page, so the first page is new_pgno and the second page is *	old_pgno.  new_pgno is empty, but can have deleted cursors *	pointing at indx 0, so we need to be careful of the orders *	there.  This is DB_HAM_DELFIRSTPG. * *	2) The page is somewhere in the middle of a bucket.  Our caller *	can just delete such a page, so it's old_pgno.  old_pgno is *	empty, but may have deleted cursors pointing at indx 0, so we *	need to be careful of indx 0 when we move those cursors to *	new_pgno.  This is DB_HAM_DELMIDPG. * *	3) The page is the last in a bucket.  Again the empty page is *	old_pgno, and again it should only have cursors that are deleted *	and at indx == 0.  This time, though, there's no next page to *	move them to, so we set them to indx == num_ent on the previous *	page--and indx == num_ent is the index whose cursors we need to *	be careful of.  This is DB_HAM_DELLASTPG. */static int__ham_c_delpg(dbc, old_pgno, new_pgno, num_ent, op, orderp)	DBC *dbc;	db_pgno_t old_pgno, new_pgno;	u_int32_t num_ent;	db_ham_mode op;	u_int32_t *orderp;{	DB *dbp, *ldbp;	DB_ENV *dbenv;	DB_LSN lsn;	DB_TXN *my_txn;	DBC *cp;	HASH_CURSOR *hcp;	int found, ret;	db_indx_t indx;	u_int32_t order;	/* Which is the worrisome index? */	indx = (op == DB_HAM_DELLASTPG) ? num_ent : 0;	dbp = dbc->dbp;	dbenv = dbp->dbenv;	my_txn = IS_SUBTRANSACTION(dbc->txn) ? dbc->txn : NULL;	found = 0;	MUTEX_THREAD_LOCK(dbenv, dbenv->dblist_mutexp);	/*	 * Find the highest order of any cursor our movement	 * may collide with.	 */	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 (cp = TAILQ_FIRST(&ldbp->active_queue); cp != NULL;		    cp = TAILQ_NEXT(cp, links)) {			if (cp == dbc || cp->dbtype != DB_HASH)				continue;			hcp = (HASH_CURSOR *)cp->internal;			if (hcp->pgno == new_pgno) {				if (hcp->indx == indx &&				    F_ISSET(hcp, H_DELETED) &&				    hcp->order >= order)					order = hcp->order + 1;				DB_ASSERT(op != DB_HAM_DELFIRSTPG ||				    hcp->indx == NDX_INVALID ||				    (hcp->indx == 0 &&				    F_ISSET(hcp, H_DELETED)));			}		}		MUTEX_THREAD_UNLOCK(dbenv, dbp->mutexp);	}	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 (cp = TAILQ_FIRST(&ldbp->active_queue); cp != NULL;		    cp = TAILQ_NEXT(cp, links)) {			if (cp == dbc || cp->dbtype != DB_HASH)				continue;			hcp = (HASH_CURSOR *)cp->internal;			if (hcp->pgno == old_pgno) {				switch (op) {				case DB_HAM_DELFIRSTPG:					/*					 * We're moving all items,					 * regardless of index.					 */					hcp->pgno = new_pgno;					/*					 * But we have to be careful of					 * the order values.					 */					if (hcp->indx == indx)						hcp->order += order;					break;				case DB_HAM_DELMIDPG:					hcp->pgno = new_pgno;					DB_ASSERT(hcp->indx == 0 &&					    F_ISSET(hcp, H_DELETED));					hcp->order += order;					break;				case DB_HAM_DELLASTPG:					hcp->pgno = new_pgno;					DB_ASSERT(hcp->indx == 0 &&					    F_ISSET(hcp, H_DELETED));					hcp->indx = indx;					hcp->order += order;					break;				default:					DB_ASSERT(0);					return (__db_panic(dbenv, EINVAL));				}				if (my_txn != NULL && cp->txn != my_txn)					found = 1;			}		}		MUTEX_THREAD_UNLOCK(dbenv, dbp->mutexp);	}	MUTEX_THREAD_UNLOCK(dbenv, dbenv->dblist_mutexp);	if (found != 0 && DBC_LOGGING(dbc)) {		if ((ret = __ham_chgpg_log(dbp, my_txn, &lsn, 0, op,		    old_pgno, new_pgno, indx, order)) != 0)			return (ret);	}	*orderp = order;	return (0);}

⌨️ 快捷键说明

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