]> granicus.if.org Git - postgresql/commitdiff
Minor GIN code refactoring.
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>
Thu, 3 Oct 2013 08:47:17 +0000 (11:47 +0300)
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>
Thu, 3 Oct 2013 08:51:31 +0000 (11:51 +0300)
It makes for cleaner code to have separate Get/Add functions for PostingItems
and ItemPointers.  A few callsites that have to deal with both types need to
be duplicated because of this, but all the callers have to know which one
they're dealing with anyway. Overall, this reduces the amount of casting
required.

Extracted from Alexander Korotkov's larger patch to change the data page
format.

src/backend/access/gin/gindatapage.c
src/backend/access/gin/ginget.c
src/backend/access/gin/ginvacuum.c
src/backend/access/gin/ginxlog.c
src/include/access/gin_private.h

index f017de0cdc8c1c257a2f8d36a7ddd82cb8a689f2..2c6447d7faa14c0c1f79feba3eb84fd7e7fcdc38 100644 (file)
@@ -105,7 +105,7 @@ dataLocateItem(GinBtree btree, GinBtreeStack *stack)
        {
                OffsetNumber mid = low + ((high - low) / 2);
 
-               pitem = (PostingItem *) GinDataPageGetItem(page, mid);
+               pitem = GinDataPageGetPostingItem(page, mid);
 
                if (mid == maxoff)
                {
@@ -117,7 +117,7 @@ dataLocateItem(GinBtree btree, GinBtreeStack *stack)
                }
                else
                {
-                       pitem = (PostingItem *) GinDataPageGetItem(page, mid);
+                       pitem = GinDataPageGetPostingItem(page, mid);
                        result = ginCompareItemPointers(btree->items + btree->curitem, &(pitem->key));
                }
 
@@ -135,7 +135,7 @@ dataLocateItem(GinBtree btree, GinBtreeStack *stack)
        Assert(high >= FirstOffsetNumber && high <= maxoff);
 
        stack->off = high;
-       pitem = (PostingItem *) GinDataPageGetItem(page, high);
+       pitem = GinDataPageGetPostingItem(page, high);
        return PostingItemGetBlockNumber(pitem);
 }
 
