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

📄 gindatapage.c

📁 postgresql8.3.4源码,开源数据库
💻 C
📖 第 1 页 / 共 2 页
字号:
/*------------------------------------------------------------------------- * * gindatapage.c *	  page utilities routines for the postgres inverted index access method. * * * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION *			$PostgreSQL: pgsql/src/backend/access/gin/gindatapage.c,v 1.9 2008/01/01 19:45:46 momjian Exp $ *------------------------------------------------------------------------- */#include "postgres.h"#include "access/gin.h"intcompareItemPointers(ItemPointer a, ItemPointer b){	if (GinItemPointerGetBlockNumber(a) == GinItemPointerGetBlockNumber(b))	{		if (GinItemPointerGetOffsetNumber(a) == GinItemPointerGetOffsetNumber(b))			return 0;		return (GinItemPointerGetOffsetNumber(a) > GinItemPointerGetOffsetNumber(b)) ? 1 : -1;	}	return (GinItemPointerGetBlockNumber(a) > GinItemPointerGetBlockNumber(b)) ? 1 : -1;}/* * Merge two ordered array of itempointer */voidMergeItemPointers(ItemPointerData *dst, ItemPointerData *a, uint32 na, ItemPointerData *b, uint32 nb){	ItemPointerData *dptr = dst;	ItemPointerData *aptr = a,			   *bptr = b;	while (aptr - a < na && bptr - b < nb)	{		if (compareItemPointers(aptr, bptr) > 0)			*dptr++ = *bptr++;		else			*dptr++ = *aptr++;	}	while (aptr - a < na)		*dptr++ = *aptr++;	while (bptr - b < nb)		*dptr++ = *bptr++;}/* * Checks, should we move to right link... * Compares inserting itemp pointer with right bound of current page */static booldataIsMoveRight(GinBtree btree, Page page){	ItemPointer iptr = GinDataPageGetRightBound(page);	if (GinPageRightMost(page))		return FALSE;	return (compareItemPointers(btree->items + btree->curitem, iptr) > 0) ? TRUE : FALSE;}/* * Find correct PostingItem in non-leaf page. It supposed that page * correctly chosen and searching value SHOULD be on page */static BlockNumberdataLocateItem(GinBtree btree, GinBtreeStack *stack){	OffsetNumber low,				high,				maxoff;	PostingItem *pitem = NULL;	int			result;	Page		page = BufferGetPage(stack->buffer);	Assert(!GinPageIsLeaf(page));	Assert(GinPageIsData(page));	if (btree->fullScan)	{		stack->off = FirstOffsetNumber;		stack->predictNumber *= GinPageGetOpaque(page)->maxoff;		return btree->getLeftMostPage(btree, page);	}	low = FirstOffsetNumber;	maxoff = high = GinPageGetOpaque(page)->maxoff;	Assert(high >= low);	high++;	while (high > low)	{		OffsetNumber mid = low + ((high - low) / 2);		pitem = (PostingItem *) GinDataPageGetItem(page, mid);		if (mid == maxoff)			/*			 * Right infinity, page already correctly chosen with a help of			 * dataIsMoveRight			 */			result = -1;		else		{			pitem = (PostingItem *) GinDataPageGetItem(page, mid);			result = compareItemPointers(btree->items + btree->curitem, &(pitem->key));		}		if (result == 0)		{			stack->off = mid;			return PostingItemGetBlockNumber(pitem);		}		else if (result > 0)			low = mid + 1;		else			high = mid;	}	Assert(high >= FirstOffsetNumber && high <= maxoff);	stack->off = high;	pitem = (PostingItem *) GinDataPageGetItem(page, high);	return PostingItemGetBlockNumber(pitem);}/* * Searches correct position for value on leaf page. * Page should be correctly chosen. * Returns true if value found on page. */static booldataLocateLeafItem(GinBtree btree, GinBtreeStack *stack){	Page		page = BufferGetPage(stack->buffer);	OffsetNumber low,				high;	int			result;	Assert(GinPageIsLeaf(page));	Assert(GinPageIsData(page));	if (btree->fullScan)	{		stack->off = FirstOffsetNumber;		return TRUE;	}	low = FirstOffsetNumber;	high = GinPageGetOpaque(page)->maxoff;	if (high < low)	{		stack->off = FirstOffsetNumber;		return false;	}	high++;	while (high > low)	{		OffsetNumber mid = low + ((high - low) / 2);		result = compareItemPointers(btree->items + btree->curitem, (ItemPointer) GinDataPageGetItem(page, mid));		if (result == 0)		{			stack->off = mid;			return true;		}		else if (result > 0)			low = mid + 1;		else			high = mid;	}	stack->off = high;	return false;}/* * Finds links to blkno on non-leaf page, returns * offset of PostingItem */static OffsetNumberdataFindChildPtr(GinBtree btree, Page page, BlockNumber blkno, OffsetNumber storedOff){	OffsetNumber i,				maxoff = GinPageGetOpaque(page)->maxoff;	PostingItem *pitem;	Assert(!GinPageIsLeaf(page));	Assert(GinPageIsData(page));	/* if page isn't changed, we returns storedOff */	if (storedOff >= FirstOffsetNumber && storedOff <= maxoff)	{		pitem = (PostingItem *) GinDataPageGetItem(page, storedOff);		if (PostingItemGetBlockNumber(pitem) == blkno)			return storedOff;		/*		 * we hope, that needed pointer goes to right. It's true if there		 * wasn't a deletion		 */		for (i = storedOff + 1; i <= maxoff; i++)		{			pitem = (PostingItem *) GinDataPageGetItem(page, i);			if (PostingItemGetBlockNumber(pitem) == blkno)				return i;		}		maxoff = storedOff - 1;	}	/* last chance */	for (i = FirstOffsetNumber; i <= maxoff; i++)	{		pitem = (PostingItem *) GinDataPageGetItem(page, i);		if (PostingItemGetBlockNumber(pitem) == blkno)			return i;	}	return InvalidOffsetNumber;}/* * returns blkno of leftmost child */static BlockNumberdataGetLeftMostPage(GinBtree btree, Page page){	PostingItem *pitem;	Assert(!GinPageIsLeaf(page));	Assert(GinPageIsData(page));	Assert(GinPageGetOpaque(page)->maxoff >= FirstOffsetNumber);	pitem = (PostingItem *) GinDataPageGetItem(page, FirstOffsetNumber);	return PostingItemGetBlockNumber(pitem);}/* * add ItemPointer or PostingItem to page. data should point to * correct value! depending on leaf or non-leaf page */voidGinDataPageAddItem(Page page, void *data, OffsetNumber offset){	OffsetNumber maxoff = GinPageGetOpaque(page)->maxoff;	char	   *ptr;	if (offset == InvalidOffsetNumber)	{		ptr = GinDataPageGetItem(page, maxoff + 1);	}	else	{		ptr = GinDataPageGetItem(page, offset);		if (maxoff + 1 - offset != 0)			memmove(ptr + GinSizeOfItem(page), ptr, (maxoff - offset + 1) * GinSizeOfItem(page));	}	memcpy(ptr, data, GinSizeOfItem(page));	GinPageGetOpaque(page)->maxoff++;}/* * Deletes posting item from non-leaf page */voidPageDeletePostingItem(Page page, OffsetNumber offset){	OffsetNumber maxoff = GinPageGetOpaque(page)->maxoff;	Assert(!GinPageIsLeaf(page));	Assert(offset >= FirstOffsetNumber && offset <= maxoff);	if (offset != maxoff)		memmove(GinDataPageGetItem(page, offset), GinDataPageGetItem(page, offset + 1),				sizeof(PostingItem) * (maxoff - offset));	GinPageGetOpaque(page)->maxoff--;}/* * checks space to install new value, * item pointer never deletes! */static booldataIsEnoughSpace(GinBtree btree, Buffer buf, OffsetNumber off){	Page		page = BufferGetPage(buf);	Assert(GinPageIsData(page));	Assert(!btree->isDelete);	if (GinPageIsLeaf(page))	{		if (GinPageRightMost(page) && off > GinPageGetOpaque(page)->maxoff)		{			if ((btree->nitem - btree->curitem) * sizeof(ItemPointerData) <= GinDataPageGetFreeSpace(page))				return true;		}		else if (sizeof(ItemPointerData) <= GinDataPageGetFreeSpace(page))			return true;	}	else if (sizeof(PostingItem) <= GinDataPageGetFreeSpace(page))		return true;	return false;}

⌨️ 快捷键说明

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