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

📄 bt_delete.c

📁 代码检索工具GLOBAL源码。可用来浏览分析LINUX源码。
💻 C
📖 第 1 页 / 共 2 页
字号:
		deleted = 1;	} while (e->index < NEXTINDEX(h) && __bt_cmp(t, key, e) == 0);	/* Check for right-hand edge of the page. */	if (e->index == NEXTINDEX(h))		redo = 1;	/* Delete from the key to the beginning of the page. */	while (e->index-- > 0) {		if (__bt_cmp(t, key, e) != 0)			break;		if (__bt_dleaf(t, key, h, e->index) == RET_ERROR) {			mpool_put(t->bt_mp, h, 0);			return (RET_ERROR);		}		if (e->index == 0)			redo = 1;	}	/* Check for an empty page. */	if (NEXTINDEX(h) == 0) {		if (__bt_pdelete(t, h))			return (RET_ERROR);		goto loop;	}	/* Put the page. */	mpool_put(t->bt_mp, h, MPOOL_DIRTY);	if (redo)		goto loop;	return (RET_SUCCESS);}/* * __bt_pdelete -- *	Delete a single page from the tree. * * Parameters: *	t:	tree *	h:	leaf page * * Returns: *	RET_SUCCESS, RET_ERROR. * * Side-effects: *	mpool_put's the page */static int__bt_pdelete(t, h)	BTREE *t;	PAGE *h;{	BINTERNAL *bi;	PAGE *pg;	EPGNO *parent;	indx_t cnt, index, *ip, offset;	u_int32_t nksize;	char *from;	/*	 * Walk the parent page stack -- a LIFO stack of the pages that were	 * traversed when we searched for the page where the delete occurred.	 * Each stack entry is a page number and a page index offset.  The	 * offset is for the page traversed on the search.  We've just deleted	 * a page, so we have to delete the key from the parent page.	 *	 * If the delete from the parent page makes it empty, this process may	 * continue all the way up the tree.  We stop if we reach the root page	 * (which is never deleted, it's just not worth the effort) or if the	 * delete does not empty the page.	 */	while ((parent = BT_POP(t)) != NULL) {		/* Get the parent page. */		if ((pg = mpool_get(t->bt_mp, parent->pgno, 0)) == NULL)			return (RET_ERROR);				index = parent->index;		bi = GETBINTERNAL(pg, index);		/* Free any overflow pages. */		if (bi->flags & P_BIGKEY &&		    __ovfl_delete(t, bi->bytes) == RET_ERROR) {			mpool_put(t->bt_mp, pg, 0);			return (RET_ERROR);		}		/*		 * Free the parent if it has only the one key and it's not the		 * root page. If it's the rootpage, turn it back into an empty		 * leaf page.		 */		if (NEXTINDEX(pg) == 1)			if (pg->pgno == P_ROOT) {				pg->lower = BTDATAOFF;				pg->upper = t->bt_psize;				pg->flags = P_BLEAF;			} else {				if (__bt_relink(t, pg) || __bt_free(t, pg))					return (RET_ERROR);				continue;			}		else {			/* Pack remaining key items at the end of the page. */			nksize = NBINTERNAL(bi->ksize);			from = (char *)pg + pg->upper;			memmove(from + nksize, from, (char *)bi - from);			pg->upper += nksize;			/* Adjust indices' offsets, shift the indices down. */			offset = pg->linp[index];			for (cnt = index, ip = &pg->linp[0]; cnt--; ++ip)				if (ip[0] < offset)					ip[0] += nksize;			for (cnt = NEXTINDEX(pg) - index; --cnt; ++ip)				ip[0] = ip[1] < offset ? ip[1] + nksize : ip[1];			pg->lower -= sizeof(indx_t);		}		mpool_put(t->bt_mp, pg, MPOOL_DIRTY);		break;	}	/* Free the leaf page, as long as it wasn't the root. */	if (h->pgno == P_ROOT) {		mpool_put(t->bt_mp, h, MPOOL_DIRTY);		return (RET_SUCCESS);	}	return (__bt_relink(t, h) || __bt_free(t, h));}/* * __bt_dleaf -- *	Delete a single record from a leaf page. * * Parameters: *	t:	tree *    key:	referenced key *	h:	page *	index:	index on page to delete * * Returns: *	RET_SUCCESS, RET_ERROR. */int__bt_dleaf(t, key, h, index)	BTREE *t;	const DBT *key;	PAGE *h;	u_int index;{	BLEAF *bl;	indx_t cnt, *ip, offset;	u_int32_t nbytes;	void *to;	char *from;	/* If this record is referenced by the cursor, delete the cursor. */	if (F_ISSET(&t->bt_cursor, CURS_INIT) &&	    !F_ISSET(&t->bt_cursor, CURS_ACQUIRE) &&	    t->bt_cursor.pg.pgno == h->pgno && t->bt_cursor.pg.index == index &&	    __bt_curdel(t, key, h, index))		return (RET_ERROR);	/* If the entry uses overflow pages, make them available for reuse. */	to = bl = GETBLEAF(h, index);	if (bl->flags & P_BIGKEY && __ovfl_delete(t, bl->bytes) == RET_ERROR)		return (RET_ERROR);	if (bl->flags & P_BIGDATA &&	    __ovfl_delete(t, bl->bytes + bl->ksize) == RET_ERROR)		return (RET_ERROR);	/* Pack the remaining key/data items at the end of the page. */	nbytes = NBLEAF(bl);	from = (char *)h + h->upper;	memmove(from + nbytes, from, (char *)to - from);	h->upper += nbytes;	/* Adjust the indices' offsets, shift the indices down. */	offset = h->linp[index];	for (cnt = index, ip = &h->linp[0]; cnt--; ++ip)		if (ip[0] < offset)			ip[0] += nbytes;	for (cnt = NEXTINDEX(h) - index; --cnt; ++ip)		ip[0] = ip[1] < offset ? ip[1] + nbytes : ip[1];	h->lower -= sizeof(indx_t);	/* If the cursor is on this page, adjust it as necessary. */	if (F_ISSET(&t->bt_cursor, CURS_INIT) &&	    !F_ISSET(&t->bt_cursor, CURS_ACQUIRE) &&	    t->bt_cursor.pg.pgno == h->pgno && t->bt_cursor.pg.index > index)		--t->bt_cursor.pg.index;	return (RET_SUCCESS);}/* * __bt_curdel -- *	Delete the cursor. * * Parameters: *	t:	tree *    key:	referenced key (or NULL) *	h:	page *  index:	index on page to delete * * Returns: *	RET_SUCCESS, RET_ERROR. */static int__bt_curdel(t, key, h, index)	BTREE *t;	const DBT *key;	PAGE *h;	u_int index;{	CURSOR *c;	EPG e;	PAGE *pg;	int curcopy, status;	/*	 * If there are duplicates, move forward or backward to one.	 * Otherwise, copy the key into the cursor area.	 */	c = &t->bt_cursor;	F_CLR(c, CURS_AFTER | CURS_BEFORE | CURS_ACQUIRE);	curcopy = 0;	if (!F_ISSET(t, B_NODUPS)) {		/*		 * We're going to have to do comparisons.  If we weren't		 * provided a copy of the key, i.e. the user is deleting		 * the current cursor position, get one.		 */		if (key == NULL) {			e.page = h;			e.index = index;			if ((status = __bt_ret(t, &e,			    &c->key, &c->key, NULL, NULL, 1)) != RET_SUCCESS)				return (status);			curcopy = 1;			key = &c->key;		}		/* Check previous key, if not at the beginning of the page. */		if (index > 0) { 			e.page = h;			e.index = index - 1;			if (__bt_cmp(t, key, &e) == 0) {				F_SET(c, CURS_BEFORE);				goto dup2;			}		}		/* Check next key, if not at the end of the page. */		if (index < NEXTINDEX(h) - 1) {			e.page = h;			e.index = index + 1;			if (__bt_cmp(t, key, &e) == 0) {				F_SET(c, CURS_AFTER);				goto dup2;			}		}		/* Check previous key if at the beginning of the page. */		if (index == 0 && h->prevpg != P_INVALID) {			if ((pg = mpool_get(t->bt_mp, h->prevpg, 0)) == NULL)				return (RET_ERROR);			e.page = pg;			e.index = NEXTINDEX(pg) - 1;			if (__bt_cmp(t, key, &e) == 0) {				F_SET(c, CURS_BEFORE);				goto dup1;			}			mpool_put(t->bt_mp, pg, 0);		}		/* Check next key if at the end of the page. */		if (index == NEXTINDEX(h) - 1 && h->nextpg != P_INVALID) {			if ((pg = mpool_get(t->bt_mp, h->nextpg, 0)) == NULL)				return (RET_ERROR);			e.page = pg;			e.index = 0;			if (__bt_cmp(t, key, &e) == 0) {				F_SET(c, CURS_AFTER);dup1:				mpool_put(t->bt_mp, pg, 0);dup2:				c->pg.pgno = e.page->pgno;				c->pg.index = e.index;				return (RET_SUCCESS);			}			mpool_put(t->bt_mp, pg, 0);		}	}	e.page = h;	e.index = index;	if (curcopy || (status =	    __bt_ret(t, &e, &c->key, &c->key, NULL, NULL, 1)) == RET_SUCCESS) {		F_SET(c, CURS_ACQUIRE);		return (RET_SUCCESS);	}	return (status);}/* * __bt_relink -- *	Link around a deleted page. * * Parameters: *	t:	tree *	h:	page to be deleted */static int__bt_relink(t, h)	BTREE *t;	PAGE *h;{	PAGE *pg;	if (h->nextpg != P_INVALID) {		if ((pg = mpool_get(t->bt_mp, h->nextpg, 0)) == NULL)			return (RET_ERROR);		pg->prevpg = h->prevpg;		mpool_put(t->bt_mp, pg, MPOOL_DIRTY);	}	if (h->prevpg != P_INVALID) {		if ((pg = mpool_get(t->bt_mp, h->prevpg, 0)) == NULL)			return (RET_ERROR);		pg->nextpg = h->nextpg;		mpool_put(t->bt_mp, pg, MPOOL_DIRTY);	}	return (0);}

⌨️ 快捷键说明

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