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

📄 db_overflow.c

📁 这是linux下运行的mysql软件包,可用于linux 下安装 php + mysql + apach 的网络配置
💻 C
📖 第 1 页 / 共 2 页
字号:
 * * Given a starting page number and a key, return <0, 0, >0 to indicate if the * key on the page is less than, equal to or greater than the key specified. * We optimize this by doing chunk at a time comparison unless the user has * specified a comparison function.  In this case, we need to materialize * the entire object and call their comparison routine. * * PUBLIC: int __db_moff __P((DB *, const DBT *, db_pgno_t, u_int32_t, * PUBLIC:     int (*)(DB *, const DBT *, const DBT *), int *)); */int__db_moff(dbp, dbt, pgno, tlen, cmpfunc, cmpp)	DB *dbp;	const DBT *dbt;	db_pgno_t pgno;	u_int32_t tlen;	int (*cmpfunc) __P((DB *, const DBT *, const DBT *)), *cmpp;{	DBT local_dbt;	DB_MPOOLFILE *mpf;	PAGE *pagep;	void *buf;	u_int32_t bufsize, cmp_bytes, key_left;	u_int8_t *p1, *p2;	int ret;	mpf = dbp->mpf;	/*	 * If there is a user-specified comparison function, build a	 * contiguous copy of the key, and call it.	 */	if (cmpfunc != NULL) {		memset(&local_dbt, 0, sizeof(local_dbt));		buf = NULL;		bufsize = 0;		if ((ret = __db_goff(dbp,		    &local_dbt, tlen, pgno, &buf, &bufsize)) != 0)			return (ret);		/* Pass the key as the first argument */		*cmpp = cmpfunc(dbp, dbt, &local_dbt);		__os_free(dbp->dbenv, buf);		return (0);	}	/* While there are both keys to compare. */	for (*cmpp = 0, p1 = dbt->data,	    key_left = dbt->size; key_left > 0 && pgno != PGNO_INVALID;) {		if ((ret = mpf->get(mpf, &pgno, 0, &pagep)) != 0)			return (ret);		cmp_bytes = OV_LEN(pagep) < key_left ? OV_LEN(pagep) : key_left;		tlen -= cmp_bytes;		key_left -= cmp_bytes;		for (p2 = (u_int8_t *)pagep + P_OVERHEAD(dbp);		    cmp_bytes-- > 0; ++p1, ++p2)			if (*p1 != *p2) {				*cmpp = (long)*p1 - (long)*p2;				break;			}		pgno = NEXT_PGNO(pagep);		if ((ret = mpf->put(mpf, pagep, 0)) != 0)			return (ret);		if (*cmpp != 0)			return (0);	}	if (key_left > 0)		/* DBT is longer than the page key. */		*cmpp = 1;	else if (tlen > 0)		/* DBT is shorter than the page key. */		*cmpp = -1;	else		*cmpp = 0;	return (0);}/* * __db_vrfy_overflow -- *	Verify overflow page. * * PUBLIC: int __db_vrfy_overflow __P((DB *, VRFY_DBINFO *, PAGE *, db_pgno_t, * PUBLIC:     u_int32_t)); */int__db_vrfy_overflow(dbp, vdp, h, pgno, flags)	DB *dbp;	VRFY_DBINFO *vdp;	PAGE *h;	db_pgno_t pgno;	u_int32_t flags;{	VRFY_PAGEINFO *pip;	int isbad, ret, t_ret;	isbad = 0;	if ((ret = __db_vrfy_getpageinfo(vdp, pgno, &pip)) != 0)		return (ret);	if ((ret = __db_vrfy_datapage(dbp, vdp, h, pgno, flags)) != 0) {		if (ret == DB_VERIFY_BAD)			isbad = 1;		else			goto err;	}	pip->refcount = OV_REF(h);	if (pip->refcount < 1) {		EPRINT((dbp->dbenv,		    "Page %lu: overflow page has zero reference count",		    (u_long)pgno));		isbad = 1;	}	/* Just store for now. */	pip->olen = HOFFSET(h);err:	if ((t_ret = __db_vrfy_putpageinfo(dbp->dbenv, vdp, pip)) != 0)		ret = t_ret;	return ((ret == 0 && isbad == 1) ? DB_VERIFY_BAD : ret);}/* * __db_vrfy_ovfl_structure -- *	Walk a list of overflow pages, avoiding cycles and marking *	pages seen. * * PUBLIC: int __db_vrfy_ovfl_structure * PUBLIC:     __P((DB *, VRFY_DBINFO *, db_pgno_t, u_int32_t, u_int32_t)); */int__db_vrfy_ovfl_structure(dbp, vdp, pgno, tlen, flags)	DB *dbp;	VRFY_DBINFO *vdp;	db_pgno_t pgno;	u_int32_t tlen;	u_int32_t flags;{	DB *pgset;	VRFY_PAGEINFO *pip;	db_pgno_t next, prev;	int isbad, p, ret, t_ret;	u_int32_t refcount;	pgset = vdp->pgset;	DB_ASSERT(pgset != NULL);	isbad = 0;	/* This shouldn't happen, but just to be sure. */	if (!IS_VALID_PGNO(pgno))		return (DB_VERIFY_BAD);	/*	 * Check the first prev_pgno;  it ought to be PGNO_INVALID,	 * since there's no prev page.	 */	if ((ret = __db_vrfy_getpageinfo(vdp, pgno, &pip)) != 0)		return (ret);	/* The refcount is stored on the first overflow page. */	refcount = pip->refcount;	if (pip->type != P_OVERFLOW) {		EPRINT((dbp->dbenv,		    "Page %lu: overflow page of invalid type %lu",		    (u_long)pgno, (u_long)pip->type));		ret = DB_VERIFY_BAD;		goto err;		/* Unsafe to continue. */	}	prev = pip->prev_pgno;	if (prev != PGNO_INVALID) {		EPRINT((dbp->dbenv,	    "Page %lu: first page in overflow chain has a prev_pgno %lu",		    (u_long)pgno, (u_long)prev));		isbad = 1;	}	for (;;) {		/*		 * This is slightly gross.  Btree leaf pages reference		 * individual overflow trees multiple times if the overflow page		 * is the key to a duplicate set.  The reference count does not		 * reflect this multiple referencing.  Thus, if this is called		 * during the structure verification of a btree leaf page, we		 * check to see whether we've seen it from a leaf page before		 * and, if we have, adjust our count of how often we've seen it		 * accordingly.		 *		 * (This will screw up if it's actually referenced--and		 * correctly refcounted--from two different leaf pages, but		 * that's a very unlikely brokenness that we're not checking for		 * anyway.)		 */		if (LF_ISSET(ST_OVFL_LEAF)) {			if (F_ISSET(pip, VRFY_OVFL_LEAFSEEN)) {				if ((ret =				    __db_vrfy_pgset_dec(pgset, pgno)) != 0)					goto err;			} else				F_SET(pip, VRFY_OVFL_LEAFSEEN);		}		if ((ret = __db_vrfy_pgset_get(pgset, pgno, &p)) != 0)			goto err;		/*		 * We may have seen this elsewhere, if the overflow entry		 * has been promoted to an internal page.		 */		if ((u_int32_t)p > refcount) {			EPRINT((dbp->dbenv,			    "Page %lu: encountered twice in overflow traversal",			    (u_long)pgno));			ret = DB_VERIFY_BAD;			goto err;		}		if ((ret = __db_vrfy_pgset_inc(pgset, pgno)) != 0)			goto err;		/* Keep a running tab on how much of the item we've seen. */		tlen -= pip->olen;		/* Send feedback to the application about our progress. */		if (!LF_ISSET(DB_SALVAGE))			__db_vrfy_struct_feedback(dbp, vdp);		next = pip->next_pgno;		/* Are we there yet? */		if (next == PGNO_INVALID)			break;		/*		 * We've already checked this when we saved it, but just		 * to be sure...		 */		if (!IS_VALID_PGNO(next)) {			DB_ASSERT(0);			EPRINT((dbp->dbenv,			    "Page %lu: bad next_pgno %lu on overflow page",			    (u_long)pgno, (u_long)next));			ret = DB_VERIFY_BAD;			goto err;		}		if ((ret = __db_vrfy_putpageinfo(dbp->dbenv, vdp, pip)) != 0 ||		    (ret = __db_vrfy_getpageinfo(vdp, next, &pip)) != 0)			return (ret);		if (pip->prev_pgno != pgno) {			EPRINT((dbp->dbenv,		"Page %lu: bad prev_pgno %lu on overflow page (should be %lu)",			    (u_long)next, (u_long)pip->prev_pgno,			    (u_long)pgno));			isbad = 1;			/*			 * It's safe to continue because we have separate			 * cycle detection.			 */		}		pgno = next;	}	if (tlen > 0) {		isbad = 1;		EPRINT((dbp->dbenv,		    "Page %lu: overflow item incomplete", (u_long)pgno));	}err:	if ((t_ret =	    __db_vrfy_putpageinfo(dbp->dbenv, vdp, pip)) != 0 && ret == 0)		ret = t_ret;	return ((ret == 0 && isbad == 1) ? DB_VERIFY_BAD : ret);}/* * __db_safe_goff -- *	Get an overflow item, very carefully, from an untrusted database, *	in the context of the salvager. * * PUBLIC: int __db_safe_goff __P((DB *, VRFY_DBINFO *, db_pgno_t, * PUBLIC:     DBT *, void **, u_int32_t)); */int__db_safe_goff(dbp, vdp, pgno, dbt, buf, flags)	DB *dbp;	VRFY_DBINFO *vdp;	db_pgno_t pgno;	DBT *dbt;	void **buf;	u_int32_t flags;{	DB_MPOOLFILE *mpf;	PAGE *h;	int ret, t_ret;	u_int32_t bytesgot, bytes;	u_int8_t *src, *dest;	mpf = dbp->mpf;	h = NULL;	ret = t_ret = 0;	bytesgot = bytes = 0;	while ((pgno != PGNO_INVALID) && (IS_VALID_PGNO(pgno))) {		/*		 * Mark that we're looking at this page;  if we've seen it		 * already, quit.		 */		if ((ret = __db_salvage_markdone(vdp, pgno)) != 0)			break;		if ((ret = mpf->get(mpf, &pgno, 0, &h)) != 0)			break;		/*		 * Make sure it's really an overflow page, unless we're		 * being aggressive, in which case we pretend it is.		 */		if (!LF_ISSET(DB_AGGRESSIVE) && TYPE(h) != P_OVERFLOW) {			ret = DB_VERIFY_BAD;			break;		}		src = (u_int8_t *)h + P_OVERHEAD(dbp);		bytes = OV_LEN(h);		if (bytes + P_OVERHEAD(dbp) > dbp->pgsize)			bytes = dbp->pgsize - P_OVERHEAD(dbp);		if ((ret = __os_realloc(dbp->dbenv,		    bytesgot + bytes, buf)) != 0)			break;		dest = (u_int8_t *)*buf + bytesgot;		bytesgot += bytes;		memcpy(dest, src, bytes);		pgno = NEXT_PGNO(h);		if ((ret = mpf->put(mpf, h, 0)) != 0)			break;		h = NULL;	}	/*	 * If we're being aggressive, salvage a partial datum if there	 * was an error somewhere along the way.	 */	if (ret == 0 || LF_ISSET(DB_AGGRESSIVE)) {		dbt->size = bytesgot;		dbt->data = *buf;	}	/* If we broke out on error, don't leave pages pinned. */	if (h != NULL && (t_ret = mpf->put(mpf, h, 0)) != 0 && ret == 0)		ret = t_ret;	return (ret);}

⌨️ 快捷键说明

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