]> granicus.if.org Git - postgresql/commitdiff
Refactor the internal GIN B-tree interface for forming a downlink.
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>
Wed, 20 Nov 2013 14:57:41 +0000 (16:57 +0200)
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>
Wed, 20 Nov 2013 14:57:41 +0000 (16:57 +0200)
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.

src/backend/access/gin/ginbtree.c
src/backend/access/gin/gindatapage.c
src/backend/access/gin/ginentrypage.c
src/backend/access/gin/ginxlog.c
src/include/access/gin_private.h

index 0d93c52e04326fdb1521a05f36d00fa3b06d9aaf..c4801d5cd8937fbb3977733ab756427e5b5fe847 100644 (file)
@@ -452,6 +452,7 @@ ginInsertValue(GinBtree btree, GinBtreeStack *stack, GinStatsData *buildStats)
                        }
                }
 
+               btree->prepareDownlink(btree, stack->buffer);
                btree->isDelete = FALSE;
 
                /* search parent to lock */
index 67d748bd7112bf2bad04771407579f27f9c55fc0..fbdde1dc02437b4a18b8cc0d5176b7204b553888 100644 (file)
@@ -580,12 +580,20 @@ dataSplitPage(GinBtree btree, Buffer lbuf, Buffer rbuf, OffsetNumber off, XLogRe
        rdata[1].len = MAXALIGN(maxoff * sizeofitem);
        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));
        btree->pitem.key = *GinDataPageGetRightBound(lpage);
