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

📄 bt_recno.c

📁 这是linux下运行的mysql软件包,可用于linux 下安装 php + mysql + apach 的网络配置
💻 C
📖 第 1 页 / 共 3 页
字号:
		__db_err(dbp->dbenv, "illegal record number of 0");		return (EINVAL);	}	if (rep != NULL)		*rep = recno;	/*	 * Btree can neither create records nor read them in.  Recno can	 * do both, see if we can find the record.	 */	return (dbc->dbtype == DB_RECNO ?	    __ram_update(dbc, recno, can_create) : 0);}/* * __ram_update -- *	Ensure the tree has records up to and including the specified one. */static int__ram_update(dbc, recno, can_create)	DBC *dbc;	db_recno_t recno;	int can_create;{	BTREE *t;	DB *dbp;	DBT *rdata;	db_recno_t nrecs;	int ret;	dbp = dbc->dbp;	t = dbp->bt_internal;	/*	 * If we can't create records and we've read the entire backing input	 * file, we're done.	 */	if (!can_create && t->re_eof)		return (0);	/*	 * If we haven't seen this record yet, try to get it from the original	 * file.	 */	if ((ret = __bam_nrecs(dbc, &nrecs)) != 0)		return (ret);	if (!t->re_eof && recno > nrecs) {		if ((ret = __ram_sread(dbc, recno)) != 0 && ret != DB_NOTFOUND)			return (ret);		if ((ret = __bam_nrecs(dbc, &nrecs)) != 0)			return (ret);	}	/*	 * If we can create records, create empty ones up to the requested	 * record.	 */	if (!can_create || recno <= nrecs + 1)		return (0);	rdata = &dbc->my_rdata;	rdata->flags = 0;	rdata->size = 0;	while (recno > ++nrecs)		if ((ret = __ram_add(dbc,		    &nrecs, rdata, 0, BI_DELETED)) != 0)			return (ret);	return (0);}/* * __ram_source -- *	Load information about the backing file. */static int__ram_source(dbp)	DB *dbp;{	BTREE *t;	char *source;	int ret;	t = dbp->bt_internal;	/* Find the real name, and swap out the one we had before. */	if ((ret = __db_appname(dbp->dbenv,	    DB_APP_DATA, t->re_source, 0, NULL, &source)) != 0)		return (ret);	__os_free(dbp->dbenv, t->re_source);	t->re_source = source;	/*	 * !!!	 * It's possible that the backing source file is read-only.  We don't	 * much care other than we'll complain if there are any modifications	 * when it comes time to write the database back to the source.	 */	if ((t->re_fp = fopen(t->re_source, "r")) == NULL) {		ret = errno;		__db_err(dbp->dbenv, "%s: %s", t->re_source, db_strerror(ret));		return (ret);	}	t->re_eof = 0;	return (0);}/* * __ram_writeback -- *	Rewrite the backing file. * * PUBLIC: int __ram_writeback __P((DB *)); */int__ram_writeback(dbp)	DB *dbp;{	BTREE *t;	DB_ENV *dbenv;	DBC *dbc;	DBT key, data;	FILE *fp;	db_recno_t keyno;	int ret, t_ret;	u_int8_t delim, *pad;	t = dbp->bt_internal;	dbenv = dbp->dbenv;	fp = NULL;	pad = NULL;	/* If the file wasn't modified, we're done. */	if (!t->re_modified)		return (0);	/* If there's no backing source file, we're done. */	if (t->re_source == NULL) {		t->re_modified = 0;		return (0);	}	/* Allocate a cursor. */	if ((ret = dbp->cursor(dbp, NULL, &dbc, 0)) != 0)		return (ret);	/*	 * Read any remaining records into the tree.	 *	 * !!!	 * This is why we can't support transactions when applications specify	 * backing (re_source) files.  At this point we have to read in the	 * rest of the records from the file so that we can write all of the	 * records back out again, which could modify a page for which we'd	 * have to log changes and which we don't have locked.  This could be	 * partially fixed by taking a snapshot of the entire file during the	 * DB->open as DB->open is transaction protected.  But, if a checkpoint	 * occurs then, the part of the log holding the copy of the file could	 * be discarded, and that would make it impossible to recover in the	 * face of disaster.  This could all probably be fixed, but it would	 * require transaction protecting the backing source file.	 *	 * XXX	 * This could be made to work now that we have transactions protecting	 * file operations.  Margo has specifically asked for the privilege of	 * doing this work.	 */	if ((ret =	    __ram_update(dbc, DB_MAX_RECORDS, 0)) != 0 && ret != DB_NOTFOUND)		return (ret);	/*	 * Close any existing file handle and re-open the file, truncating it.	 */	if (t->re_fp != NULL) {		if (fclose(t->re_fp) != 0) {			ret = errno;			goto err;		}		t->re_fp = NULL;	}	if ((fp = fopen(t->re_source, "w")) == NULL) {		ret = errno;		__db_err(dbenv, "%s: %s", t->re_source, db_strerror(ret));		goto err;	}	/*	 * We step through the records, writing each one out.  Use the record	 * number and the dbp->get() function, instead of a cursor, so we find	 * and write out "deleted" or non-existent records.  The DB handle may	 * be threaded, so allocate memory as we go.	 */	memset(&key, 0, sizeof(key));	key.size = sizeof(db_recno_t);	key.data = &keyno;	memset(&data, 0, sizeof(data));	F_SET(&data, DB_DBT_REALLOC);	/*	 * We'll need the delimiter if we're doing variable-length records,	 * and the pad character if we're doing fixed-length records.	 */	delim = t->re_delim;	if (F_ISSET(dbp, DB_AM_FIXEDLEN)) {		if ((ret = __os_malloc(dbenv, t->re_len, &pad)) != 0)			goto err;		memset(pad, t->re_pad, t->re_len);	}	for (keyno = 1;; ++keyno) {		switch (ret = dbp->get(dbp, NULL, &key, &data, 0)) {		case 0:			if (data.size != 0 && (u_int32_t)fwrite(			    data.data, 1, data.size, fp) != data.size)				goto write_err;			break;		case DB_KEYEMPTY:			if (F_ISSET(dbp, DB_AM_FIXEDLEN) &&			    (u_int32_t)fwrite(pad, 1, t->re_len, fp) !=			    t->re_len)				goto write_err;			break;		case DB_NOTFOUND:			ret = 0;			goto done;		default:			goto err;		}		if (!F_ISSET(dbp, DB_AM_FIXEDLEN) &&		    fwrite(&delim, 1, 1, fp) != 1) {write_err:		ret = errno;			__db_err(dbp->dbenv,			    "%s: write failed to backing file: %s",			    t->re_source, strerror(ret));			goto err;		}	}err:done:	/* Close the file descriptor. */	if (fp != NULL && fclose(fp) != 0) {		if (ret == 0)			ret = errno;		__db_err(dbenv, "%s: %s", t->re_source, db_strerror(errno));	}	/* Discard the cursor. */	if ((t_ret = dbc->c_close(dbc)) != 0 && ret == 0)		ret = t_ret;	/* Discard memory allocated to hold the data items. */	if (data.data != NULL)		__os_ufree(dbenv, data.data);	if (pad != NULL)		__os_free(dbenv, pad);	if (ret == 0)		t->re_modified = 0;	return (ret);}/* * __ram_sread -- *	Read records from a source file. */static int__ram_sread(dbc, top)	DBC *dbc;	db_recno_t top;{	BTREE *t;	DB *dbp;	DBT data, *rdata;	db_recno_t recno;	size_t len;	int ch, ret, was_modified;	t = dbc->dbp->bt_internal;	dbp = dbc->dbp;	was_modified = t->re_modified;	if ((ret = __bam_nrecs(dbc, &recno)) != 0)		return (ret);	/*	 * Use the record key return memory, it's only a short-term use.	 * The record data return memory is used by __bam_iitem, which	 * we'll indirectly call, so use the key so as not to collide.	 */	len = F_ISSET(dbp, DB_AM_FIXEDLEN) ? t->re_len : 256;	rdata = &dbc->my_rkey;	if (rdata->ulen < len) {		if ((ret = __os_realloc(		    dbp->dbenv, len, &rdata->data)) != 0) {			rdata->ulen = 0;			rdata->data = NULL;			return (ret);		}		rdata->ulen = (u_int32_t)len;	}	memset(&data, 0, sizeof(data));	while (recno < top) {		data.data = rdata->data;		data.size = 0;		if (F_ISSET(dbp, DB_AM_FIXEDLEN))			for (len = t->re_len; len > 0; --len) {				if ((ch = getc(t->re_fp)) == EOF) {					if (data.size == 0)						goto eof;					break;				}				((u_int8_t *)data.data)[data.size++] = ch;			}		else			for (;;) {				if ((ch = getc(t->re_fp)) == EOF) {					if (data.size == 0)						goto eof;					break;				}				if (ch == t->re_delim)					break;				((u_int8_t *)data.data)[data.size++] = ch;				if (data.size == rdata->ulen) {					if ((ret = __os_realloc(dbp->dbenv,					    rdata->ulen *= 2,					    &rdata->data)) != 0) {						rdata->ulen = 0;						rdata->data = NULL;						return (ret);					} else						data.data = rdata->data;				}			}		/*		 * Another process may have read this record from the input		 * file and stored it into the database already, in which		 * case we don't need to repeat that operation.  We detect		 * this by checking if the last record we've read is greater		 * or equal to the number of records in the database.		 */		if (t->re_last >= recno) {			++recno;			if ((ret = __ram_add(dbc, &recno, &data, 0, 0)) != 0)				goto err;		}		++t->re_last;	}	if (0) {eof:		t->re_eof = 1;		ret = DB_NOTFOUND;	}err:	if (!was_modified)		t->re_modified = 0;	return (ret);}/* * __ram_add -- *	Add records into the tree. */static int__ram_add(dbc, recnop, data, flags, bi_flags)	DBC *dbc;	db_recno_t *recnop;	DBT *data;	u_int32_t flags, bi_flags;{	BTREE_CURSOR *cp;	int exact, ret, stack;	cp = (BTREE_CURSOR *)dbc->internal;retry:	/* Find the slot for insertion. */	if ((ret = __bam_rsearch(dbc, recnop,	    S_INSERT | (flags == DB_APPEND ? S_APPEND : 0), 1, &exact)) != 0)		return (ret);	stack = 1;	/* Copy the page into the cursor. */	STACK_TO_CURSOR(cp);	/*	 * The application may modify the data based on the selected record	 * number.	 */	if (flags == DB_APPEND && dbc->dbp->db_append_recno != NULL &&	    (ret = dbc->dbp->db_append_recno(dbc->dbp, data, *recnop)) != 0)		goto err;	/*	 * Select the arguments for __bam_iitem() and do the insert.  If the	 * key is an exact match, or we're replacing the data item with a	 * new data item, replace the current item.  If the key isn't an exact	 * match, we're inserting a new key/data pair, before the search	 * location.	 */	switch (ret = __bam_iitem(dbc,	    NULL, data, exact ? DB_CURRENT : DB_BEFORE, bi_flags)) {	case 0:		/*		 * Don't adjust anything.		 *		 * If we inserted a record, no cursors need adjusting because		 * the only new record it's possible to insert is at the very		 * end of the tree.  The necessary adjustments to the internal		 * page counts were made by __bam_iitem().		 *		 * If we overwrote a record, no cursors need adjusting because		 * future DBcursor->get calls will simply return the underlying		 * record (there's no adjustment made for the DB_CURRENT flag		 * when a cursor get operation immediately follows a cursor		 * delete operation, and the normal adjustment for the DB_NEXT		 * flag is still correct).		 */		break;	case DB_NEEDSPLIT:		/* Discard the stack of pages and split the page. */		(void)__bam_stkrel(dbc, STK_CLRDBC);		stack = 0;		if ((ret = __bam_split(dbc, recnop, NULL)) != 0)			goto err;		goto retry;		/* NOTREACHED */	default:		goto err;	}err:	if (stack)		__bam_stkrel(dbc, STK_CLRDBC);	return (ret);}

⌨️ 快捷键说明

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