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

📄 ginxlog.c

📁 postgresql8.3.4源码,开源数据库
💻 C
📖 第 1 页 / 共 2 页
字号:
/*------------------------------------------------------------------------- * * ginxlog.c *	  WAL replay logic for inverted index. * * * 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/ginxlog.c,v 1.12 2008/01/01 19:45:46 momjian Exp $ *------------------------------------------------------------------------- */#include "postgres.h"#include "access/gin.h"#include "access/heapam.h"#include "utils/memutils.h"static MemoryContext opCtx;		/* working memory for operations */static MemoryContext topCtx;typedef struct ginIncompleteSplit{	RelFileNode node;	BlockNumber leftBlkno;	BlockNumber rightBlkno;	BlockNumber rootBlkno;} ginIncompleteSplit;static List *incomplete_splits;static voidpushIncompleteSplit(RelFileNode node, BlockNumber leftBlkno, BlockNumber rightBlkno, BlockNumber rootBlkno){	ginIncompleteSplit *split;	MemoryContextSwitchTo(topCtx);	split = palloc(sizeof(ginIncompleteSplit));	split->node = node;	split->leftBlkno = leftBlkno;	split->rightBlkno = rightBlkno;	split->rootBlkno = rootBlkno;	incomplete_splits = lappend(incomplete_splits, split);	MemoryContextSwitchTo(opCtx);}static voidforgetIncompleteSplit(RelFileNode node, BlockNumber leftBlkno, BlockNumber updateBlkno){	ListCell   *l;	foreach(l, incomplete_splits)	{		ginIncompleteSplit *split = (ginIncompleteSplit *) lfirst(l);		if (RelFileNodeEquals(node, split->node) && leftBlkno == split->leftBlkno && updateBlkno == split->rightBlkno)		{			incomplete_splits = list_delete_ptr(incomplete_splits, split);			break;		}	}}static voidginRedoCreateIndex(XLogRecPtr lsn, XLogRecord *record){	RelFileNode *node = (RelFileNode *) XLogRecGetData(record);	Relation	reln;	Buffer		buffer;	Page		page;	reln = XLogOpenRelation(*node);	buffer = XLogReadBuffer(reln, GIN_ROOT_BLKNO, true);	Assert(BufferIsValid(buffer));	page = (Page) BufferGetPage(buffer);	GinInitBuffer(buffer, GIN_LEAF);	PageSetLSN(page, lsn);	PageSetTLI(page, ThisTimeLineID);	MarkBufferDirty(buffer);	UnlockReleaseBuffer(buffer);}static voidginRedoCreatePTree(XLogRecPtr lsn, XLogRecord *record){	ginxlogCreatePostingTree *data = (ginxlogCreatePostingTree *) XLogRecGetData(record);	ItemPointerData *items = (ItemPointerData *) (XLogRecGetData(record) + sizeof(ginxlogCreatePostingTree));	Relation	reln;	Buffer		buffer;	Page		page;	reln = XLogOpenRelation(data->node);	buffer = XLogReadBuffer(reln, data->blkno, true);	Assert(BufferIsValid(buffer));	page = (Page) BufferGetPage(buffer);	GinInitBuffer(buffer, GIN_DATA | GIN_LEAF);	memcpy(GinDataPageGetData(page), items, sizeof(ItemPointerData) * data->nitem);	GinPageGetOpaque(page)->maxoff = data->nitem;	PageSetLSN(page, lsn);	PageSetTLI(page, ThisTimeLineID);	MarkBufferDirty(buffer);	UnlockReleaseBuffer(buffer);}static voidginRedoInsert(XLogRecPtr lsn, XLogRecord *record){	ginxlogInsert *data = (ginxlogInsert *) XLogRecGetData(record);	Relation	reln;	Buffer		buffer;	Page		page;	/* nothing else to do if page was backed up */	if (record->xl_info & XLR_BKP_BLOCK_1)		return;	reln = XLogOpenRelation(data->node);	buffer = XLogReadBuffer(reln, data->blkno, false);	Assert(BufferIsValid(buffer));	page = (Page) BufferGetPage(buffer);	if (data->isData)	{		Assert(data->isDelete == FALSE);		Assert(GinPageIsData(page));		if (!XLByteLE(lsn, PageGetLSN(page)))		{			if (data->isLeaf)			{				OffsetNumber i;				ItemPointerData *items = (ItemPointerData *) (XLogRecGetData(record) + sizeof(ginxlogInsert));				Assert(GinPageIsLeaf(page));				Assert(data->updateBlkno == InvalidBlockNumber);				for (i = 0; i < data->nitem; i++)					GinDataPageAddItem(page, items + i, data->offset + i);			}			else			{				PostingItem *pitem;				Assert(!GinPageIsLeaf(page));				if (data->updateBlkno != InvalidBlockNumber)				{					/* update link to right page after split */					pitem = (PostingItem *) GinDataPageGetItem(page, data->offset);					PostingItemSetBlockNumber(pitem, data->updateBlkno);				}				pitem = (PostingItem *) (XLogRecGetData(record) + sizeof(ginxlogInsert));				GinDataPageAddItem(page, pitem, data->offset);			}		}		if (!data->isLeaf && data->updateBlkno != InvalidBlockNumber)		{			PostingItem *pitem = (PostingItem *) (XLogRecGetData(record) + sizeof(ginxlogInsert));			forgetIncompleteSplit(data->node, PostingItemGetBlockNumber(pitem), data->updateBlkno);		}	}	else	{		IndexTuple	itup;		Assert(!GinPageIsData(page));		if (!XLByteLE(lsn, PageGetLSN(page)))		{			if (data->updateBlkno != InvalidBlockNumber)			{				/* update link to right page after split */				Assert(!GinPageIsLeaf(page));				Assert(data->offset >= FirstOffsetNumber && data->offset <= PageGetMaxOffsetNumber(page));				itup = (IndexTuple) PageGetItem(page, PageGetItemId(page, data->offset));				ItemPointerSet(&itup->t_tid, data->updateBlkno, InvalidOffsetNumber);			}			if (data->isDelete)			{				Assert(GinPageIsLeaf(page));				Assert(data->offset >= FirstOffsetNumber && data->offset <= PageGetMaxOffsetNumber(page));				PageIndexTupleDelete(page, data->offset);			}			itup = (IndexTuple) (XLogRecGetData(record) + sizeof(ginxlogInsert));			if (PageAddItem(page, (Item) itup, IndexTupleSize(itup), data->offset, false, false) == InvalidOffsetNumber)				elog(ERROR, "failed to add item to index page in %u/%u/%u",				  data->node.spcNode, data->node.dbNode, data->node.relNode);		}		if (!data->isLeaf && data->updateBlkno != InvalidBlockNumber)		{			itup = (IndexTuple) (XLogRecGetData(record) + sizeof(ginxlogInsert));			forgetIncompleteSplit(data->node, GinItemPointerGetBlockNumber(&itup->t_tid), data->updateBlkno);		}	}	if (!XLByteLE(lsn, PageGetLSN(page)))	{		PageSetLSN(page, lsn);		PageSetTLI(page, ThisTimeLineID);		MarkBufferDirty(buffer);	}	UnlockReleaseBuffer(buffer);}static voidginRedoSplit(XLogRecPtr lsn, XLogRecord *record){	ginxlogSplit *data = (ginxlogSplit *) XLogRecGetData(record);	Relation	reln;	Buffer		lbuffer,				rbuffer;	Page		lpage,				rpage;	uint32		flags = 0;	reln = XLogOpenRelation(data->node);	if (data->isLeaf)		flags |= GIN_LEAF;	if (data->isData)		flags |= GIN_DATA;	lbuffer = XLogReadBuffer(reln, data->lblkno, data->isRootSplit);	Assert(BufferIsValid(lbuffer));	lpage = (Page) BufferGetPage(lbuffer);	GinInitBuffer(lbuffer, flags);	rbuffer = XLogReadBuffer(reln, data->rblkno, true);	Assert(BufferIsValid(rbuffer));	rpage = (Page) BufferGetPage(rbuffer);	GinInitBuffer(rbuffer, flags);	GinPageGetOpaque(lpage)->rightlink = BufferGetBlockNumber(rbuffer);	GinPageGetOpaque(rpage)->rightlink = data->rrlink;	if (data->isData)	{		char	   *ptr = XLogRecGetData(record) + sizeof(ginxlogSplit);		Size		sizeofitem = GinSizeOfItem(lpage);		OffsetNumber i;		ItemPointer bound;		for (i = 0; i < data->separator; i++)		{			GinDataPageAddItem(lpage, ptr, InvalidOffsetNumber);			ptr += sizeofitem;		}		for (i = data->separator; i < data->nitem; i++)		{			GinDataPageAddItem(rpage, ptr, InvalidOffsetNumber);			ptr += sizeofitem;		}		/* set up right key */		bound = GinDataPageGetRightBound(lpage);		if (data->isLeaf)			*bound = *(ItemPointerData *) GinDataPageGetItem(lpage, GinPageGetOpaque(lpage)->maxoff);		else			*bound = ((PostingItem *) GinDataPageGetItem(lpage, GinPageGetOpaque(lpage)->maxoff))->key;		bound = GinDataPageGetRightBound(rpage);		*bound = data->rightbound;	}	else	{		IndexTuple	itup = (IndexTuple) (XLogRecGetData(record) + sizeof(ginxlogSplit));		OffsetNumber i;		for (i = 0; i < data->separator; i++)		{			if (PageAddItem(lpage, (Item) itup, IndexTupleSize(itup), InvalidOffsetNumber, false, false) == InvalidOffsetNumber)				elog(ERROR, "failed to add item to index page in %u/%u/%u",				  data->node.spcNode, data->node.dbNode, data->node.relNode);			itup = (IndexTuple) (((char *) itup) + MAXALIGN(IndexTupleSize(itup)));		}		for (i = data->separator; i < data->nitem; i++)		{			if (PageAddItem(rpage, (Item) itup, IndexTupleSize(itup), InvalidOffsetNumber, false, false) == InvalidOffsetNumber)				elog(ERROR, "failed to add item to index page in %u/%u/%u",				  data->node.spcNode, data->node.dbNode, data->node.relNode);			itup = (IndexTuple) (((char *) itup) + MAXALIGN(IndexTupleSize(itup)));		}	}	PageSetLSN(rpage, lsn);	PageSetTLI(rpage, ThisTimeLineID);	MarkBufferDirty(rbuffer);	PageSetLSN(lpage, lsn);

⌨️ 快捷键说明

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