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

📄 ginentrypage.c

📁 postgresql8.3.4源码,开源数据库
💻 C
📖 第 1 页 / 共 2 页
字号:
		itupsz = MAXALIGN(IndexTupleSize(itup)) + sizeof(ItemIdData);	}	if (PageGetFreeSpace(page) + itupsz >= MAXALIGN(IndexTupleSize(btree->entry)) + sizeof(ItemIdData))		return true;	return false;}/* * Delete tuple on leaf page if tuples was existed and we * should update it, update old child blkno to new right page * if child split is occured */static BlockNumberentryPreparePage(GinBtree btree, Page page, OffsetNumber off){	BlockNumber ret = InvalidBlockNumber;	Assert(btree->entry);	Assert(!GinPageIsData(page));	if (btree->isDelete)	{		Assert(GinPageIsLeaf(page));		PageIndexTupleDelete(page, off);	}	if (!GinPageIsLeaf(page) && btree->rightblkno != InvalidBlockNumber)	{		IndexTuple	itup = (IndexTuple) PageGetItem(page, PageGetItemId(page, off));		ItemPointerSet(&itup->t_tid, btree->rightblkno, InvalidOffsetNumber);		ret = btree->rightblkno;	}	btree->rightblkno = InvalidBlockNumber;	return ret;}/* * Place tuple on page and fills WAL record */static voidentryPlaceToPage(GinBtree btree, Buffer buf, OffsetNumber off, XLogRecData **prdata){	Page		page = BufferGetPage(buf);	static XLogRecData rdata[3];	OffsetNumber placed;	static ginxlogInsert data;	int			cnt = 0;	*prdata = rdata;	data.updateBlkno = entryPreparePage(btree, page, off);	placed = PageAddItem(page, (Item) btree->entry, IndexTupleSize(btree->entry), off, false, false);	if (placed != off)		elog(ERROR, "failed to add item to index page in \"%s\"",			 RelationGetRelationName(btree->index));	data.node = btree->index->rd_node;	data.blkno = BufferGetBlockNumber(buf);	data.offset = off;	data.nitem = 1;	data.isDelete = btree->isDelete;	data.isData = false;	data.isLeaf = GinPageIsLeaf(page) ? TRUE : FALSE;	/*	 * Prevent full page write if child's split occurs. That is needed to	 * remove incomplete splits while replaying WAL	 *	 * data.updateBlkno contains new block number (of newly created right	 * page) for recently splited page.	 */	if (data.updateBlkno == InvalidBlockNumber)	{		rdata[0].buffer = buf;		rdata[0].buffer_std = TRUE;		rdata[0].data = NULL;		rdata[0].len = 0;		rdata[0].next = &rdata[1];		cnt++;	}	rdata[cnt].buffer = InvalidBuffer;	rdata[cnt].data = (char *) &data;	rdata[cnt].len = sizeof(ginxlogInsert);	rdata[cnt].next = &rdata[cnt + 1];	cnt++;	rdata[cnt].buffer = InvalidBuffer;	rdata[cnt].data = (char *) btree->entry;	rdata[cnt].len = IndexTupleSize(btree->entry);	rdata[cnt].next = NULL;	btree->entry = NULL;}/* * Returns new tuple with copied value from source tuple. * New tuple will not store posting list */static IndexTuplecopyIndexTuple(IndexTuple itup, Page page){	IndexTuple	nitup;	if (GinPageIsLeaf(page) && !GinIsPostingTree(itup))	{		nitup = (IndexTuple) palloc(MAXALIGN(GinGetOrigSizePosting(itup)));		memcpy(nitup, itup, GinGetOrigSizePosting(itup));		nitup->t_info &= ~INDEX_SIZE_MASK;		nitup->t_info |= GinGetOrigSizePosting(itup);	}	else	{		nitup = (IndexTuple) palloc(MAXALIGN(IndexTupleSize(itup)));		memcpy(nitup, itup, IndexTupleSize(itup));	}	return nitup;}/* * Place tuple and split page, original buffer(lbuf) leaves untouched, * returns shadow page of lbuf filled new data. * Tuples are distributed between pages by equal size on its, not * an equal number! */static PageentrySplitPage(GinBtree btree, Buffer lbuf, Buffer rbuf, OffsetNumber off, XLogRecData **prdata){	static XLogRecData rdata[2];	OffsetNumber i,				maxoff,				separator = InvalidOffsetNumber;	Size		totalsize = 0;	Size		lsize = 0,				size;	static char tupstore[2 * BLCKSZ];	char	   *ptr;	IndexTuple	itup,				leftrightmost = NULL;	static ginxlogSplit data;	Page		page;	Page		lpage = GinPageGetCopyPage(BufferGetPage(lbuf));	Page		rpage = BufferGetPage(rbuf);	Size		pageSize = PageGetPageSize(lpage);	*prdata = rdata;	data.leftChildBlkno = (GinPageIsLeaf(lpage)) ?		InvalidOffsetNumber : GinItemPointerGetBlockNumber(&(btree->entry->t_tid));	data.updateBlkno = entryPreparePage(btree, lpage, off);	maxoff = PageGetMaxOffsetNumber(lpage);	ptr = tupstore;	for (i = FirstOffsetNumber; i <= maxoff; i++)	{		if (i == off)		{			size = MAXALIGN(IndexTupleSize(btree->entry));			memcpy(ptr, btree->entry, size);			ptr += size;			totalsize += size + sizeof(ItemIdData);		}		itup = (IndexTuple) PageGetItem(lpage, PageGetItemId(lpage, i));		size = MAXALIGN(IndexTupleSize(itup));		memcpy(ptr, itup, size);		ptr += size;		totalsize += size + sizeof(ItemIdData);	}	if (off == maxoff + 1)	{		size = MAXALIGN(IndexTupleSize(btree->entry));		memcpy(ptr, btree->entry, size);		ptr += size;		totalsize += size + sizeof(ItemIdData);	}	GinInitPage(rpage, GinPageGetOpaque(lpage)->flags, pageSize);	GinInitPage(lpage, GinPageGetOpaque(rpage)->flags, pageSize);	ptr = tupstore;	maxoff++;	lsize = 0;	page = lpage;	for (i = FirstOffsetNumber; i <= maxoff; i++)	{		itup = (IndexTuple) ptr;		if (lsize > totalsize / 2)		{			if (separator == InvalidOffsetNumber)				separator = i - 1;			page = rpage;		}		else		{			leftrightmost = itup;			lsize += MAXALIGN(IndexTupleSize(itup)) + sizeof(ItemIdData);		}		if (PageAddItem(page, (Item) itup, IndexTupleSize(itup), InvalidOffsetNumber, false, false) == InvalidOffsetNumber)			elog(ERROR, "failed to add item to index page in \"%s\"",				 RelationGetRelationName(btree->index));		ptr += MAXALIGN(IndexTupleSize(itup));	}	btree->entry = copyIndexTuple(leftrightmost, lpage);	ItemPointerSet(&(btree->entry)->t_tid, BufferGetBlockNumber(lbuf), InvalidOffsetNumber);	btree->rightblkno = BufferGetBlockNumber(rbuf);	data.node = btree->index->rd_node;	data.rootBlkno = InvalidBlockNumber;	data.lblkno = BufferGetBlockNumber(lbuf);	data.rblkno = BufferGetBlockNumber(rbuf);	data.separator = separator;	data.nitem = maxoff;	data.isData = FALSE;	data.isLeaf = GinPageIsLeaf(lpage) ? TRUE : FALSE;	data.isRootSplit = FALSE;	rdata[0].buffer = InvalidBuffer;	rdata[0].data = (char *) &data;	rdata[0].len = sizeof(ginxlogSplit);	rdata[0].next = &rdata[1];	rdata[1].buffer = InvalidBuffer;	rdata[1].data = tupstore;	rdata[1].len = MAXALIGN(totalsize);	rdata[1].next = NULL;	return lpage;}/* * return newly allocate rightmost tuple */IndexTupleginPageGetLinkItup(Buffer buf){	IndexTuple	itup,				nitup;	Page		page = BufferGetPage(buf);	itup = getRightMostTuple(page);	nitup = copyIndexTuple(itup, page);	ItemPointerSet(&nitup->t_tid, BufferGetBlockNumber(buf), InvalidOffsetNumber);	return nitup;}/* * Fills new root by rightest values from child. * Also called from ginxlog, should not use btree */voidentryFillRoot(GinBtree btree, Buffer root, Buffer lbuf, Buffer rbuf){	Page		page;	IndexTuple	itup;	page = BufferGetPage(root);	itup = ginPageGetLinkItup(lbuf);	if (PageAddItem(page, (Item) itup, IndexTupleSize(itup), InvalidOffsetNumber, false, false) == InvalidOffsetNumber)		elog(ERROR, "failed to add item to index root page");	itup = ginPageGetLinkItup(rbuf);	if (PageAddItem(page, (Item) itup, IndexTupleSize(itup), InvalidOffsetNumber, false, false) == InvalidOffsetNumber)		elog(ERROR, "failed to add item to index root page");}voidprepareEntryScan(GinBtree btree, Relation index, Datum value, GinState *ginstate){	memset(btree, 0, sizeof(GinBtreeData));	btree->isMoveRight = entryIsMoveRight;	btree->findChildPage = entryLocateEntry;	btree->findItem = entryLocateLeafEntry;	btree->findChildPtr = entryFindChildPtr;	btree->getLeftMostPage = entryGetLeftMostPage;	btree->isEnoughSpace = entryIsEnoughSpace;	btree->placeToPage = entryPlaceToPage;	btree->splitPage = entrySplitPage;	btree->fillRoot = entryFillRoot;	btree->index = index;	btree->ginstate = ginstate;	btree->entryValue = value;	btree->isDelete = FALSE;	btree->searchMode = FALSE;	btree->fullScan = FALSE;	btree->isBuild = FALSE;}

⌨️ 快捷键说明

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