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

📄 hash_rec.c

📁 这是国外的resip协议栈
💻 C
📖 第 1 页 / 共 3 页
字号:
		else if (cmp_n == 0 && DB_UNDO(op))			mmeta->lsn = argp->mmetalsn;	} else		mmeta = (DBMETA *)hcp->hdr;#ifdef HAVE_FTRUNCATE	if (cmp_n == 0 && DB_UNDO(op))		mmeta->last_pgno = argp->last_pgno;	else if (DB_REDO(op))#endif	if (mmeta->last_pgno < pgno)		mmeta->last_pgno = pgno;	mmeta_flags = DB_MPOOL_DIRTY;	if (argp->mmpgno != argp->mpgno &&	    (ret = __memp_fput(mpf, mmeta, mmeta_flags)) != 0)		goto out;	mmeta = NULL;	if (did_recover)		F_SET(hcp, H_DIRTY);done:	*lsnp = argp->prev_lsn;	ret = 0;out:	if (mmeta != NULL)		(void)__memp_fput(mpf, mmeta, 0);	if (dbc != NULL)		(void)__ham_release_meta(dbc);	if (ret == ENOENT && op == DB_TXN_BACKWARD_ALLOC)		ret = 0;	REC_CLOSE;}/* * __ham_groupalloc_recover -- *	Recover the batch creation of a set of pages for a new database. * * PUBLIC: int __ham_groupalloc_recover * PUBLIC:   __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *)); */int__ham_groupalloc_recover(dbenv, dbtp, lsnp, op, info)	DB_ENV *dbenv;	DBT *dbtp;	DB_LSN *lsnp;	db_recops op;	void *info;{	__ham_groupalloc_args *argp;	DBMETA *mmeta;	DB_MPOOLFILE *mpf;	DB *file_dbp;	DBC *dbc;	PAGE *pagep;	db_pgno_t pgno;	int cmp_n, cmp_p, modified, ret;	mmeta = NULL;	modified = 0;	REC_PRINT(__ham_groupalloc_print);	REC_INTRO(__ham_groupalloc_read, 0);	pgno = PGNO_BASE_MD;	if ((ret = __memp_fget(mpf, &pgno, 0, &mmeta)) != 0) {		if (DB_REDO(op)) {			ret = __db_pgerr(file_dbp, pgno, ret);			goto out;		} else			goto done;	}	cmp_n = log_compare(lsnp, &LSN(mmeta));	cmp_p = log_compare(&LSN(mmeta), &argp->meta_lsn);	CHECK_LSN(op, cmp_p, &LSN(mmeta), &argp->meta_lsn);	/*	 * Basically, we used mpool to allocate a chunk of pages.	 * We need to either add those to a free list (in the undo	 * case) or initialize them (in the redo case).	 *	 * If we are redoing and this is a hash subdatabase, it's possible	 * that the pages were never allocated, so we'd better check for	 * that and handle it here.	 */	pgno = argp->start_pgno + argp->num - 1;	if (DB_REDO(op)) {		if ((ret = __ham_alloc_pages(file_dbp, argp, lsnp)) != 0)			goto out;		if (cmp_p == 0) {			LSN(mmeta) = *lsnp;			modified = 1;		}	} else if (DB_UNDO(op)) {		/*		 * Fetch the last page and determine if it is in		 * the post allocation state.		 */		pagep = NULL;		if ((ret = __memp_fget(mpf, &pgno, 0, &pagep)) == 0) {			if (log_compare(&pagep->lsn, lsnp) != 0) {				if ((ret = __memp_fput(mpf,				     pagep, DB_MPOOL_DISCARD)) != 0)					goto out;				pagep = NULL;			}		} else if (ret != DB_PAGE_NOTFOUND)			goto out;#ifdef HAVE_FTRUNCATE		COMPQUIET(info, NULL);		/*		 * If the last page was allocated then truncate back		 * to the first page.		 */		if (pagep != NULL) {			if ((ret =			    __memp_fput(mpf, pagep, DB_MPOOL_DISCARD)) != 0)				goto out;			if ((ret =			     __memp_ftruncate(mpf, argp->start_pgno, 0)) != 0)				goto out;		}		/*		 * If we are rolling back the metapage, then make		 * sure it reflects the the correct last_pgno.		 */		if (cmp_n == 0) {			mmeta->last_pgno = argp->last_pgno;			modified = 1;		}		pgno = 0;#else		/*		 * Reset the last page back to its preallocation state.		 */		if (pagep != NULL) {			if (log_compare(&pagep->lsn, lsnp) == 0)				ZERO_LSN(pagep->lsn);			if ((ret =			    __memp_fput(mpf, pagep, DB_MPOOL_DIRTY)) != 0)				goto out;		}		/*		 * Put the pages into the limbo list and free them later.		 */		if ((ret = __db_add_limbo(dbenv,		    info, argp->fileid, argp->start_pgno, argp->num)) != 0)			goto out;#endif		if (cmp_n == 0) {			LSN(mmeta) = argp->meta_lsn;			modified = 1;		}	}	/*	 * In both REDO and UNDO, we have grown the file and need to make	 * sure that last_pgno is correct.  If we HAVE_FTRUNCATE pgno	 * will only be valid on REDO.	 */	if (pgno > mmeta->last_pgno) {		mmeta->last_pgno = pgno;		modified = 1;	}done:	if (ret == 0)		*lsnp = argp->prev_lsn;	ret = 0;out:	if (mmeta != NULL)		(void)__memp_fput(mpf, mmeta, modified ? DB_MPOOL_DIRTY : 0);	if (ret == ENOENT && op == DB_TXN_BACKWARD_ALLOC)		ret = 0;	REC_CLOSE;}/* * __ham_alloc_pages -- * * Called during redo of a file create.  We create new pages in the file * using the MPOOL_NEW_GROUP flag.  We then log the meta-data page with a * __crdel_metasub message.  If we manage to crash without the newly written * pages getting to disk (I'm not sure this can happen anywhere except our * test suite?!), then we need to go through a recreate the final pages. * Hash normally has holes in its files and handles them appropriately. */static int__ham_alloc_pages(dbp, argp, lsnp)	DB *dbp;	__ham_groupalloc_args *argp;	DB_LSN *lsnp;{	DB_MPOOLFILE *mpf;	PAGE *pagep;	db_pgno_t pgno;	int ret;	mpf = dbp->mpf;	/* Read the last page of the allocation. */	pgno = argp->start_pgno + argp->num - 1;	/* If the page exists, and it has been initialized, then we're done. */	if ((ret = __memp_fget(mpf, &pgno, 0, &pagep)) == 0) {		if (NUM_ENT(pagep) == 0 && IS_ZERO_LSN(pagep->lsn))			goto reinit_page;		if ((ret = __memp_fput(mpf, pagep, 0)) != 0)			return (ret);		return (0);	}	/* Had to create the page. */	if ((ret = __memp_fget(mpf, &pgno, DB_MPOOL_CREATE, &pagep)) != 0)		return (__db_pgerr(dbp, pgno, ret));reinit_page:	/* Initialize the newly allocated page. */	P_INIT(pagep, dbp->pgsize, pgno, PGNO_INVALID, PGNO_INVALID, 0, P_HASH);	pagep->lsn = *lsnp;	if ((ret = __memp_fput(mpf, pagep, DB_MPOOL_DIRTY)) != 0)		return (ret);	return (0);}/* * __ham_curadj_recover -- *	Undo cursor adjustments if a subtransaction fails. * * PUBLIC: int __ham_curadj_recover * PUBLIC:   __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *)); */int__ham_curadj_recover(dbenv, dbtp, lsnp, op, info)	DB_ENV *dbenv;	DBT *dbtp;	DB_LSN *lsnp;	db_recops op;	void *info;{	__ham_curadj_args *argp;	DB_MPOOLFILE *mpf;	DB *file_dbp;	DBC *dbc;	int ret;	HASH_CURSOR *hcp;	COMPQUIET(info, NULL);	REC_PRINT(__ham_curadj_print);	REC_INTRO(__ham_curadj_read, 0);	if (op != DB_TXN_ABORT)		goto done;	/*	 * Undo the adjustment by reinitializing the the cursor to look like	 * the one that was used to do the adjustment, then we invert the	 * add so that undo the adjustment.	 */	hcp = (HASH_CURSOR *)dbc->internal;	hcp->pgno = argp->pgno;	hcp->indx = argp->indx;	hcp->dup_off = argp->dup_off;	hcp->order = argp->order;	if (!argp->add)		F_SET(hcp, H_DELETED);	(void)__ham_c_update(dbc, argp->len, !argp->add, argp->is_dup);done:	*lsnp = argp->prev_lsn;out:	REC_CLOSE;}/* * __ham_chgpg_recover -- *	Undo cursor adjustments if a subtransaction fails. * * PUBLIC: int __ham_chgpg_recover * PUBLIC:   __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *)); */int__ham_chgpg_recover(dbenv, dbtp, lsnp, op, info)	DB_ENV *dbenv;	DBT *dbtp;	DB_LSN *lsnp;	db_recops op;	void *info;{	__ham_chgpg_args *argp;	BTREE_CURSOR *opdcp;	DB_MPOOLFILE *mpf;	DB *file_dbp, *ldbp;	DBC *dbc;	int ret;	DBC *cp;	HASH_CURSOR *lcp;	u_int32_t order, indx;	COMPQUIET(info, NULL);	REC_PRINT(__ham_chgpg_print);	REC_INTRO(__ham_chgpg_read, 0);	if (op != DB_TXN_ABORT)		goto done;	/* Overloaded fields for DB_HAM_DEL*PG */	indx = argp->old_indx;	order = argp->new_indx;	MUTEX_THREAD_LOCK(dbenv, dbenv->dblist_mutexp);	for (ldbp = __dblist_get(dbenv, file_dbp->adj_fileid);	    ldbp != NULL && ldbp->adj_fileid == file_dbp->adj_fileid;	    ldbp = LIST_NEXT(ldbp, dblistlinks)) {		MUTEX_THREAD_LOCK(dbenv, file_dbp->mutexp);		for (cp = TAILQ_FIRST(&ldbp->active_queue); cp != NULL;		    cp = TAILQ_NEXT(cp, links)) {			lcp = (HASH_CURSOR *)cp->internal;			switch (argp->mode) {			case DB_HAM_DELFIRSTPG:				if (lcp->pgno != argp->new_pgno)					break;				if (lcp->indx != indx ||				    !F_ISSET(lcp, H_DELETED) ||				    lcp->order >= order) {					lcp->pgno = argp->old_pgno;					if (lcp->indx == indx)						lcp->order -= order;				}				break;			case DB_HAM_DELMIDPG:			case DB_HAM_DELLASTPG:				if (lcp->pgno == argp->new_pgno &&				    lcp->indx == indx &&				    F_ISSET(lcp, H_DELETED) &&				    lcp->order >= order) {					lcp->pgno = argp->old_pgno;					lcp->order -= order;					lcp->indx = 0;				}				break;			case DB_HAM_CHGPG:				/*				 * If we're doing a CHGPG, we're undoing				 * the move of a non-deleted item to a				 * new page.  Any cursors with the deleted				 * flag set do not belong to this item;				 * don't touch them.				 */				if (F_ISSET(lcp, H_DELETED))					break;				/* FALLTHROUGH */			case DB_HAM_SPLIT:				if (lcp->pgno == argp->new_pgno &&				    lcp->indx == argp->new_indx) {					lcp->indx = argp->old_indx;					lcp->pgno = argp->old_pgno;				}				break;			case DB_HAM_DUP:				if (lcp->opd == NULL)					break;				opdcp = (BTREE_CURSOR *)lcp->opd->internal;				if (opdcp->pgno != argp->new_pgno ||				    opdcp->indx != argp->new_indx)					break;				if (F_ISSET(opdcp, C_DELETED))					F_SET(lcp, H_DELETED);				/*				 * We can't close a cursor while we have the				 * dbp mutex locked, since c_close reacquires				 * it.  It should be safe to drop the mutex				 * here, though, since newly opened cursors				 * are put only at the end of the tailq and				 * the cursor we're adjusting can't be closed				 * under us.				 */				MUTEX_THREAD_UNLOCK(dbenv, file_dbp->mutexp);				if ((ret = __db_c_close(lcp->opd)) != 0)					goto out;				MUTEX_THREAD_LOCK(dbenv, file_dbp->mutexp);				lcp->opd = NULL;				break;			}		}		MUTEX_THREAD_UNLOCK(dbenv, file_dbp->mutexp);	}	MUTEX_THREAD_UNLOCK(dbenv, dbenv->dblist_mutexp);done:	*lsnp = argp->prev_lsn;out:	REC_CLOSE;}

⌨️ 快捷键说明

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