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

📄 bt_delete.c

📁 代码检索工具GLOBAL源码。可用来浏览分析LINUX源码。
💻 C
📖 第 1 页 / 共 2 页
字号:
/*- * 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 * Mike Olson. * * 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. */#if defined(LIBC_SCCS) && !defined(lint)static char sccsid[] = "@(#)bt_delete.c	8.13 (Berkeley) 7/28/94";#endif /* LIBC_SCCS and not lint */#ifdef HAVE_CONFIG_H#include <config.h>#endif#include <sys/types.h>#include <errno.h>#include <stdio.h>#ifdef HAVE_STRING_H#include <string.h>#else#include <strings.h>#endif#include "db.h"#include "btree.h"static int __bt_bdelete(BTREE *, const DBT *);static int __bt_curdel(BTREE *, const DBT *, PAGE *, u_int);static int __bt_pdelete(BTREE *, PAGE *);static int __bt_relink(BTREE *, PAGE *);static int __bt_stkacq(BTREE *, PAGE **, CURSOR *);/* * __bt_delete *	Delete the item(s) referenced by a key. * * Return RET_SPECIAL if the key is not found. */int__bt_delete(dbp, key, flags)	const DB *dbp;	const DBT *key;	u_int flags;{	BTREE *t;	CURSOR *c;	PAGE *h;	int status;	t = dbp->internal;	/* Toss any page pinned across calls. */	if (t->bt_pinned != NULL) {		mpool_put(t->bt_mp, t->bt_pinned, 0);		t->bt_pinned = NULL;	}	/* Check for change to a read-only tree. */	if (F_ISSET(t, B_RDONLY)) {		errno = EPERM;		return (RET_ERROR);	}	switch (flags) {	case 0:		status = __bt_bdelete(t, key);		break;	case R_CURSOR:		/*		 * If flags is R_CURSOR, delete the cursor.  Must already		 * have started a scan and not have already deleted it.		 */		c = &t->bt_cursor;		if (F_ISSET(c, CURS_INIT)) {			if (F_ISSET(c, CURS_ACQUIRE | CURS_AFTER | CURS_BEFORE))				return (RET_SPECIAL);			if ((h = mpool_get(t->bt_mp, c->pg.pgno, 0)) == NULL)				return (RET_ERROR);			/*			 * If the page is about to be emptied, we'll need to			 * delete it, which means we have to acquire a stack.			 */			if (NEXTINDEX(h) == 1)				if (__bt_stkacq(t, &h, &t->bt_cursor))					return (RET_ERROR);			status = __bt_dleaf(t, NULL, h, c->pg.index);			if (NEXTINDEX(h) == 0 && status == RET_SUCCESS) {				if (__bt_pdelete(t, h))					return (RET_ERROR);			} else				mpool_put(t->bt_mp,				    h, status == RET_SUCCESS ? MPOOL_DIRTY : 0);			break;		}		/* FALLTHROUGH */	default:		errno = EINVAL;		return (RET_ERROR);	}	if (status == RET_SUCCESS)		F_SET(t, B_MODIFIED);	return (status);}/* * __bt_stkacq -- *	Acquire a stack so we can delete a cursor entry. * * Parameters: *	  t:	tree *	 hp:	pointer to current, pinned PAGE pointer *	  c:	pointer to the cursor * * Returns: *	0 on success, 1 on failure */static int__bt_stkacq(t, hp, c)	BTREE *t;	PAGE **hp;	CURSOR *c;{	BINTERNAL *bi;	EPG *e;	EPGNO *parent;	PAGE *h;	indx_t index = 0;	pgno_t pgno;	recno_t nextpg, prevpg;	int exact, level;		/*	 * Find the first occurrence of the key in the tree.  Toss the	 * currently locked page so we don't hit an already-locked page.	 */	h = *hp;	mpool_put(t->bt_mp, h, 0);	if ((e = __bt_search(t, &c->key, &exact)) == NULL)		return (1);	h = e->page;	/* See if we got it in one shot. */	if (h->pgno == c->pg.pgno)		goto ret;	/*	 * Move right, looking for the page.  At each move we have to move	 * up the stack until we don't have to move to the next page.  If	 * we have to change pages at an internal level, we have to fix the	 * stack back up.	 */	while (h->pgno != c->pg.pgno) {		if ((nextpg = h->nextpg) == P_INVALID)			break;		mpool_put(t->bt_mp, h, 0);		/* Move up the stack. */		for (level = 0; (parent = BT_POP(t)) != NULL; ++level) {			/* Get the parent page. */			if ((h = mpool_get(t->bt_mp, parent->pgno, 0)) == NULL)				return (1);			/* Move to the next index. */			if (parent->index != NEXTINDEX(h) - 1) {				index = parent->index + 1;				BT_PUSH(t, h->pgno, index);				break;			}			mpool_put(t->bt_mp, h, 0);		}		/* Restore the stack. */		while (level--) {			/* Push the next level down onto the stack. */			bi = GETBINTERNAL(h, index);			pgno = bi->pgno;			BT_PUSH(t, pgno, 0);			/* Lose the currently pinned page. */			mpool_put(t->bt_mp, h, 0);			/* Get the next level down. */			if ((h = mpool_get(t->bt_mp, pgno, 0)) == NULL)				return (1);			index = 0;		}		mpool_put(t->bt_mp, h, 0);		if ((h = mpool_get(t->bt_mp, nextpg, 0)) == NULL)			return (1);	}	if (h->pgno == c->pg.pgno)		goto ret;	/* Reacquire the original stack. */	mpool_put(t->bt_mp, h, 0);	if ((e = __bt_search(t, &c->key, &exact)) == NULL)		return (1);	h = e->page;	/*	 * Move left, looking for the page.  At each move we have to move	 * up the stack until we don't have to change pages to move to the	 * next page.  If we have to change pages at an internal level, we	 * have to fix the stack back up.	 */	while (h->pgno != c->pg.pgno) {		if ((prevpg = h->prevpg) == P_INVALID)			break;		mpool_put(t->bt_mp, h, 0);		/* Move up the stack. */		for (level = 0; (parent = BT_POP(t)) != NULL; ++level) {			/* Get the parent page. */			if ((h = mpool_get(t->bt_mp, parent->pgno, 0)) == NULL)				return (1);			/* Move to the next index. */			if (parent->index != 0) {				index = parent->index - 1;				BT_PUSH(t, h->pgno, index);				break;			}			mpool_put(t->bt_mp, h, 0);		}		/* Restore the stack. */		while (level--) {			/* Push the next level down onto the stack. */			bi = GETBINTERNAL(h, index);			pgno = bi->pgno;			/* Lose the currently pinned page. */			mpool_put(t->bt_mp, h, 0);			/* Get the next level down. */			if ((h = mpool_get(t->bt_mp, pgno, 0)) == NULL)				return (1);			index = NEXTINDEX(h) - 1;			BT_PUSH(t, pgno, index);		}		mpool_put(t->bt_mp, h, 0);		if ((h = mpool_get(t->bt_mp, prevpg, 0)) == NULL)			return (1);	}	ret:	mpool_put(t->bt_mp, h, 0);	return ((*hp = mpool_get(t->bt_mp, c->pg.pgno, 0)) == NULL);}/* * __bt_bdelete -- *	Delete all key/data pairs matching the specified key. * * Parameters: *	  t:	tree *	key:	key to delete * * Returns: *	RET_ERROR, RET_SUCCESS and RET_SPECIAL if the key not found. */static int__bt_bdelete(t, key)	BTREE *t;	const DBT *key;{	EPG *e;	PAGE *h;	int deleted, exact, redo;	deleted = 0;	/* Find any matching record; __bt_search pins the page. */loop:	if ((e = __bt_search(t, key, &exact)) == NULL)		return (deleted ? RET_SUCCESS : RET_ERROR);	if (!exact) {		mpool_put(t->bt_mp, e->page, 0);		return (deleted ? RET_SUCCESS : RET_SPECIAL);	}	/*	 * Delete forward, then delete backward, from the found key.  If	 * there are duplicates and we reach either side of the page, do	 * the key search again, so that we get them all.	 */	redo = 0;	h = e->page;	do {		if (__bt_dleaf(t, key, h, e->index)) {			mpool_put(t->bt_mp, h, 0);			return (RET_ERROR);		}		if (F_ISSET(t, B_NODUPS)) {			if (NEXTINDEX(h) == 0) {				if (__bt_pdelete(t, h))					return (RET_ERROR);			} else				mpool_put(t->bt_mp, h, MPOOL_DIRTY);			return (RET_SUCCESS);		}

⌨️ 快捷键说明

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