summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane2017-11-03 21:21:59 +0000
committerTom Lane2017-11-03 21:21:59 +0000
commita9169f0200fc57e01cbd216bbd41c9ea3a79a7b0 (patch)
tree58e6a30aa84fae179f5469f1c0a4b1f9d5aa31f9
parent4c11d2c559e76892156fd08d6a3cf5e1848a017f (diff)
Avoid looping through line pointers twice in PageRepairFragmentation().
There doesn't seem to be any good reason to do the filling of the itemidbase[] array separately from the first traversal of the pointers. It's certainly not a win if there are any line pointers with storage, and even if there aren't, this change doesn't insert code into the part of the first loop that will be traversed in that case. So let's just merge the two loops. Yura Sokolov, reviewed by Claudio Freire Discussion: https://postgr.es/m/[email protected]
-rw-r--r--src/backend/storage/page/bufpage.c46
1 files changed, 21 insertions, 25 deletions
diff --git a/src/backend/storage/page/bufpage.c b/src/backend/storage/page/bufpage.c
index 41642eb59c..b6aa2af818 100644
--- a/src/backend/storage/page/bufpage.c
+++ b/src/backend/storage/page/bufpage.c
@@ -481,6 +481,8 @@ PageRepairFragmentation(Page page)
Offset pd_lower = ((PageHeader) page)->pd_lower;
Offset pd_upper = ((PageHeader) page)->pd_upper;
Offset pd_special = ((PageHeader) page)->pd_special;
+ itemIdSortData itemidbase[MaxHeapTuplesPerPage];
+ itemIdSort itemidptr;
ItemId lp;
int nline,
nstorage,
@@ -505,15 +507,31 @@ PageRepairFragmentation(Page page)
errmsg("corrupted page pointers: lower = %u, upper = %u, special = %u",
pd_lower, pd_upper, pd_special)));
+ /*
+ * Run through the line pointer array and collect data about live items.
+ */
nline = PageGetMaxOffsetNumber(page);
- nunused = nstorage = 0;
+ itemidptr = itemidbase;
+ nunused = totallen = 0;
for (i = FirstOffsetNumber; i <= nline; i++)
{
lp = PageGetItemId(page, i);
if (ItemIdIsUsed(lp))
{
if (ItemIdHasStorage(lp))
- nstorage++;
+ {
+ itemidptr->offsetindex = i - 1;
+ itemidptr->itemoff = ItemIdGetOffset(lp);
+ if (unlikely(itemidptr->itemoff < (int) pd_upper ||
+ itemidptr->itemoff >= (int) pd_special))
+ ereport(ERROR,
+ (errcode(ERRCODE_DATA_CORRUPTED),
+ errmsg("corrupted item pointer: %u",
+ itemidptr->itemoff)));
+ itemidptr->alignedlen = MAXALIGN(ItemIdGetLength(lp));
+ totallen += itemidptr->alignedlen;
+ itemidptr++;
+ }
}
else
{
@@ -523,6 +541,7 @@ PageRepairFragmentation(Page page)
}
}
+ nstorage = itemidptr - itemidbase;
if (nstorage == 0)
{
/* Page is completely empty, so just reset it quickly */
@@ -531,29 +550,6 @@ PageRepairFragmentation(Page page)
else
{
/* Need to compact the page the hard way */
- itemIdSortData itemidbase[MaxHeapTuplesPerPage];
- itemIdSort itemidptr = itemidbase;
-
- totallen = 0;
- for (i = 0; i < nline; i++)
- {
- lp = PageGetItemId(page, i + 1);
- if (ItemIdHasStorage(lp))
- {
- itemidptr->offsetindex = i;
- itemidptr->itemoff = ItemIdGetOffset(lp);
- if (itemidptr->itemoff < (int) pd_upper ||
- itemidptr->itemoff >= (int) pd_special)
- ereport(ERROR,
- (errcode(ERRCODE_DATA_CORRUPTED),
- errmsg("corrupted item pointer: %u",
- itemidptr->itemoff)));
- itemidptr->alignedlen = MAXALIGN(ItemIdGetLength(lp));
- totallen += itemidptr->alignedlen;
- itemidptr++;
- }
- }
-
if (totallen > (Size) (pd_special - pd_lower))
ereport(ERROR,
(errcode(ERRCODE_DATA_CORRUPTED),