Refactor the internal GIN B-tree interface for forming a downlink.

This creates a new gin-btree callback function for creating a downlink for
a page. Previously, ginxlog.c duplicated the logic used during normal
operation.
This commit is contained in:
Heikki Linnakangas 2013-11-20 16:57:41 +02:00
parent 04965ad40e
commit 501012631e
5 changed files with 38 additions and 40 deletions

View File

@ -452,6 +452,7 @@ ginInsertValue(GinBtree btree, GinBtreeStack *stack, GinStatsData *buildStats)
} }
} }
btree->prepareDownlink(btree, stack->buffer);
btree->isDelete = FALSE; btree->isDelete = FALSE;
/* search parent to lock */ /* search parent to lock */

View File

@ -580,12 +580,20 @@ dataSplitPage(GinBtree btree, Buffer lbuf, Buffer rbuf, OffsetNumber off, XLogRe
rdata[1].len = MAXALIGN(maxoff * sizeofitem); rdata[1].len = MAXALIGN(maxoff * sizeofitem);
rdata[1].next = NULL; rdata[1].next = NULL;
/* Prepare a downlink tuple for insertion to the parent */ return lpage;
}
/*
* Prepare the state in 'btree' for inserting a downlink for given buffer.
*/
static void
dataPrepareDownlink(GinBtree btree, Buffer lbuf)
{
Page lpage = BufferGetPage(lbuf);
PostingItemSetBlockNumber(&(btree->pitem), BufferGetBlockNumber(lbuf)); PostingItemSetBlockNumber(&(btree->pitem), BufferGetBlockNumber(lbuf));
btree->pitem.key = *GinDataPageGetRightBound(lpage); btree->pitem.key = *GinDataPageGetRightBound(lpage);
btree->rightblkno = BufferGetBlockNumber(rbuf); btree->rightblkno = GinPageGetOpaque(lpage)->rightlink;
return lpage;
} }
/* /*
@ -704,6 +712,7 @@ ginPrepareDataScan(GinBtree btree, Relation index)
btree->placeToPage = dataPlaceToPage; btree->placeToPage = dataPlaceToPage;
btree->splitPage = dataSplitPage; btree->splitPage = dataSplitPage;
btree->fillRoot = ginDataFillRoot; btree->fillRoot = ginDataFillRoot;
btree->prepareDownlink = dataPrepareDownlink;
btree->isData = TRUE; btree->isData = TRUE;
btree->isDelete = FALSE; btree->isDelete = FALSE;

View File

@ -570,8 +570,7 @@ entrySplitPage(GinBtree btree, Buffer lbuf, Buffer rbuf, OffsetNumber off, XLogR
Size lsize = 0, Size lsize = 0,
size; size;
char *ptr; char *ptr;
IndexTuple itup, IndexTuple itup;
leftrightmost = NULL;
Page page; Page page;
Page lpage = PageGetTempPageCopy(BufferGetPage(lbuf)); Page lpage = PageGetTempPageCopy(BufferGetPage(lbuf));
Page rpage = BufferGetPage(rbuf); Page rpage = BufferGetPage(rbuf);
@ -635,7 +634,6 @@ entrySplitPage(GinBtree btree, Buffer lbuf, Buffer rbuf, OffsetNumber off, XLogR
} }
else else
{ {
leftrightmost = itup;
lsize += MAXALIGN(IndexTupleSize(itup)) + sizeof(ItemIdData); lsize += MAXALIGN(IndexTupleSize(itup)) + sizeof(ItemIdData);
} }
@ -645,11 +643,6 @@ entrySplitPage(GinBtree btree, Buffer lbuf, Buffer rbuf, OffsetNumber off, XLogR
ptr += MAXALIGN(IndexTupleSize(itup)); ptr += MAXALIGN(IndexTupleSize(itup));
} }
btree->entry = GinFormInteriorTuple(leftrightmost, lpage,
BufferGetBlockNumber(lbuf));
btree->rightblkno = BufferGetBlockNumber(rbuf);
data.node = btree->index->rd_node; data.node = btree->index->rd_node;
data.rootBlkno = InvalidBlockNumber; data.rootBlkno = InvalidBlockNumber;
data.lblkno = BufferGetBlockNumber(lbuf); data.lblkno = BufferGetBlockNumber(lbuf);
@ -674,19 +667,20 @@ entrySplitPage(GinBtree btree, Buffer lbuf, Buffer rbuf, OffsetNumber off, XLogR
} }
/* /*
* return newly allocated rightmost tuple * Prepare the state in 'btree' for inserting a downlink for given buffer.
*/ */
IndexTuple static void
ginPageGetLinkItup(Buffer buf) entryPrepareDownlink(GinBtree btree, Buffer lbuf)
{ {
IndexTuple itup, Page lpage = BufferGetPage(lbuf);
nitup; IndexTuple itup;
Page page = BufferGetPage(buf);
itup = getRightMostTuple(page); itup = getRightMostTuple(lpage);
nitup = GinFormInteriorTuple(itup, page, BufferGetBlockNumber(buf));
return nitup; btree->entry = GinFormInteriorTuple(itup,
lpage,
BufferGetBlockNumber(lbuf));
btree->rightblkno = GinPageGetOpaque(lpage)->rightlink;
} }
/* /*
@ -696,17 +690,21 @@ ginPageGetLinkItup(Buffer buf)
void void
ginEntryFillRoot(GinBtree btree, Buffer root, Buffer lbuf, Buffer rbuf) ginEntryFillRoot(GinBtree btree, Buffer root, Buffer lbuf, Buffer rbuf)
{ {
Page page; Page page = BufferGetPage(root);
Page lpage = BufferGetPage(lbuf);
Page rpage = BufferGetPage(rbuf);
IndexTuple itup; IndexTuple itup;
page = BufferGetPage(root); itup = GinFormInteriorTuple(getRightMostTuple(lpage),
lpage,
itup = ginPageGetLinkItup(lbuf); BufferGetBlockNumber(lbuf));
if (PageAddItem(page, (Item) itup, IndexTupleSize(itup), InvalidOffsetNumber, false, false) == InvalidOffsetNumber) if (PageAddItem(page, (Item) itup, IndexTupleSize(itup), InvalidOffsetNumber, false, false) == InvalidOffsetNumber)
elog(ERROR, "failed to add item to index root page"); elog(ERROR, "failed to add item to index root page");
pfree(itup); pfree(itup);
itup = ginPageGetLinkItup(rbuf); itup = GinFormInteriorTuple(getRightMostTuple(rpage),
rpage,
BufferGetBlockNumber(rbuf));
if (PageAddItem(page, (Item) itup, IndexTupleSize(itup), InvalidOffsetNumber, false, false) == InvalidOffsetNumber) if (PageAddItem(page, (Item) itup, IndexTupleSize(itup), InvalidOffsetNumber, false, false) == InvalidOffsetNumber)
elog(ERROR, "failed to add item to index root page"); elog(ERROR, "failed to add item to index root page");
pfree(itup); pfree(itup);
@ -736,6 +734,7 @@ ginPrepareEntryScan(GinBtree btree, OffsetNumber attnum,
btree->placeToPage = entryPlaceToPage; btree->placeToPage = entryPlaceToPage;
btree->splitPage = entrySplitPage; btree->splitPage = entrySplitPage;
btree->fillRoot = ginEntryFillRoot; btree->fillRoot = ginEntryFillRoot;
btree->prepareDownlink = entryPrepareDownlink;
btree->isData = FALSE; btree->isData = FALSE;
btree->fullScan = FALSE; btree->fullScan = FALSE;

View File

@ -799,31 +799,20 @@ ginContinueSplit(ginIncompleteSplit *split)
ginPrepareEntryScan(&btree, ginPrepareEntryScan(&btree,
InvalidOffsetNumber, (Datum) 0, GIN_CAT_NULL_KEY, InvalidOffsetNumber, (Datum) 0, GIN_CAT_NULL_KEY,
&ginstate); &ginstate);
btree.entry = ginPageGetLinkItup(buffer);
} }
else else
{ {
Page page = BufferGetPage(buffer);
ginPrepareDataScan(&btree, reln); ginPrepareDataScan(&btree, reln);
PostingItemSetBlockNumber(&(btree.pitem), split->leftBlkno);
if (GinPageIsLeaf(page))
btree.pitem.key = *GinDataPageGetItemPointer(page,
GinPageGetOpaque(page)->maxoff);
else
btree.pitem.key = GinDataPageGetPostingItem(page,
GinPageGetOpaque(page)->maxoff)->key;
} }
btree.rightblkno = split->rightBlkno;
stack.blkno = split->leftBlkno; stack.blkno = split->leftBlkno;
stack.buffer = buffer; stack.buffer = buffer;
stack.off = InvalidOffsetNumber; stack.off = InvalidOffsetNumber;
stack.parent = NULL; stack.parent = NULL;
ginFindParents(&btree, &stack, split->rootBlkno); ginFindParents(&btree, &stack, split->rootBlkno);
btree.prepareDownlink(&btree, buffer);
ginInsertValue(&btree, stack.parent, NULL); ginInsertValue(&btree, stack.parent, NULL);
FreeFakeRelcacheEntry(reln); FreeFakeRelcacheEntry(reln);

View File

@ -487,6 +487,7 @@ typedef struct GinBtreeData
OffsetNumber (*findChildPtr) (GinBtree, Page, BlockNumber, OffsetNumber); OffsetNumber (*findChildPtr) (GinBtree, Page, BlockNumber, OffsetNumber);
bool (*placeToPage) (GinBtree, Buffer, OffsetNumber, XLogRecData **); bool (*placeToPage) (GinBtree, Buffer, OffsetNumber, XLogRecData **);
Page (*splitPage) (GinBtree, Buffer, Buffer, OffsetNumber, XLogRecData **); Page (*splitPage) (GinBtree, Buffer, Buffer, OffsetNumber, XLogRecData **);
void (*prepareDownlink) (GinBtree, Buffer);
void (*fillRoot) (GinBtree, Buffer, Buffer, Buffer); void (*fillRoot) (GinBtree, Buffer, Buffer, Buffer);
bool isData; bool isData;
@ -529,7 +530,6 @@ extern void ginPrepareEntryScan(GinBtree btree, OffsetNumber attnum,
Datum key, GinNullCategory category, Datum key, GinNullCategory category,
GinState *ginstate); GinState *ginstate);
extern void ginEntryFillRoot(GinBtree btree, Buffer root, Buffer lbuf, Buffer rbuf); extern void ginEntryFillRoot(GinBtree btree, Buffer root, Buffer lbuf, Buffer rbuf);
extern IndexTuple ginPageGetLinkItup(Buffer buf);
/* gindatapage.c */ /* gindatapage.c */
extern BlockNumber createPostingTree(Relation index, extern BlockNumber createPostingTree(Relation index,