summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/backend/access/gin/gindatapage.c121
-rw-r--r--src/backend/access/gin/ginget.c12
-rw-r--r--src/backend/access/gin/ginvacuum.c6
-rw-r--r--src/backend/access/gin/ginxlog.c28
-rw-r--r--src/include/access/gin_private.h11
5 files changed, 123 insertions, 55 deletions
diff --git a/src/backend/access/gin/gindatapage.c b/src/backend/access/gin/gindatapage.c
index f017de0cdc8..2c6447d7faa 100644
--- a/src/backend/access/gin/gindatapage.c
+++ b/src/backend/access/gin/gindatapage.c
@@ -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
diff --git a/src/backend/access/gin/ginget.c b/src/backend/access/gin/ginget.c
index cb17d383bc8..cb779aa7f74 100644
--- a/src/backend/access/gin/ginget.c
+++ b/src/backend/access/gin/ginget.c
@@ -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);
diff --git a/src/backend/access/gin/ginvacuum.c b/src/backend/access/gin/ginvacuum.c
index b84d3a30de3..bda9c60279a 100644
--- a/src/backend/access/gin/ginvacuum.c
+++ b/src/backend/access/gin/ginvacuum.c
@@ -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--;
diff --git a/src/backend/access/gin/ginxlog.c b/src/backend/access/gin/ginxlog.c
index 5daabb0eef9..4d0ccb876f2 100644
--- a/src/backend/access/gin/ginxlog.c
+++ b/src/backend/access/gin/ginxlog.c
@@ -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;
diff --git a/src/include/access/gin_private.h b/src/include/access/gin_private.h
index c603521c957..7af3a870c75 100644
--- a/src/include/access/gin_private.h
+++ b/src/include/access/gin_private.h
@@ -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