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

📄 hash_rec.c

📁 这是国外的resip协议栈
💻 C
📖 第 1 页 / 共 3 页
字号:
/*- * See the file LICENSE for redistribution information. * * Copyright (c) 1996-2004 *	Sleepycat Software.  All rights reserved. *//* * Copyright (c) 1995, 1996 *	Margo Seltzer.  All rights reserved. *//* * Copyright (c) 1995, 1996 *	The President and Fellows of Harvard University.  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. * * $Id: hash_rec.c,v 11.83 2004/10/25 16:52:13 ubell Exp $ */#include "db_config.h"#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/btree.h"#include "dbinc/hash.h"#include "dbinc/log.h"#include "dbinc/mp.h"static int __ham_alloc_pages __P((DB *, __ham_groupalloc_args *, DB_LSN *));/* * __ham_insdel_recover -- * * PUBLIC: int __ham_insdel_recover * PUBLIC:     __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *)); */int__ham_insdel_recover(dbenv, dbtp, lsnp, op, info)	DB_ENV *dbenv;	DBT *dbtp;	DB_LSN *lsnp;	db_recops op;	void *info;{	__ham_insdel_args *argp;	DB *file_dbp;	DBC *dbc;	DB_MPOOLFILE *mpf;	PAGE *pagep;	u_int32_t flags, opcode;	int cmp_n, cmp_p, ret, type;	pagep = NULL;	COMPQUIET(info, NULL);	REC_PRINT(__ham_insdel_print);	REC_INTRO(__ham_insdel_read, 1);	if ((ret = __memp_fget(mpf, &argp->pgno, 0, &pagep)) != 0) {		if (DB_UNDO(op)) {			if (ret == DB_PAGE_NOTFOUND)				goto done;			else {				ret = __db_pgerr(file_dbp, argp->pgno, ret);				goto out;			}		}#ifdef HAVE_FTRUNCATE		/* If the page is not here then it was later truncated. */		if (!IS_ZERO_LSN(argp->pagelsn))			goto done;#endif		/*		 * This page was created by a group allocation and		 * the file may not have been extend yet.		 * Create the page if necessary.		 */		if ((ret = __memp_fget(mpf,		     &argp->pgno, DB_MPOOL_CREATE, &pagep)) != 0) {			ret = __db_pgerr(file_dbp, argp->pgno, ret);			goto out;		}	}	cmp_n = log_compare(lsnp, &LSN(pagep));	cmp_p = log_compare(&LSN(pagep), &argp->pagelsn);	CHECK_LSN(op, cmp_p, &LSN(pagep), &argp->pagelsn);	/*	 * Two possible things going on:	 * redo a delete/undo a put: delete the item from the page.	 * redo a put/undo a delete: add the item to the page.	 * If we are undoing a delete, then the information logged is the	 * entire entry off the page, not just the data of a dbt.  In	 * this case, we want to copy it back onto the page verbatim.	 * We do this by calling __putitem with the type H_OFFPAGE instead	 * of H_KEYDATA.	 */	opcode = OPCODE_OF(argp->opcode);	flags = 0;	if ((opcode == DELPAIR && cmp_n == 0 && DB_UNDO(op)) ||	    (opcode == PUTPAIR && cmp_p == 0 && DB_REDO(op))) {		/*		 * Need to redo a PUT or undo a delete.  If we are undoing a		 * delete, we've got to restore the item back to its original		 * position.  That's a royal pain in the butt (because we do		 * not store item lengths on the page), but there's no choice.		 */		if (opcode != DELPAIR ||		    argp->ndx == (u_int32_t)NUM_ENT(pagep)) {			__ham_putitem(file_dbp, pagep, &argp->key,			    DB_UNDO(op) || PAIR_ISKEYBIG(argp->opcode) ?			    H_OFFPAGE : H_KEYDATA);			if (PAIR_ISDATADUP(argp->opcode))				type = H_DUPLICATE;			else if (DB_UNDO(op) || PAIR_ISDATABIG(argp->opcode))				type = H_OFFPAGE;			else				type = H_KEYDATA;			__ham_putitem(file_dbp, pagep, &argp->data, type);		} else			__ham_reputpair(file_dbp, pagep,			    argp->ndx, &argp->key, &argp->data);		LSN(pagep) = DB_REDO(op) ? *lsnp : argp->pagelsn;		flags = DB_MPOOL_DIRTY;	} else if ((opcode == DELPAIR && cmp_p == 0 && DB_REDO(op)) ||	    (opcode == PUTPAIR && cmp_n == 0 && DB_UNDO(op))) {		/* Need to undo a put or redo a delete. */		__ham_dpair(file_dbp, pagep, argp->ndx);		LSN(pagep) = DB_REDO(op) ? *lsnp : argp->pagelsn;		flags = DB_MPOOL_DIRTY;	}	if ((ret = __memp_fput(mpf, pagep, flags)) != 0)		goto out;	pagep = NULL;	/* Return the previous LSN. */done:	*lsnp = argp->prev_lsn;	ret = 0;out:	if (pagep != NULL)		(void)__memp_fput(mpf, pagep, 0);	REC_CLOSE;}/* * __ham_newpage_recover -- *	This log message is used when we add/remove overflow pages.  This *	message takes care of the pointer chains, not the data on the pages. * * PUBLIC: int __ham_newpage_recover * PUBLIC:     __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *)); */int__ham_newpage_recover(dbenv, dbtp, lsnp, op, info)	DB_ENV *dbenv;	DBT *dbtp;	DB_LSN *lsnp;	db_recops op;	void *info;{	__ham_newpage_args *argp;	DB *file_dbp;	DBC *dbc;	DB_MPOOLFILE *mpf;	PAGE *pagep;	u_int32_t flags;	int cmp_n, cmp_p, ret;	pagep = NULL;	COMPQUIET(info, NULL);	REC_PRINT(__ham_newpage_print);	REC_INTRO(__ham_newpage_read, 1);	REC_FGET(mpf, argp->new_pgno, &pagep, ppage);	/*	 * There are potentially three pages we need to check: the one	 * that we created/deleted, the one before it and the one after	 * it.	 */	cmp_n = log_compare(lsnp, &LSN(pagep));	cmp_p = log_compare(&LSN(pagep), &argp->pagelsn);	CHECK_LSN(op, cmp_p, &LSN(pagep), &argp->pagelsn);	flags = 0;	if ((cmp_p == 0 && DB_REDO(op) && argp->opcode == PUTOVFL) ||	    (cmp_n == 0 && DB_UNDO(op) && argp->opcode == DELOVFL)) {		/* Redo a create new page or undo a delete new page. */		P_INIT(pagep, file_dbp->pgsize, argp->new_pgno,		    argp->prev_pgno, argp->next_pgno, 0, P_HASH);		flags = DB_MPOOL_DIRTY;	} else if ((cmp_p == 0 && DB_REDO(op) && argp->opcode == DELOVFL) ||	    (cmp_n == 0 && DB_UNDO(op) && argp->opcode == PUTOVFL)) {		/*		 * Redo a delete or undo a create new page.  All we		 * really need to do is change the LSN.		 */		flags = DB_MPOOL_DIRTY;	}	if (flags)		LSN(pagep) = DB_REDO(op) ? *lsnp : argp->pagelsn;	if ((ret = __memp_fput(mpf, pagep, flags)) != 0)		goto out;	pagep = NULL;	/* Now do the prev page. */ppage:	if (argp->prev_pgno != PGNO_INVALID) {		REC_FGET(mpf, argp->prev_pgno, &pagep, npage);		cmp_n = log_compare(lsnp, &LSN(pagep));		cmp_p = log_compare(&LSN(pagep), &argp->prevlsn);		CHECK_LSN(op, cmp_p, &LSN(pagep), &argp->prevlsn);		flags = 0;		if ((cmp_p == 0 && DB_REDO(op) && argp->opcode == PUTOVFL) ||		    (cmp_n == 0 && DB_UNDO(op) && argp->opcode == DELOVFL)) {			/* Redo a create new page or undo a delete new page. */			pagep->next_pgno = argp->new_pgno;			flags = DB_MPOOL_DIRTY;		} else if ((cmp_p == 0 &&		    DB_REDO(op) && argp->opcode == DELOVFL) ||		    (cmp_n == 0 && DB_UNDO(op) && argp->opcode == PUTOVFL)) {			/* Redo a delete or undo a create new page. */			pagep->next_pgno = argp->next_pgno;			flags = DB_MPOOL_DIRTY;		}		if (flags)			LSN(pagep) = DB_REDO(op) ? *lsnp : argp->prevlsn;		if ((ret = __memp_fput(mpf, pagep, flags)) != 0)			goto out;		pagep = NULL;	}	/* Now time to do the next page */npage:	if (argp->next_pgno != PGNO_INVALID) {		REC_FGET(mpf, argp->next_pgno, &pagep, done);		cmp_n = log_compare(lsnp, &LSN(pagep));		cmp_p = log_compare(&LSN(pagep), &argp->nextlsn);		CHECK_LSN(op, cmp_p, &LSN(pagep), &argp->nextlsn);		flags = 0;		if ((cmp_p == 0 && DB_REDO(op) && argp->opcode == PUTOVFL) ||		    (cmp_n == 0 && DB_UNDO(op) && argp->opcode == DELOVFL)) {			/* Redo a create new page or undo a delete new page. */			pagep->prev_pgno = argp->new_pgno;			flags = DB_MPOOL_DIRTY;		} else if ((cmp_p == 0 &&		    DB_REDO(op) && argp->opcode == DELOVFL) ||		    (cmp_n == 0 && DB_UNDO(op) && argp->opcode == PUTOVFL)) {			/* Redo a delete or undo a create new page. */			pagep->prev_pgno = argp->prev_pgno;			flags = DB_MPOOL_DIRTY;		}		if (flags)			LSN(pagep) = DB_REDO(op) ? *lsnp : argp->nextlsn;		if ((ret = __memp_fput(mpf, pagep, flags)) != 0)			goto out;		pagep = NULL;	}done:	*lsnp = argp->prev_lsn;	ret = 0;out:	if (pagep != NULL)		(void)__memp_fput(mpf, pagep, 0);	REC_CLOSE;}/* * __ham_replace_recover -- *	This log message refers to partial puts that are local to a single *	page.  You can think of them as special cases of the more general *	insdel log message. * * PUBLIC: int __ham_replace_recover * PUBLIC:    __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *)); */int__ham_replace_recover(dbenv, dbtp, lsnp, op, info)	DB_ENV *dbenv;	DBT *dbtp;	DB_LSN *lsnp;	db_recops op;	void *info;{	__ham_replace_args *argp;	DB *file_dbp;	DBC *dbc;	DB_MPOOLFILE *mpf;	DBT dbt;	PAGE *pagep;	u_int32_t flags;	u_int32_t change;	int cmp_n, cmp_p, is_plus, ret;	u_int8_t *hk;	pagep = NULL;	COMPQUIET(info, NULL);	REC_PRINT(__ham_replace_print);	REC_INTRO(__ham_replace_read, 1);	REC_FGET(mpf, argp->pgno, &pagep, done);	cmp_n = log_compare(lsnp, &LSN(pagep));	cmp_p = log_compare(&LSN(pagep), &argp->pagelsn);	CHECK_LSN(op, cmp_p, &LSN(pagep), &argp->pagelsn);	memset(&dbt, 0, sizeof(dbt));	flags = 0;	/*	 * Before we know the direction of the transformation we will	 * determine the size differential; then once we know if we are	 * redoing or undoing, we'll adjust the sign (is_plus) appropriately.	 */	if (argp->newitem.size > argp->olditem.size) {		change = argp->newitem.size - argp->olditem.size;		is_plus = 1;	} else {		change = argp->olditem.size - argp->newitem.size;		is_plus = 0;	}	if (cmp_p == 0 && DB_REDO(op)) {		/* Reapply the change as specified. */		dbt.data = argp->newitem.data;		dbt.size = argp->newitem.size;		LSN(pagep) = *lsnp;		/*		 * The is_plus flag is set properly to reflect		 * newitem.size - olditem.size.		 */		flags = DB_MPOOL_DIRTY;	} else if (cmp_n == 0 && DB_UNDO(op)) {		/* Undo the already applied change. */		dbt.data = argp->olditem.data;		dbt.size = argp->olditem.size;		/*		 * Invert is_plus to reflect sign of		 * olditem.size - newitem.size.		 */		is_plus = !is_plus;		LSN(pagep) = argp->pagelsn;		flags = DB_MPOOL_DIRTY;	}	if (flags) {		__ham_onpage_replace(file_dbp, pagep,		    argp->ndx, argp->off, change, is_plus, &dbt);		if (argp->makedup) {			hk = P_ENTRY(file_dbp, pagep, argp->ndx);			if (DB_REDO(op))				HPAGE_PTYPE(hk) = H_DUPLICATE;			else				HPAGE_PTYPE(hk) = H_KEYDATA;		}

⌨️ 快捷键说明

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