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

📄 hash_page.c

📁 这是linux下运行的mysql软件包,可用于linux 下安装 php + mysql + apach 的网络配置
💻 C
📖 第 1 页 / 共 4 页
字号:
/*- * See the file LICENSE for redistribution information. * * Copyright (c) 1996-2002 *	Sleepycat Software.  All rights reserved. *//* * Copyright (c) 1990, 1993, 1994 *	Margo Seltzer.  All rights reserved. *//* * Copyright (c) 1990, 1993, 1994 *	The Regents of the University of California.  All rights reserved. * * This code is derived from software contributed to Berkeley by * Margo Seltzer. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */#include "db_config.h"#ifndef lintstatic const char revid[] = "$Id: hash_page.c,v 11.87 2002/08/15 02:46:20 bostic Exp $";#endif /* not lint *//* * PACKAGE:  hashing * * DESCRIPTION: *	Page manipulation for hashing package. */#ifndef NO_SYSTEM_INCLUDES#include <sys/types.h>#include <string.h>#endif#include "db_int.h"#include "dbinc/db_page.h"#include "dbinc/db_shash.h"#include "dbinc/hash.h"#include "dbinc/lock.h"static int __ham_c_delpg    __P((DBC *, db_pgno_t, db_pgno_t, u_int32_t, db_ham_mode, u_int32_t *));/* * PUBLIC: int __ham_item __P((DBC *, db_lockmode_t, db_pgno_t *)); */int__ham_item(dbc, mode, pgnop)	DBC *dbc;	db_lockmode_t mode;	db_pgno_t *pgnop;{	DB *dbp;	HASH_CURSOR *hcp;	db_pgno_t next_pgno;	int ret;	dbp = dbc->dbp;	hcp = (HASH_CURSOR *)dbc->internal;	if (F_ISSET(hcp, H_DELETED)) {		__db_err(dbp->dbenv, "Attempt to return a deleted item");		return (EINVAL);	}	F_CLR(hcp, H_OK | H_NOMORE);	/* Check if we need to get a page for this cursor. */	if ((ret = __ham_get_cpage(dbc, mode)) != 0)		return (ret);recheck:	/* Check if we are looking for space in which to insert an item. */	if (hcp->seek_size && hcp->seek_found_page == PGNO_INVALID &&	    hcp->seek_size < P_FREESPACE(dbp, hcp->page))		hcp->seek_found_page = hcp->pgno;	/* Check for off-page duplicates. */	if (hcp->indx < NUM_ENT(hcp->page) &&	    HPAGE_TYPE(dbp, hcp->page, H_DATAINDEX(hcp->indx)) == H_OFFDUP) {		memcpy(pgnop,		    HOFFDUP_PGNO(H_PAIRDATA(dbp, hcp->page, hcp->indx)),		    sizeof(db_pgno_t));		F_SET(hcp, H_OK);		return (0);	}	/* Check if we need to go on to the next page. */	if (F_ISSET(hcp, H_ISDUP))		/*		 * ISDUP is set, and offset is at the beginning of the datum.		 * We need to grab the length of the datum, then set the datum		 * pointer to be the beginning of the datum.		 */		memcpy(&hcp->dup_len,		    HKEYDATA_DATA(H_PAIRDATA(dbp, hcp->page, hcp->indx)) +		    hcp->dup_off, sizeof(db_indx_t));	if (hcp->indx >= (db_indx_t)NUM_ENT(hcp->page)) {		/* Fetch next page. */		if (NEXT_PGNO(hcp->page) == PGNO_INVALID) {			F_SET(hcp, H_NOMORE);			return (DB_NOTFOUND);		}		next_pgno = NEXT_PGNO(hcp->page);		hcp->indx = 0;		if ((ret = __ham_next_cpage(dbc, next_pgno, 0)) != 0)			return (ret);		goto recheck;	}	F_SET(hcp, H_OK);	return (0);}/* * PUBLIC: int __ham_item_reset __P((DBC *)); */int__ham_item_reset(dbc)	DBC *dbc;{	DB *dbp;	DB_MPOOLFILE *mpf;	HASH_CURSOR *hcp;	int ret;	dbp = dbc->dbp;	mpf = dbp->mpf;	hcp = (HASH_CURSOR *)dbc->internal;	ret = 0;	if (hcp->page != NULL)		ret = mpf->put(mpf, hcp->page, 0);	__ham_item_init(dbc);	return (ret);}/* * PUBLIC: void __ham_item_init __P((DBC *)); */void__ham_item_init(dbc)	DBC *dbc;{	HASH_CURSOR *hcp;	hcp = (HASH_CURSOR *)dbc->internal;	/*	 * If this cursor still holds any locks, we must	 * release them if we are not running with transactions.	 */	(void)__TLPUT(dbc, hcp->lock);	/*	 * The following fields must *not* be initialized here	 * because they may have meaning across inits.	 *	hlock, hdr, split_buf, stats	 */	hcp->bucket = BUCKET_INVALID;	hcp->lbucket = BUCKET_INVALID;	LOCK_INIT(hcp->lock);	hcp->lock_mode = DB_LOCK_NG;	hcp->dup_off = 0;	hcp->dup_len = 0;	hcp->dup_tlen = 0;	hcp->seek_size = 0;	hcp->seek_found_page = PGNO_INVALID;	hcp->flags = 0;	hcp->pgno = PGNO_INVALID;	hcp->indx = NDX_INVALID;	hcp->page = NULL;}/* * Returns the last item in a bucket. * * PUBLIC: int __ham_item_last __P((DBC *, db_lockmode_t, db_pgno_t *)); */int__ham_item_last(dbc, mode, pgnop)	DBC *dbc;	db_lockmode_t mode;	db_pgno_t *pgnop;{	HASH_CURSOR *hcp;	int ret;	hcp = (HASH_CURSOR *)dbc->internal;	if ((ret = __ham_item_reset(dbc)) != 0)		return (ret);	hcp->bucket = hcp->hdr->max_bucket;	hcp->pgno = BUCKET_TO_PAGE(hcp, hcp->bucket);	F_SET(hcp, H_OK);	return (__ham_item_prev(dbc, mode, pgnop));}/* * PUBLIC: int __ham_item_first __P((DBC *, db_lockmode_t, db_pgno_t *)); */int__ham_item_first(dbc, mode, pgnop)	DBC *dbc;	db_lockmode_t mode;	db_pgno_t *pgnop;{	HASH_CURSOR *hcp;	int ret;	hcp = (HASH_CURSOR *)dbc->internal;	if ((ret = __ham_item_reset(dbc)) != 0)		return (ret);	F_SET(hcp, H_OK);	hcp->bucket = 0;	hcp->pgno = BUCKET_TO_PAGE(hcp, hcp->bucket);	return (__ham_item_next(dbc, mode, pgnop));}/* * __ham_item_prev -- *	Returns a pointer to key/data pair on a page.  In the case of *	bigkeys, just returns the page number and index of the bigkey *	pointer pair. * * PUBLIC: int __ham_item_prev __P((DBC *, db_lockmode_t, db_pgno_t *)); */int__ham_item_prev(dbc, mode, pgnop)	DBC *dbc;	db_lockmode_t mode;	db_pgno_t *pgnop;{	DB *dbp;	HASH_CURSOR *hcp;	db_pgno_t next_pgno;	int ret;	hcp = (HASH_CURSOR *)dbc->internal;	dbp = dbc->dbp;	/*	 * There are 5 cases for backing up in a hash file.	 * Case 1: In the middle of a page, no duplicates, just dec the index.	 * Case 2: In the middle of a duplicate set, back up one.	 * Case 3: At the beginning of a duplicate set, get out of set and	 *	back up to next key.	 * Case 4: At the beginning of a page; go to previous page.	 * Case 5: At the beginning of a bucket; go to prev bucket.	 */	F_CLR(hcp, H_OK | H_NOMORE | H_DELETED);	if ((ret = __ham_get_cpage(dbc, mode)) != 0)		return (ret);	/*	 * First handle the duplicates.  Either you'll get the key here	 * or you'll exit the duplicate set and drop into the code below	 * to handle backing up through keys.	 */	if (!F_ISSET(hcp, H_NEXT_NODUP) && F_ISSET(hcp, H_ISDUP)) {		if (HPAGE_TYPE(dbp, hcp->page, H_DATAINDEX(hcp->indx)) ==		    H_OFFDUP) {			memcpy(pgnop,			    HOFFDUP_PGNO(H_PAIRDATA(dbp, hcp->page, hcp->indx)),			    sizeof(db_pgno_t));			F_SET(hcp, H_OK);			return (0);		}		/* Duplicates are on-page. */		if (hcp->dup_off != 0) {			memcpy(&hcp->dup_len, HKEYDATA_DATA(			    H_PAIRDATA(dbp, hcp->page, hcp->indx))			    + hcp->dup_off - sizeof(db_indx_t),			    sizeof(db_indx_t));			hcp->dup_off -=			    DUP_SIZE(hcp->dup_len);			return (__ham_item(dbc, mode, pgnop));		}	}	/*	 * If we get here, we are not in a duplicate set, and just need	 * to back up the cursor.  There are still three cases:	 * midpage, beginning of page, beginning of bucket.	 */	if (F_ISSET(hcp, H_DUPONLY)) {		F_CLR(hcp, H_OK);		F_SET(hcp, H_NOMORE);		return (0);	} else		/*		 * We are no longer in a dup set;  flag this so the dup code		 * will reinitialize should we stumble upon another one.		 */		F_CLR(hcp, H_ISDUP);	if (hcp->indx == 0) {		/* Beginning of page. */		hcp->pgno = PREV_PGNO(hcp->page);		if (hcp->pgno == PGNO_INVALID) {			/* Beginning of bucket. */			F_SET(hcp, H_NOMORE);			return (DB_NOTFOUND);		} else if ((ret =		    __ham_next_cpage(dbc, hcp->pgno, 0)) != 0)			return (ret);		else			hcp->indx = NUM_ENT(hcp->page);	}	/*	 * Either we've got the cursor set up to be decremented, or we	 * have to find the end of a bucket.	 */	if (hcp->indx == NDX_INVALID) {		DB_ASSERT(hcp->page != NULL);		hcp->indx = NUM_ENT(hcp->page);		for (next_pgno = NEXT_PGNO(hcp->page);		    next_pgno != PGNO_INVALID;		    next_pgno = NEXT_PGNO(hcp->page)) {			if ((ret = __ham_next_cpage(dbc, next_pgno, 0)) != 0)				return (ret);			hcp->indx = NUM_ENT(hcp->page);		}		if (hcp->indx == 0) {			/* Bucket was empty. */			F_SET(hcp, H_NOMORE);			return (DB_NOTFOUND);		}	}	hcp->indx -= 2;	return (__ham_item(dbc, mode, pgnop));}/* * Sets the cursor to the next key/data pair on a page. * * PUBLIC: int __ham_item_next __P((DBC *, db_lockmode_t, db_pgno_t *)); */int__ham_item_next(dbc, mode, pgnop)	DBC *dbc;	db_lockmode_t mode;	db_pgno_t *pgnop;{	HASH_CURSOR *hcp;	int ret;	hcp = (HASH_CURSOR *)dbc->internal;	if ((ret = __ham_get_cpage(dbc, mode)) != 0)		return (ret);	/*	 * Deleted on-page duplicates are a weird case. If we delete the last	 * one, then our cursor is at the very end of a duplicate set and	 * we actually need to go on to the next key.	 */	if (F_ISSET(hcp, H_DELETED)) {		if (hcp->indx != NDX_INVALID &&		    F_ISSET(hcp, H_ISDUP) &&		    HPAGE_TYPE(dbc->dbp, hcp->page, H_DATAINDEX(hcp->indx))			== H_DUPLICATE && hcp->dup_tlen == hcp->dup_off) {			if (F_ISSET(hcp, H_DUPONLY)) {				F_CLR(hcp, H_OK);				F_SET(hcp, H_NOMORE);				return (0);			} else {				F_CLR(hcp, H_ISDUP);				hcp->indx += 2;			}		} else if (!F_ISSET(hcp, H_ISDUP) && F_ISSET(hcp, H_DUPONLY)) {			F_CLR(hcp, H_OK);			F_SET(hcp, H_NOMORE);			return (0);		} else if (F_ISSET(hcp, H_ISDUP) &&		    F_ISSET(hcp, H_NEXT_NODUP)) {			F_CLR(hcp, H_ISDUP);			hcp->indx += 2;		}		F_CLR(hcp, H_DELETED);	} else if (hcp->indx == NDX_INVALID) {		hcp->indx = 0;		F_CLR(hcp, H_ISDUP);	} else if (F_ISSET(hcp, H_NEXT_NODUP)) {		hcp->indx += 2;		F_CLR(hcp, H_ISDUP);	} else if (F_ISSET(hcp, H_ISDUP) && hcp->dup_tlen != 0) {		if (hcp->dup_off + DUP_SIZE(hcp->dup_len) >=		    hcp->dup_tlen && F_ISSET(hcp, H_DUPONLY)) {			F_CLR(hcp, H_OK);			F_SET(hcp, H_NOMORE);			return (0);		}		hcp->dup_off += DUP_SIZE(hcp->dup_len);		if (hcp->dup_off >= hcp->dup_tlen) {			F_CLR(hcp, H_ISDUP);			hcp->indx += 2;		}	} else if (F_ISSET(hcp, H_DUPONLY)) {		F_CLR(hcp, H_OK);		F_SET(hcp, H_NOMORE);		return (0);	} else {		hcp->indx += 2;		F_CLR(hcp, H_ISDUP);	}	return (__ham_item(dbc, mode, pgnop));}/* * PUBLIC: void __ham_putitem __P((DB *, PAGE *p, const DBT *, int)); * * This is a little bit sleazy in that we're overloading the meaning * of the H_OFFPAGE type here.  When we recover deletes, we have the * entire entry instead of having only the DBT, so we'll pass type * H_OFFPAGE to mean, "copy the whole entry" as opposed to constructing * an H_KEYDATA around it. */void__ham_putitem(dbp, p, dbt, type)	DB *dbp;	PAGE *p;	const DBT *dbt;	int type;{	u_int16_t n, off;	db_indx_t *inp;	n = NUM_ENT(p);	inp = P_INP(dbp, p);

⌨️ 快捷键说明

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