-       btree->rightblkno = BufferGetBlockNumber(rbuf);
-
-       return lpage;
+       btree->rightblkno = GinPageGetOpaque(lpage)->rightlink;
 }
 
 /*
@@ -704,6 +712,7 @@ ginPrepareDataScan(GinBtree btree, Relation index)
        btree->placeToPage = dataPlaceToPage;
        btree->splitPage = dataSplitPage;
        btree->fillRoot = ginDataFillRoot;
+       btree->prepareDownlink = dataPrepareDownlink;
 
        btree->isData = TRUE;
        btree->isDelete = FALSE;
index a22fd32d9dab502f307719f7bc36460aa3e39e35..ec0114e7d39da2d12dbb9320a8e5f68ca6882673 100644 (file)
@@ -570,8 +570,7 @@ entrySplitPage(GinBtree btree, Buffer lbuf, Buffer rbuf, OffsetNumber off, XLogR
        Size            lsize = 0,
                                size;
        char       *ptr;
-       IndexTuple      itup,
-                               leftrightmost = NULL;
+       IndexTuple      itup;
        Page            page;
        Page            lpage = PageGetTempPageCopy(BufferGetPage(lbuf));
        Page            rpage = BufferGetPage(rbuf);
@@ -635,7 +634,6 @@ entrySplitPage(GinBtree btree, Buffer lbuf, Buffer rbuf, OffsetNumber off, XLogR
                }
                else
                {
-                       leftrightmost = itup;
                        lsize += MAXALIGN(IndexTupleSize(itup)) + sizeof(ItemIdData);
                }
 
@@ -645,11 +643,6 @@ entrySplitPage(GinBtree btree, Buffer lbuf, Buffer rbuf, OffsetNumber off, XLogR
                ptr += MAXALIGN(IndexTupleSize(itup));
        }
 
-       btree->entry = GinFormInteriorTuple(leftrightmost, lpage,
-                                                                               BufferGetBlockNumber(lbuf));
-
-       btree->rightblkno = BufferGetBlockNumber(rbuf);
-
        data.node = btree->index->rd_node;
        data.rootBlkno = InvalidBlockNumber;
        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
-ginPageGetLinkItup(Buffer buf)
+static void
+entryPrepareDownlink(GinBtree btree, Buffer lbuf)
 {
-       IndexTuple      itup,
-                               nitup;
-       Page            page = BufferGetPage(buf);
+       Page            lpage = BufferGetPage(lbuf);
+       IndexTuple      itup;
 
-       itup = getRightMostTuple(page);
-       nitup = GinFormInteriorTuple(itup, page, BufferGetBlockNumber(buf));
+       itup = getRightMostTuple(lpage);
 
-       return nitup;
+       btree->entry = GinFormInteriorTuple(itup,
+                                                                               lpage,
+                                                                               BufferGetBlockNumber(lbuf));
+       btree->rightblkno = GinPageGetOpaque(lpage)->rightlink;
 }
 
 /*
@@ -696,17 +690,21 @@ ginPageGetLinkItup(Buffer buf)
 void
 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;
 
-       page = BufferGetPage(root);
-
-       itup = ginPageGetLinkItup(lbuf);
+       itup = GinFormInteriorTuple(getRightMostTuple(lpage),
+                                                               lpage,
+                                                               BufferGetBlockNumber(lbuf));
        if (PageAddItem(page, (Item) itup, IndexTupleSize(itup), InvalidOffsetNumber, false, false) == InvalidOffsetNumber)
                elog(ERROR, "failed to add item to index root page");
        pfree(itup);
 
-       itup = ginPageGetLinkItup(rbuf);
+       itup = GinFormInteriorTuple(getRightMostTuple(rpage),
+                                                               rpage,
+                                                               BufferGetBlockNumber(rbuf));
        if (PageAddItem(page, (Item) itup, IndexTupleSize(itup), InvalidOffsetNumber, false, false) == InvalidOffsetNumber)
                elog(ERROR, "failed to add item to index root page");
        pfree(itup);
@@ -736,6 +734,7 @@ ginPrepareEntryScan(GinBtree btree, OffsetNumber attnum,
        btree->placeToPage = entryPlaceToPage;
        btree->splitPage = entrySplitPage;
        btree->fillRoot = ginEntryFillRoot;
+       btree->prepareDownlink = entryPrepareDownlink;
 
        btree->isData = FALSE;
        btree->fullScan = FALSE;
index 4d0ccb876f21f5971c2940e772ce9ffb9645f5f1..ddac34306131ef7f464f37d039233b02e45a6009 100644 (file)
@@ -799,31 +799,20 @@ ginContinueSplit(ginIncompleteSplit *split)
                ginPrepareEntryScan(&btree,
                                                        InvalidOffsetNumber, (Datum) 0, GIN_CAT_NULL_KEY,
                                                        &ginstate);
-               btree.entry = ginPageGetLinkItup(buffer);
        }
        else
        {
-               Page            page = BufferGetPage(buffer);
-
                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.buffer = buffer;
        stack.off = InvalidOffsetNumber;
        stack.parent = NULL;
 
        ginFindParents(&btree, &stack, split->rootBlkno);
+
+       btree.prepareDownlink(&btree, buffer);
        ginInsertValue(&btree, stack.parent, NULL);
 
        FreeFakeRelcacheEntry(reln);
index 7491d7cf0ca67c59ae8699552096e5280726a696..39529353d17b472c23adebc0f354bcf5ee1ac408 100644 (file)
@@ -487,6 +487,7 @@ typedef struct GinBtreeData
        OffsetNumber (*findChildPtr) (GinBtree, Page, BlockNumber, OffsetNumber);
        bool            (*placeToPage) (GinBtree, Buffer, OffsetNumber, XLogRecData **);
        Page            (*splitPage) (GinBtree, Buffer, Buffer, OffsetNumber, XLogRecData **);
+       void            (*prepareDownlink) (GinBtree, Buffer);
        void            (*fillRoot) (GinBtree, Buffer, Buffer, Buffer);
 
        bool            isData;
@@ -529,7 +530,6 @@ extern void ginPrepareEntryScan(GinBtree btree, OffsetNumber attnum,
                                        Datum key, GinNullCategory category,
                                        GinState *ginstate);
 extern void ginEntryFillRoot(GinBtree btree, Buffer root, Buffer lbuf, Buffer rbuf);
-extern IndexTuple ginPageGetLinkItup(Buffer buf);
 
 /* gindatapage.c */
 extern BlockNumber createPostingTree(Relation index,