/* Struct of generic xlog data for single page */ typedefstruct
{
Buffer buffer; /* registered buffer */ int flags; /* flags for this buffer */ int deltaLen; /* space consumed in delta field */ char *image; /* copy of page image for modification, do not
* do it in-place to have aligned memory chunk */ char delta[MAX_DELTA_SIZE]; /* delta between page images */
} GenericXLogPageData;
/* *Stateofgenericxlogrecordconstruction.MustbeallocatedatanI/O *alignedaddress.
*/ struct GenericXLogState
{ /* Page images (properly aligned, must be first) */
PGIOAlignedBlock images[MAX_GENERIC_XLOG_PAGES]; /* Info about each page, see above */
GenericXLogPageData pages[MAX_GENERIC_XLOG_PAGES]; bool isLogged;
};
staticvoid writeFragment(GenericXLogPageData *pageData, OffsetNumber offset,
OffsetNumber length, constchar *data); staticvoid computeRegionDelta(GenericXLogPageData *pageData, constchar *curpage, constchar *targetpage, int targetStart, int targetEnd, int validStart, int validEnd); staticvoid computeDelta(GenericXLogPageData *pageData, Page curpage, Page targetpage); staticvoid applyPageRedo(Page page, constchar *delta, Size deltaSize);
/* *ComputetheXLOGfragmentsneededtotransformaregionofcurpageintothe *correspondingregionoftargetpage,andappendthemtopageData'sdelta *field.TheregiontotransformrunsfromtargetStarttotargetEnd-1. *BytesincurpageoutsidetherangevalidStarttovalidEnd-1shouldbe *consideredinvalid,andalwaysoverwrittenwithtargetdata. * *Thisfunctionisahotspot,soit'sworthbeingastenseaspossible *aboutthedata-matchingloops.
*/ staticvoid
computeRegionDelta(GenericXLogPageData *pageData, constchar *curpage, constchar *targetpage, int targetStart, int targetEnd, int validStart, int validEnd)
{ int i,
loopEnd,
fragmentBegin = -1,
fragmentEnd = -1;
/* Deal with any invalid start region by including it in first fragment */ if (validStart > targetStart)
{
fragmentBegin = targetStart;
targetStart = validStart;
}
/* We'll deal with any invalid end region after the main loop */
loopEnd = Min(targetEnd, validEnd);
/* Examine all the potentially matchable bytes */
i = targetStart; while (i < loopEnd)
{ if (curpage[i] != targetpage[i])
{ /* On unmatched byte, start new fragment if not already in one */ if (fragmentBegin < 0)
fragmentBegin = i; /* Mark unmatched-data endpoint as uncertain */
fragmentEnd = -1; /* Extend the fragment as far as possible in a tight loop */
i++; while (i < loopEnd && curpage[i] != targetpage[i])
i++; if (i >= loopEnd) break;
}
/* Found a matched byte, so remember end of unmatched fragment */
fragmentEnd = i;
/* *Extendthematchasfaraspossibleinatightloop.(Ontypical *workloads,thisinnerloopisthebulkofthisfunction'sruntime.)
*/
i++; while (i < loopEnd && curpage[i] == targetpage[i])
i++;
/* Deal with any invalid end region by including it in final fragment */ if (loopEnd < targetEnd)
{ if (fragmentBegin < 0)
fragmentBegin = loopEnd;
fragmentEnd = targetEnd;
}
/* Write final fragment if any */ if (fragmentBegin >= 0)
{ if (fragmentEnd < 0)
fragmentEnd = targetEnd;
writeFragment(pageData, fragmentBegin,
fragmentEnd - fragmentBegin,
targetpage + fragmentBegin);
}
}
/* Compute delta records for lower part of page ... */
computeRegionDelta(pageData, curpage, targetpage, 0, targetLower, 0, curLower); /* ... and for upper part, ignoring what's between */
computeRegionDelta(pageData, curpage, targetpage,
targetUpper, BLCKSZ,
curUpper, BLCKSZ);
/* Insert xlog record */
lsn = XLogInsert(RM_GENERIC_ID, 0);
/* Set LSN */ for (i = 0; i < MAX_GENERIC_XLOG_PAGES; i++)
{
GenericXLogPageData *pageData = &state->pages[i];
if (BufferIsInvalid(pageData->buffer)) continue;
PageSetLSN(BufferGetPage(pageData->buffer), lsn);
}
END_CRIT_SECTION();
} else
{ /* Unlogged relation: skip xlog-related stuff */
START_CRIT_SECTION(); for (i = 0; i < MAX_GENERIC_XLOG_PAGES; i++)
{
GenericXLogPageData *pageData = &state->pages[i];
if (BufferIsInvalid(pageData->buffer)) continue;
memcpy(BufferGetPage(pageData->buffer),
pageData->image,
BLCKSZ); /* We don't worry about zeroing the "hole" in this case */
MarkBufferDirty(pageData->buffer);
}
END_CRIT_SECTION(); /* We don't have a LSN to return, in this case */
lsn = InvalidXLogRecPtr;
}
/* Changes are done: unlock and release all buffers */ for (block_id = 0; block_id <= XLogRecMaxBlockId(record); block_id++)
{ if (BufferIsValid(buffers[block_id]))
UnlockReleaseBuffer(buffers[block_id]);
}
}
[Diese Firma untersucht Systeme, entwickelt Software und berät
Organisationen zu Themen der Informationstechnolgie. Dabei wird Wert auf anerkannte Normen und Standards gelegt.
Die Qualität eigener und fremder Produkte ist Leitlinie und Ziel zugleich.
Unter bestimmten Bedingungen finden Sie hier weiterführende Anregungen.0.19Die F&E-Firma in NorddeutschlandÜbersetzung europäischer Sprachen durch Browser2026-08-08]