@@ -176,7 +176,8 @@ dataLocateLeafItem(GinBtree btree, GinBtreeStack *stack)
        {
                OffsetNumber mid = low + ((high - low) / 2);
 
-               result = ginCompareItemPointers(btree->items + btree->curitem, (ItemPointer) GinDataPageGetItem(page, mid));
+               result = ginCompareItemPointers(btree->items + btree->curitem,
+                                                                               GinDataPageGetItemPointer(page, mid));
 
                if (result == 0)
                {
@@ -210,7 +211,7 @@ dataFindChildPtr(GinBtree btree, Page page, BlockNumber blkno, OffsetNumber stor
        /* if page isn't changed, we return storedOff */
        if (storedOff >= FirstOffsetNumber && storedOff <= maxoff)
        {
-               pitem = (PostingItem *) GinDataPageGetItem(page, storedOff);
+               pitem = GinDataPageGetPostingItem(page, storedOff);
                if (PostingItemGetBlockNumber(pitem) == blkno)
                        return storedOff;
 
@@ -220,7 +221,7 @@ dataFindChildPtr(GinBtree btree, Page page, BlockNumber blkno, OffsetNumber stor
                 */
                for (i = storedOff + 1; i <= maxoff; i++)
                {
-                       pitem = (PostingItem *) GinDataPageGetItem(page, i);
+                       pitem = GinDataPageGetPostingItem(page, i);
                        if (PostingItemGetBlockNumber(pitem) == blkno)
                                return i;
                }
@@ -231,7 +232,7 @@ dataFindChildPtr(GinBtree btree, Page page, BlockNumber blkno, OffsetNumber stor
        /* last chance */
        for (i = FirstOffsetNumber; i <= maxoff; i++)
        {
-               pitem = (PostingItem *) GinDataPageGetItem(page, i);
+               pitem = GinDataPageGetPostingItem(page, i);
                if (PostingItemGetBlockNumber(pitem) == blkno)
                        return i;
        }
@@ -251,33 +252,62 @@ dataGetLeftMostPage(GinBtree btree, Page page)
        Assert(GinPageIsData(page));
        Assert(GinPageGetOpaque(page)->maxoff >= FirstOffsetNumber);
 
-       pitem = (PostingItem *) GinDataPageGetItem(page, FirstOffsetNumber);
+       pitem = GinDataPageGetPostingItem(page, FirstOffsetNumber);
        return PostingItemGetBlockNumber(pitem);
 }
 
 /*
- * add ItemPointer or PostingItem to page. data should point to
- * correct value! depending on leaf or non-leaf page
+ * add ItemPointer to a leaf page.
  */
 void
-GinDataPageAddItem(Page page, void *data, OffsetNumber offset)
+GinDataPageAddItemPointer(Page page, ItemPointer data, OffsetNumber offset)
 {
        OffsetNumber maxoff = GinPageGetOpaque(page)->maxoff;
        char       *ptr;
 
+       Assert(GinPageIsLeaf(page));
+
+       if (offset == InvalidOffsetNumber)
+       {
+               ptr = (char *) GinDataPageGetItemPointer(page, maxoff + 1);
+       }
+       else
+       {
+               ptr = (char *) GinDataPageGetItemPointer(page, offset);
+               if (maxoff + 1 - offset != 0)
+                       memmove(ptr + sizeof(ItemPointerData),
+                                       ptr,
+                                       (maxoff - offset + 1) * sizeof(ItemPointerData));
+       }
+       memcpy(ptr, data, sizeof(ItemPointerData));
+
+       GinPageGetOpaque(page)->maxoff++;
+}
+
+/*
+ * add PostingItem to a non-leaf page.
+ */
+void
+GinDataPageAddPostingItem(Page page, PostingItem *data, OffsetNumber offset)
+{
+       OffsetNumber maxoff = GinPageGetOpaque(page)->maxoff;
+       char       *ptr;
+
+       Assert(!GinPageIsLeaf(page));
+
        if (offset == InvalidOffsetNumber)
        {
-               ptr = GinDataPageGetItem(page, maxoff + 1);
+               ptr = (char *) GinDataPageGetPostingItem(page, maxoff + 1);
        }
        else
        {
-               ptr = GinDataPageGetItem(page, offset);
+               ptr = (char *) GinDataPageGetPostingItem(page, offset);
                if (maxoff + 1 - offset != 0)
-                       memmove(ptr + GinSizeOfDataPageItem(page),
+                       memmove(ptr + sizeof(PostingItem),
                                        ptr,
-                                       (maxoff - offset + 1) * GinSizeOfDataPageItem(page));
+                                       (maxoff - offset + 1) * sizeof(PostingItem));
        }
-       memcpy(ptr, data, GinSizeOfDataPageItem(page));
+       memcpy(ptr, data, sizeof(PostingItem));
 
        GinPageGetOpaque(page)->maxoff++;
 }
@@ -294,7 +324,8 @@ GinPageDeletePostingItem(Page page, OffsetNumber offset)
        Assert(offset >= FirstOffsetNumber && offset <= maxoff);
 
        if (offset != maxoff)
-               memmove(GinDataPageGetItem(page, offset), GinDataPageGetItem(page, offset + 1),
+               memmove(GinDataPageGetPostingItem(page, offset),
+                               GinDataPageGetPostingItem(page, offset + 1),
                                sizeof(PostingItem) * (maxoff - offset));
 
        GinPageGetOpaque(page)->maxoff--;
@@ -342,7 +373,7 @@ dataPrepareData(GinBtree btree, Page page, OffsetNumber off)
 
        if (!GinPageIsLeaf(page) && btree->rightblkno != InvalidBlockNumber)
        {
-               PostingItem *pitem = (PostingItem *) GinDataPageGetItem(page, off);
+               PostingItem *pitem = GinDataPageGetPostingItem(page, off);
 
                PostingItemSetBlockNumber(pitem, btree->rightblkno);
                ret = btree->rightblkno;
@@ -418,7 +449,7 @@ dataPlaceToPage(GinBtree btree, Buffer buf, OffsetNumber off, XLogRecData **prda
 
                        while (btree->curitem < btree->nitem)
                        {
-                               GinDataPageAddItem(page, btree->items + btree->curitem, off);
+                               GinDataPageAddItemPointer(page, btree->items + btree->curitem, off);
                                off++;
                                btree->curitem++;
                        }
@@ -427,12 +458,12 @@ dataPlaceToPage(GinBtree btree, Buffer buf, OffsetNumber off, XLogRecData **prda
                }
                else
                {
-                       GinDataPageAddItem(page, btree->items + btree->curitem, off);
+                       GinDataPageAddItemPointer(page, btree->items + btree->curitem, off);
                        btree->curitem++;
                }
        }
        else
-               GinDataPageAddItem(page, &(btree->pitem), off);
+               GinDataPageAddPostingItem(page, &(btree->pitem), off);
 }
 
 /*
@@ -448,6 +479,7 @@ dataSplitPage(GinBtree btree, Buffer lbuf, Buffer rbuf, OffsetNumber off, XLogRe
        OffsetNumber separator;
        ItemPointer bound;
        Page            lpage = PageGetTempPageCopy(BufferGetPage(lbuf));
+       bool            isleaf = GinPageIsLeaf(lpage);
        ItemPointerData oldbound = *GinDataPageGetRightBound(lpage);
        int                     sizeofitem = GinSizeOfDataPageItem(lpage);
        OffsetNumber maxoff = GinPageGetOpaque(lpage)->maxoff;
@@ -469,10 +501,20 @@ dataSplitPage(GinBtree btree, Buffer lbuf, Buffer rbuf, OffsetNumber off, XLogRe
                InvalidOffsetNumber : PostingItemGetBlockNumber(&(btree->pitem));
        data.updateBlkno = dataPrepareData(btree, lpage, off);
 
-       memcpy(vector, GinDataPageGetItem(lpage, FirstOffsetNumber),
-                  maxoff * sizeofitem);
+       if (isleaf)
+       {
+               memcpy(vector,
+                          GinDataPageGetItemPointer(lpage, FirstOffsetNumber),
+                          maxoff * sizeof(ItemPointerData));
+       }
+       else
+       {
+               memcpy(vector,
+                          GinDataPageGetPostingItem(lpage, FirstOffsetNumber),
+                          maxoff * sizeof(PostingItem));
+       }
 
-       if (GinPageIsLeaf(lpage) && GinPageRightMost(lpage) && off > GinPageGetOpaque(lpage)->maxoff)
+       if (isleaf && GinPageRightMost(lpage) && off > GinPageGetOpaque(lpage)->maxoff)
        {
                nCopied = 0;
                while (btree->curitem < btree->nitem &&
@@ -491,7 +533,7 @@ dataSplitPage(GinBtree btree, Buffer lbuf, Buffer rbuf, OffsetNumber off, XLogRe
                ptr = vector + (off - 1) * sizeofitem;
                if (maxoff + 1 - off != 0)
                        memmove(ptr + sizeofitem, ptr, (maxoff - off + 1) * sizeofitem);
-               if (GinPageIsLeaf(lpage))
+               if (isleaf)
                {
                        memcpy(ptr, btree->items + btree->curitem, sizeofitem);
                        btree->curitem++;
@@ -514,19 +556,32 @@ dataSplitPage(GinBtree btree, Buffer lbuf, Buffer rbuf, OffsetNumber off, XLogRe
        GinInitPage(rpage, GinPageGetOpaque(lpage)->flags, pageSize);
        GinInitPage(lpage, GinPageGetOpaque(rpage)->flags, pageSize);
 
-       memcpy(GinDataPageGetItem(lpage, FirstOffsetNumber), vector, separator * sizeofitem);
+       if (isleaf)
+               memcpy(GinDataPageGetItemPointer(lpage, FirstOffsetNumber),
+                          vector, separator * sizeof(ItemPointerData));
+       else
+               memcpy(GinDataPageGetPostingItem(lpage, FirstOffsetNumber),
+                          vector, separator * sizeof(PostingItem));
+
        GinPageGetOpaque(lpage)->maxoff = separator;
-       memcpy(GinDataPageGetItem(rpage, FirstOffsetNumber),
-                vector + separator * sizeofitem, (maxoff - separator) * sizeofitem);
+       if (isleaf)
+               memcpy(GinDataPageGetItemPointer(rpage, FirstOffsetNumber),
+                          vector + separator * sizeof(ItemPointerData),
+                          (maxoff - separator) * sizeof(ItemPointerData));
+       else
+               memcpy(GinDataPageGetPostingItem(rpage, FirstOffsetNumber),
+                          vector + separator * sizeof(PostingItem),
+                          (maxoff - separator) * sizeof(PostingItem));
+
        GinPageGetOpaque(rpage)->maxoff = maxoff - separator;
 
        PostingItemSetBlockNumber(&(btree->pitem), BufferGetBlockNumber(lbuf));
        if (GinPageIsLeaf(lpage))
-               btree->pitem.key = *(ItemPointerData *) GinDataPageGetItem(lpage,
+               btree->pitem.key = *GinDataPageGetItemPointer(lpage,
                                                                                        GinPageGetOpaque(lpage)->maxoff);
        else
-               btree->pitem.key = ((PostingItem *) GinDataPageGetItem(lpage,
-                                                                         GinPageGetOpaque(lpage)->maxoff))->key;
+               btree->pitem.key = GinDataPageGetPostingItem(lpage,
+                                                                         GinPageGetOpaque(lpage)->maxoff)->key;
        btree->rightblkno = BufferGetBlockNumber(rbuf);
 
        /* set up right bound for left page */
@@ -576,11 +631,11 @@ ginDataFillRoot(GinBtree btree, Buffer root, Buffer lbuf, Buffer rbuf)
 
        li.key = *GinDataPageGetRightBound(lpage);
        PostingItemSetBlockNumber(&li, BufferGetBlockNumber(lbuf));
-       GinDataPageAddItem(page, &li, InvalidOffsetNumber);
+       GinDataPageAddPostingItem(page, &li, InvalidOffsetNumber);
 
        ri.key = *GinDataPageGetRightBound(rpage);
        PostingItemSetBlockNumber(&ri, BufferGetBlockNumber(rbuf));
-       GinDataPageAddItem(page, &ri, InvalidOffsetNumber);
+       GinDataPageAddPostingItem(page, &ri, InvalidOffsetNumber);
 }
 
 void
index cb17d383bc845a5c922dc2cfdfdc83df2ab9eb41..cb779aa7f74e7beb4f066368413918c5eff11a9a 100644 (file)
@@ -83,7 +83,7 @@ findItemInPostingPage(Page page, ItemPointer item, OffsetNumber *off)
         */
        for (*off = FirstOffsetNumber; *off <= maxoff; (*off)++)
        {
-               res = ginCompareItemPointers(item, (ItemPointer) GinDataPageGetItem(page, *off));
+               res = ginCompareItemPointers(item, GinDataPageGetItemPointer(page, *off));
 
                if (res <= 0)
                        return true;
@@ -154,7 +154,7 @@ scanPostingTree(Relation index, GinScanEntry scanEntry,
                        GinPageGetOpaque(page)->maxoff >= FirstOffsetNumber)
                {
                        tbm_add_tuples(scanEntry->matchBitmap,
-                                  (ItemPointer) GinDataPageGetItem(page, FirstOffsetNumber),
+                                                  GinDataPageGetItemPointer(page, FirstOffsetNumber),
                                                   GinPageGetOpaque(page)->maxoff, false);
                        scanEntry->predictNumberResult += GinPageGetOpaque(page)->maxoff;
                }
@@ -467,7 +467,8 @@ restartScanEntry:
                         */
                        entry->list = (ItemPointerData *) palloc(BLCKSZ);
                        entry->nlist = GinPageGetOpaque(page)->maxoff;
-                       memcpy(entry->list, GinDataPageGetItem(page, FirstOffsetNumber),
+                       memcpy(entry->list,
+                                  GinDataPageGetItemPointer(page, FirstOffsetNumber),
                                   GinPageGetOpaque(page)->maxoff * sizeof(ItemPointerData));
 
                        LockBuffer(entry->buffer, GIN_UNLOCK);
@@ -587,8 +588,9 @@ entryGetNextItem(GinState *ginstate, GinScanEntry entry)
                                 * Found position equal to or greater than stored
                                 */
                                entry->nlist = GinPageGetOpaque(page)->maxoff;
-                               memcpy(entry->list, GinDataPageGetItem(page, FirstOffsetNumber),
-                                  GinPageGetOpaque(page)->maxoff * sizeof(ItemPointerData));
+                               memcpy(entry->list,
+                                          GinDataPageGetItemPointer(page, FirstOffsetNumber),
+                                          GinPageGetOpaque(page)->maxoff * sizeof(ItemPointerData));
 
                                LockBuffer(entry->buffer, GIN_UNLOCK);
 
index b84d3a30de39b135897355b98ba6f5c4f86d8ffb..bda9c60279ac5e30998be9af766229432516f083 100644 (file)
@@ -210,7 +210,7 @@ ginVacuumPostingTreeLeaves(GinVacuumState *gvs, BlockNumber blkno, bool isRoot,
 
                for (i = FirstOffsetNumber; i <= GinPageGetOpaque(page)->maxoff; i++)
                {
-                       PostingItem *pitem = (PostingItem *) GinDataPageGetItem(page, i);
+                       PostingItem *pitem = GinDataPageGetPostingItem(page, i);
 
                        if (ginVacuumPostingTreeLeaves(gvs, PostingItemGetBlockNumber(pitem), FALSE, NULL))
                                isChildHasVoid = TRUE;
@@ -283,7 +283,7 @@ ginDeletePage(GinVacuumState *gvs, BlockNumber deleteBlkno, BlockNumber leftBlkn
 #ifdef USE_ASSERT_CHECKING
        do
        {
-               PostingItem *tod = (PostingItem *) GinDataPageGetItem(parentPage, myoff);
+               PostingItem *tod = GinDataPageGetPostingItem(parentPage, myoff);
 
                Assert(PostingItemGetBlockNumber(tod) == deleteBlkno);
        } while (0);
@@ -422,7 +422,7 @@ ginScanToDelete(GinVacuumState *gvs, BlockNumber blkno, bool isRoot, DataPageDel
                me->blkno = blkno;
                for (i = FirstOffsetNumber; i <= GinPageGetOpaque(page)->maxoff; i++)
                {
-                       PostingItem *pitem = (PostingItem *) GinDataPageGetItem(page, i);
+                       PostingItem *pitem = GinDataPageGetPostingItem(page, i);
 
                        if (ginScanToDelete(gvs, PostingItemGetBlockNumber(pitem), FALSE, me, i))
                                i--;
index 5daabb0eef9885dda57adc9c0dd0fcdc9d2292d0..4d0ccb876f21f5971c2940e772ce9ffb9645f5f1 100644 (file)
@@ -189,7 +189,7 @@ ginRedoInsert(XLogRecPtr lsn, XLogRecord *record)
                                Assert(data->updateBlkno == InvalidBlockNumber);
 
                                for (i = 0; i < data->nitem; i++)
-                                       GinDataPageAddItem(page, items + i, data->offset + i);
+                                       GinDataPageAddItemPointer(page, &items[i], data->offset + i);
                        }
                        else
                        {
@@ -200,13 +200,13 @@ ginRedoInsert(XLogRecPtr lsn, XLogRecord *record)
                                if (data->updateBlkno != InvalidBlockNumber)
                                {
                                        /* update link to right page after split */
-                                       pitem = (PostingItem *) GinDataPageGetItem(page, data->offset);
+                                       pitem = GinDataPageGetPostingItem(page, data->offset);
                                        PostingItemSetBlockNumber(pitem, data->updateBlkno);
                                }
 
                                pitem = (PostingItem *) (XLogRecGetData(record) + sizeof(ginxlogInsert));
 
-                               GinDataPageAddItem(page, pitem, data->offset);
+                               GinDataPageAddPostingItem(page, pitem, data->offset);
                        }
                }
                else
@@ -286,22 +286,28 @@ ginRedoSplit(XLogRecPtr lsn, XLogRecord *record)
 
                for (i = 0; i < data->separator; i++)
                {
-                       GinDataPageAddItem(lpage, ptr, InvalidOffsetNumber);
+                       if (data->isLeaf)
+                               GinDataPageAddItemPointer(lpage, (ItemPointer) ptr, InvalidOffsetNumber);
+                       else
+                               GinDataPageAddPostingItem(lpage, (PostingItem *) ptr, InvalidOffsetNumber);
                        ptr += sizeofitem;
                }
 
                for (i = data->separator; i < data->nitem; i++)
                {
-                       GinDataPageAddItem(rpage, ptr, InvalidOffsetNumber);
+                       if (data->isLeaf)
+                               GinDataPageAddItemPointer(rpage, (ItemPointer) ptr, InvalidOffsetNumber);
+                       else
+                               GinDataPageAddPostingItem(rpage, (PostingItem *) ptr, InvalidOffsetNumber);
                        ptr += sizeofitem;
                }
 
                /* set up right key */
                bound = GinDataPageGetRightBound(lpage);
                if (data->isLeaf)
-                       *bound = *(ItemPointerData *) GinDataPageGetItem(lpage, GinPageGetOpaque(lpage)->maxoff);
+                       *bound = *GinDataPageGetItemPointer(lpage, GinPageGetOpaque(lpage)->maxoff);
                else
-                       *bound = ((PostingItem *) GinDataPageGetItem(lpage, GinPageGetOpaque(lpage)->maxoff))->key;
+                       *bound = GinDataPageGetPostingItem(lpage, GinPageGetOpaque(lpage)->maxoff)->key;
 
                bound = GinDataPageGetRightBound(rpage);
                *bound = data->rightbound;
@@ -803,11 +809,11 @@ ginContinueSplit(ginIncompleteSplit *split)
 
                PostingItemSetBlockNumber(&(btree.pitem), split->leftBlkno);
                if (GinPageIsLeaf(page))
-                       btree.pitem.key = *(ItemPointerData *) GinDataPageGetItem(page,
-                                                                                        GinPageGetOpaque(page)->maxoff);
+                       btree.pitem.key = *GinDataPageGetItemPointer(page,
+                                                                                                                GinPageGetOpaque(page)->maxoff);
                else
-                       btree.pitem.key = ((PostingItem *) GinDataPageGetItem(page,
-                                                                          GinPageGetOpaque(page)->maxoff))->key;
+                       btree.pitem.key = GinDataPageGetPostingItem(page,
+                                                                                                               GinPageGetOpaque(page)->maxoff)->key;
        }
 
        btree.rightblkno = split->rightBlkno;
index c603521c9574fda6331889c5034ac956f86b2cff..7af3a870c7511bd4be9bc1288fa9bbeeb48587d0 100644 (file)
@@ -232,10 +232,14 @@ typedef signed char GinNullCategory;
 #define GinDataPageGetRightBound(page) ((ItemPointer) PageGetContents(page))
 #define GinDataPageGetData(page)       \
        (PageGetContents(page) + MAXALIGN(sizeof(ItemPointerData)))
+/* non-leaf pages contain PostingItems */
+#define GinDataPageGetPostingItem(page, i)     \
+       ((PostingItem *) (GinDataPageGetData(page) + ((i)-1) * sizeof(PostingItem)))
+/* leaf pages contain ItemPointers */
+#define GinDataPageGetItemPointer(page, i)     \
+       ((ItemPointer) (GinDataPageGetData(page) + ((i)-1) * sizeof(ItemPointerData)))
 #define GinSizeOfDataPageItem(page) \
        (GinPageIsLeaf(page) ? sizeof(ItemPointerData) : sizeof(PostingItem))
-#define GinDataPageGetItem(page,i)     \
-       (GinDataPageGetData(page) + ((i)-1) * GinSizeOfDataPageItem(page))
 
 #define GinDataPageGetFreeSpace(page)  \
        (BLCKSZ - MAXALIGN(SizeOfPageHeaderData) \
@@ -534,7 +538,8 @@ extern uint32 ginMergeItemPointers(ItemPointerData *dst,
                                         ItemPointerData *a, uint32 na,
                                         ItemPointerData *b, uint32 nb);
 
-extern void GinDataPageAddItem(Page page, void *data, OffsetNumber offset);
+extern void GinDataPageAddItemPointer(Page page, ItemPointer data, OffsetNumber offset);
+extern void GinDataPageAddPostingItem(Page page, PostingItem *data, OffsetNumber offset);
 extern void GinPageDeletePostingItem(Page page, OffsetNumber offset);
 
 typedef struct