@@ -390,7 +390,15 @@ GinDataPageAddPostingItem(Page page, PostingItem *data, OffsetNumber offset)
390
390
}
391
391
memcpy (ptr , data , sizeof (PostingItem ));
392
392
393
- GinPageGetOpaque (page )-> maxoff ++ ;
393
+ maxoff ++ ;
394
+ GinPageGetOpaque (page )-> maxoff = maxoff ;
395
+
396
+ /*
397
+ * Also set pd_lower to the end of the posting items, to follow the
398
+ * "standard" page layout, so that we can squeeze out the unused space
399
+ * from full-page images.
400
+ */
401
+ GinDataPageSetDataSize (page , maxoff * sizeof (PostingItem ));
394
402
}
395
403
396
404
/*
@@ -409,7 +417,10 @@ GinPageDeletePostingItem(Page page, OffsetNumber offset)
409
417
GinDataPageGetPostingItem (page , offset + 1 ),
410
418
sizeof (PostingItem ) * (maxoff - offset ));
411
419
412
- GinPageGetOpaque (page )-> maxoff -- ;
420
+ maxoff -- ;
421
+ GinPageGetOpaque (page )-> maxoff = maxoff ;
422
+
423
+ GinDataPageSetDataSize (page , maxoff * sizeof (PostingItem ));
413
424
}
414
425
415
426
/*
@@ -520,7 +531,7 @@ dataPlaceToPageLeaf(GinBtree btree, Buffer buf, GinBtreeStack *stack,
520
531
* a single byte, and we can use all the free space on the old page as
521
532
* well as the new page. For simplicity, ignore segment overhead etc.
522
533
*/
523
- maxitems = Min (maxitems , freespace + GinDataLeafMaxContentSize );
534
+ maxitems = Min (maxitems , freespace + GinDataPageMaxDataSize );
524
535
}
525
536
else
526
537
{
@@ -535,7 +546,7 @@ dataPlaceToPageLeaf(GinBtree btree, Buffer buf, GinBtreeStack *stack,
535
546
int nnewsegments ;
536
547
537
548
nnewsegments = freespace / GinPostingListSegmentMaxSize ;
538
- nnewsegments += GinDataLeafMaxContentSize / GinPostingListSegmentMaxSize ;
549
+ nnewsegments += GinDataPageMaxDataSize / GinPostingListSegmentMaxSize ;
539
550
maxitems = Min (maxitems , nnewsegments * MinTuplesPerSegment );
540
551
}
541
552
@@ -648,8 +659,8 @@ dataPlaceToPageLeaf(GinBtree btree, Buffer buf, GinBtreeStack *stack,
648
659
leaf -> lastleft = dlist_prev_node (& leaf -> segments , leaf -> lastleft );
649
660
}
650
661
}
651
- Assert (leaf -> lsize <= GinDataLeafMaxContentSize );
652
- Assert (leaf -> rsize <= GinDataLeafMaxContentSize );
662
+ Assert (leaf -> lsize <= GinDataPageMaxDataSize );
663
+ Assert (leaf -> rsize <= GinDataPageMaxDataSize );
653
664
654
665
/*
655
666
* Fetch the max item in the left page's last segment; it becomes the
@@ -716,7 +727,7 @@ ginVacuumPostingTreeLeaf(Relation indexrel, Buffer buffer, GinVacuumState *gvs)
716
727
if (seginfo -> seg )
717
728
oldsegsize = SizeOfGinPostingList (seginfo -> seg );
718
729
else
719
- oldsegsize = GinDataLeafMaxContentSize ;
730
+ oldsegsize = GinDataPageMaxDataSize ;
720
731
721
732
cleaned = ginVacuumItemPointers (gvs ,
722
733
seginfo -> items ,
@@ -987,8 +998,8 @@ dataPlaceToPageLeafRecompress(Buffer buf, disassembledLeaf *leaf)
987
998
}
988
999
}
989
1000
990
- Assert (newsize <= GinDataLeafMaxContentSize );
991
- GinDataLeafPageSetPostingListSize (page , newsize );
1001
+ Assert (newsize <= GinDataPageMaxDataSize );
1002
+ GinDataPageSetDataSize (page , newsize );
992
1003
}
993
1004
994
1005
/*
@@ -1043,7 +1054,7 @@ dataPlaceToPageLeafSplit(Buffer buf, disassembledLeaf *leaf,
1043
1054
}
1044
1055
}
1045
1056
Assert (lsize == leaf -> lsize );
1046
- GinDataLeafPageSetPostingListSize (lpage , lsize );
1057
+ GinDataPageSetDataSize (lpage , lsize );
1047
1058
* GinDataPageGetRightBound (lpage ) = lbound ;
1048
1059
1049
1060
/* Copy the segments that go to the right page */
@@ -1067,7 +1078,7 @@ dataPlaceToPageLeafSplit(Buffer buf, disassembledLeaf *leaf,
1067
1078
break ;
1068
1079
}
1069
1080
Assert (rsize == leaf -> rsize );
1070
- GinDataLeafPageSetPostingListSize (rpage , rsize );
1081
+ GinDataPageSetDataSize (rpage , rsize );
1071
1082
* GinDataPageGetRightBound (rpage ) = rbound ;
1072
1083
1073
1084
/* Create WAL record */
@@ -1139,7 +1150,7 @@ dataPlaceToPageInternal(GinBtree btree, Buffer buf, GinBtreeStack *stack,
1139
1150
data .newitem = * pitem ;
1140
1151
1141
1152
rdata .buffer = buf ;
1142
- rdata .buffer_std = false ;
1153
+ rdata .buffer_std = TRUE ;
1143
1154
rdata .data = (char * ) & data ;
1144
1155
rdata .len = sizeof (ginxlogInsertDataInternal );
1145
1156
rdata .next = NULL ;
@@ -1183,6 +1194,8 @@ dataSplitPageInternal(GinBtree btree, Buffer origbuf,
1183
1194
Page oldpage = BufferGetPage (origbuf );
1184
1195
OffsetNumber off = stack -> off ;
1185
1196
int nitems = GinPageGetOpaque (oldpage )-> maxoff ;
1197
+ int nleftitems ;
1198
+ int nrightitems ;
1186
1199
Size pageSize = PageGetPageSize (oldpage );
1187
1200
ItemPointerData oldbound = * GinDataPageGetRightBound (oldpage );
1188
1201
ItemPointer bound ;
@@ -1226,17 +1239,27 @@ dataSplitPageInternal(GinBtree btree, Buffer origbuf,
1226
1239
separator = GinNonLeafDataPageGetFreeSpace (rpage ) / sizeof (PostingItem );
1227
1240
else
1228
1241
separator = nitems / 2 ;
1242
+ nleftitems = separator ;
1243
+ nrightitems = nitems - separator ;
1229
1244
1230
- memcpy (GinDataPageGetPostingItem (lpage , FirstOffsetNumber ), allitems , separator * sizeof (PostingItem ));
1231
- GinPageGetOpaque (lpage )-> maxoff = separator ;
1245
+ memcpy (GinDataPageGetPostingItem (lpage , FirstOffsetNumber ),
1246
+ allitems ,
1247
+ nleftitems * sizeof (PostingItem ));
1248
+ GinPageGetOpaque (lpage )-> maxoff = nleftitems ;
1232
1249
memcpy (GinDataPageGetPostingItem (rpage , FirstOffsetNumber ),
1233
- & allitems [separator ], (nitems - separator ) * sizeof (PostingItem ));
1234
- GinPageGetOpaque (rpage )-> maxoff = nitems - separator ;
1250
+ & allitems [separator ],
1251
+ nrightitems * sizeof (PostingItem ));
1252
+ GinPageGetOpaque (rpage )-> maxoff = nrightitems ;
1253
+
1254
+ /*
1255
+ * Also set pd_lower for both pages, like GinDataPageAddPostingItem does.
1256
+ */
1257
+ GinDataPageSetDataSize (lpage , nleftitems * sizeof (PostingItem ));
1258
+ GinDataPageSetDataSize (rpage , nrightitems * sizeof (PostingItem ));
1235
1259
1236
1260
/* set up right bound for left page */
1237
1261
bound = GinDataPageGetRightBound (lpage );
1238
- * bound = GinDataPageGetPostingItem (lpage ,
1239
- GinPageGetOpaque (lpage )-> maxoff )-> key ;
1262
+ * bound = GinDataPageGetPostingItem (lpage , nleftitems )-> key ;
1240
1263
1241
1264
/* set up right bound for right page */
1242
1265
* GinDataPageGetRightBound (rpage ) = oldbound ;
@@ -1619,7 +1642,7 @@ leafRepackItems(disassembledLeaf *leaf, ItemPointer remaining)
1619
1642
* copying to the page. Did we exceed the size that fits on one page?
1620
1643
*/
1621
1644
segsize = SizeOfGinPostingList (seginfo -> seg );
1622
- if (pgused + segsize > GinDataLeafMaxContentSize )
1645
+ if (pgused + segsize > GinDataPageMaxDataSize )
1623
1646
{
1624
1647
if (!needsplit )
1625
1648
{
@@ -1659,8 +1682,8 @@ leafRepackItems(disassembledLeaf *leaf, ItemPointer remaining)
1659
1682
else
1660
1683
leaf -> rsize = pgused ;
1661
1684
1662
- Assert (leaf -> lsize <= GinDataLeafMaxContentSize );
1663
- Assert (leaf -> rsize <= GinDataLeafMaxContentSize );
1685
+ Assert (leaf -> lsize <= GinDataPageMaxDataSize );
1686
+ Assert (leaf -> rsize <= GinDataPageMaxDataSize );
1664
1687
1665
1688
/*
1666
1689
* Make a palloc'd copy of every segment after the first modified one,
@@ -1735,7 +1758,7 @@ createPostingTree(Relation index, ItemPointerData *items, uint32 nitems,
1735
1758
GinPostingListSegmentMaxSize ,
1736
1759
& npacked );
1737
1760
segsize = SizeOfGinPostingList (segment );
1738
- if (rootsize + segsize > GinDataLeafMaxContentSize )
1761
+ if (rootsize + segsize > GinDataPageMaxDataSize )
1739
1762
break ;
1740
1763
1741
1764
memcpy (ptr , segment , segsize );
@@ -1744,7 +1767,7 @@ createPostingTree(Relation index, ItemPointerData *items, uint32 nitems,
1744
1767
nrootitems += npacked ;
1745
1768
pfree (segment );
1746
1769
}
1747
- GinDataLeafPageSetPostingListSize (tmppage , rootsize );
1770
+ GinDataPageSetDataSize (tmppage , rootsize );
1748
1771
1749
1772
/*
1750
1773
* All set. Get a new physical page, and copy the in-memory page to it.
0 commit comments