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

📄 qam_files.c

📁 这是国外的resip协议栈
💻 C
📖 第 1 页 / 共 2 页
字号:
/*- * See the file LICENSE for redistribution information. * * Copyright (c) 1999-2004 *	Sleepycat Software.  All rights reserved. * * $Id: qam_files.c,v 1.88 2004/10/21 14:54:42 bostic Exp $ */#include "db_config.h"#ifndef NO_SYSTEM_INCLUDES#include <sys/types.h>#include <stdlib.h>#include <string.h>#include <ctype.h>#endif#include "db_int.h"#include "dbinc/db_page.h"#include "dbinc/db_shash.h"#include "dbinc/db_am.h"#include "dbinc/log.h"#include "dbinc/fop.h"#include "dbinc/mp.h"#include "dbinc/qam.h"#define	QAM_EXNAME(Q, I, B, L)						\	snprintf((B), (L),						\	    QUEUE_EXTENT, (Q)->dir, PATH_SEPARATOR[0], (Q)->name, (I))/* * __qam_fprobe -- calculate and open extent * * Calculate which extent the page is in, open and create if necessary. * * PUBLIC: int __qam_fprobe * PUBLIC:	   __P((DB *, db_pgno_t, void *, qam_probe_mode, u_int32_t)); */int__qam_fprobe(dbp, pgno, addrp, mode, flags)	DB *dbp;	db_pgno_t pgno;	void *addrp;	qam_probe_mode mode;	u_int32_t flags;{	DB_ENV *dbenv;	DB_MPOOLFILE *mpf;	MPFARRAY *array;	QUEUE *qp;	u_int8_t fid[DB_FILE_ID_LEN];	u_int32_t extid, maxext, numext, offset, oldext, openflags;	char buf[MAXPATHLEN];	int ftype, less, ret, t_ret;	dbenv = dbp->dbenv;	qp = (QUEUE *)dbp->q_internal;	ret = 0;	if (qp->page_ext == 0) {		mpf = dbp->mpf;		return (mode == QAM_PROBE_GET ?		    __memp_fget(mpf, &pgno, flags, addrp) :		    __memp_fput(mpf, addrp, flags));	}	mpf = NULL;	/*	 * Need to lock long enough to find the mpf or create the file.	 * The file cannot go away because we must have a record locked	 * in that file.	 */	MUTEX_THREAD_LOCK(dbenv, dbp->mutexp);	extid = QAM_PAGE_EXTENT(dbp, pgno);	/* Array1 will always be in use if array2 is in use. */	array = &qp->array1;	if (array->n_extent == 0) {		/* Start with 4 extents */		array->n_extent = 4;		array->low_extent = extid;		numext = offset = oldext = 0;		less = 0;		goto alloc;	}	if (extid < array->low_extent) {		less = 1;		offset = array->low_extent - extid;	} else {		less = 0;		offset = extid - array->low_extent;	}	if (qp->array2.n_extent != 0 &&	    (extid >= qp->array2.low_extent ?	    offset > extid - qp->array2.low_extent :	    offset > qp->array2.low_extent - extid)) {		array = &qp->array2;		if (extid < array->low_extent) {			less = 1;			offset = array->low_extent - extid;		} else {			less = 0;			offset = extid - array->low_extent;		}	}	/*	 * Check to see if the requested extent is outside the range of	 * extents in the array.  This is true by default if there are	 * no extents here yet.	 */	if (less == 1 || offset >= array->n_extent) {		oldext = array->n_extent;		numext = (array->hi_extent - array->low_extent) + 1;		if (less == 1 && offset + numext <= array->n_extent) {			/*			 * If we can fit this one into the existing array by			 * shifting the existing entries then we do not have			 * to allocate.			 */			memmove(&array->mpfarray[offset],			    array->mpfarray, numext			    * sizeof(array->mpfarray[0]));			memset(array->mpfarray, 0, offset			    * sizeof(array->mpfarray[0]));			offset = 0;		} else if (less == 0 && offset == array->n_extent &&		    mode != QAM_PROBE_MPF && array->mpfarray[0].pinref == 0) {			/*			 * If this is at the end of the array and the file at			 * the beginning has a zero pin count we can close			 * the bottom extent and put this one at the end.			 * TODO: If this process is "slow" then it might be			 * appending but miss one or more extents.			 * We could check to see if all the extents			 * are unpinned and close them in the else			 * clause below.			 */			mpf = array->mpfarray[0].mpf;			if (mpf != NULL && (ret = __memp_fclose(mpf, 0)) != 0)				goto err;			memmove(&array->mpfarray[0], &array->mpfarray[1],			    (array->n_extent - 1) * sizeof(array->mpfarray[0]));			array->low_extent++;			array->hi_extent++;			offset--;			array->mpfarray[offset].mpf = NULL;			array->mpfarray[offset].pinref = 0;		} else {			/*			 * See if we have wrapped around the queue.			 * If it has then allocate the second array.			 * Otherwise just expand the one we are using.			 */			maxext = (u_int32_t) UINT32_MAX			    / (qp->page_ext * qp->rec_page);			if (offset >= maxext/2) {				array = &qp->array2;				DB_ASSERT(array->n_extent == 0);				oldext = 0;				array->n_extent = 4;				array->low_extent = extid;				offset = 0;				numext = 0;			} else {				/*				 * Increase the size to at least include				 * the new one and double it.				 */				array->n_extent += offset;				array->n_extent <<= 2;			}alloc:			if ((ret = __os_realloc(dbenv,			    array->n_extent * sizeof(struct __qmpf),			    &array->mpfarray)) != 0)				goto err;			if (less == 1) {				/*				 * Move the array up and put the new one				 * in the first slot.				 */				memmove(&array->mpfarray[offset],				    array->mpfarray,				    numext * sizeof(array->mpfarray[0]));				memset(array->mpfarray, 0,				    offset * sizeof(array->mpfarray[0]));				memset(&array->mpfarray[numext + offset], 0,				    (array->n_extent - (numext + offset))				    * sizeof(array->mpfarray[0]));				offset = 0;			}			else				/* Clear the new part of the array. */				memset(&array->mpfarray[oldext], 0,				    (array->n_extent - oldext) *				    sizeof(array->mpfarray[0]));		}	}	/* Update the low and hi range of saved extents. */	if (extid < array->low_extent)		array->low_extent = extid;	if (extid > array->hi_extent)		array->hi_extent = extid;	/* If the extent file is not yet open, open it. */	if (array->mpfarray[offset].mpf == NULL) {		QAM_EXNAME(qp, extid, buf, sizeof(buf));		if ((ret = __memp_fcreate(		    dbenv, &array->mpfarray[offset].mpf)) != 0)			goto err;		mpf = array->mpfarray[offset].mpf;		(void)__memp_set_lsn_offset(mpf, 0);		(void)__memp_set_pgcookie(mpf, &qp->pgcookie);		(void)__memp_get_ftype(dbp->mpf, &ftype);		(void)__memp_set_ftype(mpf, ftype);		/* Set up the fileid for this extent. */		__qam_exid(dbp, fid, extid);		(void)__memp_set_fileid(mpf, fid);		openflags = DB_EXTENT;		if (LF_ISSET(DB_MPOOL_CREATE))			openflags |= DB_CREATE;		if (F_ISSET(dbp, DB_AM_RDONLY))			openflags |= DB_RDONLY;		if (F_ISSET(dbenv, DB_ENV_DIRECT_DB))			openflags |= DB_DIRECT;		if ((ret = __memp_fopen(		    mpf, NULL, buf, openflags, qp->mode, dbp->pgsize)) != 0) {			array->mpfarray[offset].mpf = NULL;			(void)__memp_fclose(mpf, 0);			goto err;		}	}	/*	 * We have found the right file.  Update its ref count	 * before dropping the dbp mutex so it does not go away.	 */	mpf = array->mpfarray[offset].mpf;	if (mode == QAM_PROBE_GET)		array->mpfarray[offset].pinref++;	/*	 * If we may create the page, then we are writing,	 * the file may nolonger be empty after this operation	 * so we clear the UNLINK flag.	 */	if (LF_ISSET(DB_MPOOL_CREATE))		(void)__memp_set_flags(mpf, DB_MPOOL_UNLINK, 0);err:	MUTEX_THREAD_UNLOCK(dbenv, dbp->mutexp);	if (ret == 0) {		if (mode == QAM_PROBE_MPF) {			*(DB_MPOOLFILE **)addrp = mpf;			return (0);		}		pgno--;		pgno %= qp->page_ext;		if (mode == QAM_PROBE_GET) {			if ((ret = __memp_fget(mpf, &pgno, flags, addrp)) == 0)				return (ret);		} else			ret = __memp_fput(mpf, addrp, flags);		MUTEX_THREAD_LOCK(dbenv, dbp->mutexp);		/* Recalculate because we dropped the lock. */		offset = extid - array->low_extent;		DB_ASSERT(array->mpfarray[offset].pinref > 0);		if (--array->mpfarray[offset].pinref == 0 &&		    (mode == QAM_PROBE_GET || ret == 0)) {			/* Check to see if this file will be unlinked. */			(void)__memp_get_flags(mpf, &flags);			if (LF_ISSET(DB_MPOOL_UNLINK)) {				array->mpfarray[offset].mpf = NULL;				if ((t_ret =				    __memp_fclose(mpf, 0)) != 0 && ret == 0)					ret = t_ret;			}		}		MUTEX_THREAD_UNLOCK(dbenv, dbp->mutexp);	}	return (ret);}/* * __qam_fclose -- close an extent. * * Calculate which extent the page is in and close it. * We assume the mpf entry is present. * * PUBLIC: int __qam_fclose __P((DB *, db_pgno_t)); */int__qam_fclose(dbp, pgnoaddr)	DB *dbp;	db_pgno_t pgnoaddr;{	DB_ENV *dbenv;	DB_MPOOLFILE *mpf;	MPFARRAY *array;	QUEUE *qp;	u_int32_t extid, offset;	int ret;	ret = 0;	dbenv = dbp->dbenv;	qp = (QUEUE *)dbp->q_internal;	MUTEX_THREAD_LOCK(dbenv, dbp->mutexp);	extid = QAM_PAGE_EXTENT(dbp, pgnoaddr);	array = &qp->array1;	if (array->low_extent > extid || array->hi_extent < extid)		array = &qp->array2;	offset = extid - array->low_extent;	DB_ASSERT(extid >= array->low_extent && offset < array->n_extent);	/* If other threads are still using this file, leave it. */	if (array->mpfarray[offset].pinref != 0)		goto done;	mpf = array->mpfarray[offset].mpf;	array->mpfarray[offset].mpf = NULL;	ret = __memp_fclose(mpf, 0);done:	MUTEX_THREAD_UNLOCK(dbenv, dbp->mutexp);	return (ret);}/* * __qam_fremove -- remove an extent. * * Calculate which extent the page is in and remove it.  There is no way * to remove an extent without probing it first and seeing that is is empty * so we assume the mpf entry is present. * * PUBLIC: int __qam_fremove __P((DB *, db_pgno_t)); */int__qam_fremove(dbp, pgnoaddr)	DB *dbp;	db_pgno_t pgnoaddr;{	DB_ENV *dbenv;	DB_MPOOLFILE *mpf;	MPFARRAY *array;	QUEUE *qp;	u_int32_t extid, offset;#ifdef CONFIG_TEST	char buf[MAXPATHLEN], *real_name;#endif	int ret;	qp = (QUEUE *)dbp->q_internal;	dbenv = dbp->dbenv;	ret = 0;	MUTEX_THREAD_LOCK(dbenv, dbp->mutexp);	extid = QAM_PAGE_EXTENT(dbp, pgnoaddr);	array = &qp->array1;	if (array->low_extent > extid || array->hi_extent < extid)		array = &qp->array2;	offset = extid - array->low_extent;	DB_ASSERT(extid >= array->low_extent && offset < array->n_extent);#ifdef CONFIG_TEST	real_name = NULL;	/* Find the real name of the file. */	QAM_EXNAME(qp, extid, buf, sizeof(buf));	if ((ret = __db_appname(dbenv,	    DB_APP_DATA, buf, 0, NULL, &real_name)) != 0)		goto err;#endif	/*	 * The log must be flushed before the file is deleted.  We depend on	 * the log record of the last delete to recreate the file if we crash.	 */	if (LOGGING_ON(dbenv) && (ret = __log_flush(dbenv, NULL)) != 0)		goto err;	mpf = array->mpfarray[offset].mpf;	(void)__memp_set_flags(mpf, DB_MPOOL_UNLINK, 1);	/* Someone could be real slow, let them close it down. */	if (array->mpfarray[offset].pinref != 0)		goto err;	array->mpfarray[offset].mpf = NULL;	if ((ret = __memp_fclose(mpf, 0)) != 0)		goto err;	/*	 * If the file is at the bottom of the array	 * shift things down and adjust the end points.	 */	if (offset == 0) {		memmove(array->mpfarray, &array->mpfarray[1],		    (array->hi_extent - array->low_extent)		    * sizeof(array->mpfarray[0]));		array->mpfarray[		    array->hi_extent - array->low_extent].mpf = NULL;		if (array->low_extent != array->hi_extent)

⌨️ 快捷键说明

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