aboutsummaryrefslogtreecommitdiff
path: root/src/backend/access/heap/heapam.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/access/heap/heapam.c')
-rw-r--r--src/backend/access/heap/heapam.c73
1 files changed, 19 insertions, 54 deletions
diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c
index f081d2fe8f4..690d139fb28 100644
--- a/src/backend/access/heap/heapam.c
+++ b/src/backend/access/heap/heapam.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/access/heap/heapam.c,v 1.249.2.1 2008/03/04 19:54:13 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/access/heap/heapam.c,v 1.249.2.2 2008/03/08 21:58:07 tgl Exp $
*
*
* INTERFACE ROUTINES
@@ -3967,11 +3967,13 @@ heap_xlog_clean(XLogRecPtr lsn, XLogRecord *record, bool clean_move)
Relation reln;
Buffer buffer;
Page page;
- OffsetNumber *offnum;
OffsetNumber *end;
+ OffsetNumber *redirected;
+ OffsetNumber *nowdead;
+ OffsetNumber *nowunused;
int nredirected;
int ndead;
- int i;
+ int nunused;
if (record->xl_info & XLR_BKP_BLOCK_1)
return;
@@ -3990,61 +3992,24 @@ heap_xlog_clean(XLogRecPtr lsn, XLogRecord *record, bool clean_move)
nredirected = xlrec->nredirected;
ndead = xlrec->ndead;
- offnum = (OffsetNumber *) ((char *) xlrec + SizeOfHeapClean);
end = (OffsetNumber *) ((char *) xlrec + record->xl_len);
-
- /* Update all redirected or moved line pointers */
- for (i = 0; i < nredirected; i++)
- {
- OffsetNumber fromoff = *offnum++;
- OffsetNumber tooff = *offnum++;
- ItemId fromlp = PageGetItemId(page, fromoff);
-
- if (clean_move)
- {
- /* Physically move the "to" item to the "from" slot */
- ItemId tolp = PageGetItemId(page, tooff);
- HeapTupleHeader htup;
-
- *fromlp = *tolp;
- ItemIdSetUnused(tolp);
-
- /* We also have to clear the tuple's heap-only bit */
- Assert(ItemIdIsNormal(fromlp));
- htup = (HeapTupleHeader) PageGetItem(page, fromlp);
- Assert(HeapTupleHeaderIsHeapOnly(htup));
- HeapTupleHeaderClearHeapOnly(htup);
- }
- else
- {
- /* Just insert a REDIRECT link at fromoff */
- ItemIdSetRedirect(fromlp, tooff);
- }
- }
-
- /* Update all now-dead line pointers */
- for (i = 0; i < ndead; i++)
- {
- OffsetNumber off = *offnum++;
- ItemId lp = PageGetItemId(page, off);
-
- ItemIdSetDead(lp);
- }
-
- /* Update all now-unused line pointers */
- while (offnum < end)
- {
- OffsetNumber off = *offnum++;
- ItemId lp = PageGetItemId(page, off);
-
- ItemIdSetUnused(lp);
- }
+ redirected = (OffsetNumber *) ((char *) xlrec + SizeOfHeapClean);
+ nowdead = redirected + (nredirected * 2);
+ nowunused = nowdead + ndead;
+ nunused = (end - nowunused);
+ Assert(nunused >= 0);
+
+ /* Update all item pointers per the record, and repair fragmentation */
+ heap_page_prune_execute(reln, buffer,
+ redirected, nredirected,
+ nowdead, ndead,
+ nowunused, nunused,
+ clean_move);
/*
- * Finally, repair any fragmentation, and update the page's hint bit about
- * whether it has free pointers.
+ * Note: we don't worry about updating the page's prunability hints.
+ * At worst this will cause an extra prune cycle to occur soon.
*/
- PageRepairFragmentation(page);
PageSetLSN(page, lsn);
PageSetTLI(page, ThisTimeLineID);