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

📄 ginentrypage.c

📁 postgresql8.3.4源码,开源数据库
💻 C
📖 第 1 页 / 共 2 页
字号:
/*------------------------------------------------------------------------- * * ginentrypage.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/ginentrypage.c,v 1.12 2008/01/01 19:45:46 momjian Exp $ *------------------------------------------------------------------------- */#include "postgres.h"#include "access/gin.h"#include "access/tuptoaster.h"/* * forms tuple for entry tree. On leaf page, Index tuple has * non-traditional layout. Tuple may contain posting list or * root blocknumber of posting tree. Macros GinIsPostingTre: (itup) / GinSetPostingTree(itup, blkno) * 1) Posting list *		- itup->t_info & INDEX_SIZE_MASK contains size of tuple as usual *		- ItemPointerGetBlockNumber(&itup->t_tid) contains original *		  size of tuple (without posting list). *		  Macroses: GinGetOrigSizePosting(itup) / GinSetOrigSizePosting(itup,n) *		- ItemPointerGetOffsetNumber(&itup->t_tid) contains number *		  of elements in posting list (number of heap itempointer) *		  Macroses: GinGetNPosting(itup) / GinSetNPosting(itup,n) *		- After usual part of tuple there is a posting list *		  Macros: GinGetPosting(itup) * 2) Posting tree *		- itup->t_info & INDEX_SIZE_MASK contains size of tuple as usual *		- ItemPointerGetBlockNumber(&itup->t_tid) contains block number of *		  root of posting tree *		- ItemPointerGetOffsetNumber(&itup->t_tid) contains magic number GIN_TREE_POSTING */IndexTupleGinFormTuple(GinState *ginstate, Datum key, ItemPointerData *ipd, uint32 nipd){	bool		isnull = FALSE;	IndexTuple	itup;	itup = index_form_tuple(ginstate->tupdesc, &key, &isnull);	GinSetOrigSizePosting(itup, IndexTupleSize(itup));	if (nipd > 0)	{		uint32		newsize = MAXALIGN(SHORTALIGN(IndexTupleSize(itup)) + sizeof(ItemPointerData) * nipd);		if (newsize >= INDEX_SIZE_MASK)			return NULL;		if (newsize > TOAST_INDEX_TARGET && nipd > 1)			return NULL;		itup = repalloc(itup, newsize);		/* set new size */		itup->t_info &= ~INDEX_SIZE_MASK;		itup->t_info |= newsize;		if (ipd)			memcpy(GinGetPosting(itup), ipd, sizeof(ItemPointerData) * nipd);		GinSetNPosting(itup, nipd);	}	else	{		GinSetNPosting(itup, 0);	}	return itup;}/* * Entry tree is a "static", ie tuple never deletes from it, * so we don't use right bound, we use rightest key instead. */static IndexTuplegetRightMostTuple(Page page){	OffsetNumber maxoff = PageGetMaxOffsetNumber(page);	return (IndexTuple) PageGetItem(page, PageGetItemId(page, maxoff));}DatumginGetHighKey(GinState *ginstate, Page page){	IndexTuple	itup;	bool		isnull;	itup = getRightMostTuple(page);	return index_getattr(itup, FirstOffsetNumber, ginstate->tupdesc, &isnull);}static boolentryIsMoveRight(GinBtree btree, Page page){	Datum		highkey;	if (GinPageRightMost(page))		return FALSE;	highkey = ginGetHighKey(btree->ginstate, page);	if (compareEntries(btree->ginstate, btree->entryValue, highkey) > 0)		return TRUE;	return FALSE;}/* * Find correct tuple in non-leaf page. It supposed that * page correctly choosen and searching value SHOULD be on page */static BlockNumberentryLocateEntry(GinBtree btree, GinBtreeStack *stack){	OffsetNumber low,				high,				maxoff;	IndexTuple	itup = NULL;	int			result;	Page		page = BufferGetPage(stack->buffer);	Assert(!GinPageIsLeaf(page));	Assert(!GinPageIsData(page));	if (btree->fullScan)	{		stack->off = FirstOffsetNumber;		stack->predictNumber *= PageGetMaxOffsetNumber(page);		return btree->getLeftMostPage(btree, page);	}	low = FirstOffsetNumber;	maxoff = high = PageGetMaxOffsetNumber(page);	Assert(high >= low);	high++;	while (high > low)	{		OffsetNumber mid = low + ((high - low) / 2);		if (mid == maxoff && GinPageRightMost(page))			/* Right infinity */			result = -1;		else		{			bool		isnull;			itup = (IndexTuple) PageGetItem(page, PageGetItemId(page, mid));			result = compareEntries(btree->ginstate, btree->entryValue,									index_getattr(itup, FirstOffsetNumber, btree->ginstate->tupdesc, &isnull));		}		if (result == 0)		{			stack->off = mid;			Assert(GinItemPointerGetBlockNumber(&(itup)->t_tid) != GIN_ROOT_BLKNO);			return GinItemPointerGetBlockNumber(&(itup)->t_tid);		}		else if (result > 0)			low = mid + 1;		else			high = mid;	}	Assert(high >= FirstOffsetNumber && high <= maxoff);	stack->off = high;	itup = (IndexTuple) PageGetItem(page, PageGetItemId(page, high));	Assert(GinItemPointerGetBlockNumber(&(itup)->t_tid) != GIN_ROOT_BLKNO);	return GinItemPointerGetBlockNumber(&(itup)->t_tid);}/* * Searches correct position for value on leaf page. * Page should be corrrectly choosen. * Returns true if value found on page. */static boolentryLocateLeafEntry(GinBtree btree, GinBtreeStack *stack){	Page		page = BufferGetPage(stack->buffer);	OffsetNumber low,				high;	IndexTuple	itup;	Assert(GinPageIsLeaf(page));	Assert(!GinPageIsData(page));	if (btree->fullScan)	{		stack->off = FirstOffsetNumber;		return TRUE;	}	low = FirstOffsetNumber;	high = PageGetMaxOffsetNumber(page);	if (high < low)	{		stack->off = FirstOffsetNumber;		return false;	}	high++;	while (high > low)	{		OffsetNumber mid = low + ((high - low) / 2);		bool		isnull;		int			result;		itup = (IndexTuple) PageGetItem(page, PageGetItemId(page, mid));		result = compareEntries(btree->ginstate, btree->entryValue,								index_getattr(itup, FirstOffsetNumber, btree->ginstate->tupdesc, &isnull));		if (result == 0)		{			stack->off = mid;			return true;		}		else if (result > 0)			low = mid + 1;		else			high = mid;	}	stack->off = high;	return false;}static OffsetNumberentryFindChildPtr(GinBtree btree, Page page, BlockNumber blkno, OffsetNumber storedOff){	OffsetNumber i,				maxoff = PageGetMaxOffsetNumber(page);	IndexTuple	itup;	Assert(!GinPageIsLeaf(page));	Assert(!GinPageIsData(page));	/* if page isn't changed, we returns storedOff */	if (storedOff >= FirstOffsetNumber && storedOff <= maxoff)	{		itup = (IndexTuple) PageGetItem(page, PageGetItemId(page, storedOff));		if (GinItemPointerGetBlockNumber(&(itup)->t_tid) == 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++)		{			itup = (IndexTuple) PageGetItem(page, PageGetItemId(page, i));			if (GinItemPointerGetBlockNumber(&(itup)->t_tid) == blkno)				return i;		}		maxoff = storedOff - 1;	}	/* last chance */	for (i = FirstOffsetNumber; i <= maxoff; i++)	{		itup = (IndexTuple) PageGetItem(page, PageGetItemId(page, i));		if (GinItemPointerGetBlockNumber(&(itup)->t_tid) == blkno)			return i;	}	return InvalidOffsetNumber;}static BlockNumberentryGetLeftMostPage(GinBtree btree, Page page){	IndexTuple	itup;	Assert(!GinPageIsLeaf(page));	Assert(!GinPageIsData(page));	Assert(PageGetMaxOffsetNumber(page) >= FirstOffsetNumber);	itup = (IndexTuple) PageGetItem(page, PageGetItemId(page, FirstOffsetNumber));	return GinItemPointerGetBlockNumber(&(itup)->t_tid);}static boolentryIsEnoughSpace(GinBtree btree, Buffer buf, OffsetNumber off){	Size		itupsz = 0;	Page		page = BufferGetPage(buf);	Assert(btree->entry);	Assert(!GinPageIsData(page));	if (btree->isDelete)	{		IndexTuple	itup = (IndexTuple) PageGetItem(page, PageGetItemId(page, off));

⌨️ 快捷键说明

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